Skip to content

Commit 4682a1b

Browse files
authored
Make fuzzy find popup scrollable (#1734)
* Added: Make fuzzy find popup scrollable * Fuzzy_find: Add scrollbar to matches list * Update CHANGELOG
1 parent bdba065 commit 4682a1b

File tree

2 files changed

+86
-49
lines changed

2 files changed

+86
-49
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5151
* allow `copy` file path on revision files and status tree [[@yanganto]](https://github.com/yanganto) ([#1516](https://github.com/extrawurst/gitui/pull/1516))
5252
* print message of where log will be written if `-l` is set ([#1472](https://github.com/extrawurst/gitui/pull/1472))
5353
* show remote branches in log [[@cruessler](https://github.com/cruessler)] ([#1501](https://github.com/extrawurst/gitui/issues/1501))
54+
* scrolling functionality to fuzzy-find [[@AmmarAbouZor](https://github.com/AmmarAbouZor)] ([#1732](https://github.com/extrawurst/gitui/issues/1732))
5455

5556
### Fixes
5657
* 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))

src/components/fuzzy_find_popup.rs

Lines changed: 85 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,90 @@ impl FuzzyFindPopup {
172172

173173
false
174174
}
175+
176+
#[inline]
177+
fn draw_matches_list<B: Backend>(
178+
&self,
179+
f: &mut Frame<B>,
180+
mut area: Rect,
181+
) {
182+
{
183+
// Block has two lines up and down which need to be considered
184+
const HEIGHT_BLOCK_MARGIN: usize = 2;
185+
186+
let title = format!("Hits: {}", self.filtered.len());
187+
188+
let height = usize::from(area.height);
189+
let width = usize::from(area.width);
190+
191+
let list_height =
192+
height.saturating_sub(HEIGHT_BLOCK_MARGIN);
193+
194+
let scroll_skip =
195+
self.selection.saturating_sub(list_height);
196+
197+
let items = self
198+
.filtered
199+
.iter()
200+
.skip(scroll_skip)
201+
.take(height)
202+
.map(|(idx, indicies)| {
203+
let selected = self
204+
.selected_index
205+
.map_or(false, |index| index == *idx);
206+
let full_text =
207+
trim_length_left(&self.contents[*idx], width);
208+
let trim_length =
209+
self.contents[*idx].graphemes(true).count()
210+
- full_text.graphemes(true).count();
211+
Line::from(
212+
full_text
213+
.graphemes(true)
214+
.enumerate()
215+
.map(|(c_idx, c)| {
216+
Span::styled(
217+
Cow::from(c.to_string()),
218+
self.theme.text(
219+
selected,
220+
indicies.contains(
221+
&(c_idx + trim_length),
222+
),
223+
),
224+
)
225+
})
226+
.collect::<Vec<_>>(),
227+
)
228+
});
229+
230+
ui::draw_list_block(
231+
f,
232+
area,
233+
Block::default()
234+
.title(Span::styled(
235+
title,
236+
self.theme.title(true),
237+
))
238+
.borders(Borders::TOP),
239+
items,
240+
);
241+
242+
// Draw scrollbar when needed
243+
if self.filtered.len() > list_height {
244+
// Reset list area margin
245+
area.width += 1;
246+
area.height += 1;
247+
248+
ui::draw_scrollbar(
249+
f,
250+
area,
251+
&self.theme,
252+
self.filtered.len().saturating_sub(1),
253+
self.selection,
254+
ui::Orientation::Vertical,
255+
);
256+
}
257+
}
258+
}
175259
}
176260

177261
impl DrawableComponent for FuzzyFindPopup {
@@ -233,55 +317,7 @@ impl DrawableComponent for FuzzyFindPopup {
233317
self.find_text.draw(f, chunks[0])?;
234318

235319
if any_hits {
236-
let title = format!("Hits: {}", self.filtered.len());
237-
238-
let height = usize::from(chunks[1].height);
239-
let width = usize::from(chunks[1].width);
240-
241-
let items =
242-
self.filtered.iter().take(height).map(
243-
|(idx, indicies)| {
244-
let selected = self
245-
.selected_index
246-
.map_or(false, |index| index == *idx);
247-
let full_text = trim_length_left(
248-
&self.contents[*idx],
249-
width,
250-
);
251-
let trim_length = self.contents[*idx]
252-
.graphemes(true)
253-
.count() - full_text
254-
.graphemes(true)
255-
.count();
256-
Line::from(
257-
full_text
258-
.graphemes(true)
259-
.enumerate()
260-
.map(|(c_idx, c)| {
261-
Span::styled(
262-
Cow::from(c.to_string()),
263-
self.theme.text(
264-
selected,
265-
indicies.contains(&(c_idx + trim_length)),
266-
),
267-
)
268-
})
269-
.collect::<Vec<_>>(),
270-
)
271-
},
272-
);
273-
274-
ui::draw_list_block(
275-
f,
276-
chunks[1],
277-
Block::default()
278-
.title(Span::styled(
279-
title,
280-
self.theme.title(true),
281-
))
282-
.borders(Borders::TOP),
283-
items,
284-
);
320+
self.draw_matches_list(f, chunks[1]);
285321
}
286322
}
287323
Ok(())

0 commit comments

Comments
 (0)