diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | src/grid/mod.rs | 33 | ||||
-rw-r--r-- | src/term/mod.rs | 13 |
3 files changed, 23 insertions, 24 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index a228ad49..b6283e41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Windows started as unfocused now show the hollow cursor if the setting is enabled - Empty lines in selections are now properly copied to the clipboard - Selection start point lagging behind initial cursor position +- Rendering of selections which start above the visible area and end below it ### Deprecated diff --git a/src/grid/mod.rs b/src/grid/mod.rs index b8feb421..9e15bd02 100644 --- a/src/grid/mod.rs +++ b/src/grid/mod.rs @@ -116,6 +116,13 @@ pub enum Scroll { Bottom, } +#[derive(Copy, Clone)] +pub enum ViewportPosition { + Visible(Line), + Above, + Below, +} + impl<T: Copy + Clone> Grid<T> { pub fn new(lines: index::Line, cols: index::Column, scrollback: usize, template: T) -> Grid<T> { let raw = Storage::with_capacity(lines, Row::new(cols, &template)); @@ -137,18 +144,14 @@ impl<T: Copy + Clone> Grid<T> { } } - pub fn buffer_to_visible(&self, point: Point<usize>) -> Point { - Point { - line: self.buffer_line_to_visible(point.line).expect("Line not visible"), - col: point.col - } - } - - pub fn buffer_line_to_visible(&self, line: usize) -> Option<Line> { - if line >= self.display_offset { - self.offset_to_line(line - self.display_offset) + pub fn buffer_line_to_visible(&self, line: usize) -> ViewportPosition { + let offset = line.saturating_sub(self.display_offset); + if line < self.display_offset { + ViewportPosition::Below + } else if offset >= *self.num_lines() { + ViewportPosition::Above } else { - None + ViewportPosition::Visible(self.lines - offset - 1) } } @@ -300,14 +303,6 @@ impl<T: Copy + Clone> Grid<T> { *(self.num_lines() - line - 1) } - pub fn offset_to_line(&self, offset: usize) -> Option<Line> { - if offset < *self.num_lines() { - Some(self.lines - offset - 1) - } else { - None - } - } - #[inline] pub fn scroll_down( &mut self, diff --git a/src/term/mod.rs b/src/term/mod.rs index af464320..9be8b96b 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -23,7 +23,7 @@ use unicode_width::UnicodeWidthChar; use font::{self, Size}; use ansi::{self, Color, NamedColor, Attr, Handler, CharsetIndex, StandardCharset, CursorStyle}; -use grid::{BidirectionalIterator, Grid, Indexed, IndexRegion, DisplayIter, Scroll}; +use grid::{BidirectionalIterator, Grid, Indexed, IndexRegion, DisplayIter, Scroll, ViewportPosition}; use index::{self, Point, Column, Line, IndexRange, Contains, RangeInclusive, Linear}; use selection::{self, Selection, Locations}; use config::{Config, VisualBellAnimation}; @@ -136,16 +136,19 @@ impl<'a> RenderableCellsIter<'a> { // Get start/end locations based on what part of selection is on screen let locations = match (start_line, end_line) { - (Some(start_line), Some(end_line)) => { + (ViewportPosition::Visible(start_line), ViewportPosition::Visible(end_line)) => { Some((start_line, loc.start.col, end_line, loc.end.col)) }, - (Some(start_line), None) => { + (ViewportPosition::Visible(start_line), ViewportPosition::Above) => { Some((start_line, loc.start.col, Line(0), Column(0))) }, - (None, Some(end_line)) => { + (ViewportPosition::Below, ViewportPosition::Visible(end_line)) => { Some((grid.num_lines(), Column(0), end_line, loc.end.col)) }, - (None, None) => None, + (ViewportPosition::Below, ViewportPosition::Above) => { + Some((grid.num_lines(), Column(0), Line(0), Column(0))) + }, + _ => None, }; if let Some((start_line, start_col, end_line, end_col)) = locations { |