mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:07:46 +00:00
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
This commit is contained in:
parent
782b1d20f5
commit
f7458b3e17
3 changed files with 37 additions and 0 deletions
|
@ -384,6 +384,34 @@ DeprecatedString TextDocument::text_in_range(TextRange const& a_range) const
|
||||||
return builder.to_deprecated_string();
|
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
|
u32 TextDocument::code_point_at(TextPosition const& position) const
|
||||||
{
|
{
|
||||||
VERIFY(position.line() < line_count());
|
VERIFY(position.line() < line_count());
|
||||||
|
|
|
@ -102,6 +102,9 @@ public:
|
||||||
TextPosition next_position_after(TextPosition const&, SearchShouldWrap = SearchShouldWrap::Yes) const;
|
TextPosition next_position_after(TextPosition const&, SearchShouldWrap = SearchShouldWrap::Yes) const;
|
||||||
TextPosition previous_position_before(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;
|
u32 code_point_at(TextPosition const&) const;
|
||||||
|
|
||||||
TextRange range_for_entire_line(size_t line_index) const;
|
TextRange range_for_entire_line(size_t line_index) const;
|
||||||
|
|
|
@ -961,6 +961,9 @@ void TextEditor::keydown_event(KeyEvent& event)
|
||||||
if (event.modifiers() == Mod_Ctrl) {
|
if (event.modifiers() == Mod_Ctrl) {
|
||||||
auto word_break_pos = document().first_word_break_after(m_cursor);
|
auto word_break_pos = document().first_word_break_after(m_cursor);
|
||||||
erase_count = word_break_pos.column() - m_cursor.column();
|
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 });
|
TextRange erased_range(m_cursor, { m_cursor.line(), m_cursor.column() + erase_count });
|
||||||
execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range);
|
execute<RemoveTextCommand>(document().text_in_range(erased_range), erased_range);
|
||||||
|
@ -1001,6 +1004,9 @@ void TextEditor::keydown_event(KeyEvent& event)
|
||||||
else
|
else
|
||||||
new_column = (m_cursor.column() / m_soft_tab_width) * m_soft_tab_width;
|
new_column = (m_cursor.column() / m_soft_tab_width) * m_soft_tab_width;
|
||||||
erase_count = m_cursor.column() - new_column;
|
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
|
// Backspace within line
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue