From a7e7f62d08c4dab602c082e4919dc3564e3e3f5e Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Sat, 10 Jul 2021 21:48:49 +0100 Subject: VimEditingEngine: Operate on real lines rather than wrapped ones In the normal editing engine keys like Home, End etc work on visual lines, but vim operates on real ones. Eg if you have a really long line and wrapping is on then in normal editing Home would take you to the beginning of the wrapped line, but 'I' would put you insert mode at the beginning of the real line in vim. --- Userland/Libraries/LibGUI/EditingEngine.cpp | 34 ++++++++++++++++---------- Userland/Libraries/LibGUI/EditingEngine.h | 2 ++ Userland/Libraries/LibGUI/VimEditingEngine.cpp | 18 +++++++------- 3 files changed, 32 insertions(+), 22 deletions(-) (limited to 'Userland') diff --git a/Userland/Libraries/LibGUI/EditingEngine.cpp b/Userland/Libraries/LibGUI/EditingEngine.cpp index 99f2f779be..8f49701fb4 100644 --- a/Userland/Libraries/LibGUI/EditingEngine.cpp +++ b/Userland/Libraries/LibGUI/EditingEngine.cpp @@ -241,34 +241,42 @@ void EditingEngine::move_to_next_span(const KeyEvent& event) } } -void EditingEngine::move_to_line_beginning() +void EditingEngine::move_to_logical_line_beginning() { TextPosition new_cursor; + size_t first_nonspace_column = m_editor->current_line().first_non_whitespace_column(); + if (m_editor->cursor().column() == first_nonspace_column) { + new_cursor = { m_editor->cursor().line(), 0 }; + } else { + new_cursor = { m_editor->cursor().line(), first_nonspace_column }; + } + m_editor->set_cursor(new_cursor); +} + +void EditingEngine::move_to_line_beginning() +{ if (m_editor->is_wrapping_enabled()) { // FIXME: Replicate the first_nonspace_column behavior in wrapping mode. auto home_position = m_editor->cursor_content_rect().location().translated(-m_editor->width(), 0); - new_cursor = m_editor->text_position_at_content_position(home_position); + m_editor->set_cursor(m_editor->text_position_at_content_position(home_position)); } else { - size_t first_nonspace_column = m_editor->current_line().first_non_whitespace_column(); - if (m_editor->cursor().column() == first_nonspace_column) { - new_cursor = { m_editor->cursor().line(), 0 }; - } else { - new_cursor = { m_editor->cursor().line(), first_nonspace_column }; - } + move_to_logical_line_beginning(); } - m_editor->set_cursor(new_cursor); } void EditingEngine::move_to_line_end() { - TextPosition new_cursor; if (m_editor->is_wrapping_enabled()) { auto end_position = m_editor->cursor_content_rect().location().translated(m_editor->width(), 0); - new_cursor = m_editor->text_position_at_content_position(end_position); + m_editor->set_cursor(m_editor->text_position_at_content_position(end_position)); } else { - new_cursor = { m_editor->cursor().line(), m_editor->current_line().length() }; + move_to_logical_line_end(); } - m_editor->set_cursor(new_cursor); +} + +void EditingEngine::move_to_logical_line_end() +{ + m_editor->set_cursor({ m_editor->cursor().line(), m_editor->current_line().length() }); } void EditingEngine::move_one_up(const KeyEvent& event) diff --git a/Userland/Libraries/LibGUI/EditingEngine.h b/Userland/Libraries/LibGUI/EditingEngine.h index d2783f27e4..f3cc449224 100644 --- a/Userland/Libraries/LibGUI/EditingEngine.h +++ b/Userland/Libraries/LibGUI/EditingEngine.h @@ -48,6 +48,8 @@ protected: void move_one_down(const KeyEvent& event); void move_to_previous_span(); void move_to_next_span(const KeyEvent& event); + void move_to_logical_line_beginning(); + void move_to_logical_line_end(); void move_to_line_beginning(); void move_to_line_end(); void move_page_up(); diff --git a/Userland/Libraries/LibGUI/VimEditingEngine.cpp b/Userland/Libraries/LibGUI/VimEditingEngine.cpp index da687b614c..ec26c41e4a 100644 --- a/Userland/Libraries/LibGUI/VimEditingEngine.cpp +++ b/Userland/Libraries/LibGUI/VimEditingEngine.cpp @@ -834,10 +834,10 @@ bool VimEditingEngine::on_key_in_normal_mode(const KeyEvent& event) delete_line(); if (was_second_last_line || (m_editor->cursor().line() != 0 && m_editor->cursor().line() != m_editor->line_count() - 1)) { move_one_up(event); - move_to_line_end(); + move_to_logical_line_end(); m_editor->add_code_point(0x0A); } else if (m_editor->cursor().line() == 0) { - move_to_line_beginning(); + move_to_logical_line_beginning(); m_editor->add_code_point(0x0A); move_one_up(event); } else if (m_editor->cursor().line() == m_editor->line_count() - 1) { @@ -896,15 +896,15 @@ bool VimEditingEngine::on_key_in_normal_mode(const KeyEvent& event) if (event.shift() && !event.ctrl() && !event.alt()) { switch (event.key()) { case (KeyCode::Key_A): - move_to_line_end(); + move_to_logical_line_end(); switch_to_insert_mode(); return true; case (KeyCode::Key_I): - move_to_line_beginning(); + move_to_logical_line_beginning(); switch_to_insert_mode(); return true; case (KeyCode::Key_O): - move_to_line_beginning(); + move_to_logical_line_beginning(); m_editor->add_code_point(0x0A); move_one_up(event); switch_to_insert_mode(); @@ -958,7 +958,7 @@ bool VimEditingEngine::on_key_in_normal_mode(const KeyEvent& event) switch_to_insert_mode(); return true; case (KeyCode::Key_O): - move_to_line_end(); + move_to_logical_line_end(); m_editor->add_code_point(0x0A); switch_to_insert_mode(); return true; @@ -1043,11 +1043,11 @@ bool VimEditingEngine::on_key_in_visual_mode(const KeyEvent& event) if (event.shift() && !event.ctrl() && !event.alt()) { switch (event.key()) { case (KeyCode::Key_A): - move_to_line_end(); + move_to_logical_line_end(); switch_to_insert_mode(); return true; case (KeyCode::Key_I): - move_to_line_beginning(); + move_to_logical_line_beginning(); switch_to_insert_mode(); return true; default: @@ -1230,7 +1230,7 @@ void VimEditingEngine::yank(TextRange range) void VimEditingEngine::put() { if (m_yank_type == YankType::Line) { - move_to_line_end(); + move_to_logical_line_end(); StringBuilder sb = StringBuilder(m_yank_buffer.length() + 1); sb.append_code_point(0x0A); sb.append(m_yank_buffer); -- cgit v1.2.3