Fix auto complete not working in middle of text

This commit is contained in:
Stone_Red
2026-08-02 23:55:24 +02:00
parent 433de54d45
commit b712ca6cc9
3 changed files with 35 additions and 11 deletions
@@ -31,7 +31,9 @@ public sealed class AutocompleteController(IEnumerable<AutocompleteProvider> pro
public int TriggerCharIndex { get; private set; }
public void Update(string text)
public int WordEndIndex { get; private set; }
public void Update(string text, int caretIndex)
{
if (string.IsNullOrEmpty(text) || _providers.Count == 0)
{
@@ -39,7 +41,8 @@ public sealed class AutocompleteController(IEnumerable<AutocompleteProvider> pro
return;
}
Match match = TriggerPattern.Match(text);
int clampedCaret = Math.Clamp(caretIndex, 0, text.Length);
Match match = TriggerPattern.Match(text[..clampedCaret]);
if (!match.Success)
{
Reset();
@@ -58,6 +61,7 @@ public sealed class AutocompleteController(IEnumerable<AutocompleteProvider> pro
ActiveProvider = provider;
FilterText = filter;
TriggerCharIndex = match.Index;
WordEndIndex = match.Index + match.Length;
List<string> items = provider.ItemsSource().ToList();
List<string> filtered = items
@@ -106,8 +106,6 @@ public sealed class MessageComposerViewModel : ViewModelBase
(draft, hasFiles, isReadOnly) =>
(!string.IsNullOrWhiteSpace(draft) || hasFiles) && !isReadOnly);
SendCommand = ReactiveCommand.Create(Send, canSend);
_ = this.WhenAnyValue(x => x.Draft).Subscribe(OnDraftChanged);
}
public void UpdateAvailableUsers(IEnumerable<UserViewModel> users)
@@ -179,17 +177,24 @@ public sealed class MessageComposerViewModel : ViewModelBase
return _commandHandler?.IsCommand(input) ?? input.StartsWith('/');
}
public void InsertAutocomplete(string item)
public int InsertAutocomplete(string item)
{
string? insertion = Autocomplete.GetInsertion(item);
if (insertion is null)
{
return;
return -1;
}
string before = Draft[..Autocomplete.TriggerCharIndex];
Draft = $"{before}{insertion}";
string after = Draft[Autocomplete.WordEndIndex..];
if (after.Length > 0 && char.IsWhiteSpace(after[0]))
{
insertion = insertion.TrimEnd();
}
Draft = $"{before}{insertion}{after}";
Autocomplete.Reset();
return before.Length + insertion.Length;
}
public void ClearReplyTarget()
@@ -226,8 +231,8 @@ public sealed class MessageComposerViewModel : ViewModelBase
: string.Empty;
}
private void OnDraftChanged(string? draft)
public void UpdateAutocomplete(string text, int caretIndex)
{
Autocomplete.Update(draft ?? string.Empty);
Autocomplete.Update(text, caretIndex);
}
}
+17 -2
View File
@@ -1,3 +1,4 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
@@ -29,6 +30,11 @@ public partial class MessageComposerView : UserControl
// Intercept Enter before the TextBox processes it (AcceptsReturn=True would insert a newline)
MessageTextBox.AddHandler(InputElement.KeyDownEvent, OnTextBoxTunnelingKeyDown, RoutingStrategies.Tunnel);
MessageTextBox.GetObservable(TextBox.TextProperty)
.Subscribe(_ => UpdateAutocomplete(MessageTextBox.Text ?? string.Empty, MessageTextBox.CaretIndex));
MessageTextBox.GetObservable(TextBox.CaretIndexProperty)
.Subscribe(_ => UpdateAutocomplete(MessageTextBox.Text ?? string.Empty, MessageTextBox.CaretIndex));
_spellChecker = new TextBoxSpellChecker(SpellCheckerConfig.Create("en_GB"));
_spellChecker.Initialize(MessageTextBox);
}
@@ -47,6 +53,12 @@ public partial class MessageComposerView : UserControl
}
}
private void UpdateAutocomplete(string text, int caretIndex)
{
MessageComposerViewModel? vm = this.GetDataContext<MessageComposerViewModel>();
vm?.UpdateAutocomplete(text, caretIndex);
}
private void OnTextBoxKeyDown(object? sender, KeyEventArgs e)
{
MessageComposerViewModel? vm = this.GetDataContext<MessageComposerViewModel>();
@@ -137,8 +149,11 @@ public partial class MessageComposerView : UserControl
return;
}
vm.InsertAutocomplete(item);
MessageTextBox.CaretIndex = MessageTextBox.Text?.Length ?? 0;
int newCaret = vm.InsertAutocomplete(item);
if (newCaret >= 0)
{
MessageTextBox.CaretIndex = newCaret;
}
_ = MessageTextBox.Focus();
}