diff options
author | Fausto Tommasi <fgtommasi@gmail.com> | 2023-02-15 07:49:01 -0600 |
---|---|---|
committer | Tim Flynn <trflynn89@pm.me> | 2023-02-17 07:50:09 -0500 |
commit | f7458b3e177fe847113e20b202e6c667a23f6b42 (patch) | |
tree | 3b7d59caf153f7c87781f4acabb331060f017024 /Userland | |
parent | 782b1d20f5e5f14c7107be2942a2ac00747a8e65 (diff) | |
download | serenity-f7458b3e177fe847113e20b202e6c667a23f6b42.zip |
LibGUI: Update TextEditor to delete emoji based on gbp cluster
Updated TextDocument and TextEditor to use calls to
`find_grapheme_segmentation_boundary` in order to make "correct-feeling"
deletions on backspace and delete keys being pressed
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibGUI/TextDocument.cpp | 28 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/TextDocument.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/TextEditor.cpp | 6 |
3 files changed, 37 insertions, 0 deletions
diff --git a/Userland/Libraries/LibGUI/TextDocument.cpp b/Userland/Libraries/LibGUI/TextDocument.cpp index 1c33dabb0b..6fb2cee439 100644 --- a/Userland/Libraries/LibGUI/TextDocument.cpp +++ b/Userland/Libraries/LibGUI/TextDocument.cpp @@ -384,6 +384,34 @@ DeprecatedString TextDocument::text_in_range(TextRange const& a_range) const return builder.to_deprecated_string(); } +// This function will return the position of the previous grapheme cluster +// break, relative to the cursor, for "correct looking" parsing of unicode based +// on grapheme cluster boundary algorithm. +size_t TextDocument::get_previous_grapheme_cluster_boundary(TextPosition const& cursor) const +{ + if (!cursor.is_valid()) + return 0; + + auto const& line = this->line(cursor.line()); + + auto index = Unicode::previous_grapheme_segmentation_boundary(line.view(), cursor.column()); + return index.value_or(cursor.column() - 1); +} + +// This function will return the position of the next grapheme cluster break, +// relative to the cursor, for "correct looking" parsing of unicode based on +// grapheme cluster boundary algorithm. +size_t TextDocument::get_next_grapheme_cluster_boundary(TextPosition const& cursor) const +{ + if (!cursor.is_valid()) + return 0; + + auto const& line = this->line(cursor.line()); + + auto index = Unicode::next_grapheme_segmentation_boundary(line.view(), cursor.column()); + return index.value_or(cursor.column() + 1); +} + u32 TextDocument::code_point_at(TextPosition const& position) const { VERIFY(position.line() < line_count()); diff --git a/Userland/Libraries/LibGUI/TextDocument.h b/Userland/Libraries/LibGUI/TextDocument.h index 3bae9594fa..48c1452055 100644 --- a/Userland/Libraries/LibGUI/TextDocument.h +++ b/Userland/Libraries/LibGUI/TextDocument.h @@ -102,6 +102,9 @@ public: TextPosition next_position_after(TextPosition const&, SearchShouldWrap = SearchShouldWrap::Yes) const; TextPosition previous_position_before(TextPosition const&, SearchShouldWrap = SearchShouldWrap::Yes) const; + size_t get_next_grapheme_cluster_boundary(TextPosition const& cursor) const; + size_t get_previous_grapheme_cluster_boundary(TextPosition const& cursor) const; + u32 code_point_at(TextPosition const&) const; TextRange range_for_entire_line(size_t line_index) const; diff --git a/Userland/Libraries/LibGUI/TextEditor.cpp b/Userland/Libraries/LibGUI/TextEditor.cpp index 62896900d8..f27dd14c67 100644 --- a/Userland/Libraries/LibGUI/TextEditor.cpp +++ b/Userland/Libraries/LibGUI/TextEditor.cpp @@ -961,6 +961,9 @@ void TextEditor::keydown_event(KeyEvent& event) if (event.modifiers() == Mod_Ctrl) { auto word_break_pos = document().first_word_break_after(m_cursor); erase_count = word_break_pos.column() - m_cursor.column(); + } else { + auto grapheme_break_position = document().get_next_grapheme_cluster_boundary(m_cursor); + erase_count = grapheme_break_position - m_cursor.column(); } TextRange erased_range(m_cursor, { m_cursor.line(), m_cursor.column() + erase_count }); execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range); @@ -1001,6 +1004,9 @@ void TextEditor::keydown_event(KeyEvent& event) else new_column = (m_cursor.column() / m_soft_tab_width) * m_soft_tab_width; erase_count = m_cursor.column() - new_column; + } else { + auto grapheme_break_position = document().get_previous_grapheme_cluster_boundary(m_cursor); + erase_count = m_cursor.column() - grapheme_break_position; } // Backspace within line |