Skip to content

Add highlighting for matches in fuzzy finder #947

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Added
- add `trace-libgit` feature to make git tracing optional [[@dm9pZCAq](https://github.com/dm9pZCAq)] ([#902](https://github.com/extrawurst/gitui/issues/902))
- support merging and rebasing remote branches ([#920](https://github.com/extrawurst/gitui/issues/920))
- add highlighting matches in fuzzy finder ([#893](https://github.com/extrawurst/gitui/issues/893))

## [0.18] - 2021-10-11

Expand Down
59 changes: 36 additions & 23 deletions src/components/file_find_popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::borrow::Cow;
use tui::{
backend::Backend,
layout::{Constraint, Direction, Layout, Margin, Rect},
text::Span,
text::{Span, Spans},
widgets::{Block, Borders, Clear},
Frame,
};
Expand All @@ -31,7 +31,7 @@ pub struct FileFindPopup {
files: Vec<TreeFile>,
selection: usize,
selected_index: Option<usize>,
files_filtered: Vec<usize>,
files_filtered: Vec<(usize, Vec<usize>)>,
key_config: SharedKeyConfig,
}

Expand Down Expand Up @@ -91,8 +91,9 @@ impl FileFindPopup {
self.files_filtered.extend(
self.files.iter().enumerate().filter_map(|a| {
a.1.path.to_str().and_then(|path| {
//TODO: use fuzzy_indices and highlight hits
matcher.fuzzy_match(path, q).map(|_| a.0)
matcher
.fuzzy_indices(path, q)
.map(|(_, indicies)| (a.0, indicies))
})
}),
);
Expand All @@ -104,7 +105,7 @@ impl FileFindPopup {

fn refresh_selection(&mut self) {
let selection =
self.files_filtered.get(self.selection).copied();
self.files_filtered.get(self.selection).map(|a| a.0);

if self.selected_index != selection {
self.selected_index = selection;
Expand Down Expand Up @@ -217,24 +218,36 @@ impl DrawableComponent for FileFindPopup {
let height = usize::from(chunks[1].height);
let width = usize::from(chunks[1].width);

let items =
self.files_filtered.iter().take(height).map(
|idx| {
let selected = self
.selected_index
.map_or(false, |index| index == *idx);
Span::styled(
Cow::from(trim_length_left(
self.files[*idx]
.path
.to_str()
.unwrap_or_default(),
width,
)),
self.theme.text(selected, false),
)
},
);
let items = self
.files_filtered
.iter()
.take(height)
.map(|(idx, indicies)| {
let selected = self
.selected_index
.map_or(false, |index| index == *idx);
let full_text = trim_length_left(
self.files[*idx]
.path
.to_str()
.unwrap_or_default(),
width,
);
Spans::from(
full_text
.char_indices()
.map(|(c_idx, c)| {
Span::styled(
Cow::from(c.to_string()),
self.theme.text(
selected,
indicies.contains(&c_idx),
),
)
})
.collect::<Vec<_>>(),
)
});

ui::draw_list_block(
f,
Expand Down
27 changes: 16 additions & 11 deletions src/ui/scrolllist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ use tui::{
buffer::Buffer,
layout::Rect,
style::Style,
text::Span,
text::{Span, Text},
widgets::{Block, Borders, List, ListItem, Widget},
Frame,
};

///
struct ScrollableList<'b, L>
struct ScrollableList<'b, L, S>
where
L: Iterator<Item = Span<'b>>,
S: Into<Text<'b>>,
L: Iterator<Item = S>,
{
block: Option<Block<'b>>,
/// Items to be displayed
Expand All @@ -22,9 +23,10 @@ where
style: Style,
}

impl<'b, L> ScrollableList<'b, L>
impl<'b, L, S> ScrollableList<'b, L, S>
where
L: Iterator<Item = Span<'b>>,
S: Into<Text<'b>>,
L: Iterator<Item = S>,
{
fn new(items: L) -> Self {
Self {
Expand All @@ -40,9 +42,10 @@ where
}
}

impl<'b, L> Widget for ScrollableList<'b, L>
impl<'b, L, S> Widget for ScrollableList<'b, L, S>
where
L: Iterator<Item = Span<'b>>,
S: Into<Text<'b>>,
L: Iterator<Item = S>,
{
fn render(self, area: Rect, buf: &mut Buffer) {
// Render items
Expand All @@ -55,15 +58,16 @@ where
}
}

pub fn draw_list<'b, B: Backend, L>(
pub fn draw_list<'b, B: Backend, L, S>(
f: &mut Frame<B>,
r: Rect,
title: &'b str,
items: L,
selected: bool,
theme: &SharedTheme,
) where
L: Iterator<Item = Span<'b>>,
S: Into<Text<'b>>,
L: Iterator<Item = S>,
{
let list = ScrollableList::new(items).block(
Block::default()
Expand All @@ -74,13 +78,14 @@ pub fn draw_list<'b, B: Backend, L>(
f.render_widget(list, r);
}

pub fn draw_list_block<'b, B: Backend, L>(
pub fn draw_list_block<'b, B: Backend, L, S>(
f: &mut Frame<B>,
r: Rect,
block: Block<'b>,
items: L,
) where
L: Iterator<Item = Span<'b>>,
S: Into<Text<'b>>,
L: Iterator<Item = S>,
{
let list = ScrollableList::new(items).block(block);
f.render_widget(list, r);
Expand Down
3 changes: 2 additions & 1 deletion src/ui/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ impl Theme {

pub fn text(&self, enabled: bool, selected: bool) -> Style {
match (enabled, selected) {
(false, _) => Style::default().fg(self.disabled_fg),
(false, false) => Style::default().fg(self.disabled_fg),
(false, true) => Style::default().bg(self.selection_bg),
(true, false) => Style::default(),
(true, true) => Style::default()
.fg(self.command_fg)
Expand Down