diff options
author | Ludwig Stecher | 2022-03-01 01:30:02 +0000 |
---|---|---|
committer | GitHub | 2022-03-01 01:30:02 +0000 |
commit | 59c691d2dbdf14c02d0a4b8f9b014112ead6cda5 (patch) | |
tree | 2cca8faf55782aa8d6fff65a5108d1c0c5681229 /helix-term | |
parent | b13d44156c0f2ebe700c4169e87839c976c4fedc (diff) |
Highlight matching text in file picker suggestions (#1635)
* Highlight matching text in file picker suggestions
* Remove cache, specialize highlighting code
* Fix outdated comments
Diffstat (limited to 'helix-term')
-rw-r--r-- | helix-term/src/ui/editor.rs | 4 | ||||
-rw-r--r-- | helix-term/src/ui/picker.rs | 40 |
2 files changed, 29 insertions, 15 deletions
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 064c74ee..b6aaf9e0 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -688,12 +688,12 @@ impl EditorView { surface.set_string_truncated( viewport.x + 8, // 8: 1 space + 3 char mode string + 1 space + 1 spinner + 1 space viewport.y, - title, + &title, viewport .width .saturating_sub(6) .saturating_sub(right_side_text.width() as u16 + 1) as usize, // "+ 1": a space between the title and the selection info - base_style, + |_| base_style, true, true, ); diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 34709e8b..06e50f51 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -24,7 +24,7 @@ use crate::ui::{Prompt, PromptEvent}; use helix_core::{movement::Direction, Position}; use helix_view::{ editor::Action, - graphics::{Color, CursorKind, Margin, Rect, Style}, + graphics::{Color, CursorKind, Margin, Modifier, Rect, Style}, Document, Editor, }; @@ -343,7 +343,7 @@ impl<T> Picker<T> { } // TODO: maybe using format_fn isn't the best idea here let text = (self.format_fn)(option); - // TODO: using fuzzy_indices could give us the char idx for match highlighting + // Highlight indices are computed lazily in the render function self.matcher .fuzzy_match(&text, pattern) .map(|score| (index, score)) @@ -483,6 +483,8 @@ impl<T: 'static> Component for Picker<T> { fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) { let text_style = cx.editor.theme.get("ui.text"); + let selected = cx.editor.theme.get("ui.text.focus"); + let highlighted = cx.editor.theme.get("special").add_modifier(Modifier::BOLD); // -- Render the frame: // clear area @@ -525,29 +527,41 @@ impl<T: 'static> Component for Picker<T> { // subtract area of prompt from top and current item marker " > " from left let inner = inner.clip_top(2).clip_left(3); - let selected = cx.editor.theme.get("ui.text.focus"); - let rows = inner.height; let offset = self.cursor - (self.cursor % std::cmp::max(1, rows as usize)); - let files = self.matches.iter().skip(offset).map(|(index, _score)| { - (index, self.options.get(*index).unwrap()) // get_unchecked - }); + let files = self + .matches + .iter_mut() + .skip(offset) + .map(|(index, _score)| (*index, self.options.get(*index).unwrap())); for (i, (_index, option)) in files.take(rows as usize).enumerate() { - if i == (self.cursor - offset) { + let is_active = i == (self.cursor - offset); + if is_active { surface.set_string(inner.x.saturating_sub(2), inner.y + i as u16, ">", selected); } + let formatted = (self.format_fn)(option); + + let (_score, highlights) = self + .matcher + .fuzzy_indices(&formatted, &self.prompt.line) + .unwrap_or_default(); + surface.set_string_truncated( inner.x, inner.y + i as u16, - (self.format_fn)(option), + &formatted, inner.width as usize, - if i == (self.cursor - offset) { - selected - } else { - text_style + |idx| { + if highlights.contains(&idx) { + highlighted + } else if is_active { + selected + } else { + text_style + } }, true, self.truncate_start, |