better file syncing (poorly)

This commit is contained in:
Matt Parker
2025-10-18 12:47:00 +10:00
parent 639945007b
commit 4d67503e13
4 changed files with 27 additions and 9 deletions

View File

@@ -9,6 +9,7 @@ namespace SharpIDE.Application.Features.FilePersistence;
/// Holds the in memory copies of files, and manages saving/loading them to/from disk.
public class IdeOpenTabsFileManager
{
public static IdeOpenTabsFileManager Instance { get; set; } = null!;
private ConcurrentDictionary<SharpIdeFile, Lazy<Task<string>>> _openFiles = new();
/// Implicitly 'opens' a file if not already open, and returns the text.
@@ -46,12 +47,17 @@ public class IdeOpenTabsFileManager
var newTextTaskLazy = new Lazy<Task<string>>(() => File.ReadAllTextAsync(file.Path));
_openFiles[file] = newTextTaskLazy;
var textTask = newTextTaskLazy.Value;
if (file.IsRoslynWorkspaceFile)
{
var text = await textTask;
await RoslynAnalysis.UpdateDocument(file, text);
GlobalEvents.Instance.SolutionAltered.InvokeParallelFireAndForget();
}
}
public async Task<bool> ReloadFileFromDiskIfOpenInEditor(SharpIdeFile file)
{
if (!_openFiles.ContainsKey(file)) return false;
var newTextTaskLazy = new Lazy<Task<string>>(() => File.ReadAllTextAsync(file.Path));
_openFiles[file] = newTextTaskLazy;
//var textTask = newTextTaskLazy.Value;
return true;
}
public async Task SaveFileAsync(SharpIdeFile file)

View File

@@ -1,6 +1,7 @@
using SharpIDE.Application.Features.Analysis;
using SharpIDE.Application.Features.Evaluation;
using SharpIDE.Application.Features.Events;
using SharpIDE.Application.Features.FilePersistence;
using SharpIDE.Application.Features.SolutionDiscovery;
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
@@ -38,6 +39,16 @@ public class IdeFileSavedToDiskHandler
private async Task HandleWorkspaceFileChanged(SharpIdeFile file)
{
// TODO: Don't reload from disk if we raised the change event ourselves (e.g. save from IDE). Cleanup this whole disaster
var wasOpenAndUpdated = await IdeOpenTabsFileManager.Instance.ReloadFileFromDiskIfOpenInEditor(file);
if (file.IsRoslynWorkspaceFile)
{
var fileText = wasOpenAndUpdated ?
await IdeOpenTabsFileManager.Instance.GetFileTextAsync(file) :
await File.ReadAllTextAsync(file.Path);
await RoslynAnalysis.UpdateDocument(file, fileText);
GlobalEvents.Instance.SolutionAltered.InvokeParallelFireAndForget();
}
await RoslynAnalysis.UpdateSolutionDiagnostics();
}
}

View File

@@ -60,6 +60,8 @@ public partial class SharpIdeCodeEdit : CodeEdit
{
if (_currentFile is null) return;
GD.Print("Solution altered, updating project diagnostics for current file");
var documentDiagnostics = await RoslynAnalysis.GetDocumentDiagnostics(_currentFile);
await this.InvokeAsync(() => SetDiagnostics(documentDiagnostics));
var projectDiagnostics = await RoslynAnalysis.GetProjectDiagnosticsForFile(_currentFile);
await this.InvokeAsync(() => SetProjectDiagnostics(projectDiagnostics));
}
@@ -308,7 +310,6 @@ public partial class SharpIdeCodeEdit : CodeEdit
var syntaxHighlighting = RoslynAnalysis.GetDocumentSyntaxHighlighting(_currentFile);
var razorSyntaxHighlighting = RoslynAnalysis.GetRazorDocumentSyntaxHighlighting(_currentFile);
var diagnostics = RoslynAnalysis.GetDocumentDiagnostics(_currentFile);
var slnDiagnostics = RoslynAnalysis.UpdateSolutionDiagnostics();
await Task.WhenAll(syntaxHighlighting, razorSyntaxHighlighting, diagnostics);
Callable.From(() =>
{
@@ -323,7 +324,6 @@ public partial class SharpIdeCodeEdit : CodeEdit
SetVScroll(vScroll);
EndComplexOperation();
}).CallDeferred();
await slnDiagnostics;
}
public void SetFileLinePosition(SharpIdeFileLinePosition fileLinePosition)

View File

@@ -45,11 +45,12 @@ public partial class IdeRoot : Control
GodotGlobalEvents.Instance = new GodotGlobalEvents();
GlobalEvents.Instance = new GlobalEvents();
BuildService.Instance = new BuildService(); // TODO: Sort out this mess with singletons, especially access across Application services
IdeOpenTabsFileManager.Instance = new IdeOpenTabsFileManager();
Singletons.RunService = new RunService();
Singletons.BuildService = BuildService.Instance;
Singletons.FileWatcher?.Dispose();
Singletons.FileWatcher = new IdeFileWatcher();
Singletons.OpenTabsFileManager = new IdeOpenTabsFileManager();
Singletons.OpenTabsFileManager = IdeOpenTabsFileManager.Instance;
Singletons.FileExternalChangeHandler = new IdeFileExternalChangeHandler();
Singletons.FileSavedToDiskHandler = new IdeFileSavedToDiskHandler();
}