aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2025-05-26 08:58:59 +0000
committerGitHub <noreply@github.com>2025-05-26 17:58:59 +0900
commit00a516abc78f54fe16ec820e58613bd8ac394d44 (patch)
treea2c82df1a842f3310e1f61cf235e42aa8a47a146
parentb02e4fce05c513eb9c375d461dd325ad18f9f63a (diff)
downloadr-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.md1
-rw-r--r--alacritty_terminal/src/term/search.rs62
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));
+ }
}