From 42f36d4865d003bab2b19e4f378b1f30ec92cd47 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 26 Sep 2022 16:52:26 +0100 Subject: [PATCH] LibGUI: Make "Home" key behavior comfier on wrapped lines :^) There's a big comment explaining it because it's somewhat confusing, but the behavior I'm copying from other editors is, when you repeatedly press the `Home` key: 1. Go to the start of the visual line, where it wraps. 2. Go to the first non-whitespace character on the logical line, which is what happens in non-wrapped lines. 3. Go to column 0. 4. GOTO 2 --- Userland/Libraries/LibGUI/EditingEngine.cpp | 24 +++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibGUI/EditingEngine.cpp b/Userland/Libraries/LibGUI/EditingEngine.cpp index 028a7bb24e..f46535b65c 100644 --- a/Userland/Libraries/LibGUI/EditingEngine.cpp +++ b/Userland/Libraries/LibGUI/EditingEngine.cpp @@ -223,9 +223,29 @@ void EditingEngine::move_to_logical_line_beginning() void EditingEngine::move_to_line_beginning() { if (m_editor->is_wrapping_enabled()) { - // FIXME: Replicate the first_nonspace_column behavior in wrapping mode. + TextPosition new_cursor; + auto home_position = m_editor->cursor_content_rect().location().translated(-m_editor->width(), 0); - m_editor->set_cursor(m_editor->text_position_at_content_position(home_position)); + auto start_of_visual_line = m_editor->text_position_at_content_position(home_position); + auto first_non_space_column = m_editor->current_line().first_non_whitespace_column(); + + // Subsequent "move_to_line_beginning()" calls move us in the following way: + // 1. To the start of the current visual line + // 2. To the first non-whitespace character on the logical line + // 3. To the first character on the logical line + // ...and then repeat 2 and 3. + if (m_editor->cursor() == start_of_visual_line) { + // Already at 1 so go to 2 + new_cursor = { m_editor->cursor().line(), first_non_space_column }; + } else if (m_editor->cursor().column() == first_non_space_column) { + // At 2 so go to 3 + new_cursor = { m_editor->cursor().line(), 0 }; + } else { + // Anything else, so go to 1 + new_cursor = start_of_visual_line; + } + + m_editor->set_cursor(new_cursor); } else { move_to_logical_line_beginning(); }