Fix search bug with wrapline on first character

This fixes an issue where an inline search in the left direction would
incorrectly assume that the first cell searched would not contain the
`WRAPLINE` flag, causing the second search for the match end to
terminate prematurely.

Fixes #8060.
This commit is contained in:
Christian Duerr 2024-07-05 12:12:15 +02:00 committed by GitHub
parent 5e6b92db85
commit b3f0f68184
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 28 additions and 16 deletions

View File

@ -31,6 +31,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its
- Leaking FDs when closing windows on Unix systems
- Config emitting errors for nonexistent import paths
- Kitty keyboard protocol reporting shifted key codes
- Broken search with words broken across line boundary on the first character
## 0.13.2

View File

@ -187,14 +187,9 @@ impl GlyphCache {
///
/// This will fail when the glyph could not be rasterized. Usually this is due to the glyph
/// not being present in any font.
pub fn get<L: ?Sized>(
&mut self,
glyph_key: GlyphKey,
loader: &mut L,
show_missing: bool,
) -> Glyph
pub fn get<L>(&mut self, glyph_key: GlyphKey, loader: &mut L, show_missing: bool) -> Glyph
where
L: LoadGlyph,
L: LoadGlyph + ?Sized,
{
// Try to load glyph from cache.
if let Some(glyph) = self.cache.get(&glyph_key) {
@ -242,9 +237,9 @@ impl GlyphCache {
/// Load glyph into the atlas.
///
/// This will apply all transforms defined for the glyph cache to the rasterized glyph before
pub fn load_glyph<L: ?Sized>(&self, loader: &mut L, mut glyph: RasterizedGlyph) -> Glyph
pub fn load_glyph<L>(&self, loader: &mut L, mut glyph: RasterizedGlyph) -> Glyph
where
L: LoadGlyph,
L: LoadGlyph + ?Sized,
{
glyph.left += i32::from(self.glyph_offset.x);
glyph.top += i32::from(self.glyph_offset.y);

View File

@ -1445,15 +1445,15 @@ impl<T: EventListener> Handler for Term<T> {
/// edition, in LINE FEED mode,
///
/// > The execution of the formatter functions LINE FEED (LF), FORM FEED
/// (FF), LINE TABULATION (VT) cause only movement of the active position in
/// the direction of the line progression.
/// > (FF), LINE TABULATION (VT) cause only movement of the active position in
/// > the direction of the line progression.
///
/// In NEW LINE mode,
///
/// > The execution of the formatter functions LINE FEED (LF), FORM FEED
/// (FF), LINE TABULATION (VT) cause movement to the line home position on
/// the following line, the following form, etc. In the case of LF this is
/// referred to as the New Line (NL) option.
/// > (FF), LINE TABULATION (VT) cause movement to the line home position on
/// > the following line, the following form, etc. In the case of LF this is
/// > referred to as the New Line (NL) option.
///
/// Additionally, ECMA-48 4th edition says that this option is deprecated.
/// ECMA-48 5th edition only mentions this option (without explanation)
@ -2187,7 +2187,7 @@ impl<T: EventListener> Handler for Term<T> {
fn set_title(&mut self, title: Option<String>) {
trace!("Setting title to '{:?}'", title);
self.title = title.clone();
self.title.clone_from(&title);
let title_event = match title {
Some(title) => Event::Title(title),

View File

@ -293,12 +293,12 @@ impl<T> Term<T> {
let mut state = regex.dfa.start_state_forward(&mut regex.cache, &input).unwrap();
let mut iter = self.grid.iter_from(start);
let mut last_wrapped = false;
let mut regex_match = None;
let mut done = false;
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 point = iter.point();
@ -1155,4 +1155,20 @@ mod tests {
assert_eq!(start, Point::new(Line(1), Column(0)));
assert_eq!(end, Point::new(Line(1), Column(2)));
}
#[test]
fn inline_word_search() {
#[rustfmt::skip]
let term = mock_term("\
word word word word w\n\
ord word word word\
");
let mut regex = RegexSearch::new("word").unwrap();
let start = Point::new(Line(1), Column(4));
let end = Point::new(Line(0), Column(0));
let match_start = Point::new(Line(0), Column(20));
let match_end = Point::new(Line(1), Column(2));
assert_eq!(term.regex_search_left(&mut regex, start, end), Some(match_start..=match_end));
}
}