diff --git a/src/AvaloniaEdit/Editing/TextArea.cs b/src/AvaloniaEdit/Editing/TextArea.cs index e84ec39c..d45edf9e 100644 --- a/src/AvaloniaEdit/Editing/TextArea.cs +++ b/src/AvaloniaEdit/Editing/TextArea.cs @@ -1137,6 +1137,7 @@ public void RaiseScrollInvalidated(EventArgs e) private class TextAreaTextInputMethodClient : TextInputMethodClient { private TextArea _textArea; + private TextSelection _emptySelection; public TextAreaTextInputMethodClient() { @@ -1196,17 +1197,39 @@ public override TextSelection Selection { if (_textArea == null) return new TextSelection(0, 0); - return new TextSelection(_textArea.Caret.Position.Column, _textArea.Caret.Position.Column + _textArea.Selection.Length); + + if (_textArea.Selection.IsEmpty) + return _emptySelection; + + var startLocation = _textArea.Selection.StartPosition.Location; + var endLocation = _textArea.Selection.EndPosition.Location; + + var lineNumber = _textArea.Caret.Line; + var line = _textArea.Document.GetLineByNumber(lineNumber); + + var selectionStart = startLocation.Line == lineNumber + ? startLocation.Column - 1 + : line.Offset; + var selectionEnd = endLocation.Line == lineNumber + ? endLocation.Column - 1 + : line.EndOffset; + + return new TextSelection(selectionStart, selectionEnd); } set { if (_textArea == null) return; - var selection = _textArea.Selection; - if (selection.StartPosition.Line == 0) return; + var selection = _textArea.Selection; + + var lineNumber = _textArea.Caret.Line; + var start = value.Start + 1; + var end = value.End + 1; _textArea.Selection = selection.StartSelectionOrSetEndpoint( - new TextViewPosition(selection.StartPosition.Line, value.Start), - new TextViewPosition(selection.StartPosition.Line, value.End)); + new TextViewPosition(lineNumber, start), + new TextViewPosition(lineNumber, end)); + + RaiseSelectionChanged(); } } @@ -1215,6 +1238,7 @@ public void SetTextArea(TextArea textArea) if (_textArea != null) { _textArea.Caret.PositionChanged -= Caret_PositionChanged; + _textArea.SelectionChanged -= TextArea_SelectionChanged; } _textArea = textArea; @@ -1222,6 +1246,7 @@ public void SetTextArea(TextArea textArea) if (_textArea != null) { _textArea.Caret.PositionChanged += Caret_PositionChanged; + _textArea.SelectionChanged += TextArea_SelectionChanged; } RaiseTextViewVisualChanged(); @@ -1231,11 +1256,30 @@ public void SetTextArea(TextArea textArea) RaiseSurroundingTextChanged(); } + private void TextArea_SelectionChanged(object sender, EventArgs e) + { + RaiseSelectionChanged(); + } + private void Caret_PositionChanged(object sender, EventArgs e) { RaiseCursorRectangleChanged(); RaiseSurroundingTextChanged(); - RaiseSelectionChanged(); + + if (_textArea.Selection.IsEmpty) + { + // We need to select something before empty selection so that the IME be able to complete/correct words + // Atleast while its working so + // Maybe this was designed for Avalonia TextBox where selection changing by two steps (start index, end index) + var currentSelectionIdx = _textArea.Caret.Position.Column - 1; + + // Raise selection step by step to new location + _emptySelection.Start = currentSelectionIdx; + RaiseSelectionChanged(); + + _emptySelection.End = currentSelectionIdx; + RaiseSelectionChanged(); + } } public override void SetPreeditText(string text)