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.
@@ -206,24 +213,35 @@ public partial class SharpIdeCodeEdit : CodeEdit
//SetSymbolLookupWordAsValid(valid); //SetSymbolLookupWordAsValid(valid);
SetSymbolLookupWordAsValid(true); SetSymbolLookupWordAsValid(true);
} }
private async ValueTask ProcessSelectionChanged(CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested) return;
string? selectedText = null;
await this.InvokeAsync(() =>
{
if (HasSelection() is false) return;
selectedText = GetSelectedText();
});
if (string.IsNullOrWhiteSpace(selectedText)) return;
var lineBreakCount = 0;
var slashRsToRemove = 0;
foreach (var c in selectedText.AsSpan())
{
if (c is '\n') lineBreakCount++;
else if (c is '\r') slashRsToRemove++;
}
var charLength = selectedText.Length - lineBreakCount - slashRsToRemove;
_editorCaretPositionService.SelectionInfo = (charLength, lineBreakCount);
}
private void OnCaretChanged() private void OnCaretChanged()
{ {
var caretPosition = GetCaretPosition(startAt1: true); var caretPosition = GetCaretPosition(startAt1: true);
if (HasSelection()) if (HasSelection())
{ {
// Probably should be debounced _selectionChangedQueue.AddWork();
var selectedText = GetSelectedText();
var lineBreakCount = 0;
var slashRsToRemove = 0;
foreach (var c in selectedText.AsSpan())
{
if (c is '\n') lineBreakCount++;
else if (c is '\r') slashRsToRemove++;
}
var charLength = selectedText.Length - lineBreakCount - slashRsToRemove;
_editorCaretPositionService.SelectionInfo = (charLength, lineBreakCount);
} }
else else
{ {