aboutsummaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/selection.rs
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2021-03-30 23:25:38 +0000
committerGitHub <noreply@github.com>2021-03-30 23:25:38 +0000
commit3bd5ac221ab3b122962063edd1f4c10f9f2d117f (patch)
treeb0a367b91611e911344aec9ff35354e5a473b6aa /alacritty_terminal/src/selection.rs
parent974392cdc6fdf1ba0d213145ae578a9316e9d404 (diff)
downloadalacritty-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.rs323
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)));
}
}