summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorSnow <i@xkun.dev>2022-12-02 16:14:57 +0800
committerSam Atkins <atkinssj@gmail.com>2022-12-11 19:47:42 +0000
commit2f8c7b1b3094811d61b439f15b272b3a3a09d7f9 (patch)
treecd22e2883ccc63541cd18f045a115fdc4a345248 /Userland/Libraries
parente06f9174a1fa5c877ae32f0f6fe71ac5338f7fa4 (diff)
downloadserenity-2f8c7b1b3094811d61b439f15b272b3a3a09d7f9.zip
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.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibGUI/TextDocument.cpp49
-rw-r--r--Userland/Libraries/LibGUI/TextDocument.h21
-rw-r--r--Userland/Libraries/LibGUI/TextEditor.cpp11
3 files changed, 81 insertions, 0 deletions
diff --git a/Userland/Libraries/LibGUI/TextDocument.cpp b/Userland/Libraries/LibGUI/TextDocument.cpp
index abe9f2b33e..e238660af7 100644
--- a/Userland/Libraries/LibGUI/TextDocument.cpp
+++ b/Userland/Libraries/LibGUI/TextDocument.cpp
@@ -919,6 +919,55 @@ void RemoveTextCommand::undo()
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)
: TextDocumentUndoCommand(document)
, m_text(text)
diff --git a/Userland/Libraries/LibGUI/TextDocument.h b/Userland/Libraries/LibGUI/TextDocument.h
index c26bad0890..912354f04d 100644
--- a/Userland/Libraries/LibGUI/TextDocument.h
+++ b/Userland/Libraries/LibGUI/TextDocument.h
@@ -246,6 +246,27 @@ private:
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 {
public:
diff --git a/Userland/Libraries/LibGUI/TextEditor.cpp b/Userland/Libraries/LibGUI/TextEditor.cpp
index 617a73e5b1..dd3e3be72d 100644
--- a/Userland/Libraries/LibGUI/TextEditor.cpp
+++ b/Userland/Libraries/LibGUI/TextEditor.cpp
@@ -890,6 +890,17 @@ void TextEditor::keydown_event(KeyEvent& event)
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 (m_autocomplete_provider) {
try_show_autocomplete(UserRequestedAutocomplete::Yes);