summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-06-19 18:17:18 +0430
committerAndreas Kling <kling@serenityos.org>2021-06-23 19:04:08 +0200
commit424965954f88bbac0516529ee984f7a2276a139e (patch)
tree577db67685a5bcfb03526fcc8111232be8f47138
parentc38fafbf4ed622271a6f8f7d5e271324417fed73 (diff)
downloadserenity-424965954f88bbac0516529ee984f7a2276a139e.zip
LibVT: Keep track of the 'true' line endings
-rw-r--r--Userland/Libraries/LibVT/Line.h12
-rw-r--r--Userland/Libraries/LibVT/Terminal.cpp15
-rw-r--r--Userland/Libraries/LibVT/Terminal.h3
-rw-r--r--Userland/Libraries/LibVT/TerminalWidget.cpp5
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,