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 IdeOpenTabsFileManager _openTabsFileManager;
private readonly AsyncBatchingWorkQueue _updateSolutionDiagnosticsQueue;
public static readonly IAsynchronousOperationListener NullListener = new AsynchronousOperationListenerProvider.NullOperationListener();
public FileChangedService(RoslynAnalysis roslynAnalysis, IdeOpenTabsFileManager openTabsFileManager)
{
_roslynAnalysis = roslynAnalysis;
_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!;
@@ -177,3 +176,12 @@ public class FileChangedService
_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.CodeActions;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Tags;
using Microsoft.CodeAnalysis.Text;
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 _fileDeleted;
private IDisposable? _projectDiagnosticsObserveDisposable;
private readonly AsyncBatchingWorkQueue _selectionChangedQueue;
[Inject] private readonly IdeOpenTabsFileManager _openTabsFileManager = null!;
[Inject] private readonly RunService _runService = null!;
@@ -69,6 +71,11 @@ public partial class SharpIdeCodeEdit : CodeEdit
"(", ",", "=", "\t", ":"
];
public SharpIdeCodeEdit()
{
_selectionChangedQueue = new AsyncBatchingWorkQueue(TimeSpan.FromMilliseconds(150), ProcessSelectionChanged, IAsynchronousOperationListener.Instance, CancellationToken.None);
}
public override void _Ready()
{
// _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(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()
{
var caretPosition = GetCaretPosition(startAt1: true);
if (HasSelection())
{
// Probably should be debounced
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);
_selectionChangedQueue.AddWork();
}
else
{