diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-06-19 18:17:18 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-23 19:04:08 +0200 |
commit | 424965954f88bbac0516529ee984f7a2276a139e (patch) | |
tree | 577db67685a5bcfb03526fcc8111232be8f47138 | |
parent | c38fafbf4ed622271a6f8f7d5e271324417fed73 (diff) | |
download | serenity-424965954f88bbac0516529ee984f7a2276a139e.zip |
LibVT: Keep track of the 'true' line endings
-rw-r--r-- | Userland/Libraries/LibVT/Line.h | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibVT/Terminal.cpp | 15 | ||||
-rw-r--r-- | Userland/Libraries/LibVT/Terminal.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibVT/TerminalWidget.cpp | 5 |
4 files changed, 35 insertions, 0 deletions
diff --git a/Userland/Libraries/LibVT/Line.h b/Userland/Libraries/LibVT/Line.h index 1bc21b5bef..030274560c 100644 --- a/Userland/Libraries/LibVT/Line.h +++ b/Userland/Libraries/LibVT/Line.h @@ -35,6 +35,7 @@ public: void clear(const Attribute& attribute = Attribute()) { + m_terminated_at.clear(); clear_range(0, m_cells.size() - 1, attribute); } void clear_range(size_t first_column, size_t last_column, const Attribute& attribute = Attribute()); @@ -50,15 +51,26 @@ public: void set_code_point(size_t index, u32 code_point) { + if (m_terminated_at.has_value()) { + if (index > *m_terminated_at) { + m_terminated_at = index + 1; + } + } + m_cells[index].code_point = code_point; } bool is_dirty() const { return m_dirty; } void set_dirty(bool b) { m_dirty = b; } + Optional<u16> termination_column() const { return m_terminated_at; } + void set_terminated(u16 column) { m_terminated_at = column; } + private: Vector<Cell> m_cells; bool m_dirty { false }; + // Note: The alignment is 8, so this member lives in the padding (that already existed before it was introduced) + [[no_unique_address]] Optional<u16> m_terminated_at; }; } diff --git a/Userland/Libraries/LibVT/Terminal.cpp b/Userland/Libraries/LibVT/Terminal.cpp index 138ba4a3b8..ce7f61f67a 100644 --- a/Userland/Libraries/LibVT/Terminal.cpp +++ b/Userland/Libraries/LibVT/Terminal.cpp @@ -9,6 +9,7 @@ #include <AK/Debug.h> #include <AK/StringBuilder.h> #include <AK/StringView.h> +#include <AK/TemporaryChange.h> #include <LibVT/Color.h> #include <LibVT/Terminal.h> #ifdef KERNEL @@ -706,6 +707,10 @@ void Terminal::DCH(Parameters params) void Terminal::linefeed() { u16 new_row = cursor_row(); +#ifndef KERNEL + if (!m_controls_are_logically_generated) + active_buffer()[new_row].set_terminated(m_column_before_carriage_return.value_or(cursor_column())); +#endif if (cursor_row() == m_scroll_region_bottom) { scroll_up(); } else { @@ -719,6 +724,7 @@ void Terminal::linefeed() void Terminal::carriage_return() { dbgln_if(TERMINAL_DEBUG, "Carriage return"); + m_column_before_carriage_return = cursor_column(); set_cursor(cursor_row(), 0); } @@ -967,6 +973,7 @@ void Terminal::emit_code_point(u32 code_point) } if (m_stomp) { m_stomp = false; + TemporaryChange change { m_controls_are_logically_generated, true }; carriage_return(); linefeed(); put_character_at(cursor_row(), cursor_column(), code_point); @@ -980,6 +987,11 @@ void Terminal::emit_code_point(u32 code_point) void Terminal::execute_control_code(u8 code) { + ArmedScopeGuard clear_position_before_cr { + [&] { + m_column_before_carriage_return.clear(); + } + }; switch (code) { case '\a': m_client.beep(); @@ -1002,10 +1014,13 @@ void Terminal::execute_control_code(u8 code) case '\n': case '\v': case '\f': + if (m_column_before_carriage_return == m_columns - 1) + m_column_before_carriage_return = m_columns; linefeed(); return; case '\r': carriage_return(); + clear_position_before_cr.disarm(); return; default: unimplemented_control_code(code); diff --git a/Userland/Libraries/LibVT/Terminal.h b/Userland/Libraries/LibVT/Terminal.h index 1f5f974041..671312aad2 100644 --- a/Userland/Libraries/LibVT/Terminal.h +++ b/Userland/Libraries/LibVT/Terminal.h @@ -432,6 +432,9 @@ protected: Vector<bool> m_horizontal_tabs; u32 m_last_code_point { 0 }; size_t m_max_history_lines { 1024 }; + + Optional<u16> m_column_before_carriage_return; + bool m_controls_are_logically_generated { false }; }; } diff --git a/Userland/Libraries/LibVT/TerminalWidget.cpp b/Userland/Libraries/LibVT/TerminalWidget.cpp index 49b2a8061d..b469ac7761 100644 --- a/Userland/Libraries/LibVT/TerminalWidget.cpp +++ b/Userland/Libraries/LibVT/TerminalWidget.cpp @@ -339,6 +339,11 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event) if ((!visual_beep_active && !has_only_one_background_color) || should_reverse_fill_for_cursor_or_selection) painter.clear_rect(cell_rect, terminal_color_to_rgb(should_reverse_fill_for_cursor_or_selection ? attribute.effective_foreground_color() : attribute.effective_background_color())); + if constexpr (TERMINAL_DEBUG) { + if (line.termination_column() == column) + painter.clear_rect(cell_rect, Gfx::Color::Magenta); + } + enum class UnderlineStyle { None, Dotted, |