summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibVT/Line.cpp37
-rw-r--r--Userland/Libraries/LibVT/Line.h7
-rw-r--r--Userland/Libraries/LibVT/Terminal.cpp11
3 files changed, 35 insertions, 20 deletions
diff --git a/Userland/Libraries/LibVT/Line.cpp b/Userland/Libraries/LibVT/Line.cpp
index 9e080158c0..6b84c8272b 100644
--- a/Userland/Libraries/LibVT/Line.cpp
+++ b/Userland/Libraries/LibVT/Line.cpp
@@ -10,43 +10,52 @@ namespace VT {
Line::Line(size_t length)
{
- set_length(length, nullptr, nullptr);
+ set_length(length);
}
Line::~Line()
{
}
-void Line::set_length(size_t new_length, Line* next_line, CursorPosition* cursor, bool cursor_is_on_next_line)
+void Line::rewrap(size_t new_length, Line* next_line, CursorPosition* cursor, bool cursor_is_on_next_line)
{
size_t old_length = length();
if (old_length == new_length)
return;
// Drop the empty cells
- if (m_terminated_at.has_value())
+ if (m_terminated_at.has_value() && m_cells.size() > m_terminated_at.value())
m_cells.remove(m_terminated_at.value(), m_cells.size() - m_terminated_at.value());
if (!next_line)
return m_cells.resize(new_length);
if (old_length < new_length)
- take_cells_from_next_line(old_length, new_length, next_line, cursor_is_on_next_line, cursor);
+ take_cells_from_next_line(new_length, next_line, cursor_is_on_next_line, cursor);
else
- push_cells_into_next_line(old_length, new_length, next_line, cursor_is_on_next_line, cursor);
+ push_cells_into_next_line(new_length, next_line, cursor_is_on_next_line, cursor);
+}
- m_cells.resize(max(new_length, static_cast<size_t>(m_terminated_at.value_or(new_length))));
+void Line::set_length(size_t new_length)
+{
+ m_cells.resize(new_length);
}
-void Line::push_cells_into_next_line(size_t old_length, size_t new_length, Line* next_line, bool cursor_is_on_next_line, CursorPosition* cursor)
+void Line::push_cells_into_next_line(size_t new_length, Line* next_line, bool cursor_is_on_next_line, CursorPosition* cursor)
{
+ if (is_empty())
+ return;
+
+ if (length() <= new_length)
+ return;
+
// Push as many cells as _wouldn't_ fit into the next line.
auto cells_to_preserve = !next_line->m_terminated_at.has_value() && next_line->is_empty() ? 0 : m_terminated_at.value_or(0);
- auto cells_to_push_into_next_line = min(old_length - new_length, length() - cells_to_preserve);
+ auto preserved_cells = max(new_length, cells_to_preserve);
+ auto cells_to_push_into_next_line = length() - preserved_cells;
if (!cells_to_push_into_next_line)
return;
- auto preserved_cells = length() - cells_to_push_into_next_line;
if (next_line->m_terminated_at.has_value())
next_line->m_terminated_at = next_line->m_terminated_at.value() + cells_to_push_into_next_line;
@@ -71,18 +80,20 @@ void Line::push_cells_into_next_line(size_t old_length, size_t new_length, Line*
m_terminated_at = m_terminated_at.value() - cells_to_push_into_next_line;
}
-void Line::take_cells_from_next_line(size_t old_length, size_t new_length, Line* next_line, bool cursor_is_on_next_line, CursorPosition* cursor)
+void Line::take_cells_from_next_line(size_t new_length, Line* next_line, bool cursor_is_on_next_line, CursorPosition* cursor)
{
// Take as many cells as would fit from the next line
if (m_terminated_at.has_value())
return;
- auto cells_to_grab_from_next_line = min(new_length - old_length, next_line->length());
+ if (length() >= new_length)
+ return;
+
+ auto cells_to_grab_from_next_line = min(new_length - length(), next_line->length());
auto clear_next_line = false;
if (next_line->m_terminated_at.has_value()) {
- cells_to_grab_from_next_line = min(cells_to_grab_from_next_line, static_cast<size_t>(next_line->m_terminated_at.value()));
if (cells_to_grab_from_next_line == *next_line->m_terminated_at) {
- m_terminated_at = old_length + *next_line->m_terminated_at;
+ m_terminated_at = length() + *next_line->m_terminated_at;
next_line->m_terminated_at.clear();
clear_next_line = true;
} else {
diff --git a/Userland/Libraries/LibVT/Line.h b/Userland/Libraries/LibVT/Line.h
index 0939bc77f1..0ec69c2932 100644
--- a/Userland/Libraries/LibVT/Line.h
+++ b/Userland/Libraries/LibVT/Line.h
@@ -53,7 +53,8 @@ public:
{
return m_cells.size();
}
- void set_length(size_t, Line* next_line, CursorPosition* cursor, bool cursor_is_on_next_line = true);
+ void set_length(size_t);
+ void rewrap(size_t new_length, Line* next_line, CursorPosition* cursor, bool cursor_is_on_next_line = true);
u32 code_point(size_t index) const
{
@@ -78,8 +79,8 @@ public:
void set_terminated(u16 column) { m_terminated_at = column; }
private:
- void take_cells_from_next_line(size_t old_length, size_t new_length, Line* next_line, bool cursor_is_on_next_line, CursorPosition* cursor);
- void push_cells_into_next_line(size_t old_length, size_t new_length, Line* next_line, bool cursor_is_on_next_line, CursorPosition* cursor);
+ void take_cells_from_next_line(size_t new_length, Line* next_line, bool cursor_is_on_next_line, CursorPosition* cursor);
+ void push_cells_into_next_line(size_t new_length, Line* next_line, bool cursor_is_on_next_line, CursorPosition* cursor);
Vector<Cell> m_cells;
bool m_dirty { false };
diff --git a/Userland/Libraries/LibVT/Terminal.cpp b/Userland/Libraries/LibVT/Terminal.cpp
index 19bd308da9..e21635f8d9 100644
--- a/Userland/Libraries/LibVT/Terminal.cpp
+++ b/Userland/Libraries/LibVT/Terminal.cpp
@@ -1455,14 +1455,14 @@ void Terminal::set_size(u16 columns, u16 rows)
auto next_line = is_at_seam ? nullptr : &buffer[buffer.size() - i + 1];
auto& line = buffer[buffer.size() - i];
auto next_cursor = cursor_on_line(buffer.size() - i + 1);
- line.set_length(columns, next_line, next_cursor ?: cursor_on_line(buffer.size() - i), !!next_cursor);
+ line.rewrap(columns, next_line, next_cursor ?: cursor_on_line(buffer.size() - i), !!next_cursor);
}
} else {
for (size_t i = 0; i < buffer.size(); ++i) {
auto is_at_seam = i + 1 == buffer.size();
auto next_line = is_at_seam ? nullptr : &buffer[i + 1];
auto next_cursor = cursor_on_line(i + 1);
- buffer[i].set_length(columns, next_line, next_cursor ?: cursor_on_line(i), !!next_cursor);
+ buffer[i].rewrap(columns, next_line, next_cursor ?: cursor_on_line(i), !!next_cursor);
}
}
@@ -1478,7 +1478,7 @@ void Terminal::set_size(u16 columns, u16 rows)
auto next_line = is_at_seam ? nullptr : &buffer[index + 1];
auto& line = buffer[index];
auto next_cursor = cursor_on_line(index + 1);
- line.set_length(columns, next_line, next_cursor ?: cursor_on_line(index), !!next_cursor);
+ line.rewrap(columns, next_line, next_cursor ?: cursor_on_line(index), !!next_cursor);
if (line.length() > columns) {
auto current_cursor = cursor_on_line(index);
// Split the line into two (or more)
@@ -1486,7 +1486,7 @@ void Terminal::set_size(u16 columns, u16 rows)
++rows_inserted;
buffer.insert(index, make<Line>(0));
VERIFY(buffer[index].length() == 0);
- line.set_length(columns, &buffer[index], current_cursor, false);
+ line.rewrap(columns, &buffer[index], current_cursor, false);
// If we inserted a line and the old cursor was after that line, increment its row
if (!current_cursor && old_cursor.row >= index)
++old_cursor.row;
@@ -1499,6 +1499,9 @@ void Terminal::set_size(u16 columns, u16 rows)
}
}
+ for (auto& line : buffer)
+ line.set_length(columns);
+
return old_cursor;
};