Explorar o código

LibLine: Correct weird arrow up/down behaviour

Fixes #3270.
Also removes a parameter from search(), as it had no effect.
AnotherTest %!s(int64=5) %!d(string=hai) anos
pai
achega
f0ef283f3c

+ 14 - 10
Libraries/LibLine/Editor.cpp

@@ -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;
+    bool found = false;
 
     // Do not search for empty strings.
     if (allow_empty || phrase.length() > 0) {
         size_t search_offset = m_search_offset;
         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) {
                 last_matching_offset = i - 1;
-                if (search_offset == 0)
+                if (search_offset == 0) {
+                    found = true;
                     break;
+                }
                 --search_offset;
             }
         }
 
-        if (last_matching_offset == -1) {
+        if (!found) {
             fputc('\a', stderr);
             fflush(stderr);
         }
     }
 
-    m_buffer.clear();
-    m_cursor = 0;
-    if (last_matching_offset >= 0) {
+    if (found) {
+        m_buffer.clear();
+        m_cursor = 0;
         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 last_matching_offset >= 0;
+
+    return found;
 }
 
 void Editor::recalculate_origin()

+ 8 - 2
Libraries/LibLine/Editor.h

@@ -300,7 +300,7 @@ private:
 
     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()
     {
         m_is_searching = false;
@@ -323,6 +323,8 @@ private:
         m_cursor = 0;
         m_drawn_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;
         set_origin(0, 0);
         m_prompt_lines_at_suggestion_initiation = 0;
@@ -404,7 +406,11 @@ private:
     bool m_is_searching { false };
     bool m_reset_buffer_on_search_end { true };
     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 };
     Vector<u32, 1024> m_pre_search_buffer;
 

+ 24 - 16
Libraries/LibLine/InternalFunctions.cpp

@@ -48,40 +48,45 @@ Function<bool(Editor&)> Editor::find_internal_function(const StringView& name)
 
 void Editor::search_forwards()
 {
-    auto inline_search_cursor = m_inline_search_cursor;
+    ScopedValueRollback inline_search_cursor_rollback { m_inline_search_cursor };
     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();
-    auto search_changed_directions = m_searching_backwards;
-    m_searching_backwards = false;
+    if (m_search_offset_state == SearchOffsetState::Backwards)
+        --m_search_offset;
     if (m_search_offset > 0) {
-        m_search_offset -= 1 + search_changed_directions;
-        if (!search(search_phrase, true, true)) {
-            insert(search_phrase);
+        ScopedValueRollback search_offset_rollback { m_search_offset };
+        --m_search_offset;
+        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 {
-        m_search_offset = 0;
+        m_search_offset_state = SearchOffsetState::Unbiased;
         m_cursor = 0;
         m_buffer.clear();
         insert(search_phrase);
         m_refresh_needed = true;
     }
-    m_inline_search_cursor = inline_search_cursor;
 }
 
 void Editor::search_backwards()
 {
-    m_searching_backwards = true;
-    auto inline_search_cursor = m_inline_search_cursor;
+    ScopedValueRollback inline_search_cursor_rollback { m_inline_search_cursor };
     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();
-    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;
     } 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()
@@ -239,7 +244,10 @@ void Editor::enter_search()
         m_search_editor->on_display_refresh = [this](Editor& search_editor) {
             StringBuilder builder;
             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();
         };