Skip to content

Commit 075be58

Browse files
kentakom1213cantino
authored andcommitted
add: highlight Only the Matched Characters in Fuzzy Search
- [WARNING] bug occurs when search command is empty
1 parent f1478d8 commit 075be58

File tree

2 files changed

+41
-36
lines changed

2 files changed

+41
-36
lines changed

src/history/history.rs

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub struct Command {
4545
pub selected: bool,
4646
pub dir: Option<String>,
4747
pub features: Features,
48-
pub match_bounds: Vec<(usize, usize)>,
48+
pub match_indices: Vec<usize>,
4949
}
5050

5151
#[derive(Debug, Clone, Serialize)]
@@ -331,7 +331,7 @@ impl History {
331331
rank: row.get(8).unwrap_or_else(|err| {
332332
panic!("McFly error: rank to be readable ({err})")
333333
}),
334-
match_bounds: bounds,
334+
match_indices: bounds,
335335
features: Features {
336336
age_factor: row.get(9).unwrap_or_else(|err| {
337337
panic!("McFly error: age_factor to be readable ({err})")
@@ -409,10 +409,19 @@ impl History {
409409
// the likelihood of the weight flipping the outcome for
410410
// the originally lower-ranked result.
411411

412-
let a_start = a.match_bounds[0].0;
413-
let b_start = b.match_bounds[0].0;
414-
let a_len = a.match_bounds[0].1 - a_start;
415-
let b_len = b.match_bounds[0].1 - b_start;
412+
let a_start = *a.match_indices.first().unwrap();
413+
let b_start = *b.match_indices.first().unwrap();
414+
415+
let a_len = if fuzzy > 0 {
416+
a.match_indices.last().unwrap() + 1 - a_start
417+
} else {
418+
cmd.len()
419+
};
420+
let b_len = if fuzzy > 0 {
421+
b.match_indices.last().unwrap() + 1 - b_start
422+
} else {
423+
cmd.len()
424+
};
416425

417426
let a_mod =
418427
1.0 - (a_start + a_len) as f64 / (a_start + b_start + a_len + b_len) as f64;
@@ -436,7 +445,7 @@ impl History {
436445
cmd.chars().any(|c| c.is_uppercase())
437446
}
438447

439-
fn calc_match_bounds(text: &str, cmd: &str, fuzzy: i16) -> Vec<(usize, usize)> {
448+
fn calc_match_bounds(text: &str, cmd: &str, fuzzy: i16) -> Vec<usize> {
440449
let (text, cmd) = if Self::is_case_sensitive(cmd) {
441450
(text.to_string(), cmd.to_string())
442451
} else {
@@ -446,28 +455,24 @@ impl History {
446455
match fuzzy {
447456
0 => text
448457
.match_indices(&cmd)
449-
.map(|(index, _)| (index, index + cmd.len()))
450-
.collect::<Vec<_>>(),
458+
.flat_map(|(index, _)| index..index + cmd.len())
459+
.collect(),
451460
_ => {
452461
let mut search_iter = cmd.chars().peekable();
453-
let mut matches = text
454-
.match_indices(|c| {
455-
let next = search_iter.peek();
456-
457-
if next.is_some() && next.unwrap() == &c {
458-
let _advance = search_iter.next();
459462

460-
return true;
461-
}
463+
text.match_indices(|c| {
464+
let next = search_iter.peek();
462465

463-
false
464-
})
465-
.map(|m| m.0);
466+
if next.is_some() && next.unwrap() == &c {
467+
let _advance = search_iter.next();
466468

467-
let start = matches.next().unwrap_or(0);
468-
let end = matches.last().unwrap_or(start) + 1;
469+
return true;
470+
}
469471

470-
vec![(start, end)]
472+
false
473+
})
474+
.map(|m| m.0)
475+
.collect()
471476
}
472477
}
473478
}

src/interface.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,6 @@ impl<'a> Interface<'a> {
997997
base_color: Color,
998998
debug: bool,
999999
) -> String {
1000-
let mut prev: usize = 0;
10011000
let debug_space = if debug { 90 } else { 0 };
10021001
let max_grapheme_length = if width > debug_space {
10031002
width - debug_space - 9
@@ -1007,22 +1006,23 @@ impl<'a> Interface<'a> {
10071006
let mut out = FixedLengthGraphemeString::empty(max_grapheme_length);
10081007

10091008
if !search.is_empty() {
1010-
for (start, end) in &command.match_bounds {
1011-
if prev != *start {
1012-
out.push_grapheme_str(&command.cmd[prev..*start]);
1009+
let mut match_indices = command.match_indices.iter().peekable();
1010+
1011+
for (i, c) in command.cmd.char_indices() {
1012+
match match_indices.peek() {
1013+
Some(&&j) if i == j => {
1014+
let _ = match_indices.next();
1015+
execute!(out, SetForegroundColor(highlight_color)).unwrap();
1016+
out.push_grapheme_str(c);
1017+
}
1018+
_ => {
1019+
execute!(out, SetForegroundColor(base_color)).unwrap();
1020+
out.push_grapheme_str(c);
1021+
}
10131022
}
1014-
1015-
execute!(out, SetForegroundColor(highlight_color)).unwrap();
1016-
out.push_grapheme_str(&command.cmd[*start..*end]);
1017-
execute!(out, SetForegroundColor(base_color)).unwrap();
1018-
prev = *end;
10191023
}
10201024
}
10211025

1022-
if prev != command.cmd.len() {
1023-
out.push_grapheme_str(&command.cmd[prev..]);
1024-
}
1025-
10261026
if debug {
10271027
out.max_grapheme_length += debug_space;
10281028
out.push_grapheme_str(" ");

0 commit comments

Comments
 (0)