summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-06-19 06:10:10 +0430
committerAndreas Kling <kling@serenityos.org>2021-06-23 19:04:08 +0200
commit4bf14715a1be88bad433e83c46e41bb2d53165b7 (patch)
treeb9eab18ae77687bed258be6cbb1097c0f499f19c
parent2f2b7814d15c9030f6794c5e844545104421778d (diff)
downloadserenity-4bf14715a1be88bad433e83c46e41bb2d53165b7.zip
LibLine: Recalculate the origin on resize
-rw-r--r--Userland/Libraries/LibLine/Editor.cpp35
-rw-r--r--Userland/Libraries/LibLine/Editor.h16
2 files changed, 39 insertions, 12 deletions
diff --git a/Userland/Libraries/LibLine/Editor.cpp b/Userland/Libraries/LibLine/Editor.cpp
index 8364510783..bd970a6b88 100644
--- a/Userland/Libraries/LibLine/Editor.cpp
+++ b/Userland/Libraries/LibLine/Editor.cpp
@@ -598,6 +598,27 @@ void Editor::resized()
m_previous_num_columns = m_num_columns;
get_terminal_size();
+ if (!m_has_origin_reset_scheduled) {
+ // Reset the origin, but make sure it doesn't blow up if we can't read it
+ if (set_origin(false)) {
+ handle_resize_event(false);
+ } else {
+ deferred_invoke([this](auto&) { handle_resize_event(true); });
+ m_has_origin_reset_scheduled = true;
+ }
+ }
+}
+
+void Editor::handle_resize_event(bool reset_origin)
+{
+ m_has_origin_reset_scheduled = false;
+ if (reset_origin && !set_origin(false)) {
+ m_has_origin_reset_scheduled = true;
+ return deferred_invoke([this](auto&) { handle_resize_event(true); });
+ }
+
+ set_origin(m_origin_row, 1);
+
reposition_cursor(true);
m_suggestion_display->redisplay(m_suggestion_manager, m_num_lines, m_num_columns);
reposition_cursor();
@@ -1751,7 +1772,7 @@ Editor::VTState Editor::actual_rendered_string_length_step(StringMetrics& metric
return state;
}
-Vector<size_t, 2> Editor::vt_dsr()
+Result<Vector<size_t, 2>, Editor::Error> Editor::vt_dsr()
{
char buf[16];
@@ -1783,7 +1804,7 @@ Vector<size_t, 2> Editor::vt_dsr()
} while (more_junk_to_read);
if (m_input_error.has_value())
- return { 1, 1 };
+ return m_input_error.value();
fputs("\033[6n", stderr);
fflush(stderr);
@@ -1813,15 +1834,11 @@ Vector<size_t, 2> Editor::vt_dsr()
continue;
}
dbgln("Error while reading DSR: {}", strerror(errno));
- m_input_error = Error::ReadFailure;
- finish();
- return { 1, 1 };
+ return Error::ReadFailure;
}
if (nread == 0) {
- m_input_error = Error::Empty;
- finish();
dbgln("Terminal DSR issue; received no response");
- return { 1, 1 };
+ return Error::Empty;
}
switch (state) {
@@ -1897,7 +1914,7 @@ Vector<size_t, 2> Editor::vt_dsr()
if (has_error)
dbgln("Terminal DSR issue, couldn't parse DSR response");
- return { row, col };
+ return Vector<size_t, 2> { row, col };
}
String Editor::line(size_t up_to_index) const
diff --git a/Userland/Libraries/LibLine/Editor.h b/Userland/Libraries/LibLine/Editor.h
index 25100b3b76..82ab418fd9 100644
--- a/Userland/Libraries/LibLine/Editor.h
+++ b/Userland/Libraries/LibLine/Editor.h
@@ -266,10 +266,11 @@ private:
void try_update_once();
void handle_interrupt_event();
void handle_read_event();
+ void handle_resize_event(bool reset_origin);
void ensure_free_lines_from_origin(size_t count);
- Vector<size_t, 2> vt_dsr();
+ Result<Vector<size_t, 2>, Error> vt_dsr();
void remove_at_index(size_t);
enum class ModificationKind {
@@ -360,10 +361,18 @@ private:
return current_prompt_metrics().offset_with_addition(buffer_metrics, m_num_columns);
}
- void set_origin()
+ bool set_origin(bool quit_on_error = true)
{
auto position = vt_dsr();
- set_origin(position[0], position[1]);
+ if (!position.is_error()) {
+ set_origin(position.value()[0], position.value()[1]);
+ return true;
+ }
+ if (quit_on_error && position.is_error()) {
+ m_input_error = position.error();
+ finish();
+ }
+ return false;
}
void set_origin(int row, int col)
@@ -423,6 +432,7 @@ private:
// Exact position before our prompt in the terminal.
size_t m_origin_row { 0 };
size_t m_origin_column { 0 };
+ bool m_has_origin_reset_scheduled { false };
OwnPtr<SuggestionDisplay> m_suggestion_display;