diff options
author | Christian Duerr <contact@christianduerr.com> | 2021-03-30 23:25:38 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-30 23:25:38 +0000 |
commit | 3bd5ac221ab3b122962063edd1f4c10f9f2d117f (patch) | |
tree | b0a367b91611e911344aec9ff35354e5a473b6aa /alacritty_terminal/src/selection.rs | |
parent | 974392cdc6fdf1ba0d213145ae578a9316e9d404 (diff) | |
download | alacritty-3bd5ac221ab3b122962063edd1f4c10f9f2d117f.tar.gz alacritty-3bd5ac221ab3b122962063edd1f4c10f9f2d117f.zip |
Unify the grid line indexing types
Previously Alacritty was using two different ways to reference lines in
the terminal. Either a `usize`, or a `Line(usize)`. These indexing
systems both served different purposes, but made it difficult to reason
about logic involving these systems because of its inconsistency.
To resolve this issue, a single new `Line(i32)` type has been
introduced. All existing references to lines and points now rely on
this definition of a line.
The indexing starts at the top of the terminal region with the line 0,
which matches the line 1 used by escape sequences. Each line in the
history becomes increasingly negative and the bottommost line is equal
to the number of visible lines minus one.
Having a system which goes into the negatives allows following the
escape sequence's indexing system closely, while at the same time making
it trivial to implement `Ord` for points.
The Alacritty UI crate is the only place which has a different indexing
system, since rendering and input puts the zero line at the top of the
viewport, rather than the top of the terminal region.
All instances which refer to a number of lines/columns instead of just a
single Line/Column have also been changed to use a `usize` instead. This
way a Line/Column will always refer to a specific place in the grid and
no confusion is created by having a count of lines as a possible index
into the grid storage.
Diffstat (limited to 'alacritty_terminal/src/selection.rs')
-rw-r--r-- | alacritty_terminal/src/selection.rs | 323 |
1 files changed, 139 insertions, 184 deletions
diff --git a/alacritty_terminal/src/selection.rs b/alacritty_terminal/src/selection.rs index afb98c0d..95c19be4 100644 --- a/alacritty_terminal/src/selection.rs +++ b/alacritty_terminal/src/selection.rs @@ -5,7 +5,7 @@ //! when text is added/removed/scrolled on the screen. The selection should //! also be cleared if the user clicks off of the selection. -use std::convert::TryFrom; +use std::cmp::min; use std::mem; use std::ops::{Bound, Range, RangeBounds}; @@ -18,34 +18,34 @@ use crate::term::{RenderableCursor, Term}; /// A Point and side within that point. #[derive(Debug, Copy, Clone, PartialEq)] struct Anchor { - point: Point<usize>, + point: Point, side: Side, } impl Anchor { - fn new(point: Point<usize>, side: Side) -> Anchor { + fn new(point: Point, side: Side) -> Anchor { Anchor { point, side } } } /// Represents a range of selected cells. #[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct SelectionRange<L = usize> { +pub struct SelectionRange { /// Start point, top left of the selection. - pub start: Point<L>, + pub start: Point, /// End point, bottom right of the selection. - pub end: Point<L>, + pub end: Point, /// Whether this selection is a block selection. pub is_block: bool, } -impl<L> SelectionRange<L> { - pub fn new(start: Point<L>, end: Point<L>, is_block: bool) -> Self { +impl SelectionRange { + pub fn new(start: Point, end: Point, is_block: bool) -> Self { Self { start, end, is_block } } } -impl SelectionRange<Line> { +impl SelectionRange { /// Check if a point lies within the selection. pub fn contains(&self, point: Point) -> bool { self.start.line <= point.line @@ -56,7 +56,7 @@ impl SelectionRange<Line> { } /// Check if the cell at a point is part of the selection. - pub fn contains_cell(&self, indexed: &Indexed<&Cell, Line>, cursor: RenderableCursor) -> bool { + pub fn contains_cell(&self, indexed: &Indexed<&Cell>, cursor: RenderableCursor) -> bool { // Do not invert block cursor at selection boundaries. if cursor.shape == CursorShape::Block && cursor.point == indexed.point @@ -116,7 +116,7 @@ pub struct Selection { } impl Selection { - pub fn new(ty: SelectionType, location: Point<usize>, side: Side) -> Selection { + pub fn new(ty: SelectionType, location: Point, side: Side) -> Selection { Self { region: Range { start: Anchor::new(location, side), end: Anchor::new(location, side) }, ty, @@ -124,7 +124,7 @@ impl Selection { } /// Update the end of the selection. - pub fn update(&mut self, point: Point<usize>, side: Side) { + pub fn update(&mut self, point: Point, side: Side) { self.region.end = Anchor::new(point, side); } @@ -132,56 +132,52 @@ impl Selection { mut self, dimensions: &D, range: &Range<Line>, - delta: isize, + delta: i32, ) -> 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 bottommost_line = dimensions.bottommost_line(); + let range_bottom = range.end; + let range_top = range.start; let (mut start, mut end) = (&mut self.region.start, &mut self.region.end); - if Selection::points_need_swap(start.point, end.point) { + if start.point > end.point { mem::swap(&mut start, &mut end); } // Rotate start of selection. - if (start.point.line < range_top || range_top == num_lines) - && start.point.line >= range_bottom - { - start.point.line = usize::try_from(start.point.line as isize + delta).unwrap_or(0); + if (start.point.line >= range_top || range_top == 0) && start.point.line < range_bottom { + start.point.line = min(start.point.line - delta, bottommost_line); // If end is within the same region, delete selection once start rotates out. - if start.point.line < range_bottom && end.point.line >= range_bottom { + if start.point.line >= range_bottom && end.point.line < range_bottom { return None; } // Clamp selection to start of region. - if start.point.line >= range_top && range_top != num_lines { + if start.point.line < range_top && range_top != 0 { if self.ty != SelectionType::Block { start.point.column = Column(0); start.side = Side::Left; } - start.point.line = range_top - 1; + start.point.line = range_top; } } // Rotate end of selection. - if (end.point.line < range_top || range_top == num_lines) && end.point.line >= range_bottom - { - end.point.line = usize::try_from(end.point.line as isize + delta).unwrap_or(0); + if (end.point.line >= range_top || range_top == 0) && end.point.line < range_bottom { + end.point.line = min(end.point.line - delta, bottommost_line); // Delete selection if end has overtaken the start. - if end.point.line > start.point.line { + if end.point.line < start.point.line { return None; } // Clamp selection to end of region. - if end.point.line < range_bottom { + if end.point.line >= range_bottom { if self.ty != SelectionType::Block { - end.point.column = Column(num_cols - 1); + end.point.column = dimensions.last_column(); end.side = Side::Right; } - end.point.line = range_bottom; + end.point.line = range_bottom - 1; } } @@ -192,7 +188,7 @@ impl Selection { match self.ty { SelectionType::Simple => { let (mut start, mut end) = (self.region.start, self.region.end); - if Self::points_need_swap(start.point, end.point) { + if start.point > end.point { mem::swap(&mut start, &mut end); } @@ -223,27 +219,27 @@ impl Selection { } /// Check whether selection contains any point in a given range. - pub fn intersects_range<R: RangeBounds<usize>>(&self, range: R) -> bool { + pub fn intersects_range<R: RangeBounds<Line>>(&self, range: R) -> bool { let mut start = self.region.start.point.line; let mut end = self.region.end.point.line; - if Self::points_need_swap(self.region.start.point, self.region.end.point) { + if start > end { mem::swap(&mut start, &mut end); } - let range_start = match range.start_bound() { + let range_top = match range.start_bound() { Bound::Included(&range_start) => range_start, - Bound::Excluded(&range_start) => range_start.saturating_add(1), - Bound::Unbounded => 0, + Bound::Excluded(&range_start) => range_start + 1, + Bound::Unbounded => Line(i32::min_value()), }; - let range_end = match range.end_bound() { + let range_bottom = match range.end_bound() { Bound::Included(&range_end) => range_end, - Bound::Excluded(&range_end) => range_end.saturating_sub(1), - Bound::Unbounded => usize::max_value(), + Bound::Excluded(&range_end) => range_end - 1, + Bound::Unbounded => Line(i32::max_value()), }; - range_start <= start && range_end >= end + range_bottom >= start && range_top <= end } /// Expand selection sides to include all cells. @@ -257,7 +253,7 @@ impl Selection { (Side::Right, Side::Left) }, SelectionType::Block => (Side::Left, Side::Right), - _ if Self::points_need_swap(start, end) => (Side::Right, Side::Left), + _ if start > end => (Side::Right, Side::Left), _ => (Side::Left, Side::Right), }; @@ -268,63 +264,25 @@ 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.cols(); + let columns = grid.columns(); // Order start above the end. let mut start = self.region.start; let mut end = self.region.end; - if Self::points_need_swap(start.point, end.point) { + if start.point > end.point { mem::swap(&mut start, &mut end); } - // Clamp to inside the grid buffer. - let is_block = self.ty == SelectionType::Block; - 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), + SelectionType::Simple => self.range_simple(start, end, columns), SelectionType::Block => self.range_block(start, end), SelectionType::Semantic => Some(Self::range_semantic(term, start.point, end.point)), SelectionType::Lines => Some(Self::range_lines(term, start.point, end.point)), } } - /// Bring start and end points in the correct order. - fn points_need_swap(start: Point<usize>, end: Point<usize>) -> bool { - start.line < end.line || start.line == end.line && start.column > end.column - } - - /// Clamp selection inside grid to prevent OOB. - fn grid_clamp( - mut start: Anchor, - end: Anchor, - is_block: bool, - lines: usize, - ) -> Result<(Anchor, Anchor), ()> { - // Clamp selection inside of grid to prevent OOB. - if start.point.line >= lines { - // Remove selection if it is fully out of the grid. - if end.point.line >= lines { - return Err(()); - } - - // Clamp to grid if it is still partially visible. - if !is_block { - start.side = Side::Left; - start.point.column = Column(0); - } - start.point.line = lines - 1; - } - - Ok((start, end)) - } - - fn range_semantic<T>( - term: &Term<T>, - mut start: Point<usize>, - mut end: Point<usize>, - ) -> SelectionRange { + fn range_semantic<T>(term: &Term<T>, mut start: Point, mut end: Point) -> SelectionRange { if start == end { if let Some(matching) = term.bracket_search(start) { if (matching.line == start.line && matching.column < start.column) @@ -339,19 +297,15 @@ impl Selection { } } - start = term.semantic_search_left(start); - end = term.semantic_search_right(end); + let start = term.semantic_search_left(start); + let end = term.semantic_search_right(end); SelectionRange { start, end, is_block: false } } - fn range_lines<T>( - term: &Term<T>, - mut start: Point<usize>, - mut end: Point<usize>, - ) -> SelectionRange { - start = term.line_search_left(start); - end = term.line_search_right(end); + fn range_lines<T>(term: &Term<T>, start: Point, end: Point) -> SelectionRange { + let start = term.line_search_left(start); + let end = term.line_search_right(end); SelectionRange { start, end, is_block: false } } @@ -360,7 +314,7 @@ impl Selection { &self, mut start: Anchor, mut end: Anchor, - num_cols: Column, + columns: usize, ) -> Option<SelectionRange> { if self.is_empty() { return None; @@ -369,9 +323,9 @@ impl Selection { // Remove last cell if selection ends to the left of a cell. if end.side == Side::Left && start.point != end.point { // Special case when selection ends to left of first cell. - if end.point.column == Column(0) { - end.point.column = num_cols - 1; - end.point.line += 1; + if end.point.column == 0 { + end.point.column = Column(columns - 1); + end.point.line -= 1; } else { end.point.column -= 1; } @@ -382,8 +336,9 @@ impl Selection { start.point.column += 1; // Wrap to next line when selection starts to the right of last column. - if start.point.column == num_cols { - start.point = Point::new(start.point.line.saturating_sub(1), Column(0)); + if start.point.column == columns { + start.point.column = Column(0); + start.point.line += 1; } } @@ -429,7 +384,7 @@ mod tests { use super::*; use crate::config::MockConfig; - use crate::index::{Column, Line, Point, Side}; + use crate::index::{Column, Point, Side}; use crate::term::{SizeInfo, Term}; fn term(height: usize, width: usize) -> Term<()> { @@ -444,7 +399,7 @@ mod tests { /// 3. [BE] #[test] fn single_cell_left_to_right() { - let location = Point { line: 0, column: Column(0) }; + let location = Point::new(Line(0), Column(0)); let mut selection = Selection::new(SelectionType::Simple, location, Side::Left); selection.update(location, Side::Right); @@ -462,7 +417,7 @@ mod tests { /// 3. [EB] #[test] fn single_cell_right_to_left() { - let location = Point { line: 0, column: Column(0) }; + let location = Point::new(Line(0), Column(0)); let mut selection = Selection::new(SelectionType::Simple, location, Side::Right); selection.update(location, Side::Left); @@ -481,8 +436,8 @@ mod tests { #[test] fn between_adjacent_cells_left_to_right() { let mut selection = - Selection::new(SelectionType::Simple, Point::new(0, Column(0)), Side::Right); - selection.update(Point::new(0, Column(1)), Side::Left); + Selection::new(SelectionType::Simple, Point::new(Line(0), Column(0)), Side::Right); + selection.update(Point::new(Line(0), Column(1)), Side::Left); assert_eq!(selection.to_range(&term(1, 2)), None); } @@ -495,8 +450,8 @@ mod tests { #[test] fn between_adjacent_cells_right_to_left() { let mut selection = - Selection::new(SelectionType::Simple, Point::new(0, Column(1)), Side::Left); - selection.update(Point::new(0, Column(0)), Side::Right); + Selection::new(SelectionType::Simple, Point::new(Line(0), Column(1)), Side::Left); + selection.update(Point::new(Line(0), Column(0)), Side::Right); assert_eq!(selection.to_range(&term(1, 2)), None); } @@ -512,12 +467,12 @@ mod tests { #[test] fn across_adjacent_lines_upward_final_cell_exclusive() { let mut selection = - Selection::new(SelectionType::Simple, Point::new(1, Column(1)), Side::Right); - selection.update(Point::new(0, Column(1)), Side::Right); + Selection::new(SelectionType::Simple, Point::new(Line(0), Column(1)), Side::Right); + selection.update(Point::new(Line(1), Column(1)), Side::Right); assert_eq!(selection.to_range(&term(2, 5)).unwrap(), SelectionRange { - start: Point::new(1, Column(2)), - end: Point::new(0, Column(1)), + start: Point::new(Line(0), Column(2)), + end: Point::new(Line(1), Column(1)), is_block: false, }); } @@ -535,73 +490,73 @@ mod tests { #[test] fn selection_bigger_then_smaller() { let mut selection = - Selection::new(SelectionType::Simple, Point::new(0, Column(1)), Side::Right); - selection.update(Point::new(1, Column(1)), Side::Right); - selection.update(Point::new(1, Column(0)), Side::Right); + Selection::new(SelectionType::Simple, Point::new(Line(1), Column(1)), Side::Right); + selection.update(Point::new(Line(0), Column(1)), Side::Right); + selection.update(Point::new(Line(0), Column(0)), Side::Right); assert_eq!(selection.to_range(&term(2, 5)).unwrap(), SelectionRange { - start: Point::new(1, Column(1)), - end: Point::new(0, Column(1)), + start: Point::new(Line(0), Column(1)), + end: Point::new(Line(1), Column(1)), is_block: false, }); } #[test] fn line_selection() { - let size = (Line(10), Column(5)); + let size = (10, 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(&size, &(Line(0)..size.0), 7).unwrap(); + Selection::new(SelectionType::Lines, Point::new(Line(9), Column(1)), Side::Left); + selection.update(Point::new(Line(4), Column(1)), Side::Right); + selection = selection.rotate(&size, &(Line(0)..Line(size.0 as i32)), 7).unwrap(); - assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange { - start: Point::new(9, Column(0)), - end: Point::new(7, Column(4)), + assert_eq!(selection.to_range(&term(size.0, size.1)).unwrap(), SelectionRange { + start: Point::new(Line(-3), Column(0)), + end: Point::new(Line(2), Column(4)), is_block: false, }); } #[test] fn semantic_selection() { - let size = (Line(10), Column(5)); + let size = (10, 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(&size, &(Line(0)..size.0), 7).unwrap(); + Selection::new(SelectionType::Semantic, Point::new(Line(9), Column(3)), Side::Left); + selection.update(Point::new(Line(4), Column(1)), Side::Right); + selection = selection.rotate(&size, &(Line(0)..Line(size.0 as i32)), 4).unwrap(); - assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange { - start: Point::new(9, Column(0)), - end: Point::new(7, Column(3)), + assert_eq!(selection.to_range(&term(size.0, size.1)).unwrap(), SelectionRange { + start: Point::new(Line(0), Column(1)), + end: Point::new(Line(5), Column(3)), is_block: false, }); } #[test] fn simple_selection() { - let size = (Line(10), Column(5)); + let size = (10, 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(&size, &(Line(0)..size.0), 7).unwrap(); + Selection::new(SelectionType::Simple, Point::new(Line(9), Column(3)), Side::Right); + selection.update(Point::new(Line(4), Column(1)), Side::Right); + selection = selection.rotate(&size, &(Line(0)..Line(size.0 as i32)), 7).unwrap(); - assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange { - start: Point::new(9, Column(0)), - end: Point::new(7, Column(3)), + assert_eq!(selection.to_range(&term(size.0, size.1)).unwrap(), SelectionRange { + start: Point::new(Line(-3), Column(2)), + end: Point::new(Line(2), Column(3)), is_block: false, }); } #[test] fn block_selection() { - let size = (Line(10), Column(5)); + let size = (10, 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(&size, &(Line(0)..size.0), 7).unwrap(); + Selection::new(SelectionType::Block, Point::new(Line(9), Column(3)), Side::Right); + selection.update(Point::new(Line(4), Column(1)), Side::Right); + selection = selection.rotate(&size, &(Line(0)..Line(size.0 as i32)), 7).unwrap(); - assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange { - start: Point::new(9, Column(2)), - end: Point::new(7, Column(3)), + assert_eq!(selection.to_range(&term(size.0, size.1)).unwrap(), SelectionRange { + start: Point::new(Line(-3), Column(2)), + end: Point::new(Line(2), Column(3)), is_block: true }); } @@ -609,72 +564,72 @@ mod tests { #[test] fn simple_is_empty() { let mut selection = - Selection::new(SelectionType::Simple, Point::new(0, Column(0)), Side::Right); + Selection::new(SelectionType::Simple, Point::new(Line(1), Column(0)), Side::Right); assert!(selection.is_empty()); - selection.update(Point::new(0, Column(1)), Side::Left); + selection.update(Point::new(Line(1), Column(1)), Side::Left); assert!(selection.is_empty()); - selection.update(Point::new(1, Column(0)), Side::Right); + selection.update(Point::new(Line(0), Column(0)), Side::Right); assert!(!selection.is_empty()); } #[test] fn block_is_empty() { let mut selection = - Selection::new(SelectionType::Block, Point::new(0, Column(0)), Side::Right); + Selection::new(SelectionType::Block, Point::new(Line(1), Column(0)), Side::Right); assert!(selection.is_empty()); - selection.update(Point::new(0, Column(1)), Side::Left); + selection.update(Point::new(Line(1), Column(1)), Side::Left); assert!(selection.is_empty()); - selection.update(Point::new(0, Column(1)), Side::Right); + selection.update(Point::new(Line(1), Column(1)), Side::Right); assert!(!selection.is_empty()); - selection.update(Point::new(1, Column(0)), Side::Right); + selection.update(Point::new(Line(0), Column(0)), Side::Right); assert!(selection.is_empty()); - selection.update(Point::new(1, Column(1)), Side::Left); + selection.update(Point::new(Line(0), Column(1)), Side::Left); assert!(selection.is_empty()); - selection.update(Point::new(1, Column(1)), Side::Right); + selection.update(Point::new(Line(0), Column(1)), Side::Right); assert!(!selection.is_empty()); } #[test] fn rotate_in_region_up() { - let size = (Line(10), Column(5)); + let size = (10, 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(&size, &(Line(1)..(size.0 - 1)), 4).unwrap(); + Selection::new(SelectionType::Simple, Point::new(Line(7), Column(3)), Side::Right); + selection.update(Point::new(Line(4), Column(1)), Side::Right); + selection = selection.rotate(&size, &(Line(1)..Line(size.0 as i32 - 1)), 4).unwrap(); - assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange { - start: Point::new(8, Column(0)), - end: Point::new(6, Column(3)), + assert_eq!(selection.to_range(&term(size.0, size.1)).unwrap(), SelectionRange { + start: Point::new(Line(1), Column(0)), + end: Point::new(Line(3), Column(3)), is_block: false, }); } #[test] fn rotate_in_region_down() { - let size = (Line(10), Column(5)); + let size = (10, 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(&size, &(Line(1)..(size.0 - 1)), -5).unwrap(); + Selection::new(SelectionType::Simple, Point::new(Line(4), Column(3)), Side::Right); + selection.update(Point::new(Line(1), Column(1)), Side::Left); + selection = selection.rotate(&size, &(Line(1)..Line(size.0 as i32 - 1)), -5).unwrap(); - assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange { - start: Point::new(3, Column(1)), - end: Point::new(1, size.1 - 1), + assert_eq!(selection.to_range(&term(size.0, size.1)).unwrap(), SelectionRange { + start: Point::new(Line(6), Column(1)), + end: Point::new(Line(8), size.last_column()), is_block: false, }); } #[test] fn rotate_in_region_up_block() { - let size = (Line(10), Column(5)); + let size = (10, 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(&size, &(Line(1)..(size.0 - 1)), 4).unwrap(); + Selection::new(SelectionType::Block, Point::new(Line(7), Column(3)), Side::Right); + selection.update(Point::new(Line(4), Column(1)), Side::Right); + selection = selection.rotate(&size, &(Line(1)..Line(size.0 as i32 - 1)), 4).unwrap(); - assert_eq!(selection.to_range(&term(*size.0, *size.1)).unwrap(), SelectionRange { - start: Point::new(8, Column(2)), - end: Point::new(6, Column(3)), + assert_eq!(selection.to_range(&term(size.0, size.1)).unwrap(), SelectionRange { + start: Point::new(Line(1), Column(2)), + end: Point::new(Line(3), Column(3)), is_block: true, }); } @@ -682,17 +637,17 @@ mod tests { #[test] fn range_intersection() { let mut selection = - Selection::new(SelectionType::Lines, Point::new(6, Column(1)), Side::Left); - selection.update(Point::new(3, Column(1)), Side::Right); + Selection::new(SelectionType::Lines, Point::new(Line(3), Column(1)), Side::Left); + selection.update(Point::new(Line(6), Column(1)), Side::Right); assert!(selection.intersects_range(..)); - assert!(selection.intersects_range(2..)); - assert!(selection.intersects_range(2..=4)); - assert!(selection.intersects_range(2..=7)); - assert!(selection.intersects_range(4..=5)); - assert!(selection.intersects_range(5..8)); - - assert!(!selection.intersects_range(..=2)); - assert!(!selection.intersects_range(7..=8)); + assert!(selection.intersects_range(Line(2)..)); + assert!(selection.intersects_range(Line(2)..=Line(4))); + assert!(selection.intersects_range(Line(2)..=Line(7))); + assert!(selection.intersects_range(Line(4)..=Line(5))); + assert!(selection.intersects_range(Line(5)..Line(8))); + + assert!(!selection.intersects_range(..=Line(2))); + assert!(!selection.intersects_range(Line(7)..=Line(8))); } } |