From 7d1edf01c2d16eedbbfb652b1e57db0f819f12c0 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Wed, 15 Jan 2020 17:36:33 +0100 Subject: [PATCH] Expand line selection across wrapped lines --- CHANGELOG.md | 1 + alacritty_terminal/src/selection.rs | 10 +++++----- alacritty_terminal/src/term/mod.rs | 30 +++++++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e77a2..209036c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Pressing additional modifiers for mouse bindings will no longer trigger them - Renamed `WINIT_HIDPI_FACTOR` environment variable to `WINIT_X11_SCALE_FACTOR` - Print an error instead of crashing, when startup working directory is invalid +- Line selection will now expand across wrapped lines ### Fixed diff --git a/alacritty_terminal/src/selection.rs b/alacritty_terminal/src/selection.rs index 6e6dd9c..1c747d9 100644 --- a/alacritty_terminal/src/selection.rs +++ b/alacritty_terminal/src/selection.rs @@ -317,14 +317,14 @@ impl Selection { Some(Span { start, end, is_block: false }) } - fn span_lines(term: &T, mut start: Point, mut end: Point) -> Option + fn span_lines(term: &T, start: Point, end: Point) -> Option where - T: Dimensions, + T: Search, { - end.col = term.dimensions().col - 1; - start.col = Column(0); + let start = term.line_search_left(start.into()); + let end = term.line_search_right(end.into()); - Some(Span { start: start.into(), end: end.into(), is_block: false }) + Some(Span { start, end, is_block: false }) } fn span_simple( diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index 3e8d861..8edf3d3 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -56,6 +56,10 @@ pub trait Search { fn semantic_search_left(&self, _: Point) -> Point; /// Find the nearest semantic boundary _to the point_ of provided point. fn semantic_search_right(&self, _: Point) -> Point; + /// Find the beginning of a line, following line wraps. + fn line_search_left(&self, _: Point) -> Point; + /// Find the end of a line, following line wraps. + fn line_search_right(&self, _: Point) -> Point; /// Find the nearest matching bracket. fn bracket_search(&self, _: Point) -> Option>; } @@ -109,6 +113,28 @@ impl Search for Term { point } + fn line_search_left(&self, mut point: Point) -> Point { + while point.line + 1 < self.grid.len() + && self.grid[point.line + 1][self.grid.num_cols() - 1].flags.contains(Flags::WRAPLINE) + { + point.line += 1; + } + + point.col = Column(0); + + point + } + + fn line_search_right(&self, mut point: Point) -> Point { + while self.grid[point.line][self.grid.num_cols() - 1].flags.contains(Flags::WRAPLINE) { + point.line -= 1; + } + + point.col = self.grid.num_cols() - 1; + + point + } + fn bracket_search(&self, point: Point) -> Option> { let start_char = self.grid[point.line][point.col].c; @@ -973,7 +999,7 @@ impl Term { tab_mode = true; } - if !cell.flags.contains(cell::Flags::WIDE_CHAR_SPACER) { + if !cell.flags.contains(Flags::WIDE_CHAR_SPACER) { // Push cells primary character text.push(cell.c); @@ -986,7 +1012,7 @@ impl Term { if cols.end >= self.cols() - 1 && (line_end == Column(0) - || !self.grid[line][line_end - 1].flags.contains(cell::Flags::WRAPLINE)) + || !self.grid[line][line_end - 1].flags.contains(Flags::WRAPLINE)) { text.push('\n'); }