浏览代码

LibGUI: Fix wrong cursor position after undoing `RemoveTextCommand`

When you undo some forward delete shortcuts like <Del> or <Ctrl-Del>,
the cursor will be put at the end of the text deleted, while the right
position should be the start of those text.
Xuekun Li 2 年之前
父节点
当前提交
200a4a00dd

+ 4 - 3
Userland/Libraries/LibGUI/TextDocument.cpp

@@ -963,10 +963,11 @@ void InsertTextCommand::undo()
     m_document.set_all_cursors(m_range.start());
     m_document.set_all_cursors(m_range.start());
 }
 }
 
 
-RemoveTextCommand::RemoveTextCommand(TextDocument& document, DeprecatedString const& text, TextRange const& range)
+RemoveTextCommand::RemoveTextCommand(TextDocument& document, DeprecatedString const& text, TextRange const& range, TextPosition const& original_cursor_position)
     : TextDocumentUndoCommand(document)
     : TextDocumentUndoCommand(document)
     , m_text(text)
     , m_text(text)
     , m_range(range)
     , m_range(range)
+    , m_original_cursor_position(original_cursor_position)
 {
 {
 }
 }
 
 
@@ -1006,8 +1007,8 @@ void RemoveTextCommand::redo()
 
 
 void RemoveTextCommand::undo()
 void RemoveTextCommand::undo()
 {
 {
-    auto new_cursor = m_document.insert_at(m_range.start(), m_text);
-    m_document.set_all_cursors(new_cursor);
+    m_document.insert_at(m_range.start(), m_text);
+    m_document.set_all_cursors(m_original_cursor_position);
 }
 }
 
 
 InsertLineCommand::InsertLineCommand(TextDocument& document, TextPosition cursor, DeprecatedString&& text, InsertPosition pos)
 InsertLineCommand::InsertLineCommand(TextDocument& document, TextPosition cursor, DeprecatedString&& text, InsertPosition pos)

+ 2 - 1
Userland/Libraries/LibGUI/TextDocument.h

@@ -254,7 +254,7 @@ private:
 
 
 class RemoveTextCommand : public TextDocumentUndoCommand {
 class RemoveTextCommand : public TextDocumentUndoCommand {
 public:
 public:
-    RemoveTextCommand(TextDocument&, DeprecatedString const&, TextRange const&);
+    RemoveTextCommand(TextDocument&, DeprecatedString const&, TextRange const&, TextPosition const&);
     virtual ~RemoveTextCommand() = default;
     virtual ~RemoveTextCommand() = default;
     virtual void undo() override;
     virtual void undo() override;
     virtual void redo() override;
     virtual void redo() override;
@@ -265,6 +265,7 @@ public:
 private:
 private:
     DeprecatedString m_text;
     DeprecatedString m_text;
     TextRange m_range;
     TextRange m_range;
+    TextPosition m_original_cursor_position;
 };
 };
 
 
 class InsertLineCommand : public TextDocumentUndoCommand {
 class InsertLineCommand : public TextDocumentUndoCommand {

+ 13 - 13
Userland/Libraries/LibGUI/TextEditor.cpp

@@ -1126,7 +1126,7 @@ void TextEditor::keydown_event(KeyEvent& event)
                 erase_count = grapheme_break_position - m_cursor.column();
                 erase_count = grapheme_break_position - m_cursor.column();
             }
             }
             TextRange erased_range(m_cursor, { m_cursor.line(), m_cursor.column() + erase_count });
             TextRange erased_range(m_cursor, { m_cursor.line(), m_cursor.column() + erase_count });
-            execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range);
+            execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range, erased_range.start());
             return;
             return;
         }
         }
         if (m_cursor.column() == current_line().length() && m_cursor.line() != line_count() - 1) {
         if (m_cursor.column() == current_line().length() && m_cursor.line() != line_count() - 1) {
@@ -1136,7 +1136,7 @@ void TextEditor::keydown_event(KeyEvent& event)
                 erase_count = document().first_word_break_after({ m_cursor.line() + 1, 0 }).column();
                 erase_count = document().first_word_break_after({ m_cursor.line() + 1, 0 }).column();
             }
             }
             TextRange erased_range(m_cursor, { m_cursor.line() + 1, erase_count });
             TextRange erased_range(m_cursor, { m_cursor.line() + 1, erase_count });
-            execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range);
+            execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range, erased_range.end());
             return;
             return;
         }
         }
         return;
         return;
@@ -1172,14 +1172,14 @@ void TextEditor::keydown_event(KeyEvent& event)
             // Backspace within line
             // Backspace within line
             TextRange erased_range({ m_cursor.line(), m_cursor.column() - erase_count }, m_cursor);
             TextRange erased_range({ m_cursor.line(), m_cursor.column() - erase_count }, m_cursor);
             auto erased_text = document().text_in_range(erased_range);
             auto erased_text = document().text_in_range(erased_range);
-            execute<RemoveTextCommand>(erased_text, erased_range);
+            execute<RemoveTextCommand>(erased_text, erased_range, erased_range.end());
             return;
             return;
         }
         }
         if (m_cursor.column() == 0 && m_cursor.line() != 0) {
         if (m_cursor.column() == 0 && m_cursor.line() != 0) {
             // Backspace at column 0; merge with previous line
             // Backspace at column 0; merge with previous line
             size_t previous_length = line(m_cursor.line() - 1).length();
             size_t previous_length = line(m_cursor.line() - 1).length();
             TextRange erased_range({ m_cursor.line() - 1, previous_length }, m_cursor);
             TextRange erased_range({ m_cursor.line() - 1, previous_length }, m_cursor);
-            execute<RemoveTextCommand>("\n", erased_range);
+            execute<RemoveTextCommand>("\n", erased_range, erased_range.end());
             return;
             return;
         }
         }
         return;
         return;
@@ -1278,7 +1278,7 @@ void TextEditor::unindent_line()
 void TextEditor::delete_previous_word()
 void TextEditor::delete_previous_word()
 {
 {
     TextRange to_erase(document().first_word_before(m_cursor, true), m_cursor);
     TextRange to_erase(document().first_word_before(m_cursor, true), m_cursor);
-    execute<RemoveTextCommand>(document().text_in_range(to_erase), to_erase);
+    execute<RemoveTextCommand>(document().text_in_range(to_erase), to_erase, to_erase.end());
 }
 }
 
 
 void TextEditor::delete_current_line()
 void TextEditor::delete_current_line()
@@ -1300,7 +1300,7 @@ void TextEditor::delete_current_line()
     }
     }
 
 
     TextRange erased_range(start, end);
     TextRange erased_range(start, end);
-    execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range);
+    execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range, m_cursor);
 }
 }
 
 
 void TextEditor::delete_previous_char()
 void TextEditor::delete_previous_char()
@@ -1317,14 +1317,14 @@ void TextEditor::delete_previous_char()
         to_erase.set_start({ m_cursor.line() - 1, prev_line_len });
         to_erase.set_start({ m_cursor.line() - 1, prev_line_len });
     }
     }
 
 
-    execute<RemoveTextCommand>(document().text_in_range(to_erase), to_erase);
+    execute<RemoveTextCommand>(document().text_in_range(to_erase), to_erase, to_erase.end());
 }
 }
 
 
 void TextEditor::delete_from_line_start_to_cursor()
 void TextEditor::delete_from_line_start_to_cursor()
 {
 {
     TextPosition start(m_cursor.line(), current_line().first_non_whitespace_column());
     TextPosition start(m_cursor.line(), current_line().first_non_whitespace_column());
     TextRange to_erase(start, m_cursor);
     TextRange to_erase(start, m_cursor);
-    execute<RemoveTextCommand>(document().text_in_range(to_erase), to_erase);
+    execute<RemoveTextCommand>(document().text_in_range(to_erase), to_erase, m_cursor);
 }
 }
 
 
 void TextEditor::do_delete()
 void TextEditor::do_delete()
@@ -1338,13 +1338,13 @@ void TextEditor::do_delete()
     if (m_cursor.column() < current_line().length()) {
     if (m_cursor.column() < current_line().length()) {
         // Delete within line
         // Delete within line
         TextRange erased_range(m_cursor, { m_cursor.line(), m_cursor.column() + 1 });
         TextRange erased_range(m_cursor, { m_cursor.line(), m_cursor.column() + 1 });
-        execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range);
+        execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range, erased_range.start());
         return;
         return;
     }
     }
     if (m_cursor.column() == current_line().length() && m_cursor.line() != line_count() - 1) {
     if (m_cursor.column() == current_line().length() && m_cursor.line() != line_count() - 1) {
         // Delete at end of line; merge with next line
         // Delete at end of line; merge with next line
         TextRange erased_range(m_cursor, { m_cursor.line() + 1, 0 });
         TextRange erased_range(m_cursor, { m_cursor.line() + 1, 0 });
-        execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range);
+        execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range, erased_range.start());
         return;
         return;
     }
     }
 }
 }
@@ -1755,7 +1755,7 @@ void TextEditor::delete_selection()
     auto selection = normalized_selection();
     auto selection = normalized_selection();
     auto selected = selected_text();
     auto selected = selected_text();
     m_selection.clear();
     m_selection.clear();
-    execute<RemoveTextCommand>(selected, selection);
+    execute<RemoveTextCommand>(selected, selection, selection.end());
     did_update_selection();
     did_update_selection();
     did_change();
     did_change();
     set_cursor(selection.start());
     set_cursor(selection.start());
@@ -1765,7 +1765,7 @@ void TextEditor::delete_selection()
 void TextEditor::delete_text_range(TextRange range)
 void TextEditor::delete_text_range(TextRange range)
 {
 {
     auto normalized_range = range.normalized();
     auto normalized_range = range.normalized();
-    execute<RemoveTextCommand>(document().text_in_range(normalized_range), normalized_range);
+    execute<RemoveTextCommand>(document().text_in_range(normalized_range), normalized_range, normalized_range.end());
     did_change();
     did_change();
     set_cursor(normalized_range.start());
     set_cursor(normalized_range.start());
     update();
     update();
@@ -1791,7 +1791,7 @@ void TextEditor::insert_at_cursor_or_replace_selection(StringView text)
         TextPosition start(original_cursor_position.line() - 1, 0);
         TextPosition start(original_cursor_position.line() - 1, 0);
         TextPosition end(original_cursor_position.line() - 1, clear_length);
         TextPosition end(original_cursor_position.line() - 1, clear_length);
         TextRange erased_range(start, end);
         TextRange erased_range(start, end);
-        execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range);
+        execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range, erased_range.end());
         set_cursor(original_cursor_position);
         set_cursor(original_cursor_position);
     }
     }
 }
 }