From d5b3998d23775cc9ff12bf7c766b1f1411450f4b Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Fri, 15 Apr 2022 01:48:56 +0430 Subject: [PATCH] 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. --- Userland/Libraries/LibLine/Editor.cpp | 23 +++++++++++++++---- Userland/Libraries/LibLine/Editor.h | 1 + .../Libraries/LibLine/SuggestionManager.cpp | 7 +++--- .../Libraries/LibLine/SuggestionManager.h | 3 +++ Userland/Shell/Shell.cpp | 2 +- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/Userland/Libraries/LibLine/Editor.cpp b/Userland/Libraries/LibLine/Editor.cpp index 0d2baf01b4..798319bb32 100644 --- a/Userland/Libraries/LibLine/Editor.cpp +++ b/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); diff --git a/Userland/Libraries/LibLine/Editor.h b/Userland/Libraries/LibLine/Editor.h index e6a62dfedf..942fc6dadb 100644 --- a/Userland/Libraries/LibLine/Editor.h +++ b/Userland/Libraries/LibLine/Editor.h @@ -451,6 +451,7 @@ private: bool m_has_origin_reset_scheduled { false }; OwnPtr m_suggestion_display; + Vector m_remembered_suggestion_static_data; String m_new_prompt; diff --git a/Userland/Libraries/LibLine/SuggestionManager.cpp b/Userland/Libraries/LibLine/SuggestionManager.cpp index e6f00b3860..574d3b4de2 100644 --- a/Userland/Libraries/LibLine/SuggestionManager.cpp +++ b/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) { diff --git a/Userland/Libraries/LibLine/SuggestionManager.h b/Userland/Libraries/LibLine/SuggestionManager.h index b5d9d4212b..acb2c96404 100644 --- a/Userland/Libraries/LibLine/SuggestionManager.h +++ b/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 insert {}; Optional