aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/grid/mod.rs33
-rw-r--r--src/term/mod.rs13
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 {