summaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/selection.rs
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2020-01-09 23:06:41 +0000
committerGitHub <noreply@github.com>2020-01-09 23:06:41 +0000
commit3fb631b91caec163707858bd1d435015e6e6cb18 (patch)
treecfc575f224622b7c83a21281c2e23a7f8af83364 /alacritty_terminal/src/selection.rs
parent5651c3f7114dff611e616865ad02e682779979d9 (diff)
downloadalacritty-3fb631b91caec163707858bd1d435015e6e6cb18.tar.gz
alacritty-3fb631b91caec163707858bd1d435015e6e6cb18.zip
Fix cut off full width glyphs in last column
This resolves the issue with full width glyphs getting rendered in the last column. Since they need at least two glyphs, it is not possible to properly render them in the last column. Instead of rendering half of the glyph in the last column, with the other half cut off, an additional spacer is now inserted before the wide glyph. This means that the specific glyph in question is then three cells wide. Fixes #2385.
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
});
}