aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2018-03-10 14:53:54 +0100
committerJoe Wilm <joe@jwilm.com>2018-06-02 09:42:08 -0700
commit231ef51365e3cb0de760d04a47a7d2b74809c41d (patch)
tree9d96d2f0294eb318e5021c0656685e19d4a18d24 /src
parent786e274dd1d6dce26404a2ad5672ee33e6115ad0 (diff)
downloadalacritty-231ef51365e3cb0de760d04a47a7d2b74809c41d.tar.gz
alacritty-231ef51365e3cb0de760d04a47a7d2b74809c41d.zip
Fix crash when selection leaves viewport
There was an issue where alacritty tries to convert the lines in a selection to the on-screen lines even when the selection is not on the screen. This results in a crash. To prevent this from happening the selection now is not shown if it is off the screen. There currently still is a bug that when the selection is at the top of the screen but still half visible, it will not show the top line as selected but start in the second line. This bug should be resolved with https://github.com/jwilm/alacritty/pull/1171. This fixes #1148.
Diffstat (limited to 'src')
-rw-r--r--src/grid/mod.rs20
-rw-r--r--src/term/mod.rs58
2 files changed, 52 insertions, 26 deletions
diff --git a/src/grid/mod.rs b/src/grid/mod.rs
index 7f648f46..a52c27c5 100644
--- a/src/grid/mod.rs
+++ b/src/grid/mod.rs
@@ -148,13 +148,17 @@ 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),
+ line: self.buffer_line_to_visible(point.line).expect("Line not visible"),
col: point.col
}
}
- pub fn buffer_line_to_visible(&self, line: usize) -> Line {
- self.offset_to_line(line - self.display_offset)
+ pub fn buffer_line_to_visible(&self, line: usize) -> Option<Line> {
+ if line >= self.display_offset {
+ self.offset_to_line(line - self.display_offset)
+ } else {
+ None
+ }
}
pub fn visible_line_to_buffer(&self, line: Line) -> usize {
@@ -267,10 +271,12 @@ impl<T: Copy + Clone> Grid<T> {
*(self.num_lines() - line - 1)
}
- pub fn offset_to_line(&self, offset: usize) -> Line {
- assert!(offset < *self.num_lines());
-
- self.lines - offset - 1
+ pub fn offset_to_line(&self, offset: usize) -> Option<Line> {
+ if offset < *self.num_lines() {
+ Some(self.lines - offset - 1)
+ } else {
+ None
+ }
}
#[inline]
diff --git a/src/term/mod.rs b/src/term/mod.rs
index c3c3a300..54c8a7e2 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -122,29 +122,49 @@ impl<'a> RenderableCellsIter<'a> {
let cursor_offset = grid.line_to_offset(cursor.line);
let inner = grid.display_iter();
- let selection = selection.map(|loc| {
- // start and end *lines* are swapped as we switch from buffer to
- // Line coordinates.
- let mut end = Point {
- line: grid.buffer_line_to_visible(loc.start.line),
- col: loc.start.col
- };
- let mut start = Point {
- line: grid.buffer_line_to_visible(loc.end.line),
- col: loc.end.col
+ let mut selection_range = None;
+ selection.map(|loc| {
+ // Get on-screen lines of the selection's locations
+ let start_line = grid.buffer_line_to_visible(loc.start.line);
+ let end_line = grid.buffer_line_to_visible(loc.end.line);
+
+ // 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)) => {
+ Some((start_line, loc.start.col, end_line, loc.end.col))
+ },
+ (Some(start_line), None) => {
+ Some((start_line, loc.start.col, Line(0), grid.num_cols()))
+ },
+ (None, Some(end_line)) => {
+ Some((grid.num_lines(), Column(0), end_line, loc.end.col))
+ },
+ (None, None) => None,
};
- if start > end {
- ::std::mem::swap(&mut start, &mut end);
- }
+ if let Some((start_line, start_col, end_line, end_col)) = locations {
+ // start and end *lines* are swapped as we switch from buffer to
+ // Line coordinates.
+ let mut end = Point {
+ line: start_line,
+ col: start_col,
+ };
+ let mut start = Point {
+ line: end_line,
+ col: end_col,
+ };
- println!("start={:?}, end={:?}", start, end);
+ if start > end {
+ ::std::mem::swap(&mut start, &mut end);
+ }
- let cols = grid.num_cols();
- let start = Linear(start.line.0 * cols.0 + start.col.0);
- let end = Linear(end.line.0 * cols.0 + end.col.0);
+ let cols = grid.num_cols();
+ let start = Linear(start.line.0 * cols.0 + start.col.0);
+ let end = Linear(end.line.0 * cols.0 + end.col.0);
- RangeInclusive::new(start, end)
+ // Update the selection
+ selection_range = Some(RangeInclusive::new(start, end));
+ }
});
RenderableCellsIter {
@@ -153,7 +173,7 @@ impl<'a> RenderableCellsIter<'a> {
grid: grid,
inner: inner,
mode: mode,
- selection: selection,
+ selection: selection_range,
config: config,
colors: colors,
cursor_cells: ArrayDeque::new(),