From e63cf3b94a424c76fa686f028a8c2b65adb18a57 Mon Sep 17 00:00:00 2001 From: Abhishek Raturi Date: Fri, 11 Aug 2023 16:06:50 -0400 Subject: [PATCH] HackStudio: Highlight all the occurances of selected text in editor This feature is similar(somewhat) to the Clion's highlight all occurances of word under caret. This is not perfect implementation since there is a issue with resetting the `spans` `attributes` such as `color`, `background_color` HackStudio: Reset spans upon mousedown_event after double clicking Reset the spans upon mousedown_event after double clicking the text (to highlight all occurrances). Avoid highlighting if whitespace is selected --- Userland/Libraries/LibGUI/TextEditor.cpp | 25 ++++++++++++++++++++++++ Userland/Libraries/LibGUI/TextEditor.h | 2 ++ 2 files changed, 27 insertions(+) diff --git a/Userland/Libraries/LibGUI/TextEditor.cpp b/Userland/Libraries/LibGUI/TextEditor.cpp index 69bbed2d32..0822002689 100644 --- a/Userland/Libraries/LibGUI/TextEditor.cpp +++ b/Userland/Libraries/LibGUI/TextEditor.cpp @@ -248,6 +248,26 @@ TextPosition TextEditor::text_position_at(Gfx::IntPoint widget_position) const return text_position_at_content_position(content_position); } +void TextEditor::highlight_all_occurances_of(DeprecatedString const selected_text) +{ + auto search_result = document().find_all(selected_text, false, true); + if (search_result.size() > 1) { + Vector spans; + for (size_t i = 0; i < search_result.size(); ++i) { + auto& result = search_result[i]; + GUI::TextDocumentSpan span; + span.range = result; + span.attributes.color = Color::from_argb(0xff000000); + span.attributes.background_color = palette().bright_yellow(); + span.attributes.bold = true; + span.attributes.underline_style = Gfx::TextAttributes::UnderlineStyle::Solid; + spans.append(move(span)); + } + document().set_spans(highlight_selected_text_span_collection_index, spans); + update(); + } +} + void TextEditor::doubleclick_event(MouseEvent& event) { if (event.button() != MouseButton::Primary) @@ -286,6 +306,10 @@ void TextEditor::doubleclick_event(MouseEvent& event) m_selection.set_end(document().first_word_break_after(position)); } + auto selection = selected_text(); + if (!selection.is_whitespace()) + highlight_all_occurances_of(selected_text()); + set_cursor(m_selection.end()); update(); did_update_selection(); @@ -298,6 +322,7 @@ void TextEditor::mousedown_event(MouseEvent& event) if (event.button() != MouseButton::Primary) { return; } + document().set_spans(highlight_selected_text_span_collection_index, {}); auto text_position = text_position_at(event.position()); if (event.modifiers() == 0 && folding_indicator_rect(text_position.line()).contains(event.position())) { diff --git a/Userland/Libraries/LibGUI/TextEditor.h b/Userland/Libraries/LibGUI/TextEditor.h index 02d60853df..c057aadc43 100644 --- a/Userland/Libraries/LibGUI/TextEditor.h +++ b/Userland/Libraries/LibGUI/TextEditor.h @@ -245,6 +245,7 @@ public: Backward, }; TextRange find_text(StringView needle, SearchDirection, GUI::TextDocument::SearchShouldWrap, bool use_regex, bool match_case); + void highlight_all_occurances_of(DeprecatedString const selected_text); void reset_search_results(); Optional search_result_index() const { return m_search_result_index; } Vector const& search_results() const { return m_search_results; } @@ -389,6 +390,7 @@ private: void on_search_results(GUI::TextRange current, Vector all_results); static constexpr auto search_results_span_collection_index = 1; + static constexpr auto highlight_selected_text_span_collection_index = 1; Type m_type { MultiLine }; Mode m_mode { Editable };