Make fuzzy find popup scrollable (#1734)

* Added: Make fuzzy find popup scrollable
* Fuzzy_find: Add scrollbar to matches list
* Update CHANGELOG
This commit is contained in:
Ammar Abou Zor 2023-07-08 12:29:47 +02:00 committed by GitHub
parent bdba065909
commit 4682a1b75b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 49 deletions

View File

@ -51,6 +51,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* allow `copy` file path on revision files and status tree [[@yanganto]](https://github.com/yanganto) ([#1516](https://github.com/extrawurst/gitui/pull/1516))
* print message of where log will be written if `-l` is set ([#1472](https://github.com/extrawurst/gitui/pull/1472))
* show remote branches in log [[@cruessler](https://github.com/cruessler)] ([#1501](https://github.com/extrawurst/gitui/issues/1501))
* scrolling functionality to fuzzy-find [[@AmmarAbouZor](https://github.com/AmmarAbouZor)] ([#1732](https://github.com/extrawurst/gitui/issues/1732))
### Fixes
* fixed side effect of crossterm 0.26 on windows that caused double input of all keys [[@pm100]](https://github/pm100) ([#1686](https://github.com/extrawurst/gitui/pull/1686))

View File

@ -172,6 +172,90 @@ impl FuzzyFindPopup {
false
}
#[inline]
fn draw_matches_list<B: Backend>(
&self,
f: &mut Frame<B>,
mut area: Rect,
) {
{
// Block has two lines up and down which need to be considered
const HEIGHT_BLOCK_MARGIN: usize = 2;
let title = format!("Hits: {}", self.filtered.len());
let height = usize::from(area.height);
let width = usize::from(area.width);
let list_height =
height.saturating_sub(HEIGHT_BLOCK_MARGIN);
let scroll_skip =
self.selection.saturating_sub(list_height);
let items = self
.filtered
.iter()
.skip(scroll_skip)
.take(height)
.map(|(idx, indicies)| {
let selected = self
.selected_index
.map_or(false, |index| index == *idx);
let full_text =
trim_length_left(&self.contents[*idx], width);
let trim_length =
self.contents[*idx].graphemes(true).count()
- full_text.graphemes(true).count();
Line::from(
full_text
.graphemes(true)
.enumerate()
.map(|(c_idx, c)| {
Span::styled(
Cow::from(c.to_string()),
self.theme.text(
selected,
indicies.contains(
&(c_idx + trim_length),
),
),
)
})
.collect::<Vec<_>>(),
)
});
ui::draw_list_block(
f,
area,
Block::default()
.title(Span::styled(
title,
self.theme.title(true),
))
.borders(Borders::TOP),
items,
);
// Draw scrollbar when needed
if self.filtered.len() > list_height {
// Reset list area margin
area.width += 1;
area.height += 1;
ui::draw_scrollbar(
f,
area,
&self.theme,
self.filtered.len().saturating_sub(1),
self.selection,
ui::Orientation::Vertical,
);
}
}
}
}
impl DrawableComponent for FuzzyFindPopup {
@ -233,55 +317,7 @@ impl DrawableComponent for FuzzyFindPopup {
self.find_text.draw(f, chunks[0])?;
if any_hits {
let title = format!("Hits: {}", self.filtered.len());
let height = usize::from(chunks[1].height);
let width = usize::from(chunks[1].width);
let items =
self.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.contents[*idx],
width,
);
let trim_length = self.contents[*idx]
.graphemes(true)
.count() - full_text
.graphemes(true)
.count();
Line::from(
full_text
.graphemes(true)
.enumerate()
.map(|(c_idx, c)| {
Span::styled(
Cow::from(c.to_string()),
self.theme.text(
selected,
indicies.contains(&(c_idx + trim_length)),
),
)
})
.collect::<Vec<_>>(),
)
},
);
ui::draw_list_block(
f,
chunks[1],
Block::default()
.title(Span::styled(
title,
self.theme.title(true),
))
.borders(Borders::TOP),
items,
);
self.draw_matches_list(f, chunks[1]);
}
}
Ok(())