diff options
| author | Christian Duerr <contact@christianduerr.com> | 2025-05-26 08:58:59 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-26 17:58:59 +0900 |
| commit | 00a516abc78f54fe16ec820e58613bd8ac394d44 (patch) | |
| tree | a2c82df1a842f3310e1f61cf235e42aa8a47a146 | |
| parent | b02e4fce05c513eb9c375d461dd325ad18f9f63a (diff) | |
| download | r-alacritty-00a516abc78f54fe16ec820e58613bd8ac394d44.tar.gz r-alacritty-00a516abc78f54fe16ec820e58613bd8ac394d44.tar.bz2 r-alacritty-00a516abc78f54fe16ec820e58613bd8ac394d44.zip | |
Fix search for fullwidth chars in the last column
This fixes an issue for fullwidth characters where the `WRAPLINE` flag
would be checked for the cell containing the wide character, ignoring
the spacer after it.
To work around this, the wrapline character is now always checked based
on the cell *after* fullwidth expansion, instead of the original cell.
Closes #8586.
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | alacritty_terminal/src/term/search.rs | 62 |
2 files changed, 61 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index f0ff67ec..e5f9b215 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its - `glyph_offset.y` not applied to strikeout - `Enter`,`Tab`, `Backspace` not disambiguated with `shift` in kitty keyboard's disambiguate mode - Hint bindings not respecting IPC overrides +- Search matching a wrapping fullwidth character in the last column ## 0.15.1 diff --git a/alacritty_terminal/src/term/search.rs b/alacritty_terminal/src/term/search.rs index 20a427b7..d8babd92 100644 --- a/alacritty_terminal/src/term/search.rs +++ b/alacritty_terminal/src/term/search.rs @@ -298,8 +298,8 @@ impl<T> Term<T> { let mut cell = iter.cell(); self.skip_fullwidth(&mut iter, &mut cell, regex.direction); - let mut last_wrapped = cell.flags.contains(Flags::WRAPLINE); let mut c = cell.c; + let mut last_wrapped = iter.cell().flags.contains(Flags::WRAPLINE); let mut point = iter.point(); let mut last_point = point; @@ -401,8 +401,8 @@ impl<T> Term<T> { self.skip_fullwidth(&mut iter, &mut cell, regex.direction); - let wrapped = cell.flags.contains(Flags::WRAPLINE); c = cell.c; + let wrapped = iter.cell().flags.contains(Flags::WRAPLINE); last_point = mem::replace(&mut point, iter.point()); @@ -1190,4 +1190,62 @@ mod tests { assert_eq!(start, Point::new(Line(0), Column(6))); assert_eq!(end, Point::new(Line(0), Column(6))); } + + #[test] + fn fullwidth_across_lines() { + let term = mock_term("a🦇\n🦇b"); + + let mut regex = RegexSearch::new("🦇🦇").unwrap(); + let start = Point::new(Line(0), Column(0)); + let end = Point::new(Line(1), Column(2)); + let match_start = Point::new(Line(0), Column(1)); + let match_end = Point::new(Line(1), Column(1)); + assert_eq!(term.regex_search_right(&mut regex, start, end), Some(match_start..=match_end)); + + let mut regex = RegexSearch::new("🦇🦇").unwrap(); + let start = Point::new(Line(1), Column(2)); + let end = Point::new(Line(0), Column(0)); + let match_start = Point::new(Line(1), Column(1)); + let match_end = Point::new(Line(0), Column(1)); + assert_eq!(term.regex_search_left(&mut regex, start, end), Some(match_end..=match_start)); + } + + #[test] + fn fullwidth_into_halfwidth_across_lines() { + let term = mock_term("a🦇\nxab"); + + let mut regex = RegexSearch::new("🦇x").unwrap(); + let start = Point::new(Line(0), Column(0)); + let end = Point::new(Line(1), Column(2)); + let match_start = Point::new(Line(0), Column(1)); + let match_end = Point::new(Line(1), Column(0)); + assert_eq!(term.regex_search_right(&mut regex, start, end), Some(match_start..=match_end)); + + let mut regex = RegexSearch::new("🦇x").unwrap(); + let start = Point::new(Line(1), Column(2)); + let end = Point::new(Line(0), Column(0)); + let match_start = Point::new(Line(1), Column(0)); + let match_end = Point::new(Line(0), Column(1)); + assert_eq!(term.regex_search_left(&mut regex, start, end), Some(match_end..=match_start)); + } + + #[test] + fn no_spacer_fullwidth_linewrap() { + let mut term = mock_term("abY\nxab"); + term.grid_mut()[Line(0)][Column(2)].c = '🦇'; + + let mut regex = RegexSearch::new("🦇x").unwrap(); + let start = Point::new(Line(0), Column(0)); + let end = Point::new(Line(1), Column(2)); + let match_start = Point::new(Line(0), Column(2)); + let match_end = Point::new(Line(1), Column(0)); + assert_eq!(term.regex_search_right(&mut regex, start, end), Some(match_start..=match_end)); + + let mut regex = RegexSearch::new("🦇x").unwrap(); + let start = Point::new(Line(1), Column(2)); + let end = Point::new(Line(0), Column(0)); + let match_start = Point::new(Line(1), Column(0)); + let match_end = Point::new(Line(0), Column(2)); + assert_eq!(term.regex_search_left(&mut regex, start, end), Some(match_end..=match_start)); + } } |