summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibLine
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-05-16 09:45:22 +0430
committerLinus Groh <mail@linusgroh.de>2021-05-16 10:11:56 +0100
commitbbaa4630323c20e37e2a0ead478987cb5f02fc53 (patch)
tree7d670ceda162c6713d297c5afa691aaef7da146d /Userland/Libraries/LibLine
parent3f08e957d46efc624ea50fd5ef9cbae58d4d85f1 (diff)
downloadserenity-bbaa4630323c20e37e2a0ead478987cb5f02fc53.zip
LibLine: Make line management less broken when at the last line
Previously, all sorts of weird stuff would happen when the editor was at the last line of the terminal (or when the printed line would be at the last line), this commit makes the editor scroll the terminal up before trying to write to a row that doesn't actually exist (yet). This fixes ^R search making a mess when initiated at the last line (especially with multiline prompts).
Diffstat (limited to 'Userland/Libraries/LibLine')
-rw-r--r--Userland/Libraries/LibLine/Editor.cpp27
-rw-r--r--Userland/Libraries/LibLine/Editor.h2
-rw-r--r--Userland/Libraries/LibLine/InternalFunctions.cpp9
3 files changed, 28 insertions, 10 deletions
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<size_t, 2> 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.