summaryrefslogtreecommitdiff
path: root/src/selection.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/selection.rs')
-rw-r--r--src/selection.rs143
1 files changed, 34 insertions, 109 deletions
diff --git a/src/selection.rs b/src/selection.rs
index f775f1f6..20b1d601 100644
--- a/src/selection.rs
+++ b/src/selection.rs
@@ -245,127 +245,52 @@ impl Selection {
}
fn span_simple<G: Dimensions>(grid: &G, region: &Range<Anchor>) -> Option<Span> {
- let mut start = region.start.point;
+ let start = region.start.point;
let start_side = region.start.side;
- let mut end = region.end.point;
+ let end = region.end.point;
let end_side = region.end.side;
let cols = grid.dimensions().col;
- // Handle some edge cases
- if start.line > end.line {
- if end.col > Column(0) {
- start.col += 1;
- end.col -= 1;
- }
- // Special case for when a multi-line selection to the
- // bottom ends on a new line with just one cell selected
- // and the first cell should not be selected
- else {
- if start_side == Side::Right {
- start.col += 1;
- }
-
- // Remove the single selected cell if mouse left window
- if end_side == Side::Left {
- end.line += 1;
- end.col = cols - 1;
- }
-
- return Some(Span {
- cols,
- front: end,
- tail: start,
- ty: SpanType::Inclusive,
- });
- }
- } else if start.line < end.line {
- end.col += 1;
- if start.col > Column(0) {
- start.col -= 1;
- }
- // Special case for when a selection is started
- // in the first cell of a line
- else {
- let ty = match end_side {
- Side::Left => SpanType::ExcludeTail,
- Side::Right => SpanType::Inclusive,
- };
-
- // Switch start cell to last cell of previous line
- if start_side == Side::Left {
- start.line += 1;
- start.col = cols - 1;
- }
-
- return Some(Span {
- ty,
- cols,
- front: start,
- tail: end,
- });
- }
+ // No selection for single cell with identical sides or two cell with right+left sides
+ if (start == end && start_side == end_side)
+ || (start_side == Side::Right && end_side == Side::Left && end.col == start.col + 1)
+ {
+ return None;
}
- let (front, tail, front_side, tail_side) = if start > end {
- // Selected upward; start/end are swapped
- (end, start, end_side, start_side)
- } else {
- // Selected downward; no swapping
- (start, end, start_side, end_side)
- };
-
- debug_assert!(!(tail < front));
-
- // Single-cell selections are a special case
- if start == end {
- if start_side == end_side {
- return None;
+ // Make sure front is always the "bottom" and tail is always the "top"
+ let (mut front, mut tail, front_side, tail_side) =
+ if start.line > end.line || start.line == end.line && start.col <= end.col {
+ // Selected upward; start/end are swapped
+ (end, start, end_side, start_side)
} else {
- return Some(Span {
- cols,
- ty: SpanType::Inclusive,
- front,
- tail,
- });
+ // Selected downward; no swapping
+ (start, end, start_side, end_side)
+ };
+
+ // Remove last cell if selection ends to the left of a cell
+ if front_side == Side::Left && start != end {
+ if front.col != Column(0) {
+ front.col -= 1;
+ }
+ // Special case when selection starts to left of first cell
+ else {
+ front.col = cols - 1;
+ front.line += 1;
}
}
- // The other special case is two adjacent cells with no
- // selection: [ B][E ] or [ E][B ]
- let adjacent = tail.line == front.line && tail.col - front.col == Column(1);
- if adjacent && front_side == Side::Right && tail_side == Side::Left {
- return None;
+ // Remove first cell if selection starts at the right of a cell
+ if tail_side == Side::Right && front != tail {
+ tail.col += 1;
}
- Some(match (front_side, tail_side) {
- // [FX][XX][XT]
- (Side::Left, Side::Right) => Span {
- cols,
- front,
- tail,
- ty: SpanType::Inclusive
- },
- // [ F][XX][T ]
- (Side::Right, Side::Left) => Span {
- cols,
- front,
- tail,
- ty: SpanType::Exclusive
- },
- // [FX][XX][T ]
- (Side::Left, Side::Left) => Span {
- cols,
- front,
- tail,
- ty: SpanType::ExcludeTail
- },
- // [ F][XX][XT]
- (Side::Right, Side::Right) => Span {
- cols,
- front,
- tail,
- ty: SpanType::ExcludeFront
- },
+ // Return the selection with all cells inclusive
+ Some(Span {
+ cols,
+ front,
+ tail,
+ ty: SpanType::Inclusive,
})
}
}