diff --git a/Userland/Libraries/LibLine/Editor.cpp b/Userland/Libraries/LibLine/Editor.cpp index 838ac82413..208fad58ac 100644 --- a/Userland/Libraries/LibLine/Editor.cpp +++ b/Userland/Libraries/LibLine/Editor.cpp @@ -185,6 +185,24 @@ Editor::~Editor() restore(); } +void Editor::ensure_free_lines_from_origin(size_t count) +{ + if (count > m_num_lines) { + // It's hopeless... + TODO(); + } + + if (m_origin_row + count <= m_num_lines) + return; + + auto diff = m_origin_row + count - m_num_lines - 1; + out(stderr, "\x1b[{}S", diff); + fflush(stderr); + m_origin_row -= diff; + m_refresh_needed = false; + m_chars_touched_in_the_middle = 0; +} + void Editor::get_terminal_size() { struct winsize ws; @@ -1379,16 +1397,11 @@ void Editor::reposition_cursor(bool to_end) auto line = cursor_line() - 1; auto column = offset_in_line(); + ensure_free_lines_from_origin(line); + VERIFY(column + m_origin_column <= m_num_columns); VT::move_absolute(line + m_origin_row, column + m_origin_column); - if (line + m_origin_row > m_num_lines) { - for (size_t i = m_num_lines; i < line + m_origin_row; ++i) - fputc('\n', stderr); - m_origin_row -= line + m_origin_row - m_num_lines; - VT::move_relative(0, column + m_origin_column); - } - m_cursor = saved_cursor; } diff --git a/Userland/Libraries/LibLine/Editor.h b/Userland/Libraries/LibLine/Editor.h index 62e9e0cd48..2bd9636018 100644 --- a/Userland/Libraries/LibLine/Editor.h +++ b/Userland/Libraries/LibLine/Editor.h @@ -256,6 +256,8 @@ private: void handle_interrupt_event(); void handle_read_event(); + void ensure_free_lines_from_origin(size_t count); + Vector vt_dsr(); void remove_at_index(size_t); diff --git a/Userland/Libraries/LibLine/InternalFunctions.cpp b/Userland/Libraries/LibLine/InternalFunctions.cpp index 49806f543d..a5a45f14dd 100644 --- a/Userland/Libraries/LibLine/InternalFunctions.cpp +++ b/Userland/Libraries/LibLine/InternalFunctions.cpp @@ -223,6 +223,8 @@ void Editor::enter_search() m_pre_search_buffer.append(code_point); m_pre_search_cursor = m_cursor; + ensure_free_lines_from_origin(1 + num_lines()); + // Disable our own notifier so as to avoid interfering with the search editor. m_notifier->set_enabled(false); @@ -310,9 +312,6 @@ void Editor::enter_search() return false; }); - fprintf(stderr, "\n"); - fflush(stderr); - auto search_prompt = "\x1b[32msearch:\x1b[0m "; // While the search editor is active, we do not want editing events. @@ -349,6 +348,10 @@ void Editor::enter_search() reposition_cursor(); + m_refresh_needed = true; + m_cached_prompt_valid = false; + m_chars_touched_in_the_middle = 1; + if (!m_reset_buffer_on_search_end || search_metrics.total_length == 0) { // If the entry was empty, or we purposely quit without a newline, // do not return anything; instead, just end the search.