✨ Refresh files on external change
This commit is contained in:
@@ -13,4 +13,17 @@ public class GlobalEvents
|
||||
public EventWrapper<SharpIdeProjectModel, Task> ProjectStartedRunning { get; } = new(_ => Task.CompletedTask);
|
||||
public EventWrapper<SharpIdeProjectModel, Task> ProjectStoppedRunning { get; } = new(_ => Task.CompletedTask);
|
||||
public EventWrapper<ExecutionStopInfo, Task> DebuggerExecutionStopped { get; } = new(_ => Task.CompletedTask);
|
||||
|
||||
public FileSystemWatcherInternal FileSystemWatcherInternal { get; } = new();
|
||||
}
|
||||
|
||||
public class FileSystemWatcherInternal
|
||||
{
|
||||
public EventWrapper<string, Task> DirectoryCreated { get; } = new(_ => Task.CompletedTask);
|
||||
public EventWrapper<string, Task> DirectoryDeleted { get; } = new(_ => Task.CompletedTask);
|
||||
public EventWrapper<string, string, Task> DirectoryRenamed { get; } = new((_, _) => Task.CompletedTask);
|
||||
public EventWrapper<string, Task> FileCreated { get; } = new(_ => Task.CompletedTask);
|
||||
public EventWrapper<string, Task> FileDeleted { get; } = new(_ => Task.CompletedTask);
|
||||
public EventWrapper<string, string, Task> FileRenamed { get; } = new((_, _) => Task.CompletedTask);
|
||||
public EventWrapper<string, Task> FileChanged { get; } = new(_ => Task.CompletedTask);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,20 @@ public class IdeFileManager
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ReloadFileFromDisk(SharpIdeFile file)
|
||||
{
|
||||
if (!_openFiles.ContainsKey(file)) throw new InvalidOperationException("File is not open in memory.");
|
||||
|
||||
var newTextTaskLazy = new Lazy<Task<string>>(() => File.ReadAllTextAsync(file.Path));
|
||||
_openFiles[file] = newTextTaskLazy;
|
||||
var textTask = newTextTaskLazy.Value;
|
||||
if (file.IsRoslynWorkspaceFile)
|
||||
{
|
||||
var text = await textTask;
|
||||
RoslynAnalysis.UpdateDocument(file, text);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SaveFileAsync(SharpIdeFile file)
|
||||
{
|
||||
if (!_openFiles.ContainsKey(file)) throw new InvalidOperationException("File is not open in memory.");
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using SharpIDE.Application.Features.Events;
|
||||
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||
|
||||
namespace SharpIDE.Application.Features.FileWatching;
|
||||
|
||||
public class IdeFileChangeHandler
|
||||
{
|
||||
public SharpIdeSolutionModel SolutionModel { get; set; } = null!;
|
||||
public IdeFileChangeHandler()
|
||||
{
|
||||
GlobalEvents.Instance.FileSystemWatcherInternal.FileChanged.Subscribe(OnFileChanged);
|
||||
}
|
||||
|
||||
private async Task OnFileChanged(string arg)
|
||||
{
|
||||
var sharpIdeFile = SolutionModel.AllFiles.SingleOrDefault(f => f.Path == arg);
|
||||
if (sharpIdeFile is null) return;
|
||||
// TODO: Suppress if SharpIDE changed the file
|
||||
await sharpIdeFile.FileContentsChangedExternallyFromDisk.InvokeParallelAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using FileWatcherEx;
|
||||
using Microsoft.Extensions.FileSystemGlobbing;
|
||||
using SharpIDE.Application.Features.Events;
|
||||
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||
|
||||
namespace SharpIDE.Application.Features.FileWatching;
|
||||
@@ -62,7 +63,6 @@ public sealed class IdeFileWatcher : IDisposable
|
||||
|
||||
private void HandleRenamed(string? oldFullPath, string fullPath)
|
||||
{
|
||||
|
||||
Console.WriteLine($"FileSystemWatcher: Renamed - {oldFullPath}, {fullPath}");
|
||||
}
|
||||
|
||||
@@ -83,8 +83,8 @@ public sealed class IdeFileWatcher : IDisposable
|
||||
private void HandleChanged(string fullPath)
|
||||
{
|
||||
if (Path.HasExtension(fullPath) is false) return;
|
||||
// TODO: Handle updating the content of open files in editors
|
||||
Console.WriteLine($"FileSystemWatcher: Changed - {fullPath}");
|
||||
GlobalEvents.Instance.FileSystemWatcherInternal.FileChanged.InvokeParallelFireAndForget(fullPath);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using R3;
|
||||
using SharpIDE.Application.Features.Events;
|
||||
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||
|
||||
namespace SharpIDE.Application.Features.SolutionDiscovery;
|
||||
@@ -15,6 +16,8 @@ public class SharpIdeFile : ISharpIdeNode, IChildSharpIdeNode
|
||||
public bool IsCsharpFile => Path.EndsWith(".cs", StringComparison.OrdinalIgnoreCase);
|
||||
public bool IsRoslynWorkspaceFile => IsCsharpFile || IsRazorFile || IsCshtmlFile;
|
||||
public required ReactiveProperty<bool> IsDirty { get; set; }
|
||||
public EventWrapper<Task> FileContentsChangedExternallyFromDisk { get; } = new(() => Task.CompletedTask);
|
||||
public EventWrapper<Task> FileContentsChangedExternally { get; } = new(() => Task.CompletedTask);
|
||||
|
||||
[SetsRequiredMembers]
|
||||
internal SharpIdeFile(string fullPath, string name, IExpandableSharpIdeNode parent, ConcurrentBag<SharpIdeFile> allFiles)
|
||||
|
||||
Reference in New Issue
Block a user