1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 21:32:13 +03:00

tidy up basic scroll handling

Previously, we would not allocate a new line and would end up
panicking when we went off the end of the default screen height.
This commit is contained in:
Wez Furlong 2018-01-28 18:05:22 -08:00
parent 8d9cd83e6d
commit 001eda902b

View File

@ -299,6 +299,19 @@ impl Screen {
line.cells[x] = blank;
}
}
fn scroll_up(&mut self, num_rows: usize) {
let max_allowed = self.physical_rows + self.scrollback_size;
if self.lines.len() + num_rows >= max_allowed {
let lines_to_pop = (self.lines.len() + num_rows) - max_allowed;
for _ in 0..lines_to_pop {
self.lines.remove(0);
}
}
for _ in 0..num_rows {
self.lines.push(Line::new(self.physical_cols));
}
}
}
pub struct TerminalState {
@ -347,7 +360,7 @@ impl TerminalState {
}
}
fn screen(&mut self) -> &Screen {
fn screen(&self) -> &Screen {
if self.alt_screen_is_active {
&self.alt_screen
} else {
@ -426,11 +439,7 @@ impl TerminalState {
/// Returns the width of the screen and a slice over the visible rows
/// TODO: should allow an arbitrary view for scrollback
pub fn visible_cells(&self) -> (usize, &[Line]) {
let screen = if self.alt_screen_is_active {
&self.alt_screen
} else {
&self.screen
};
let screen = self.screen();
let width = screen.physical_cols;
let height = screen.physical_rows;
let len = screen.lines.len();
@ -443,6 +452,36 @@ impl TerminalState {
(self.cursor_x, self.cursor_y)
}
/// Sets the cursor position. x and y are 0-based and relative to the
/// top left of the visible screen.
/// TODO: DEC origin mode impacts the interpreation of these
fn set_cursor_pos(&mut self, x: usize, y: usize) {
self.cursor_x = x;
self.cursor_y = y;
self.state_changed = true;
}
fn scroll_up(&mut self, num_rows: usize) {
self.screen_mut().scroll_up(num_rows)
}
fn new_line(&mut self, move_to_first_column: bool) {
let x = if move_to_first_column {
0
} else {
self.cursor_x
};
let y = self.cursor_y;
let num_rows = self.screen().physical_rows;
let y = if y + 1 == num_rows {
self.scroll_up(1);
y
} else {
y + 1
};
self.set_cursor_pos(x, y);
}
fn push_answerback(&mut self, buf: &[u8]) {
let mut result = self.answerback.take().unwrap_or_else(Vec::new);
result.extend_from_slice(buf);
@ -508,15 +547,14 @@ impl vte::Perform for TerminalState {
fn execute(&mut self, byte: u8) {
match byte {
b'\n' => {
self.cursor_y += 1;
self.state_changed = true;
b'\n' | 0x0b /* VT */ | 0x0c /* FF */=> {
self.new_line(true /* TODO: depend on terminal mode */)
}
b'\r' => {
self.cursor_x = 0;
self.state_changed = true;
}
0x08 => {
0x08 /* BS */ => {
self.cursor_x -= 1;
self.state_changed = true;
}
@ -561,8 +599,7 @@ impl vte::Perform for TerminalState {
self.pen.set_invisible(on);
}
CSIAction::SetCursorXY(x, y) => {
self.cursor_x = x;
self.cursor_y = y;
self.set_cursor_pos(x, y);
}
CSIAction::EraseInLine(erase) => {
let cx = self.cursor_x;