aboutsummaryrefslogtreecommitdiff
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.rs61
1 files changed, 47 insertions, 14 deletions
diff --git a/alacritty_terminal/src/selection.rs b/alacritty_terminal/src/selection.rs
index 5f94634f..6e6dd9c8 100644
--- a/alacritty_terminal/src/selection.rs
+++ b/alacritty_terminal/src/selection.rs
@@ -183,9 +183,9 @@ impl Selection {
}
// Clamp to visible region in grid/normal
- let cols = term.dimensions().col;
- let lines = term.dimensions().line.0 as isize;
- let (start, end) = Selection::grid_clamp(start, end, lines, cols)?;
+ let num_cols = term.dimensions().col;
+ let num_lines = term.dimensions().line.0 as isize;
+ let (start, end) = Selection::grid_clamp(start, end, num_lines, num_cols)?;
let span = match *self {
Selection::Simple { ref region } => {
@@ -214,16 +214,49 @@ impl Selection {
span.map(|mut span| {
let grid = term.grid();
- if span.start.col < cols
- && grid[span.start.line][span.start.col].flags.contains(Flags::WIDE_CHAR_SPACER)
- {
- span.start.col = Column(span.start.col.saturating_sub(1));
+ // Helper for checking if cell at `point` contains `flag`
+ let flag_at = |point: Point<usize>, flag: Flags| -> bool {
+ grid[point.line][point.col].flags.contains(flag)
+ };
+
+ // Include all double-width cells and placeholders at top left of selection
+ if span.start.col < num_cols {
+ // Expand from wide char spacer to wide char
+ if span.start.line + 1 != grid.len() || span.start.col.0 != 0 {
+ let prev = span.start.sub(num_cols.0, 1, true);
+ if flag_at(span.start, Flags::WIDE_CHAR_SPACER)
+ && flag_at(prev, Flags::WIDE_CHAR)
+ {
+ span.start = prev;
+ }
+ }
+
+ // Expand from wide char to wide char spacer for linewrapping
+ if span.start.line + 1 != grid.len() || span.start.col.0 != 0 {
+ let prev = span.start.sub(num_cols.0, 1, true);
+ if (prev.line + 1 != grid.len() || prev.col.0 != 0)
+ && flag_at(prev, Flags::WIDE_CHAR_SPACER)
+ && !flag_at(prev.sub(num_cols.0, 1, true), Flags::WIDE_CHAR)
+ {
+ span.start = prev;
+ }
+ }
}
- if span.end.col.0 < cols.saturating_sub(1)
- && grid[span.end.line][span.end.col].flags.contains(Flags::WIDE_CHAR)
- {
- span.end.col += 1;
+ // Include all double-width cells and placeholders at bottom right of selection
+ if span.end.line != 0 || span.end.col < num_cols {
+ // Expand from wide char spacer for linewrapping to wide char
+ if (span.end.line + 1 != grid.len() || span.end.col.0 != 0)
+ && flag_at(span.end, Flags::WIDE_CHAR_SPACER)
+ && !flag_at(span.end.sub(num_cols.0, 1, true), Flags::WIDE_CHAR)
+ {
+ span.end = span.end.add(num_cols.0, 1, true);
+ }
+
+ // Expand from wide char to wide char spacer
+ if flag_at(span.end, Flags::WIDE_CHAR) {
+ span.end = span.end.add(num_cols.0, 1, true);
+ }
}
span
@@ -445,7 +478,7 @@ mod test {
assert_eq!(selection.to_span(&term(1, 1)).unwrap(), Span {
start: location,
end: location,
- is_block: false,
+ is_block: false
});
}
@@ -463,7 +496,7 @@ mod test {
assert_eq!(selection.to_span(&term(1, 1)).unwrap(), Span {
start: location,
end: location,
- is_block: false,
+ is_block: false
});
}
@@ -586,7 +619,7 @@ mod test {
assert_eq!(selection.to_span(&term(5, 10)).unwrap(), Span {
start: Point::new(2, Column(4)),
end: Point::new(0, Column(4)),
- is_block: true,
+ is_block: true
});
}