summaryrefslogtreecommitdiffstats
path: root/alacritty_terminal/src/selection.rs
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2020-07-09 21:45:22 +0000
committerGitHub <noreply@github.com>2020-07-09 21:45:22 +0000
commit46c0f352c40ecb68653421cb178a297acaf00c6d (patch)
tree3e1985f8237f7c8268703634f8c8ccb25f7823a5 /alacritty_terminal/src/selection.rs
parent9974bc8baa45fda0b4ba3db2ae615fb7f90f7029 (diff)
Add regex scrollback buffer search
This adds a new regex search which allows searching the entire scrollback and jumping between matches using the vi mode. All visible matches should be highlighted unless their lines are excessively long. This should help with performance since highlighting is done during render time. Fixes #1017.
Diffstat (limited to 'alacritty_terminal/src/selection.rs')
-rw-r--r--alacritty_terminal/src/selection.rs79
1 files changed, 36 insertions, 43 deletions
diff --git a/alacritty_terminal/src/selection.rs b/alacritty_terminal/src/selection.rs
index dbd11592..83dea824 100644
--- a/alacritty_terminal/src/selection.rs
+++ b/alacritty_terminal/src/selection.rs
@@ -9,8 +9,9 @@ use std::convert::TryFrom;
use std::mem;
use std::ops::{Bound, Range, RangeBounds};
+use crate::grid::Dimensions;
use crate::index::{Column, Line, Point, Side};
-use crate::term::{Search, Term};
+use crate::term::Term;
/// A Point and side within that point.
#[derive(Debug, Copy, Clone, PartialEq)]
@@ -98,20 +99,19 @@ impl Selection {
self.region.end = Anchor::new(point, side);
}
- pub fn rotate(
+ pub fn rotate<D: Dimensions>(
mut self,
- num_lines: Line,
- num_cols: Column,
+ dimensions: &D,
range: &Range<Line>,
delta: isize,
) -> Option<Selection> {
+ let num_lines = dimensions.screen_lines().0;
+ let num_cols = dimensions.cols().0;
let range_bottom = range.start.0;
let range_top = range.end.0;
- let num_lines = num_lines.0;
- let num_cols = num_cols.0;
let (mut start, mut end) = (&mut self.region.start, &mut self.region.end);
- if Self::points_need_swap(start.point, end.point) {
+ if Selection::points_need_swap(start.point, end.point) {
mem::swap(&mut start, &mut end);
}
@@ -238,7 +238,7 @@ impl Selection {
/// Convert selection to grid coordinates.
pub fn to_range<T>(&self, term: &Term<T>) -> Option<SelectionRange> {
let grid = term.grid();
- let num_cols = grid.num_cols();
+ let num_cols = grid.cols();
// Order start above the end.
let mut start = self.region.start;
@@ -250,7 +250,7 @@ impl Selection {
// Clamp to inside the grid buffer.
let is_block = self.ty == SelectionType::Block;
- let (start, end) = Self::grid_clamp(start, end, is_block, grid.len()).ok()?;
+ let (start, end) = Self::grid_clamp(start, end, is_block, grid.total_lines()).ok()?;
match self.ty {
SelectionType::Simple => self.range_simple(start, end, num_cols),
@@ -408,7 +408,7 @@ mod tests {
fn send_event(&self, _event: Event) {}
}
- fn term(width: usize, height: usize) -> Term<Mock> {
+ fn term(height: usize, width: usize) -> Term<Mock> {
let size = SizeInfo {
width: width as f32,
height: height as f32,
@@ -468,7 +468,7 @@ mod tests {
Selection::new(SelectionType::Simple, Point::new(0, Column(0)), Side::Right);
selection.update(Point::new(0, Column(1)), Side::Left);
- assert_eq!(selection.to_range(&term(2, 1)), None);
+ assert_eq!(selection.to_range(&term(1, 2)), None);
}
/// Test adjacent cell selection from right to left.
@@ -482,7 +482,7 @@ mod tests {
Selection::new(SelectionType::Simple, Point::new(0, Column(1)), Side::Left);
selection.update(Point::new(0, Column(0)), Side::Right);
- assert_eq!(selection.to_range(&term(2, 1)), None);
+ assert_eq!(selection.to_range(&term(1, 2)), None);
}
/// Test selection across adjacent lines.
@@ -499,7 +499,7 @@ mod tests {
Selection::new(SelectionType::Simple, Point::new(1, Column(1)), Side::Right);
selection.update(Point::new(0, Column(1)), Side::Right);
- assert_eq!(selection.to_range(&term(5, 2)).unwrap(), SelectionRange {
+ assert_eq!(selection.to_range(&term(2, 5)).unwrap(), SelectionRange {
start: Point::new(1, Column(2)),
end: Point::new(0, Column(1)),
is_block: false,
@@ -523,7 +523,7 @@ mod tests {
selection.update(Point::new(1, Column(1)), Side::Right);
selection.update(Point::new(1, Column(0)), Side::Right);
- assert_eq!(selection.to_range(&term(5, 2)).unwrap(), SelectionRange {
+ assert_eq!(selection.to_range(&term(2, 5)).unwrap(), SelectionRange {
start: Point::new(1, Column(1)),
end: Point::new(0, Column(1)),
is_block: false,
@@ -532,14 +532,13 @@ mod tests {
#[test]
fn line_selection() {
- let num_lines = Line(10);
- let num_cols = Column(5);
+ let size = (Line(10), Column(5));
let mut selection =
Selection::new(SelectionType::Lines, Point::new(0, Column(1)), Side::Left);
selection.update(Point::new(5, Column(1)), Side::Right);
- selection = selection.rotate(num_lines, num_cols, &(Line(0)..num_lines), 7).unwrap();
+ selection = selection.rotate(&size, &(Line(0)..size.0), 7).unwrap();
- assert_eq!(selection.to_range(&term(num_cols.0, num_lines.0)).unwrap(), SelectionRange {
+ assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange {
start: Point::new(9, Column(0)),
end: Point::new(7, Column(4)),
is_block: false,
@@ -548,14 +547,13 @@ mod tests {
#[test]
fn semantic_selection() {
- let num_lines = Line(10);
- let num_cols = Column(5);
+ let size = (Line(10), Column(5));
let mut selection =
Selection::new(SelectionType::Semantic, Point::new(0, Column(3)), Side::Left);
selection.update(Point::new(5, Column(1)), Side::Right);
- selection = selection.rotate(num_lines, num_cols, &(Line(0)..num_lines), 7).unwrap();
+ selection = selection.rotate(&size, &(Line(0)..size.0), 7).unwrap();
- assert_eq!(selection.to_range(&term(num_cols.0, num_lines.0)).unwrap(), SelectionRange {
+ assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange {
start: Point::new(9, Column(0)),
end: Point::new(7, Column(3)),
is_block: false,
@@ -564,14 +562,13 @@ mod tests {
#[test]
fn simple_selection() {
- let num_lines = Line(10);
- let num_cols = Column(5);
+ let size = (Line(10), Column(5));
let mut selection =
Selection::new(SelectionType::Simple, Point::new(0, Column(3)), Side::Right);
selection.update(Point::new(5, Column(1)), Side::Right);
- selection = selection.rotate(num_lines, num_cols, &(Line(0)..num_lines), 7).unwrap();
+ selection = selection.rotate(&size, &(Line(0)..size.0), 7).unwrap();
- assert_eq!(selection.to_range(&term(num_cols.0, num_lines.0)).unwrap(), SelectionRange {
+ assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange {
start: Point::new(9, Column(0)),
end: Point::new(7, Column(3)),
is_block: false,
@@ -580,14 +577,13 @@ mod tests {
#[test]
fn block_selection() {
- let num_lines = Line(10);
- let num_cols = Column(5);
+ let size = (Line(10), Column(5));
let mut selection =
Selection::new(SelectionType::Block, Point::new(0, Column(3)), Side::Right);
selection.update(Point::new(5, Column(1)), Side::Right);
- selection = selection.rotate(num_lines, num_cols, &(Line(0)..num_lines), 7).unwrap();
+ selection = selection.rotate(&size, &(Line(0)..size.0), 7).unwrap();
- assert_eq!(selection.to_range(&term(num_cols.0, num_lines.0)).unwrap(), SelectionRange {
+ assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange {
start: Point::new(9, Column(2)),
end: Point::new(7, Column(3)),
is_block: true
@@ -624,14 +620,13 @@ mod tests {
#[test]
fn rotate_in_region_up() {
- let num_lines = Line(10);
- let num_cols = Column(5);
+ let size = (Line(10), Column(5));
let mut selection =
Selection::new(SelectionType::Simple, Point::new(2, Column(3)), Side::Right);
selection.update(Point::new(5, Column(1)), Side::Right);
- selection = selection.rotate(num_lines, num_cols, &(Line(1)..(num_lines - 1)), 4).unwrap();
+ selection = selection.rotate(&size, &(Line(1)..(size.0 - 1)), 4).unwrap();
- assert_eq!(selection.to_range(&term(num_cols.0, num_lines.0)).unwrap(), SelectionRange {
+ assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange {
start: Point::new(8, Column(0)),
end: Point::new(6, Column(3)),
is_block: false,
@@ -640,30 +635,28 @@ mod tests {
#[test]
fn rotate_in_region_down() {
- let num_lines = Line(10);
- let num_cols = Column(5);
+ let size = (Line(10), Column(5));
let mut selection =
Selection::new(SelectionType::Simple, Point::new(5, Column(3)), Side::Right);
selection.update(Point::new(8, Column(1)), Side::Left);
- selection = selection.rotate(num_lines, num_cols, &(Line(1)..(num_lines - 1)), -5).unwrap();
+ selection = selection.rotate(&size, &(Line(1)..(size.0 - 1)), -5).unwrap();
- assert_eq!(selection.to_range(&term(num_cols.0, num_lines.0)).unwrap(), SelectionRange {
+ assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange {
start: Point::new(3, Column(1)),
- end: Point::new(1, num_cols - 1),
+ end: Point::new(1, size.1 - 1),
is_block: false,
});
}
#[test]
fn rotate_in_region_up_block() {
- let num_lines = Line(10);
- let num_cols = Column(5);
+ let size = (Line(10), Column(5));
let mut selection =
Selection::new(SelectionType::Block, Point::new(2, Column(3)), Side::Right);
selection.update(Point::new(5, Column(1)), Side::Right);
- selection = selection.rotate(num_lines, num_cols, &(Line(1)..(num_lines - 1)), 4).unwrap();
+ selection = selection.rotate(&size, &(Line(1)..(size.0 - 1)), 4).unwrap();
- assert_eq!(selection.to_range(&term(num_cols.0, num_lines.0)).unwrap(), SelectionRange {
+ assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange {
start: Point::new(8, Column(2)),
end: Point::new(6, Column(3)),
is_block: true,