diff options
author | Joe Wilm <joe@jwilm.com> | 2018-02-15 18:35:49 -0800 |
---|---|---|
committer | Joe Wilm <joe@jwilm.com> | 2018-06-02 09:32:29 -0700 |
commit | 45c2b3fbf72fa6dfd36bee590e64314c6da7c6c2 (patch) | |
tree | 9f68a9692d0d0754264931d26e1a7cf0400471ed /src/term | |
parent | 94796a70fcbc11df2dc642057fef242466822067 (diff) | |
download | alacritty-45c2b3fbf72fa6dfd36bee590e64314c6da7c6c2.tar.gz alacritty-45c2b3fbf72fa6dfd36bee590e64314c6da7c6c2.zip |
checkpoint: very basic scrolling works
Things that do not work
- Limiting how far back in the buffer it's possible to scroll
- Selections (need to transform to buffer offsets)
Diffstat (limited to 'src/term')
-rw-r--r-- | src/term/mod.rs | 183 |
1 files changed, 86 insertions, 97 deletions
diff --git a/src/term/mod.rs b/src/term/mod.rs index efcafc25..e2088413 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -24,8 +24,8 @@ use unicode_width::UnicodeWidthChar; use font::{self, Size}; use ansi::{self, Color, NamedColor, Attr, Handler, CharsetIndex, StandardCharset, CursorStyle}; -use grid::{BidirectionalIterator, Grid, ToRange, Indexed, IndexRegion}; -use index::{self, Point, Column, Line, Linear, IndexRange, Contains, RangeInclusive}; +use grid::{BidirectionalIterator, Grid, ToRange, Indexed, IndexRegion, DisplayIter}; +use index::{self, Point, Column, Line, IndexRange, Contains, RangeInclusive}; use selection::{self, Span, Selection}; use config::{Config, VisualBellAnimation}; use {MouseCursor, Rgb}; @@ -94,12 +94,11 @@ impl selection::Dimensions for Term { /// This manages the cursor during a render. The cursor location is inverted to /// draw it, and reverted after drawing to maintain state. pub struct RenderableCellsIter<'a> { + inner: DisplayIter<'a, Cell>, grid: &'a Grid<Cell>, cursor: &'a Point, - cursor_index: index::Linear, + cursor_offset: usize, mode: TermMode, - line: Line, - column: Column, config: &'a Config, colors: &'a color::List, selection: Option<RangeInclusive<index::Linear>>, @@ -120,18 +119,18 @@ impl<'a> RenderableCellsIter<'a> { selection: Option<RangeInclusive<index::Linear>>, cursor_style: CursorStyle, ) -> RenderableCellsIter<'b> { - let cursor_index = Linear(cursor.line.0 * grid.num_cols().0 + cursor.col.0); + let cursor_offset = grid.line_to_offset(cursor.line); + let inner = grid.display_iter(); RenderableCellsIter { - grid, - cursor, - cursor_index, - mode, - line: Line(0), - column: Column(0), - selection, - config, - colors, + cursor: cursor, + cursor_offset: cursor_offset, + grid: grid, + inner: inner, + mode: mode, + selection: selection, + config: config, + colors: colors, cursor_cells: ArrayDeque::new(), }.initialize(cursor_style) } @@ -318,6 +317,7 @@ impl<'a> RenderableCellsIter<'a> { } pub struct RenderableCell { + /// A _Display_ line (not necessarily an _Active_ line) pub line: Line, pub column: Column, pub c: char, @@ -336,81 +336,70 @@ impl<'a> Iterator for RenderableCellsIter<'a> { /// (eg. invert fg and bg colors). #[inline] fn next(&mut self) -> Option<Self::Item> { - while self.line < self.grid.num_lines() { - while self.column < self.grid.num_cols() { - // Grab current state for this iteration - let line = self.line; - let mut column = self.column; - let cell = &self.grid[line][column]; - - let index = Linear(line.0 * self.grid.num_cols().0 + column.0); - - let (cell, selected) = if index == self.cursor_index { - // Cursor cell - let cell = self.cursor_cells.pop_front().unwrap(); - column = cell.column; - - // Since there may be multiple cursor cells (for a wide - // char), only update iteration position after all cursor - // cells have been drawn. - if self.cursor_cells.is_empty() { - self.line = cell.line; - self.column = cell.column + 1; - } - (cell.inner, false) - } else { - // Normal cell - self.column += 1; + loop { + // Handle cursor + let (cell, selected) = if self.cursor_offset == self.inner.offset() && + self.inner.column() == self.cursor.col + { + // Cursor cell + let cell = self.cursor_cells.pop_front().unwrap(); + + // Since there may be multiple cursor cells (for a wide + // char), only update iteration position after all cursor + // cells have been drawn. + if self.cursor_cells.is_empty() { + self.inner.next(); + } + (cell, false) + } else { + let cell = self.inner.next()?; + + // XXX (jwilm) selection temp disabled + // + // let selected = self.selection.as_ref() + // .map(|range| range.contains_(index)) + // .unwrap_or(false); + let selected = false; + + // Skip empty cells + if cell.is_empty() && !selected { + continue; + } + (cell, selected) + }; - let selected = self.selection.as_ref() - .map(|range| range.contains_(index)) - .unwrap_or(false); + // Apply inversion and lookup RGB values + let mut bg_alpha = 1.0; + let fg_rgb; + let bg_rgb; - // Skip empty cells - if cell.is_empty() && !selected { - continue; - } - (*cell, selected) - }; + let invert = selected ^ cell.inverse(); - // Apply inversion and lookup RGB values - let mut bg_alpha = 1.0; - let fg_rgb; - let bg_rgb; - - let invert = selected ^ cell.inverse(); - - if invert { - if cell.fg == cell.bg { - bg_rgb = self.colors[NamedColor::Foreground]; - fg_rgb = self.colors[NamedColor::Background]; - bg_alpha = 1.0 - } else { - bg_rgb = self.compute_fg_rgb(&cell.fg, &cell); - fg_rgb = self.compute_bg_rgb(&cell.bg); - } + if invert { + if cell.fg == cell.bg { + bg_rgb = self.colors[NamedColor::Foreground]; + fg_rgb = self.colors[NamedColor::Background]; + bg_alpha = 1.0 } else { - fg_rgb = self.compute_fg_rgb(&cell.fg, &cell); - bg_rgb = self.compute_bg_rgb(&cell.bg); - bg_alpha = self.compute_bg_alpha(&cell.bg); + bg_rgb = self.compute_fg_rgb(&cell.fg, &cell); + fg_rgb = self.compute_bg_rgb(&cell.bg); } - - return Some(RenderableCell { - line, - column, - flags: cell.flags, - c: cell.c, - fg: fg_rgb, - bg: bg_rgb, - bg_alpha, - }) + } else { + fg_rgb = self.compute_fg_rgb(&cell.fg, &cell); + bg_rgb = self.compute_bg_rgb(&cell.bg); + bg_alpha = self.compute_bg_alpha(&cell.bg); } - self.column = Column(0); - self.line += 1; + return Some(RenderableCell { + line: cell.line, + column: cell.column, + flags: cell.flags, + c: cell.c, + fg: fg_rgb, + bg: bg_rgb, + bg_alpha: bg_alpha, + }) } - - None } } @@ -789,6 +778,11 @@ impl Term { self.next_title.take() } + pub fn scroll_display(&mut self, count: isize) { + self.grid.scroll_display(count); + self.dirty = true; + } + #[inline] pub fn get_next_mouse_cursor(&mut self) -> Option<MouseCursor> { self.next_mouse_cursor.take() @@ -1047,10 +1041,6 @@ impl Term { num_lines = Line(2); } - // Scroll up to keep cursor and as much context as possible in grid. - // This only runs when the lines decreases. - self.scroll_region = Line(0)..self.grid.num_lines(); - // Scroll up to keep cursor in terminal if self.cursor.point.line >= num_lines { let lines = self.cursor.point.line - num_lines + 1; @@ -1062,7 +1052,6 @@ impl Term { let lines = self.cursor_save_alt.point.line - num_lines + 1; self.alt_grid.scroll_up(&(Line(0)..old_lines), lines); } - debug!("num_cols, num_lines = {}, {}", num_cols, num_lines); // Resize grids to new size @@ -1085,16 +1074,16 @@ impl Term { .map(|i| (*i as usize) % self.tabspaces == 0) .collect::<Vec<bool>>(); - if num_lines > old_lines { - // Make sure bottom of terminal is clear - let template = self.cursor.template; - self.grid - .region_mut((self.cursor.point.line + 1)..) - .each(|c| c.reset(&template)); - self.alt_grid - .region_mut((self.cursor_save_alt.point.line + 1)..) - .each(|c| c.reset(&template)); - } + // if num_lines > old_lines { + // // Make sure bottom of terminal is clear + // let template = self.cursor.template; + // self.grid + // .region_mut((self.cursor.point.line + 1)..) + // .each(|c| c.reset(&template)); + // self.alt_grid + // .region_mut((self.cursor_save_alt.point.line + 1)..) + // .each(|c| c.reset(&template)); + // } } |