Selaa lähdekoodia

LibLine: Respect the provided completion static offset

Now that we can resolve these correctly and they're per-suggestion, we
can finally use them for their intended purpose of letting suggestions
overwrite stuff in the buffer.
Ali Mohammad Pur 3 vuotta sitten
vanhempi
commit
d5b3998d23

+ 18 - 5
Userland/Libraries/LibLine/Editor.cpp

@@ -1103,12 +1103,23 @@ void Editor::handle_read_event()
                 break;
             }
 
+            insert(Utf32View { m_remembered_suggestion_static_data.data(), m_remembered_suggestion_static_data.size() });
+            m_remembered_suggestion_static_data.clear_with_capacity();
+
             auto completion_result = m_suggestion_manager.attempt_completion(completion_mode, token_start);
 
-            auto new_cursor = m_cursor + completion_result.new_cursor_offset;
+            auto new_cursor = m_cursor;
+
+            new_cursor += completion_result.new_cursor_offset;
             for (size_t i = completion_result.offset_region_to_remove.start; i < completion_result.offset_region_to_remove.end; ++i)
                 remove_at_index(new_cursor);
 
+            new_cursor -= completion_result.static_offset_from_cursor;
+            for (size_t i = 0; i < completion_result.static_offset_from_cursor; ++i) {
+                m_remembered_suggestion_static_data.append(m_buffer[new_cursor]);
+                remove_at_index(new_cursor);
+            }
+
             m_cursor = new_cursor;
             m_inline_search_cursor = new_cursor;
             m_refresh_needed = true;
@@ -1129,6 +1140,7 @@ void Editor::handle_read_event()
             switch (completion_result.new_completion_mode) {
             case SuggestionManager::DontComplete:
                 m_times_tab_pressed = 0;
+                m_remembered_suggestion_static_data.clear_with_capacity();
                 break;
             case SuggestionManager::CompletePrefix:
                 break;
@@ -1159,14 +1171,15 @@ void Editor::handle_read_event()
                 // We have none, or just one suggestion,
                 // we should just commit that and continue
                 // after it, as if it were auto-completed.
-                m_times_tab_pressed = 0;
-                m_suggestion_manager.reset();
-                m_suggestion_display->finish();
+                reposition_cursor(stderr_stream, true);
+                cleanup_suggestions();
+                m_remembered_suggestion_static_data.clear_with_capacity();
             }
             continue;
         }
 
         // If we got here, manually cleanup the suggestions and then insert the new code point.
+        m_remembered_suggestion_static_data.clear_with_capacity();
         suggestion_cleanup.disarm();
         cleanup_suggestions();
         insert(code_point);
@@ -1185,7 +1198,7 @@ void Editor::handle_read_event()
 
 void Editor::cleanup_suggestions()
 {
-    if (m_times_tab_pressed) {
+    if (m_times_tab_pressed != 0) {
         // Apply the style of the last suggestion.
         readjust_anchored_styles(m_suggestion_manager.current_suggestion().start_index, ModificationKind::ForcedOverlapRemoval);
         stylize({ m_suggestion_manager.current_suggestion().start_index, m_cursor, Span::Mode::CodepointOriented }, m_suggestion_manager.current_suggestion().style);

+ 1 - 0
Userland/Libraries/LibLine/Editor.h

@@ -451,6 +451,7 @@ private:
     bool m_has_origin_reset_scheduled { false };
 
     OwnPtr<SuggestionDisplay> m_suggestion_display;
+    Vector<u32, 32> m_remembered_suggestion_static_data;
 
     String m_new_prompt;
 

+ 4 - 3
Userland/Libraries/LibLine/SuggestionManager.cpp

@@ -132,12 +132,13 @@ SuggestionManager::CompletionAttemptResult SuggestionManager::attempt_completion
             break;
         }
 
-        result.offset_region_to_remove = { next_suggestion.invariant_offset, shown_length };
-        result.new_cursor_offset = actual_offset;
-
         auto& suggestion = suggest();
         set_current_suggestion_initiation_index(initiation_start_index);
 
+        result.offset_region_to_remove = { next_suggestion.invariant_offset, shown_length };
+        result.new_cursor_offset = actual_offset;
+        result.static_offset_from_cursor = next_suggestion.static_offset;
+
         if (mode == CompletePrefix) {
             // Only auto-complete *if possible*.
             if (can_complete) {

+ 3 - 0
Userland/Libraries/LibLine/SuggestionManager.h

@@ -98,6 +98,9 @@ public:
             size_t end;
         } offset_region_to_remove { 0, 0 }; // The region to remove as defined by [start, end) translated by (old_cursor + new_cursor_offset)
 
+        // This bit of data will be removed, but restored if the suggestion is rejected.
+        size_t static_offset_from_cursor { 0 };
+
         Vector<Utf32View> insert {};
 
         Optional<Style> style_to_apply {};

+ 1 - 1
Userland/Shell/Shell.cpp

@@ -1474,7 +1474,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_path(StringView base, StringV
     //      since we are not suggesting anything starting with
     //      `/foo/', but rather just `bar...'
     auto token_length = escape_token(token, escape_mode).length();
-    size_t static_offset = last_slash + 1;
+    size_t static_offset = 0;
     auto invariant_offset = token_length;
     if (m_editor)
         m_editor->transform_suggestion_offsets(invariant_offset, static_offset);