diff --git a/Models/TemplateTextElementGenerator.cs b/Models/TemplateTextElementGenerator.cs index de37667..087e5b1 100644 --- a/Models/TemplateTextElementGenerator.cs +++ b/Models/TemplateTextElementGenerator.cs @@ -537,9 +537,7 @@ private void UpdateAnchorMovementTypes() return; } - template.Anchor.MovementType = caret.VisualColumn >= template.Anchor.Column - ? AnchorMovementType.BeforeInsertion - : AnchorMovementType.AfterInsertion; + template.Anchor.MovementType = AnchorMovementType.AfterInsertion; } private void OnCaretPositionChanged(object? sender, EventArgs e) => @@ -547,23 +545,19 @@ private void OnCaretPositionChanged(object? sender, EventArgs e) => private void OnEditorKeyDown(object? sender, KeyEventArgs e) { - if (!_editor.TextArea.Selection.IsEmpty) + if (e.Key is not (Key.Back or Key.Delete) || !_editor.TextArea.Selection.IsEmpty) { return; } - var caret = _editor.TextArea.Caret; - foreach (var template in _templates.Where(item => - item.Anchor.Offset == caret.Offset || item.Anchor.Offset + item.Length == caret.Offset)) + var caretOffset = _editor.TextArea.Caret.Offset; + var wouldSplitTemplate = _templates.Any(template => + caretOffset == (e.Key == Key.Back + ? template.Anchor.Offset + template.Length + : template.Anchor.Offset)); + if (wouldSplitTemplate) { - var visuallyBefore = caret.VisualColumn < template.Anchor.Column; - var visuallyAfter = caret.VisualColumn > template.Anchor.Column; - if ((e.Key == Key.Back && !visuallyBefore) || - (e.Key == Key.Delete && !visuallyAfter)) - { - e.Handled = true; - return; - } + e.Handled = true; } } diff --git a/Tests/Behavior/Editor/TemplateTextElementGeneratorTests.cs b/Tests/Behavior/Editor/TemplateTextElementGeneratorTests.cs index a5c3b07..ca4a918 100644 --- a/Tests/Behavior/Editor/TemplateTextElementGeneratorTests.cs +++ b/Tests/Behavior/Editor/TemplateTextElementGeneratorTests.cs @@ -161,9 +161,13 @@ public void RemovingAnEarlierChoicePreservesSelectionThroughUndoAndRedo() AssertTemplateState(editor, generator, viewModel, ["Two", "Three"], 1); } - [AvaloniaFact] - public void DeleteAndBackspaceDoNotSplitATemplate() + [AvaloniaTheory] + [InlineData(1)] + [InlineData(2)] + [InlineData(6)] + public void DeleteAndBackspaceDoNotSplitATemplate(int choiceLength) { + var choice = new string('C', choiceLength); var editor = new TextEditor { Text = "BeforeAfter", @@ -172,7 +176,7 @@ public void DeleteAndBackspaceDoNotSplitATemplate() }; var generator = AttachGenerator(editor); var offset = "Before".Length; - generator.AddTemplate(offset, ["Choice"], 0); + generator.AddTemplate(offset, [choice], 0); var window = new Window { Content = editor }; window.Show(); window.UpdateLayout(); @@ -182,11 +186,48 @@ public void DeleteAndBackspaceDoNotSplitATemplate() Assert.True(editor.TextArea.Focus()); editor.CaretOffset = offset; Press(window, Key.Delete); - editor.CaretOffset = offset + "Choice".Length; + editor.CaretOffset = offset + choice.Length; Press(window, Key.Back); - Assert.Equal("BeforeChoiceAfter", editor.Text); - Assert.Equal(["Choice"], generator.ExportDocument().Content[1].Options); + Assert.Equal($"Before{choice}After", editor.Text); + Assert.Equal([choice], generator.ExportDocument().Content[1].Options); + } + finally + { + window.Close(); + } + } + + [AvaloniaTheory] + [InlineData(1)] + [InlineData(2)] + [InlineData(6)] + public void DeleteAndBackspaceStillEditTheTextAroundATemplate(int choiceLength) + { + var choice = new string('C', choiceLength); + var editor = new TextEditor + { + Text = "BeforeAfter", + Width = 600, + Height = 400 + }; + var generator = AttachGenerator(editor); + var offset = "Before".Length; + generator.AddTemplate(offset, [choice], 0); + var window = new Window { Content = editor }; + window.Show(); + window.UpdateLayout(); + + try + { + Assert.True(editor.TextArea.Focus()); + editor.CaretOffset = offset + choice.Length; + Press(window, Key.Delete); + editor.CaretOffset = offset; + Press(window, Key.Back); + + Assert.Equal($"Befor{choice}fter", editor.Text); + Assert.Equal([choice], generator.ExportDocument().Content[1].Options); } finally {