summaryrefslogtreecommitdiff
path: root/Libraries/LibLine
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2020-04-10 09:53:22 +0430
committerAndreas Kling <kling@serenityos.org>2020-04-10 11:26:44 +0200
commit2315f789cc5f5e8cf382cc748999aaaca07bbffa (patch)
treeb4b6a4e3e9205c38610e5424c29a07e8ac3cfacf /Libraries/LibLine
parent1b422315fae44e83065c6f0343d8cbda875e4faf (diff)
downloadserenity-2315f789cc5f5e8cf382cc748999aaaca07bbffa.zip
LibLine: Appropriately react to window size changes
Diffstat (limited to 'Libraries/LibLine')
-rw-r--r--Libraries/LibLine/Editor.cpp64
1 files changed, 43 insertions, 21 deletions
diff --git a/Libraries/LibLine/Editor.cpp b/Libraries/LibLine/Editor.cpp
index dd35a884bc..37f9671a0a 100644
--- a/Libraries/LibLine/Editor.cpp
+++ b/Libraries/LibLine/Editor.cpp
@@ -155,18 +155,9 @@ String Editor::get_line(const String& prompt)
if (!m_buffer.is_empty())
printf("^C");
}
- if (m_was_resized) {
- m_was_resized = false;
- printf("\033[2K\r");
- m_buffer.clear();
-
- struct winsize ws;
- int rc = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
- ASSERT(rc == 0);
- m_num_columns = ws.ws_col;
+ if (m_was_resized)
+ continue;
- return String::empty();
- }
m_buffer.clear();
putchar('\n');
return String::empty();
@@ -414,6 +405,36 @@ String Editor::get_line(const String& prompt)
void Editor::refresh_display()
{
+ auto cleanup = [&] {
+ vt_move_relative(0, m_pending_chars.size() - m_chars_inserted_in_the_middle);
+ auto current_line = cursor_line();
+
+ vt_clear_lines(current_line - 1, num_lines() - current_line);
+ vt_move_relative(-num_lines() + 1, -offset_in_line() - m_old_prompt_length + m_chars_inserted_in_the_middle);
+ };
+ auto has_cleaned_up = false;
+ // someone changed the window size, figure it out
+ // and react to it, we might need to redraw
+ if (m_was_resized) {
+ auto previous_num_columns = m_num_columns;
+
+ struct winsize ws;
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
+ m_num_columns = 80;
+ else
+ m_num_columns = ws.ws_col;
+
+ if (previous_num_columns != m_num_columns) {
+ // we need to cleanup and redo everything
+ m_cached_prompt_valid = false;
+ m_refresh_needed = true;
+ swap(previous_num_columns, m_num_columns);
+ cleanup();
+ set_origin();
+ swap(previous_num_columns, m_num_columns);
+ has_cleaned_up = true;
+ }
+ }
// do not call hook on pure cursor movement
if (m_cached_prompt_valid && !m_refresh_needed && m_pending_chars.size() == 0) {
// probably just moving around
@@ -442,13 +463,10 @@ void Editor::refresh_display()
// ouch, reflow entire line
// FIXME: handle multiline stuff
- vt_move_relative(0, m_pending_chars.size() - m_chars_inserted_in_the_middle);
- auto current_line = cursor_line();
-
- vt_clear_lines(current_line - 1, num_lines() - current_line);
- vt_move_relative(-num_lines() + 1, -offset_in_line() - m_old_prompt_length + m_chars_inserted_in_the_middle);
-
- set_origin();
+ if (!has_cleaned_up) {
+ cleanup();
+ set_origin();
+ }
fputs(m_new_prompt.characters(), stdout);
@@ -636,16 +654,20 @@ Vector<size_t, 2> Editor::vt_dsr()
do {
auto nread = read(0, buf + length, 16 - length);
if (nread < 0) {
+ if (errno == ESUCCESS) {
+ // ????
+ continue;
+ }
dbg() << "Error while reading DSR: " << strerror(errno);
- return { 0, 0 };
+ return { 1, 1 };
}
if (nread == 0) {
dbg() << "Terminal DSR issue; received no response";
- return { 0, 0 };
+ return { 1, 1 };
}
length += nread;
} while (buf[length - 1] != 'R' && length < 16);
- size_t x { 0 }, y { 0 };
+ size_t x { 1 }, y { 1 };
if (buf[0] == '\033' && buf[1] == '[') {
auto parts = StringView(buf + 2, length - 3).split_view(';');