From 8a94c7a7f75adfb367d71567cf118d8ef89d867b Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Fri, 17 Feb 2023 09:40:46 -0500 Subject: [PATCH] LibGUI: Skip over grapheme clusters on left/right arrow key presses Currently, if you use the left/right arrow keys to move over a multi- code point glyph, we will move through that glyph one code point at a time. This means you can "pause" your movement in the middle of a glyph and delete a subsection of a grapheme cluster. This now moves the cursor across the entire cluster. Visually, we will need to separately track physical and virtual cursor positions. That is, when you move across a multi-code point glyph, the visual cursor should only move one position at a time, while a physical cursor stores the "real" position in terms of number of code points. This also converts a couple of ints to auto - these are actually size_t, and are being passed to functions that expect size_t, so let's not cast them to ints. --- Userland/Libraries/LibGUI/EditingEngine.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibGUI/EditingEngine.cpp b/Userland/Libraries/LibGUI/EditingEngine.cpp index 718da1b6ed..0ff7952a03 100644 --- a/Userland/Libraries/LibGUI/EditingEngine.cpp +++ b/Userland/Libraries/LibGUI/EditingEngine.cpp @@ -167,26 +167,28 @@ bool EditingEngine::on_key(KeyEvent const& event) void EditingEngine::move_one_left() { if (m_editor->cursor().column() > 0) { - int new_column = m_editor->cursor().column() - 1; + auto new_column = m_editor->document().get_previous_grapheme_cluster_boundary(m_editor->cursor()); m_editor->set_cursor(m_editor->cursor().line(), new_column); } else if (m_editor->cursor().line() > 0) { - int new_line = m_editor->cursor().line() - 1; - int new_column = m_editor->lines()[new_line].length(); + auto new_line = m_editor->cursor().line() - 1; + auto new_column = m_editor->lines()[new_line].length(); m_editor->set_cursor(new_line, new_column); } } void EditingEngine::move_one_right() { - int new_line = m_editor->cursor().line(); - int new_column = m_editor->cursor().column(); + auto new_line = m_editor->cursor().line(); + auto new_column = m_editor->cursor().column(); + if (m_editor->cursor().column() < m_editor->current_line().length()) { new_line = m_editor->cursor().line(); - new_column = m_editor->cursor().column() + 1; + new_column = m_editor->document().get_next_grapheme_cluster_boundary(m_editor->cursor()); } else if (m_editor->cursor().line() != m_editor->line_count() - 1) { new_line = m_editor->cursor().line() + 1; new_column = 0; } + m_editor->set_cursor(new_line, new_column); }