Selaa lähdekoodia

LibGUI: Add shortcut for inserting new line

This adds shortcut for inserting a new empty indented line
above/below current cursor position.

- <Ctrl-Return> for inserting line below.
- <Ctrl-Shift-Return> for inserting line above.
Snow 2 vuotta sitten
vanhempi
commit
2f8c7b1b30

+ 49 - 0
Userland/Libraries/LibGUI/TextDocument.cpp

@@ -919,6 +919,55 @@ void RemoveTextCommand::undo()
     m_document.set_all_cursors(new_cursor);
     m_document.set_all_cursors(new_cursor);
 }
 }
 
 
+InsertLineCommand::InsertLineCommand(TextDocument& document, TextPosition cursor, DeprecatedString&& text, InsertPosition pos)
+    : TextDocumentUndoCommand(document)
+    , m_cursor(cursor)
+    , m_text(move(text))
+    , m_pos(pos)
+{
+}
+
+void InsertLineCommand::redo()
+{
+    size_t line_number = compute_line_number();
+    m_document.insert_line(line_number, make<TextDocumentLine>(m_document, m_text));
+    m_document.set_all_cursors(TextPosition { line_number, m_document.line(line_number).length() });
+}
+
+void InsertLineCommand::undo()
+{
+    size_t line_number = compute_line_number();
+    m_document.remove_line(line_number);
+    m_document.set_all_cursors(m_cursor);
+}
+
+size_t InsertLineCommand::compute_line_number() const
+{
+    if (m_pos == InsertPosition::Above)
+        return m_cursor.line();
+
+    if (m_pos == InsertPosition::Below)
+        return m_cursor.line() + 1;
+
+    VERIFY_NOT_REACHED();
+}
+
+DeprecatedString InsertLineCommand::action_text() const
+{
+    StringBuilder action_text_builder;
+    action_text_builder.append("Insert Line"sv);
+
+    if (m_pos == InsertPosition::Above) {
+        action_text_builder.append(" (Above)"sv);
+    } else if (m_pos == InsertPosition::Below) {
+        action_text_builder.append(" (Below)"sv);
+    } else {
+        VERIFY_NOT_REACHED();
+    }
+
+    return action_text_builder.to_deprecated_string();
+}
+
 ReplaceAllTextCommand::ReplaceAllTextCommand(GUI::TextDocument& document, DeprecatedString const& text, GUI::TextRange const& range, DeprecatedString const& action_text)
 ReplaceAllTextCommand::ReplaceAllTextCommand(GUI::TextDocument& document, DeprecatedString const& text, GUI::TextRange const& range, DeprecatedString const& action_text)
     : TextDocumentUndoCommand(document)
     : TextDocumentUndoCommand(document)
     , m_text(text)
     , m_text(text)

+ 21 - 0
Userland/Libraries/LibGUI/TextDocument.h

@@ -246,6 +246,27 @@ private:
     TextRange m_range;
     TextRange m_range;
 };
 };
 
 
+class InsertLineCommand : public TextDocumentUndoCommand {
+public:
+    enum class InsertPosition {
+        Above,
+        Below,
+    };
+
+    InsertLineCommand(TextDocument&, TextPosition, DeprecatedString&&, InsertPosition);
+    virtual ~InsertLineCommand() = default;
+    virtual void undo() override;
+    virtual void redo() override;
+    virtual DeprecatedString action_text() const override;
+
+private:
+    size_t compute_line_number() const;
+
+    TextPosition m_cursor;
+    DeprecatedString m_text;
+    InsertPosition m_pos;
+};
+
 class ReplaceAllTextCommand final : public GUI::TextDocumentUndoCommand {
 class ReplaceAllTextCommand final : public GUI::TextDocumentUndoCommand {
 
 
 public:
 public:

+ 11 - 0
Userland/Libraries/LibGUI/TextEditor.cpp

@@ -890,6 +890,17 @@ void TextEditor::keydown_event(KeyEvent& event)
         try_update_autocomplete();
         try_update_autocomplete();
     } };
     } };
 
 
+    if (is_multi_line() && !event.alt() && event.ctrl() && event.key() == KeyCode::Key_Return) {
+        if (!is_editable())
+            return;
+
+        size_t indent_length = current_line().leading_spaces();
+        DeprecatedString indent = current_line().to_utf8().substring(0, indent_length);
+        auto insert_pos = event.shift() ? InsertLineCommand::InsertPosition::Above : InsertLineCommand::InsertPosition::Below;
+        execute<InsertLineCommand>(m_cursor, move(indent), insert_pos);
+        return;
+    }
+
     if (is_multi_line() && !event.shift() && !event.alt() && event.ctrl() && event.key() == KeyCode::Key_Space) {
     if (is_multi_line() && !event.shift() && !event.alt() && event.ctrl() && event.key() == KeyCode::Key_Space) {
         if (m_autocomplete_provider) {
         if (m_autocomplete_provider) {
             try_show_autocomplete(UserRequestedAutocomplete::Yes);
             try_show_autocomplete(UserRequestedAutocomplete::Yes);