From 8e037a582d3d0006799819607bfa52fe5e970fab Mon Sep 17 00:00:00 2001 From: Matt Parker <61717342+MattParkerDev@users.noreply.github.com> Date: Wed, 22 Oct 2025 21:14:32 +1000 Subject: [PATCH] set selected tab --- .../Features/CodeEditor/CodeEditorPanel.cs | 9 +++++---- .../Features/CodeEditor/SharpIdeCodeEdit.cs | 4 +++- .../Features/IdeSettings/IdeSolutionState.cs | 1 + src/SharpIDE.Godot/IdeRoot.cs | 9 +++++++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/SharpIDE.Godot/Features/CodeEditor/CodeEditorPanel.cs b/src/SharpIDE.Godot/Features/CodeEditor/CodeEditorPanel.cs index 60575e3..d489b8c 100644 --- a/src/SharpIDE.Godot/Features/CodeEditor/CodeEditorPanel.cs +++ b/src/SharpIDE.Godot/Features/CodeEditor/CodeEditorPanel.cs @@ -34,13 +34,15 @@ public partial class CodeEditorPanel : MarginContainer public override void _ExitTree() { + var selectedTabIndex = _tabContainer.CurrentTab; var thisSolution = Singletons.AppState.RecentSlns.Single(s => s.FilePath == Solution.FilePath); thisSolution.IdeSolutionState.OpenTabs = _tabContainer.GetChildren().OfType() - .Select(t => new OpenTab + .Select((t, index) => new OpenTab { FilePath = t.SharpIdeFile.Path, CaretLine = t.GetCaretLine(), - CaretColumn = t.GetCaretColumn() + CaretColumn = t.GetCaretColumn(), + IsSelected = index == selectedTabIndex }) .ToList(); } @@ -103,8 +105,7 @@ public partial class CodeEditorPanel : MarginContainer }).AddTo(newTab); // needs to be on ui thread }); - await newTab.SetSharpIdeFile(file); - if (fileLinePosition is not null) await this.InvokeAsync(() => newTab.SetFileLinePosition(fileLinePosition.Value)); + await newTab.SetSharpIdeFile(file, fileLinePosition); } private async Task OnDebuggerExecutionStopped(ExecutionStopInfo executionStopInfo) diff --git a/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs b/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs index c9c788c..9d74052 100644 --- a/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs +++ b/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit.cs @@ -334,7 +334,7 @@ public partial class SharpIdeCodeEdit : CodeEdit } // TODO: Ensure not running on UI thread - public async Task SetSharpIdeFile(SharpIdeFile file) + public async Task SetSharpIdeFile(SharpIdeFile file, SharpIdeFileLinePosition? fileLinePosition = null) { await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding); // get off the UI thread _currentFile = file; @@ -345,11 +345,13 @@ public partial class SharpIdeCodeEdit : CodeEdit var razorSyntaxHighlighting = _roslynAnalysis.GetRazorDocumentSyntaxHighlighting(_currentFile); var diagnostics = _roslynAnalysis.GetDocumentDiagnostics(_currentFile); var projectDiagnosticsForFile = _roslynAnalysis.GetProjectDiagnosticsForFile(_currentFile); + await readFileTask; var setTextTask = this.InvokeAsync(async () => { _fileChangingSuppressBreakpointToggleEvent = true; SetText(await readFileTask); _fileChangingSuppressBreakpointToggleEvent = false; + if (fileLinePosition is not null) SetFileLinePosition(fileLinePosition.Value); }); await Task.WhenAll(syntaxHighlighting, razorSyntaxHighlighting, setTextTask); // Text must be set before setting syntax highlighting await this.InvokeAsync(async () => SetSyntaxHighlightingModel(await syntaxHighlighting, await razorSyntaxHighlighting)); diff --git a/src/SharpIDE.Godot/Features/IdeSettings/IdeSolutionState.cs b/src/SharpIDE.Godot/Features/IdeSettings/IdeSolutionState.cs index 401ac55..f7c1c61 100644 --- a/src/SharpIDE.Godot/Features/IdeSettings/IdeSolutionState.cs +++ b/src/SharpIDE.Godot/Features/IdeSettings/IdeSolutionState.cs @@ -10,4 +10,5 @@ public class OpenTab public required string FilePath { get; set; } public required int CaretLine { get; set; } public required int CaretColumn { get; set; } + public required bool IsSelected { get; set; } } \ No newline at end of file diff --git a/src/SharpIDE.Godot/IdeRoot.cs b/src/SharpIDE.Godot/IdeRoot.cs index a43d548..26c9dc7 100644 --- a/src/SharpIDE.Godot/IdeRoot.cs +++ b/src/SharpIDE.Godot/IdeRoot.cs @@ -153,14 +153,19 @@ public partial class IdeRoot : Control var previousTabs = Singletons.AppState.RecentSlns.Single(s => s.FilePath == solutionModel.FilePath).IdeSolutionState.OpenTabs; var filesToOpen = previousTabs - .Select(s => (solutionModel.AllFiles.Single(f => f.Path == s.FilePath), new SharpIdeFileLinePosition(s.CaretLine, s.CaretColumn))) + .Select(s => (solutionModel.AllFiles.Single(f => f.Path == s.FilePath), new SharpIdeFileLinePosition(s.CaretLine, s.CaretColumn), s.IsSelected)) .ToList(); await this.InvokeDeferredAsync(async () => { - foreach (var (file, linePosition) in filesToOpen) + // Preserves order of tabs + foreach (var (file, linePosition, isSelected) in filesToOpen) { GodotGlobalEvents.Instance.FileExternallySelected.InvokeParallelFireAndForget(file, linePosition); + await Task.Delay(10).ConfigureAwait(false); // TODO: Do this properly - use InvokeParallelAsync, and fix FileExternallySelected waiting on syntax highlighting etc before returning } + // Select the selected tab + var selectedFile = filesToOpen.SingleOrDefault(f => f.IsSelected); + if (selectedFile.Item1 is not null) GodotGlobalEvents.Instance.FileExternallySelected.InvokeParallelFireAndForget(selectedFile.Item1, selectedFile.Item2); }); var tasks = solutionModel.AllProjects.Select(p => p.MsBuildEvaluationProjectTask).ToList();