mirror of
https://github.com/Stone-Red-Code/Decho.git
synced 2026-09-04 00:46:11 +02:00
Fix auto complete not working in middle of text
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user