1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 20:47:43 +00:00

LibLine: Correct weird arrow up/down behaviour

Fixes #3270.
Also removes a parameter from search(), as it had no effect.
This commit is contained in:
AnotherTest 2020-08-23 17:44:07 +04:30 committed by Andreas Kling
parent 7506adbece
commit f0ef283f3c
3 changed files with 46 additions and 28 deletions

View file

@ -867,38 +867,42 @@ void Editor::handle_read_event()
} }
} }
bool Editor::search(const StringView& phrase, bool allow_empty, bool from_beginning) bool Editor::search(const StringView& phrase, bool allow_empty)
{ {
int last_matching_offset = -1; int last_matching_offset = -1;
bool found = false;
// Do not search for empty strings. // Do not search for empty strings.
if (allow_empty || phrase.length() > 0) { if (allow_empty || phrase.length() > 0) {
size_t search_offset = m_search_offset; size_t search_offset = m_search_offset;
for (size_t i = m_history_cursor; i > 0; --i) { for (size_t i = m_history_cursor; i > 0; --i) {
auto contains = from_beginning ? m_history[i - 1].starts_with(phrase) : m_history[i - 1].contains(phrase); auto contains = m_history[i - 1].starts_with(phrase);
if (contains) { if (contains) {
last_matching_offset = i - 1; last_matching_offset = i - 1;
if (search_offset == 0) if (search_offset == 0) {
found = true;
break; break;
}
--search_offset; --search_offset;
} }
} }
if (last_matching_offset == -1) { if (!found) {
fputc('\a', stderr); fputc('\a', stderr);
fflush(stderr); fflush(stderr);
} }
} }
m_buffer.clear(); if (found) {
m_cursor = 0; m_buffer.clear();
if (last_matching_offset >= 0) { m_cursor = 0;
insert(m_history[last_matching_offset]); insert(m_history[last_matching_offset]);
// Always needed, as we have cleared the buffer above.
m_refresh_needed = true;
} }
// Always needed, as we have cleared the buffer above.
m_refresh_needed = true; return found;
return last_matching_offset >= 0;
} }
void Editor::recalculate_origin() void Editor::recalculate_origin()

View file

@ -300,7 +300,7 @@ private:
Style find_applicable_style(size_t offset) const; Style find_applicable_style(size_t offset) const;
bool search(const StringView&, bool allow_empty = false, bool from_beginning = false); bool search(const StringView&, bool allow_empty = false);
inline void end_search() inline void end_search()
{ {
m_is_searching = false; m_is_searching = false;
@ -323,6 +323,8 @@ private:
m_cursor = 0; m_cursor = 0;
m_drawn_cursor = 0; m_drawn_cursor = 0;
m_inline_search_cursor = 0; m_inline_search_cursor = 0;
m_search_offset = 0;
m_search_offset_state = SearchOffsetState::Unbiased;
m_old_prompt_metrics = m_cached_prompt_metrics; m_old_prompt_metrics = m_cached_prompt_metrics;
set_origin(0, 0); set_origin(0, 0);
m_prompt_lines_at_suggestion_initiation = 0; m_prompt_lines_at_suggestion_initiation = 0;
@ -404,7 +406,11 @@ private:
bool m_is_searching { false }; bool m_is_searching { false };
bool m_reset_buffer_on_search_end { true }; bool m_reset_buffer_on_search_end { true };
size_t m_search_offset { 0 }; size_t m_search_offset { 0 };
bool m_searching_backwards { true }; enum class SearchOffsetState {
Unbiased,
Backwards,
Forwards,
} m_search_offset_state { SearchOffsetState::Unbiased };
size_t m_pre_search_cursor { 0 }; size_t m_pre_search_cursor { 0 };
Vector<u32, 1024> m_pre_search_buffer; Vector<u32, 1024> m_pre_search_buffer;

View file

@ -48,40 +48,45 @@ Function<bool(Editor&)> Editor::find_internal_function(const StringView& name)
void Editor::search_forwards() void Editor::search_forwards()
{ {
auto inline_search_cursor = m_inline_search_cursor; ScopedValueRollback inline_search_cursor_rollback { m_inline_search_cursor };
StringBuilder builder; StringBuilder builder;
builder.append(Utf32View { m_buffer.data(), inline_search_cursor }); builder.append(Utf32View { m_buffer.data(), m_inline_search_cursor });
String search_phrase = builder.to_string(); String search_phrase = builder.to_string();
auto search_changed_directions = m_searching_backwards; if (m_search_offset_state == SearchOffsetState::Backwards)
m_searching_backwards = false; --m_search_offset;
if (m_search_offset > 0) { if (m_search_offset > 0) {
m_search_offset -= 1 + search_changed_directions; ScopedValueRollback search_offset_rollback { m_search_offset };
if (!search(search_phrase, true, true)) { --m_search_offset;
insert(search_phrase); if (search(search_phrase, true)) {
m_search_offset_state = SearchOffsetState::Forwards;
search_offset_rollback.set_override_rollback_value(m_search_offset);
} else {
m_search_offset_state = SearchOffsetState::Unbiased;
} }
} else { } else {
m_search_offset = 0; m_search_offset_state = SearchOffsetState::Unbiased;
m_cursor = 0; m_cursor = 0;
m_buffer.clear(); m_buffer.clear();
insert(search_phrase); insert(search_phrase);
m_refresh_needed = true; m_refresh_needed = true;
} }
m_inline_search_cursor = inline_search_cursor;
} }
void Editor::search_backwards() void Editor::search_backwards()
{ {
m_searching_backwards = true; ScopedValueRollback inline_search_cursor_rollback { m_inline_search_cursor };
auto inline_search_cursor = m_inline_search_cursor;
StringBuilder builder; StringBuilder builder;
builder.append(Utf32View { m_buffer.data(), inline_search_cursor }); builder.append(Utf32View { m_buffer.data(), m_inline_search_cursor });
String search_phrase = builder.to_string(); String search_phrase = builder.to_string();
if (search(search_phrase, true, true)) { if (m_search_offset_state == SearchOffsetState::Forwards)
++m_search_offset;
if (search(search_phrase, true)) {
m_search_offset_state = SearchOffsetState::Backwards;
++m_search_offset; ++m_search_offset;
} else { } else {
insert(search_phrase); m_search_offset_state = SearchOffsetState::Unbiased;
--m_search_offset;
} }
m_inline_search_cursor = inline_search_cursor;
} }
void Editor::cursor_left_word() void Editor::cursor_left_word()
@ -239,7 +244,10 @@ void Editor::enter_search()
m_search_editor->on_display_refresh = [this](Editor& search_editor) { m_search_editor->on_display_refresh = [this](Editor& search_editor) {
StringBuilder builder; StringBuilder builder;
builder.append(Utf32View { search_editor.buffer().data(), search_editor.buffer().size() }); builder.append(Utf32View { search_editor.buffer().data(), search_editor.buffer().size() });
search(builder.build()); if (!search(builder.build())) {
m_buffer.clear();
m_cursor = 0;
}
refresh_display(); refresh_display();
}; };