summaryrefslogtreecommitdiffstats
path: root/alacritty_terminal/src/selection.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty_terminal/src/selection.rs')
-rw-r--r--alacritty_terminal/src/selection.rs106
1 files changed, 55 insertions, 51 deletions
diff --git a/alacritty_terminal/src/selection.rs b/alacritty_terminal/src/selection.rs
index f663417f..369846cf 100644
--- a/alacritty_terminal/src/selection.rs
+++ b/alacritty_terminal/src/selection.rs
@@ -27,7 +27,7 @@ use crate::term::{Search, Term};
/// A Point and side within that point.
#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct Anchor {
+struct Anchor {
point: Point<usize>,
side: Side,
}
@@ -67,7 +67,7 @@ impl<L> SelectionRange<L> {
/// Different kinds of selection.
#[derive(Debug, Copy, Clone, PartialEq)]
-enum SelectionType {
+pub enum SelectionType {
Simple,
Block,
Semantic,
@@ -94,48 +94,20 @@ enum SelectionType {
/// [`update`]: enum.Selection.html#method.update
#[derive(Debug, Clone, PartialEq)]
pub struct Selection {
+ pub ty: SelectionType,
region: Range<Anchor>,
- ty: SelectionType,
}
impl Selection {
- pub fn simple(location: Point<usize>, side: Side) -> Selection {
+ pub fn new(ty: SelectionType, location: Point<usize>, side: Side) -> Selection {
Self {
region: Range { start: Anchor::new(location, side), end: Anchor::new(location, side) },
- ty: SelectionType::Simple,
+ ty,
}
}
- pub fn block(location: Point<usize>, side: Side) -> Selection {
- Self {
- region: Range { start: Anchor::new(location, side), end: Anchor::new(location, side) },
- ty: SelectionType::Block,
- }
- }
-
- pub fn semantic(location: Point<usize>) -> Selection {
- Self {
- region: Range {
- start: Anchor::new(location, Side::Left),
- end: Anchor::new(location, Side::Right),
- },
- ty: SelectionType::Semantic,
- }
- }
-
- pub fn lines(location: Point<usize>) -> Selection {
- Self {
- region: Range {
- start: Anchor::new(location, Side::Left),
- end: Anchor::new(location, Side::Right),
- },
- ty: SelectionType::Lines,
- }
- }
-
- pub fn update(&mut self, location: Point<usize>, side: Side) {
- self.region.end.point = location;
- self.region.end.side = side;
+ pub fn update(&mut self, point: Point<usize>, side: Side) {
+ self.region.end = Anchor::new(point, side);
}
pub fn rotate(
@@ -233,6 +205,24 @@ impl Selection {
}
}
+ /// Expand selection sides to include all cells.
+ pub fn include_all(&mut self) {
+ let (start, end) = (self.region.start.point, self.region.end.point);
+ let (start_side, end_side) = match self.ty {
+ SelectionType::Block
+ if start.col > end.col || (start.col == end.col && start.line < end.line) =>
+ {
+ (Side::Right, Side::Left)
+ },
+ SelectionType::Block => (Side::Left, Side::Right),
+ _ if Self::points_need_swap(start, end) => (Side::Right, Side::Left),
+ _ => (Side::Left, Side::Right),
+ };
+
+ self.region.start.side = start_side;
+ self.region.end.side = end_side;
+ }
+
/// Convert selection to grid coordinates.
pub fn to_range<T>(&self, term: &Term<T>) -> Option<SelectionRange> {
let grid = term.grid();
@@ -392,7 +382,8 @@ impl Selection {
/// look like [ B] and [E ].
#[cfg(test)]
mod tests {
- use super::{Selection, SelectionRange};
+ use super::*;
+
use crate::clipboard::Clipboard;
use crate::config::MockConfig;
use crate::event::{Event, EventListener};
@@ -425,7 +416,7 @@ mod tests {
#[test]
fn single_cell_left_to_right() {
let location = Point { line: 0, col: Column(0) };
- let mut selection = Selection::simple(location, Side::Left);
+ let mut selection = Selection::new(SelectionType::Simple, location, Side::Left);
selection.update(location, Side::Right);
assert_eq!(selection.to_range(&term(1, 1)).unwrap(), SelectionRange {
@@ -443,7 +434,7 @@ mod tests {
#[test]
fn single_cell_right_to_left() {
let location = Point { line: 0, col: Column(0) };
- let mut selection = Selection::simple(location, Side::Right);
+ let mut selection = Selection::new(SelectionType::Simple, location, Side::Right);
selection.update(location, Side::Left);
assert_eq!(selection.to_range(&term(1, 1)).unwrap(), SelectionRange {
@@ -460,7 +451,8 @@ mod tests {
/// 3. [ B][E ]
#[test]
fn between_adjacent_cells_left_to_right() {
- let mut selection = Selection::simple(Point::new(0, Column(0)), Side::Right);
+ let mut selection =
+ 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);
@@ -473,7 +465,8 @@ mod tests {
/// 3. [ E][B ]
#[test]
fn between_adjacent_cells_right_to_left() {
- let mut selection = Selection::simple(Point::new(0, Column(1)), Side::Left);
+ let mut selection =
+ 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);
@@ -489,7 +482,8 @@ mod tests {
/// [XX][XE][ ][ ][ ]
#[test]
fn across_adjacent_lines_upward_final_cell_exclusive() {
- let mut selection = Selection::simple(Point::new(1, Column(1)), Side::Right);
+ let mut selection =
+ 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 {
@@ -511,7 +505,8 @@ mod tests {
/// [XX][XB][ ][ ][ ]
#[test]
fn selection_bigger_then_smaller() {
- let mut selection = Selection::simple(Point::new(0, Column(1)), Side::Right);
+ 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);
@@ -526,7 +521,8 @@ mod tests {
fn line_selection() {
let num_lines = 10;
let num_cols = 5;
- let mut selection = Selection::lines(Point::new(0, Column(1)));
+ 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)..Line(num_lines)), 7).unwrap();
@@ -541,7 +537,8 @@ mod tests {
fn semantic_selection() {
let num_lines = 10;
let num_cols = 5;
- let mut selection = Selection::semantic(Point::new(0, Column(3)));
+ 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)..Line(num_lines)), 7).unwrap();
@@ -556,7 +553,8 @@ mod tests {
fn simple_selection() {
let num_lines = 10;
let num_cols = 5;
- let mut selection = Selection::simple(Point::new(0, Column(3)), Side::Right);
+ 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)..Line(num_lines)), 7).unwrap();
@@ -571,7 +569,8 @@ mod tests {
fn block_selection() {
let num_lines = 10;
let num_cols = 5;
- let mut selection = Selection::block(Point::new(0, Column(3)), Side::Right);
+ 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)..Line(num_lines)), 7).unwrap();
@@ -584,7 +583,8 @@ mod tests {
#[test]
fn simple_is_empty() {
- let mut selection = Selection::simple(Point::new(0, Column(0)), Side::Right);
+ let mut selection =
+ Selection::new(SelectionType::Simple, Point::new(0, Column(0)), Side::Right);
assert!(selection.is_empty());
selection.update(Point::new(0, Column(1)), Side::Left);
assert!(selection.is_empty());
@@ -594,7 +594,8 @@ mod tests {
#[test]
fn block_is_empty() {
- let mut selection = Selection::block(Point::new(0, Column(0)), Side::Right);
+ let mut selection =
+ Selection::new(SelectionType::Block, Point::new(0, Column(0)), Side::Right);
assert!(selection.is_empty());
selection.update(Point::new(0, Column(1)), Side::Left);
assert!(selection.is_empty());
@@ -612,7 +613,8 @@ mod tests {
fn rotate_in_region_up() {
let num_lines = 10;
let num_cols = 5;
- let mut selection = Selection::simple(Point::new(2, Column(3)), Side::Right);
+ 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)..Line(num_lines - 1)), 4).unwrap();
@@ -628,7 +630,8 @@ mod tests {
fn rotate_in_region_down() {
let num_lines = 10;
let num_cols = 5;
- let mut selection = Selection::simple(Point::new(5, Column(3)), Side::Right);
+ 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)..Line(num_lines - 1)), -5).unwrap();
@@ -644,7 +647,8 @@ mod tests {
fn rotate_in_region_up_block() {
let num_lines = 10;
let num_cols = 5;
- let mut selection = Selection::block(Point::new(2, Column(3)), Side::Right);
+ 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)..Line(num_lines - 1)), 4).unwrap();