From 0dec6333c39372622db01ab3b50de57a633656c6 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 14 Sep 2024 13:28:19 -0700 Subject: [PATCH 1/3] migrate TextEditor to use new text navigation keys --- docs/gui/journal.rst | 27 ++++++++------ internal/journal/text_editor.lua | 11 +++--- test/gui/journal.lua | 64 ++++++++++++++++---------------- 3 files changed, 53 insertions(+), 49 deletions(-) diff --git a/docs/gui/journal.rst b/docs/gui/journal.rst index d6004ec95..675251e24 100644 --- a/docs/gui/journal.rst +++ b/docs/gui/journal.rst @@ -8,23 +8,28 @@ gui/journal The `gui/journal` interface makes it easy to take notes and document important details for the fortresses. -With this multi-line text editor, -you can keep track of your fortress's background story, goals, notable events, -and both short-term and long-term plans. +With this multi-line text editor, you can keep track of your fortress's +background story, goals, notable events, and both short- and long-term plans. This is particularly useful when you need to take a longer break from the game. -Having detailed notes makes it much easier to resume your game after -a few weeks or months, without losing track of your progress and objectives. +Having detailed notes makes it much easier to resume your game after a few +weeks or months without losing track of your progress and objectives. Supported Features ------------------ -- Cursor Control: Navigate through text using arrow keys (left, right, up, down) for precise cursor placement. -- Fast Rewind: Use :kbd:`Ctrl` + :kbd:`Left` / :kbd:`Ctrl` + :kbd:`B` and :kbd:`Ctrl` + :kbd:`Right` / :kbd:`Ctrl` + :kbd:`F` to move the cursor one word back or forward. -- Longest X Position Memory: The cursor remembers the longest x position when moving up or down, making vertical navigation more intuitive. -- Mouse Control: Use the mouse to position the cursor within the text, providing an alternative to keyboard navigation. -- New Lines: Easily insert new lines using the :kbd:`Enter` key, supporting multiline text input. -- Text Wrapping: Text automatically wraps within the editor, ensuring lines fit within the display without manual adjustments. +- Cursor Control: Navigate through text using arrow keys (Left, Right, Up, + and Down) for precise cursor placement. +- Fast Rewind: Use :kbd:`Ctrl` + :kbd:`Left` and :kbd:`Ctrl` + :kbd:`Right` to + move the cursor one word back or forward. +- Longest X Position Memory: The cursor remembers the longest x position when + moving up or down, making vertical navigation more intuitive. +- Mouse Control: Use the mouse to position the cursor within the text, + providing an alternative to keyboard navigation. +- New Lines: Easily insert new lines using the :kbd:`Enter` key, supporting + multiline text input. +- Text Wrapping: Text automatically wraps within the editor, ensuring lines fit + within the display without manual adjustments. - Backspace Support: Use the backspace key to delete characters to the left of the cursor. - Delete Character: :kbd:`Ctrl` + :kbd:`D` deletes the character under the cursor. - Line Navigation: :kbd:`Ctrl` + :kbd:`H` (like "Home") moves the cursor to the beginning of the current line, and :kbd:`Ctrl` + :kbd:`E` (like "End") moves it to the end. diff --git a/internal/journal/text_editor.lua b/internal/journal/text_editor.lua index cf15776d4..030668714 100644 --- a/internal/journal/text_editor.lua +++ b/internal/journal/text_editor.lua @@ -768,23 +768,23 @@ function TextEditorView:onCursorInput(keys) -- go to text end self:setCursor(#self.text + 1) return true - elseif keys.CUSTOM_CTRL_B or keys.A_MOVE_W_DOWN then + elseif keys.CUSTOM_CTRL_LEFT then -- back one word local word_start = self:wordStartOffset() self:setCursor(word_start) return true - elseif keys.CUSTOM_CTRL_F or keys.A_MOVE_E_DOWN then + elseif keys.CUSTOM_CTRL_RIGHT then -- forward one word local word_end = self:wordEndOffset() self:setCursor(word_end) return true - elseif keys.CUSTOM_CTRL_H then + elseif keys.CUSTOM_HOME then -- line start self:setCursor( self:lineStartOffset() ) return true - elseif keys.CUSTOM_CTRL_E then + elseif keys.CUSTOM_END then -- line end self:setCursor( self:lineEndOffset() @@ -878,8 +878,7 @@ function TextEditorView:onTextManipulationInput(keys) self:eraseSelection() return true - elseif keys.CUSTOM_CTRL_D then - -- delete char, there is no support for `Delete` key + elseif keys.CUSTOM_DELETE then self.history:store(HISTORY_ENTRY.DELETE, self.text, self.cursor) if (self:hasSelection()) then diff --git a/test/gui/journal.lua b/test/gui/journal.lua index d845aef20..b73a37a9a 100644 --- a/test/gui/journal.lua +++ b/test/gui/journal.lua @@ -772,7 +772,7 @@ function test.handle_delete() text_area:setCursor(1) journal:onRender() - simulate_input_keys('CUSTOM_CTRL_D') + simulate_input_keys('CUSTOM_DELETE') expect.eq(read_rendered_text(text_area), table.concat({ '_: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -783,7 +783,7 @@ function test.handle_delete() text_area:setCursor(124) journal:onRender() - simulate_input_keys('CUSTOM_CTRL_D') + simulate_input_keys('CUSTOM_DELETE') expect.eq(read_rendered_text(text_area), table.concat({ '0: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -794,7 +794,7 @@ function test.handle_delete() text_area:setCursor(123) journal:onRender() - simulate_input_keys('CUSTOM_CTRL_D') + simulate_input_keys('CUSTOM_DELETE') expect.eq(read_rendered_text(text_area), table.concat({ '0: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -805,7 +805,7 @@ function test.handle_delete() text_area:setCursor(171) journal:onRender() - simulate_input_keys('CUSTOM_CTRL_D') + simulate_input_keys('CUSTOM_DELETE') expect.eq(read_rendered_text(text_area), table.concat({ '0: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -815,7 +815,7 @@ function test.handle_delete() }, '\n')); for i=1,59 do - simulate_input_keys('CUSTOM_CTRL_D') + simulate_input_keys('CUSTOM_DELETE') end expect.eq(read_rendered_text(text_area), table.concat({ @@ -824,7 +824,7 @@ function test.handle_delete() 'nibhorttitor mi, vitae rutrum eros metus nec libero._', }, '\n')); - simulate_input_keys('CUSTOM_CTRL_D') + simulate_input_keys('CUSTOM_DELETE') expect.eq(read_rendered_text(text_area), table.concat({ '0: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -849,7 +849,7 @@ function test.line_end() text_area:setCursor(1) journal:onRender() - simulate_input_keys('CUSTOM_CTRL_E') + simulate_input_keys('CUSTOM_END') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit._', @@ -861,7 +861,7 @@ function test.line_end() text_area:setCursor(70) journal:onRender() - simulate_input_keys('CUSTOM_CTRL_E') + simulate_input_keys('CUSTOM_END') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -873,7 +873,7 @@ function test.line_end() text_area:setCursor(200) journal:onRender() - simulate_input_keys('CUSTOM_CTRL_E') + simulate_input_keys('CUSTOM_END') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -882,7 +882,7 @@ function test.line_end() '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit._', }, '\n')); - simulate_input_keys('CUSTOM_CTRL_E') + simulate_input_keys('CUSTOM_END') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -905,7 +905,7 @@ function test.line_beging() simulate_input_text(text) - simulate_input_keys('CUSTOM_CTRL_H') + simulate_input_keys('CUSTOM_HOME') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -917,7 +917,7 @@ function test.line_beging() text_area:setCursor(173) journal:onRender() - simulate_input_keys('CUSTOM_CTRL_H') + simulate_input_keys('CUSTOM_HOME') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -929,7 +929,7 @@ function test.line_beging() text_area:setCursor(1) journal:onRender() - simulate_input_keys('CUSTOM_CTRL_H') + simulate_input_keys('CUSTOM_HOME') expect.eq(read_rendered_text(text_area), table.concat({ '_0: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -1355,10 +1355,10 @@ function test.line_navigation_reset_selection() 'porttitor mi, vitae rutrum eros metus nec libero.', }, '\n')); - simulate_input_keys('CUSTOM_CTRL_H') + simulate_input_keys('CUSTOM_HOME') expect.eq(read_selected_text(text_area), '') - simulate_input_keys('CUSTOM_CTRL_E') + simulate_input_keys('CUSTOM_END') expect.eq(read_selected_text(text_area), '') journal:dismiss() @@ -1496,7 +1496,7 @@ function test.delete_char_delete_selection() 'porttitor mi, vitae rutrum ero', }, '\n')); - simulate_input_keys('CUSTOM_CTRL_D') + simulate_input_keys('CUSTOM_DELETE') expect.eq(read_rendered_text(text_area), table.concat({ '60: _ metus nec libero.', @@ -2236,7 +2236,7 @@ function test.restore_text_between_sessions() local journal, text_area = arrange_empty_journal({w=80,save_on_change=true}) simulate_input_keys('CUSTOM_CTRL_A') - simulate_input_keys('CUSTOM_CTRL_D') + simulate_input_keys('CUSTOM_DELETE') local text = table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -2861,7 +2861,7 @@ function test.fast_rewind_words_right() text_area:setCursor(1) journal:onRender() - simulate_input_keys('A_MOVE_E_DOWN') + simulate_input_keys('CUSTOM_CTRL_RIGHT') expect.eq(read_rendered_text(text_area), table.concat({ '60:_Lorem ipsum dolor sit amet, consectetur adipiscing ', @@ -2871,7 +2871,7 @@ function test.fast_rewind_words_right() 'libero.', }, '\n')); - simulate_input_keys('A_MOVE_E_DOWN') + simulate_input_keys('CUSTOM_CTRL_RIGHT') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem_ipsum dolor sit amet, consectetur adipiscing ', @@ -2882,7 +2882,7 @@ function test.fast_rewind_words_right() }, '\n')); for i=1,6 do - simulate_input_keys('A_MOVE_E_DOWN') + simulate_input_keys('CUSTOM_CTRL_RIGHT') end expect.eq(read_rendered_text(text_area), table.concat({ @@ -2893,7 +2893,7 @@ function test.fast_rewind_words_right() 'libero.', }, '\n')); - simulate_input_keys('A_MOVE_E_DOWN') + simulate_input_keys('CUSTOM_CTRL_RIGHT') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing ', @@ -2903,7 +2903,7 @@ function test.fast_rewind_words_right() 'libero.', }, '\n')); - simulate_input_keys('A_MOVE_E_DOWN') + simulate_input_keys('CUSTOM_CTRL_RIGHT') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing ', @@ -2914,7 +2914,7 @@ function test.fast_rewind_words_right() }, '\n')); for i=1,17 do - simulate_input_keys('A_MOVE_E_DOWN') + simulate_input_keys('CUSTOM_CTRL_RIGHT') end expect.eq(read_rendered_text(text_area), table.concat({ @@ -2925,7 +2925,7 @@ function test.fast_rewind_words_right() 'libero._', }, '\n')); - simulate_input_keys('A_MOVE_E_DOWN') + simulate_input_keys('CUSTOM_CTRL_RIGHT') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing ', @@ -2948,7 +2948,7 @@ function test.fast_rewind_words_left() simulate_input_text(text) - simulate_input_keys('A_MOVE_W_DOWN') + simulate_input_keys('CUSTOM_CTRL_LEFT') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing ', @@ -2958,7 +2958,7 @@ function test.fast_rewind_words_left() '_ibero.', }, '\n')); - simulate_input_keys('A_MOVE_W_DOWN') + simulate_input_keys('CUSTOM_CTRL_LEFT') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing ', @@ -2969,7 +2969,7 @@ function test.fast_rewind_words_left() }, '\n')); for i=1,8 do - simulate_input_keys('A_MOVE_W_DOWN') + simulate_input_keys('CUSTOM_CTRL_LEFT') end expect.eq(read_rendered_text(text_area), table.concat({ @@ -2980,7 +2980,7 @@ function test.fast_rewind_words_left() 'libero.', }, '\n')); - simulate_input_keys('A_MOVE_W_DOWN') + simulate_input_keys('CUSTOM_CTRL_LEFT') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing ', @@ -2991,7 +2991,7 @@ function test.fast_rewind_words_left() }, '\n')); for i=1,16 do - simulate_input_keys('A_MOVE_W_DOWN') + simulate_input_keys('CUSTOM_CTRL_LEFT') end expect.eq(read_rendered_text(text_area), table.concat({ @@ -3002,7 +3002,7 @@ function test.fast_rewind_words_left() 'libero.', }, '\n')); - simulate_input_keys('A_MOVE_W_DOWN') + simulate_input_keys('CUSTOM_CTRL_LEFT') expect.eq(read_rendered_text(text_area), table.concat({ '_0: Lorem ipsum dolor sit amet, consectetur adipiscing ', @@ -3039,12 +3039,12 @@ function test.fast_rewind_reset_selection() 'porttitor mi, vitae rutrum eros metus nec libero.', }, '\n')); - simulate_input_keys('A_MOVE_W_DOWN') + simulate_input_keys('CUSTOM_CTRL_LEFT') expect.eq(read_selected_text(text_area), '') simulate_input_keys('CUSTOM_CTRL_A') - simulate_input_keys('A_MOVE_E_DOWN') + simulate_input_keys('CUSTOM_CTRL_RIGHT') expect.eq(read_selected_text(text_area), '') journal:dismiss() From efd2b70e6a9edd34013ce1f0bff7fe148d571626 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 14 Sep 2024 13:35:38 -0700 Subject: [PATCH 2/3] also make use of Ctrl-Home and Ctrl-End --- docs/gui/journal.rst | 48 +++++++++++++++++++++----------- internal/journal/text_editor.lua | 4 +-- test/gui/journal.lua | 14 +++++----- 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/docs/gui/journal.rst b/docs/gui/journal.rst index 675251e24..40d824b06 100644 --- a/docs/gui/journal.rst +++ b/docs/gui/journal.rst @@ -30,30 +30,46 @@ Supported Features multiline text input. - Text Wrapping: Text automatically wraps within the editor, ensuring lines fit within the display without manual adjustments. -- Backspace Support: Use the backspace key to delete characters to the left of the cursor. -- Delete Character: :kbd:`Ctrl` + :kbd:`D` deletes the character under the cursor. -- Line Navigation: :kbd:`Ctrl` + :kbd:`H` (like "Home") moves the cursor to the beginning of the current line, and :kbd:`Ctrl` + :kbd:`E` (like "End") moves it to the end. -- Delete Current Line: :kbd:`Ctrl` + :kbd:`U` deletes the entire current line where the cursor is located. -- Delete Rest of Line: :kbd:`Ctrl` + :kbd:`K` deletes text from the cursor to the end of the line. -- Delete Last Word: :kbd:`Ctrl` + :kbd:`W` removes the word immediately before the cursor. -- Text Selection: Select text with the mouse, with support for replacing or removing selected text. -- Jump to Beginning/End: Quickly move the cursor to the beginning or end of the text using :kbd:`Shift` + :kbd:`Up` and :kbd:`Shift` + :kbd:`Down`. -- Select Word/Line: Use double click to select current word, or triple click to select current line +- Backspace Support: Use the backspace key to delete characters to the left of + the cursor. +- Delete Character: :kbd:`Delete` deletes the character under the cursor. +- Line Navigation: :kbd:`Home` moves the cursor to the beginning of the current + line, and :kbd:`End` moves it to the end. +- Delete Current Line: :kbd:`Ctrl` + :kbd:`U` deletes the entire current line + where the cursor is located. +- Delete Rest of Line: :kbd:`Ctrl` + :kbd:`K` deletes text from the cursor to + the end of the line. +- Delete Last Word: :kbd:`Ctrl` + :kbd:`W` removes the word immediately before + the cursor. +- Text Selection: Select text with the mouse, with support for replacing or + removing selected text. +- Jump to Beginning/End: Quickly move the cursor to the beginning or end of the + text using :kbd:`Ctrl` + :kbd:`Home` and :kbd:`Ctrl` + :kbd:`End`. +- Select Word/Line: Use double click to select current word, or triple click to + select current line - Select All: Select entire text by :kbd:`Ctrl` + :kbd:`A` -- Undo/Redo: Undo/Redo changes by :kbd:`Ctrl` + :kbd:`Z` / :kbd:`Ctrl` + :kbd:`Y` -- Clipboard Operations: Perform OS clipboard cut, copy, and paste operations on selected text, allowing you to paste the copied content into other applications. +- Undo/Redo: Undo/Redo changes by :kbd:`Ctrl` + :kbd:`Z` / :kbd:`Ctrl` + + :kbd:`Y` +- Clipboard Operations: Perform OS clipboard cut, copy, and paste operations on + selected text, allowing you to paste the copied content into other + applications. - Copy Text: Use :kbd:`Ctrl` + :kbd:`C` to copy selected text. - copy selected text, if available - - If no text is selected it copy the entire current line, including the terminating newline if present. + - If no text is selected it copy the entire current line, including the + terminating newline if present. - Cut Text: Use :kbd:`Ctrl` + :kbd:`X` to cut selected text. - cut selected text, if available - - If no text is selected it will cut the entire current line, including the terminating newline if present -- Paste Text: Use :kbd:`Ctrl` + :kbd:`V` to paste text from the clipboard into the editor. + - If no text is selected it will cut the entire current line, including the + terminating newline if present +- Paste Text: Use :kbd:`Ctrl` + :kbd:`V` to paste text from the clipboard into + the editor. - replace selected text, if available - If no text is selected, paste text in the cursor position - Scrolling behaviour for long text build-in -- Table of contents (:kbd:`Ctrl` + :kbd:`O`), with headers line prefixed by '#', e.g. '# Fort history', '## Year 1' -- Table of contents navigation: jump to previous/next section by :kbd:`Ctrl` + :kbd:`Up` / :kbd:`Ctrl` + :kbd:`Down` +- Table of contents (:kbd:`Ctrl` + :kbd:`O`), with headers line prefixed by + ``#``, e.g. ``# Fort history``, ``## Year 1`` +- Table of contents navigation: jump to previous/next section by :kbd:`Ctrl` + + :kbd:`Up` / :kbd:`Ctrl` + :kbd:`Down` Usage ----- diff --git a/internal/journal/text_editor.lua b/internal/journal/text_editor.lua index 030668714..9815a2f12 100644 --- a/internal/journal/text_editor.lua +++ b/internal/journal/text_editor.lua @@ -761,10 +761,10 @@ function TextEditorView:onCursorInput(keys) self:setCursor(offset) self.last_cursor_x = last_cursor_x return true - elseif keys.KEYBOARD_CURSOR_UP_FAST then + elseif keys.CUSTOM_CTRL_HOME then self:setCursor(1) return true - elseif keys.KEYBOARD_CURSOR_DOWN_FAST then + elseif keys.CUSTOM_CTRL_END then -- go to text end self:setCursor(#self.text + 1) return true diff --git a/test/gui/journal.lua b/test/gui/journal.lua index b73a37a9a..612e86078 100644 --- a/test/gui/journal.lua +++ b/test/gui/journal.lua @@ -1110,7 +1110,7 @@ function test.jump_to_text_end() text_area:setCursor(1) journal:onRender() - simulate_input_keys('KEYBOARD_CURSOR_DOWN_FAST') + simulate_input_keys('CUSTOM_CTRL_END') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -1119,7 +1119,7 @@ function test.jump_to_text_end() '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit._', }, '\n')); - simulate_input_keys('KEYBOARD_CURSOR_DOWN_FAST') + simulate_input_keys('CUSTOM_CTRL_END') expect.eq(read_rendered_text(text_area), table.concat({ '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -1142,7 +1142,7 @@ function test.jump_to_text_begin() simulate_input_text(text) - simulate_input_keys('KEYBOARD_CURSOR_UP_FAST') + simulate_input_keys('CUSTOM_CTRL_HOME') expect.eq(read_rendered_text(text_area), table.concat({ '_0: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -1151,7 +1151,7 @@ function test.jump_to_text_begin() '60: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', }, '\n')); - simulate_input_keys('KEYBOARD_CURSOR_UP_FAST') + simulate_input_keys('CUSTOM_CTRL_HOME') expect.eq(read_rendered_text(text_area), table.concat({ '_0: Lorem ipsum dolor sit amet, consectetur adipiscing elit.', @@ -1388,10 +1388,10 @@ function test.jump_begin_or_end_reset_selection() 'porttitor mi, vitae rutrum eros metus nec libero.', }, '\n')); - simulate_input_keys('KEYBOARD_CURSOR_UP_FAST') + simulate_input_keys('CUSTOM_CTRL_HOME') expect.eq(read_selected_text(text_area), '') - simulate_input_keys('KEYBOARD_CURSOR_DOWN_FAST') + simulate_input_keys('CUSTOM_CTRL_END') expect.eq(read_selected_text(text_area), '') journal:dismiss() @@ -2426,7 +2426,7 @@ function test.scroll_follows_cursor() 'Ut gravida tortor ac accumsan suscipit.', }, '\n')) - simulate_input_keys('KEYBOARD_CURSOR_UP_FAST') + simulate_input_keys('CUSTOM_CTRL_HOME') simulate_mouse_click(text_area, 0, 9) simulate_input_keys('KEYBOARD_CURSOR_DOWN') From 663471c49004bbbc47d602c396dedc74a8eaec39 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 14 Sep 2024 13:40:13 -0700 Subject: [PATCH 3/3] formattttiiinnngg --- docs/gui/journal.rst | 56 ++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/gui/journal.rst b/docs/gui/journal.rst index 40d824b06..a13bda3e6 100644 --- a/docs/gui/journal.rst +++ b/docs/gui/journal.rst @@ -19,57 +19,57 @@ Supported Features ------------------ - Cursor Control: Navigate through text using arrow keys (Left, Right, Up, - and Down) for precise cursor placement. + and Down) for precise cursor placement. - Fast Rewind: Use :kbd:`Ctrl` + :kbd:`Left` and :kbd:`Ctrl` + :kbd:`Right` to - move the cursor one word back or forward. + move the cursor one word back or forward. - Longest X Position Memory: The cursor remembers the longest x position when - moving up or down, making vertical navigation more intuitive. + moving up or down, making vertical navigation more intuitive. - Mouse Control: Use the mouse to position the cursor within the text, - providing an alternative to keyboard navigation. + providing an alternative to keyboard navigation. - New Lines: Easily insert new lines using the :kbd:`Enter` key, supporting - multiline text input. + multiline text input. - Text Wrapping: Text automatically wraps within the editor, ensuring lines fit - within the display without manual adjustments. + within the display without manual adjustments. - Backspace Support: Use the backspace key to delete characters to the left of - the cursor. + the cursor. - Delete Character: :kbd:`Delete` deletes the character under the cursor. - Line Navigation: :kbd:`Home` moves the cursor to the beginning of the current - line, and :kbd:`End` moves it to the end. + line, and :kbd:`End` moves it to the end. - Delete Current Line: :kbd:`Ctrl` + :kbd:`U` deletes the entire current line - where the cursor is located. + where the cursor is located. - Delete Rest of Line: :kbd:`Ctrl` + :kbd:`K` deletes text from the cursor to - the end of the line. + the end of the line. - Delete Last Word: :kbd:`Ctrl` + :kbd:`W` removes the word immediately before - the cursor. + the cursor. - Text Selection: Select text with the mouse, with support for replacing or - removing selected text. + removing selected text. - Jump to Beginning/End: Quickly move the cursor to the beginning or end of the - text using :kbd:`Ctrl` + :kbd:`Home` and :kbd:`Ctrl` + :kbd:`End`. + text using :kbd:`Ctrl` + :kbd:`Home` and :kbd:`Ctrl` + :kbd:`End`. - Select Word/Line: Use double click to select current word, or triple click to - select current line + select current line - Select All: Select entire text by :kbd:`Ctrl` + :kbd:`A` - Undo/Redo: Undo/Redo changes by :kbd:`Ctrl` + :kbd:`Z` / :kbd:`Ctrl` + - :kbd:`Y` + :kbd:`Y` - Clipboard Operations: Perform OS clipboard cut, copy, and paste operations on - selected text, allowing you to paste the copied content into other - applications. + selected text, allowing you to paste the copied content into other + applications. - Copy Text: Use :kbd:`Ctrl` + :kbd:`C` to copy selected text. - - copy selected text, if available - - If no text is selected it copy the entire current line, including the - terminating newline if present. + - copy selected text, if available + - If no text is selected it copy the entire current line, including the + terminating newline if present. - Cut Text: Use :kbd:`Ctrl` + :kbd:`X` to cut selected text. - - cut selected text, if available - - If no text is selected it will cut the entire current line, including the - terminating newline if present + - cut selected text, if available + - If no text is selected it will cut the entire current line, including the + terminating newline if present - Paste Text: Use :kbd:`Ctrl` + :kbd:`V` to paste text from the clipboard into - the editor. - - replace selected text, if available - - If no text is selected, paste text in the cursor position + the editor. + - replace selected text, if available + - If no text is selected, paste text in the cursor position - Scrolling behaviour for long text build-in - Table of contents (:kbd:`Ctrl` + :kbd:`O`), with headers line prefixed by - ``#``, e.g. ``# Fort history``, ``## Year 1`` + ``#``, e.g. ``# Fort history``, ``## Year 1`` - Table of contents navigation: jump to previous/next section by :kbd:`Ctrl` + - :kbd:`Up` / :kbd:`Ctrl` + :kbd:`Down` + :kbd:`Up` / :kbd:`Ctrl` + :kbd:`Down` Usage -----