ignore disk events for files we save

This commit is contained in:
Matt Parker
2025-10-10 00:41:37 +10:00
parent 8791a23c19
commit f65ad7f18c
4 changed files with 24 additions and 8 deletions

View File

@@ -57,7 +57,7 @@ public class IdeFileManager
if (file.IsDirty.Value is false) return;
var text = await GetFileTextAsync(file);
await File.WriteAllTextAsync(file.Path, text);
await WriteAllText(file, text);
file.IsDirty.Value = false;
}
@@ -70,10 +70,23 @@ public class IdeFileManager
}
else
{
await File.WriteAllTextAsync(file.Path, newText);
await WriteAllText(file, newText);
}
}
private static async Task WriteAllText(SharpIdeFile file, string text)
{
file.SuppressDiskChangeEvents.Value = true;
await File.WriteAllTextAsync(file.Path, text);
Console.WriteLine($"Saved file {file.Path}");
_ = Task.Delay(300).ContinueWith(_ =>
{
Console.WriteLine($"Re-enabling disk change events for {file.Path}");
file.SuppressDiskChangeEvents.Value = false;
Console.WriteLine($"Value is now {file.SuppressDiskChangeEvents.Value}");
}, CancellationToken.None, TaskContinuationOptions.RunContinuationsAsynchronously, TaskScheduler.Default);
}
public async Task SaveAllOpenFilesAsync()
{
foreach (var file in _openFiles.Keys.ToList())

View File

@@ -11,11 +11,12 @@ public class IdeFileChangeHandler
GlobalEvents.Instance.FileSystemWatcherInternal.FileChanged.Subscribe(OnFileChanged);
}
private async Task OnFileChanged(string arg)
private async Task OnFileChanged(string filePath)
{
var sharpIdeFile = SolutionModel.AllFiles.SingleOrDefault(f => f.Path == arg);
var sharpIdeFile = SolutionModel.AllFiles.SingleOrDefault(f => f.Path == filePath);
if (sharpIdeFile is null) return;
// TODO: Suppress if SharpIDE changed the file
if (sharpIdeFile.SuppressDiskChangeEvents.Value is true) return;
Console.WriteLine($"IdeFileChangeHandler: Changed - {filePath}");
await sharpIdeFile.FileContentsChangedExternallyFromDisk.InvokeParallelAsync();
}
}

View File

@@ -82,8 +82,8 @@ public sealed class IdeFileWatcher : IDisposable
// TODO: Make a note to users that they should not use files without extensions
private void HandleChanged(string fullPath)
{
if (Path.HasExtension(fullPath) is false) return;
Console.WriteLine($"FileSystemWatcher: Changed - {fullPath}");
if (Path.HasExtension(fullPath) is false) return; // we don't care about directory changes
//Console.WriteLine($"FileSystemWatcher: Changed - {fullPath}");
GlobalEvents.Instance.FileSystemWatcherInternal.FileChanged.InvokeParallelFireAndForget(fullPath);
}

View File

@@ -15,7 +15,8 @@ public class SharpIdeFile : ISharpIdeNode, IChildSharpIdeNode
public bool IsCshtmlFile => Path.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase);
public bool IsCsharpFile => Path.EndsWith(".cs", StringComparison.OrdinalIgnoreCase);
public bool IsRoslynWorkspaceFile => IsCsharpFile || IsRazorFile || IsCshtmlFile;
public required ReactiveProperty<bool> IsDirty { get; set; }
public required ReactiveProperty<bool> IsDirty { get; init; }
public required ReactiveProperty<bool> SuppressDiskChangeEvents { get; init; }
public EventWrapper<Task> FileContentsChangedExternallyFromDisk { get; } = new(() => Task.CompletedTask);
public EventWrapper<Task> FileContentsChangedExternally { get; } = new(() => Task.CompletedTask);
@@ -26,6 +27,7 @@ public class SharpIdeFile : ISharpIdeNode, IChildSharpIdeNode
Name = name;
Parent = parent;
IsDirty = new ReactiveProperty<bool>(false);
SuppressDiskChangeEvents = new ReactiveProperty<bool>(false);
allFiles.Add(this);
}
}