batch selection changed calculations

This commit is contained in:
Matt Parker
2025-12-18 12:11:48 +10:00
parent bc5468cd64
commit f640958c7c
2 changed files with 40 additions and 14 deletions

View File

@@ -25,13 +25,12 @@ public class FileChangedService
private readonly RoslynAnalysis _roslynAnalysis; private readonly RoslynAnalysis _roslynAnalysis;
private readonly IdeOpenTabsFileManager _openTabsFileManager; private readonly IdeOpenTabsFileManager _openTabsFileManager;
private readonly AsyncBatchingWorkQueue _updateSolutionDiagnosticsQueue; private readonly AsyncBatchingWorkQueue _updateSolutionDiagnosticsQueue;
public static readonly IAsynchronousOperationListener NullListener = new AsynchronousOperationListenerProvider.NullOperationListener();
public FileChangedService(RoslynAnalysis roslynAnalysis, IdeOpenTabsFileManager openTabsFileManager) public FileChangedService(RoslynAnalysis roslynAnalysis, IdeOpenTabsFileManager openTabsFileManager)
{ {
_roslynAnalysis = roslynAnalysis; _roslynAnalysis = roslynAnalysis;
_openTabsFileManager = openTabsFileManager; _openTabsFileManager = openTabsFileManager;
_updateSolutionDiagnosticsQueue = new AsyncBatchingWorkQueue(TimeSpan.FromMilliseconds(200), ProcessBatchAsync, NullListener, CancellationToken.None); _updateSolutionDiagnosticsQueue = new AsyncBatchingWorkQueue(TimeSpan.FromMilliseconds(200), ProcessBatchAsync, IAsynchronousOperationListener.Instance, CancellationToken.None);
} }
public SharpIdeSolutionModel SolutionModel { get; set; } = null!; public SharpIdeSolutionModel SolutionModel { get; set; } = null!;
@@ -177,3 +176,12 @@ public class FileChangedService
_updateSolutionDiagnosticsQueue.AddWork(); _updateSolutionDiagnosticsQueue.AddWork();
} }
} }
public static class NullOperationListenerExtensions
{
private static readonly IAsynchronousOperationListener _nullOperationListener = new AsynchronousOperationListenerProvider.NullOperationListener();
extension(IAsynchronousOperationListener nullOperationListener)
{
public static IAsynchronousOperationListener Instance => _nullOperationListener;
}
}

View File

@@ -3,6 +3,7 @@ using Godot;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Tags; using Microsoft.CodeAnalysis.Tags;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Threading; using Microsoft.CodeAnalysis.Threading;
@@ -47,6 +48,7 @@ public partial class SharpIdeCodeEdit : CodeEdit
private bool _settingWholeDocumentTextSuppressLineEditsEvent; // A dodgy workaround - setting the whole document doesn't guarantee that the line count stayed the same etc. We are still going to have broken highlighting. TODO: Investigate getting minimal text change ranges, and change those ranges only private bool _settingWholeDocumentTextSuppressLineEditsEvent; // A dodgy workaround - setting the whole document doesn't guarantee that the line count stayed the same etc. We are still going to have broken highlighting. TODO: Investigate getting minimal text change ranges, and change those ranges only
private bool _fileDeleted; private bool _fileDeleted;
private IDisposable? _projectDiagnosticsObserveDisposable; private IDisposable? _projectDiagnosticsObserveDisposable;
private readonly AsyncBatchingWorkQueue _selectionChangedQueue;
[Inject] private readonly IdeOpenTabsFileManager _openTabsFileManager = null!; [Inject] private readonly IdeOpenTabsFileManager _openTabsFileManager = null!;
[Inject] private readonly RunService _runService = null!; [Inject] private readonly RunService _runService = null!;
@@ -69,6 +71,11 @@ public partial class SharpIdeCodeEdit : CodeEdit
"(", ",", "=", "\t", ":" "(", ",", "=", "\t", ":"
]; ];
public SharpIdeCodeEdit()
{
_selectionChangedQueue = new AsyncBatchingWorkQueue(TimeSpan.FromMilliseconds(150), ProcessSelectionChanged, IAsynchronousOperationListener.Instance, CancellationToken.None);
}
public override void _Ready() public override void _Ready()
{ {
// _filter_code_completion_candidates_impl uses these prefixes to determine where the completions menu is allowed to show. // _filter_code_completion_candidates_impl uses these prefixes to determine where the completions menu is allowed to show.
@@ -207,13 +214,16 @@ public partial class SharpIdeCodeEdit : CodeEdit
SetSymbolLookupWordAsValid(true); SetSymbolLookupWordAsValid(true);
} }
private void OnCaretChanged() private async ValueTask ProcessSelectionChanged(CancellationToken cancellationToken)
{ {
var caretPosition = GetCaretPosition(startAt1: true); if (cancellationToken.IsCancellationRequested) return;
if (HasSelection()) string? selectedText = null;
await this.InvokeAsync(() =>
{ {
// Probably should be debounced if (HasSelection() is false) return;
var selectedText = GetSelectedText(); selectedText = GetSelectedText();
});
if (string.IsNullOrWhiteSpace(selectedText)) return;
var lineBreakCount = 0; var lineBreakCount = 0;
var slashRsToRemove = 0; var slashRsToRemove = 0;
@@ -225,6 +235,14 @@ public partial class SharpIdeCodeEdit : CodeEdit
var charLength = selectedText.Length - lineBreakCount - slashRsToRemove; var charLength = selectedText.Length - lineBreakCount - slashRsToRemove;
_editorCaretPositionService.SelectionInfo = (charLength, lineBreakCount); _editorCaretPositionService.SelectionInfo = (charLength, lineBreakCount);
} }
private void OnCaretChanged()
{
var caretPosition = GetCaretPosition(startAt1: true);
if (HasSelection())
{
_selectionChangedQueue.AddWork();
}
else else
{ {
_editorCaretPositionService.SelectionInfo = null; _editorCaretPositionService.SelectionInfo = null;