diff options
Diffstat (limited to 'Libraries')
-rw-r--r-- | Libraries/LibGUI/GTextEditor.cpp | 48 | ||||
-rw-r--r-- | Libraries/LibGUI/GTextEditor.h | 8 |
2 files changed, 53 insertions, 3 deletions
diff --git a/Libraries/LibGUI/GTextEditor.cpp b/Libraries/LibGUI/GTextEditor.cpp index 6200499111..5dc36c5a3b 100644 --- a/Libraries/LibGUI/GTextEditor.cpp +++ b/Libraries/LibGUI/GTextEditor.cpp @@ -1105,7 +1105,23 @@ GTextPosition GTextEditor::next_position_after(const GTextPosition& position, Sh return { position.line(), position.column() + 1 }; } -GTextRange GTextEditor::find(const StringView& needle, const GTextPosition& start) +GTextPosition GTextEditor::prev_position_before(const GTextPosition& position, ShouldWrapAtStartOfDocument should_wrap) +{ + if (position.column() == 0){ + if (position.line() == 0) { + if (should_wrap == ShouldWrapAtStartOfDocument::Yes) { + auto& last_line = m_lines[line_count() - 1]; + return { line_count() - 1, last_line.length() }; + } + return {}; + } + auto& prev_line = m_lines[position.line() - 1]; + return { position.line() - 1, prev_line.length() }; + } + return { position.line(), position.column() - 1 }; +} + +GTextRange GTextEditor::find_next(const StringView& needle, const GTextPosition& start) { if (needle.is_empty()) return {}; @@ -1135,6 +1151,36 @@ GTextRange GTextEditor::find(const StringView& needle, const GTextPosition& star return {}; } +GTextRange GTextEditor::find_prev(const StringView& needle, const GTextPosition& start) +{ + if (needle.is_empty()) + return {}; + + GTextPosition position = start.is_valid() ? start : GTextPosition(0, 0); + GTextPosition original_position = position; + + GTextPosition end_of_potential_match; + int needle_index = needle.length() - 1; + + do { + auto ch = character_at(position); + if (ch == needle[needle_index]) { + if (needle_index == needle.length() - 1) + end_of_potential_match = position; + --needle_index; + if (needle_index < 0) + return { position, next_position_after(end_of_potential_match) }; + } else { + if (needle_index < needle.length() - 1) + position = end_of_potential_match; + needle_index = needle.length() - 1; + } + position = prev_position_before(position); + } while(position.is_valid() && position != original_position); + + return {}; +} + void GTextEditor::set_selection(const GTextRange& selection) { if (m_selection == selection) diff --git a/Libraries/LibGUI/GTextEditor.h b/Libraries/LibGUI/GTextEditor.h index be9468644b..dfa26ef57f 100644 --- a/Libraries/LibGUI/GTextEditor.h +++ b/Libraries/LibGUI/GTextEditor.h @@ -12,6 +12,7 @@ class GScrollBar; class Painter; enum class ShouldWrapAtEndOfDocument { No = 0, Yes }; +enum class ShouldWrapAtStartOfDocument { No = 0, Yes }; class GTextPosition { public: @@ -126,9 +127,12 @@ public: bool write_to_file(const StringView& path); - GTextRange find(const StringView&, const GTextPosition& start = {}); - GTextPosition next_position_after(const GTextPosition&, ShouldWrapAtEndOfDocument = ShouldWrapAtEndOfDocument::Yes); + GTextRange find_next(const StringView&, const GTextPosition& start = {}); + GTextRange find_prev(const StringView&, const GTextPosition& start = {}); + GTextPosition next_position_after(const GTextPosition&, ShouldWrapAtEndOfDocument = ShouldWrapAtEndOfDocument::Yes); + GTextPosition prev_position_before(const GTextPosition&, ShouldWrapAtStartOfDocument = ShouldWrapAtStartOfDocument::Yes); + bool has_selection() const { return m_selection.is_valid(); } String selected_text() const; void set_selection(const GTextRange&); |