Skip to content

Commit b81c351

Browse files
authored
fix: Restore pre-798 ColumnarMenu highlighting behavior (#991)
* fix: Restore pre-#798 ColumnarMenu highlighting behavior * Fix clippy and tests
1 parent 07fe597 commit b81c351

File tree

3 files changed

+61
-33
lines changed

3 files changed

+61
-33
lines changed

src/menu/columnar_menu.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -403,16 +403,19 @@ impl ColumnarMenu {
403403
let description_size = self.get_width().saturating_sub(left_text_size);
404404
let padding = left_text_size.saturating_sub(self.display_widths[index]);
405405

406-
let value_style = if selected {
407-
&self.settings.color.selected_text_style
406+
let text_style = &suggestion.style.unwrap_or(self.settings.color.text_style);
407+
let match_style = if selected {
408+
&self.settings.color.selected_match_style
408409
} else {
409-
&suggestion.style.unwrap_or(self.settings.color.text_style)
410+
&self.settings.color.match_style
410411
};
411412
let value_trunc = truncate_no_ansi(&suggestion.value, left_text_size);
412413
let styled_value = style_suggestion(
413-
&value_style.paint(value_trunc).to_string(),
414-
match_indices.as_ref(),
415-
&self.settings.color.match_style,
414+
&value_trunc,
415+
&match_indices,
416+
text_style,
417+
match_style,
418+
selected.then_some(&self.settings.color.selected_text_style),
416419
);
417420

418421
match &suggestion.description {
@@ -421,17 +424,20 @@ impl ColumnarMenu {
421424
let desc_trunc = truncate_no_ansi(desc.as_str(), description_size);
422425
if selected {
423426
format!(
424-
"{}{}{}{}{}",
427+
"{}{}{}{}{}{}{}",
425428
styled_value,
426-
value_style.prefix(),
429+
RESET,
430+
text_style.prefix(),
431+
self.settings.color.selected_text_style.prefix(),
427432
" ".repeat(padding),
428-
desc_trunc,
433+
self.settings.color.description_style.paint(desc_trunc),
429434
RESET,
430435
)
431436
} else {
432437
format!(
433-
"{}{}{}{}",
438+
"{}{}{}{}{}",
434439
styled_value,
440+
RESET,
435441
" ".repeat(padding),
436442
self.settings.color.description_style.paint(desc_trunc),
437443
RESET,

src/menu/ide_menu.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -523,20 +523,19 @@ impl IdeMenu {
523523

524524
let styled_string = if index == self.index() {
525525
style_suggestion(
526-
&self
527-
.settings
528-
.color
529-
.selected_text_style
530-
.paint(string)
531-
.to_string(),
526+
&string,
532527
&match_indices,
528+
&self.settings.color.selected_text_style,
533529
&self.settings.color.selected_match_style,
530+
None,
534531
)
535532
} else {
536533
style_suggestion(
537-
&suggestion_style.paint(string).to_string(),
534+
&string,
538535
&match_indices,
536+
&suggestion_style,
539537
&self.settings.color.match_style,
538+
None,
540539
)
541540
};
542541

src/menu/menu_functions.rs

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,18 @@ fn parse_ansi(s: &str) -> Vec<(usize, usize, usize)> {
417417
///
418418
/// * `match_indices` - Indices of graphemes (NOT bytes or chars) that matched the typed text
419419
/// * `match_style` - Style to use for matched characters
420-
pub fn style_suggestion(suggestion: &str, match_indices: &[usize], match_style: &Style) -> String {
420+
pub fn style_suggestion(
421+
suggestion: &str,
422+
match_indices: &[usize],
423+
text_style: &Style,
424+
match_style: &Style,
425+
selected_style: Option<&Style>,
426+
) -> String {
427+
let text_style_prefix = text_style.prefix().to_string();
428+
let match_style_prefix = match_style.prefix().to_string();
429+
let selected_prefix = selected_style
430+
.map(|s| s.prefix().to_string())
431+
.unwrap_or_default();
421432
let mut res = String::new();
422433
let mut offset = 0;
423434
for (escape_start, text_start, text_end) in parse_ansi(suggestion) {
@@ -426,14 +437,18 @@ pub fn style_suggestion(suggestion: &str, match_indices: &[usize], match_style:
426437
let graphemes = text.graphemes(true).collect::<Vec<_>>();
427438
let mut prev_matched = false;
428439

440+
res.push_str(&text_style_prefix);
441+
res.push_str(&selected_prefix);
429442
res.push_str(escape);
430443
for (i, grapheme) in graphemes.iter().enumerate() {
431444
let is_match = match_indices.contains(&(i + offset));
432445

433446
if is_match && !prev_matched {
434-
res.push_str(&match_style.prefix().to_string());
447+
res.push_str(&match_style_prefix);
435448
} else if !is_match && prev_matched && i != 0 {
436449
res.push_str(RESET);
450+
res.push_str(&text_style_prefix);
451+
res.push_str(&selected_prefix);
437452
res.push_str(escape);
438453
}
439454
res.push_str(grapheme);
@@ -826,22 +841,38 @@ mod tests {
826841

827842
#[test]
828843
fn style_fuzzy_suggestion() {
844+
let text_style = Style::new().fg(Color::Red);
829845
let match_style = Style::new().underline();
846+
let selected_style = Style::new().underline();
830847
let style1 = Style::new().on(Color::Blue);
831848
let style2 = Style::new().on(Color::Green);
832849

833850
let expected = format!(
834-
"{}{}{}{}{}{}{}{}{}{}{}{}{}",
851+
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
852+
text_style.prefix(),
853+
selected_style.prefix(),
835854
style1.prefix(),
836855
"ab",
837856
match_style.paint("汉"),
857+
text_style.prefix(),
858+
selected_style.prefix(),
838859
style1.prefix(),
839860
"d",
861+
// TODO these next two are unnecessary, make sure consecutive ANSI escapes
862+
// are treated as a single segment by parse_ansi()
863+
text_style.prefix(),
864+
selected_style.prefix(),
840865
RESET,
866+
text_style.prefix(),
867+
selected_style.prefix(),
841868
style2.prefix(),
842869
match_style.paint("y̆👩🏾"),
870+
text_style.prefix(),
871+
selected_style.prefix(),
843872
style2.prefix(),
844873
"e",
874+
text_style.prefix(),
875+
selected_style.prefix(),
845876
RESET,
846877
"b@",
847878
match_style.paint("r"),
@@ -856,7 +887,9 @@ mod tests {
856887
style_suggestion(
857888
&format!("{}{}{}", style1.paint("ab汉d"), style2.paint("y̆👩🏾e"), "b@r"),
858889
match_indices,
859-
&match_style
890+
&text_style,
891+
&match_style,
892+
Some(&selected_style),
860893
)
861894
);
862895
}
@@ -866,20 +899,10 @@ mod tests {
866899
let text_style = Style::new().on(Color::Blue).bold();
867900
let match_style = Style::new().underline();
868901

869-
let expected = format!(
870-
"{}{}{}{}",
871-
text_style.prefix(),
872-
"go",
873-
match_style.paint("o"),
874-
RESET
875-
);
902+
let expected = format!("{}{}{}", text_style.prefix(), "go", match_style.paint("o"),);
876903
assert_eq!(
877904
expected,
878-
style_suggestion(
879-
&text_style.paint("goo").to_string(),
880-
&[2, 3, 4, 6],
881-
&match_style
882-
)
905+
style_suggestion("goo", &[2, 3, 4, 6], &text_style, &match_style, None)
883906
);
884907
}
885908

0 commit comments

Comments
 (0)