summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorextrawurst <776816+extrawurst@users.noreply.github.com>2023-08-27 11:25:16 +0200
committerGitHub <noreply@github.com>2023-08-27 11:25:16 +0200
commit2675934027e83f6b7119dec45055d34ee1f7b20f (patch)
treea958f239c4c766360c8f906a650022104649f98f /src
parentc68fa3e87b75d2a2b566faffbfcca77de28240be (diff)
Index of search result (#1840)
Diffstat (limited to 'src')
-rw-r--r--src/components/commitlist.rs44
-rw-r--r--src/components/utils/logitems.rs5
-rw-r--r--src/tabs/revlog.rs50
3 files changed, 62 insertions, 37 deletions
diff --git a/src/components/commitlist.rs b/src/components/commitlist.rs
index 27208e60..c4e4fd29 100644
--- a/src/components/commitlist.rs
+++ b/src/components/commitlist.rs
@@ -18,6 +18,7 @@ use asyncgit::sync::{
};
use chrono::{DateTime, Local};
use crossterm::event::Event;
+use indexmap::IndexSet;
use itertools::Itertools;
use ratatui::{
backend::Backend,
@@ -28,12 +29,8 @@ use ratatui::{
Frame,
};
use std::{
- borrow::Cow,
- cell::Cell,
- cmp,
- collections::{BTreeMap, HashSet},
- convert::TryFrom,
- time::Instant,
+ borrow::Cow, cell::Cell, cmp, collections::BTreeMap,
+ convert::TryFrom, rc::Rc, time::Instant,
};
const ELEMENTS_PER_LINE: usize = 9;
@@ -44,8 +41,9 @@ pub struct CommitList {
repo: RepoPathRef,
title: Box<str>,
selection: usize,
+ highlighted_selection: Option<usize>,
items: ItemBatch,
- highlights: Option<HashSet<CommitId>>,
+ highlights: Option<Rc<IndexSet<CommitId>>>,
commits: Vec<CommitId>,
marked: Vec<(usize, CommitId)>,
scroll_state: (Instant, f32),
@@ -73,6 +71,7 @@ impl CommitList {
items: ItemBatch::default(),
marked: Vec::with_capacity(2),
selection: 0,
+ highlighted_selection: None,
commits: Vec::new(),
highlights: None,
scroll_state: (Instant::now(), 0_f32),
@@ -240,10 +239,11 @@ impl CommitList {
///
pub fn set_highlighting(
&mut self,
- highlighting: Option<HashSet<CommitId>>,
+ highlighting: Option<Rc<IndexSet<CommitId>>>,
) {
self.highlights = highlighting;
self.select_next_highlight();
+ self.set_highlighted_selection_index();
self.fetch_commits();
}
@@ -253,12 +253,32 @@ impl CommitList {
if let Some(position) = position {
self.selection = position;
+ self.set_highlighted_selection_index();
Ok(())
} else {
anyhow::bail!("Could not select commit. It might not be loaded yet or it might be on a different branch.");
}
}
+ ///
+ pub fn highlighted_selection_info(&self) -> (usize, usize) {
+ let amount = self
+ .highlights
+ .as_ref()
+ .map(|highlights| highlights.len())
+ .unwrap_or_default();
+ (self.highlighted_selection.unwrap_or_default(), amount)
+ }
+
+ fn set_highlighted_selection_index(&mut self) {
+ self.highlighted_selection =
+ self.highlights.as_ref().and_then(|highlights| {
+ highlights.iter().position(|entry| {
+ entry == &self.commits[self.selection]
+ })
+ });
+ }
+
const fn selection(&self) -> usize {
self.selection
}
@@ -318,6 +338,7 @@ impl CommitList {
self.selection = new_selection;
if self.selection_highlighted() {
+ self.set_highlighted_selection_index();
return Ok(true);
}
}
@@ -703,12 +724,7 @@ impl CommitList {
);
if let Ok(commits) = commits {
- self.items.set_items(
- want_min,
- commits,
- //TODO: optimize via sharable data (BTreeMap that preserves order and lookup)
- &self.highlights.clone(),
- );
+ self.items.set_items(want_min, commits, &self.highlights);
}
}
}
diff --git a/src/components/utils/logitems.rs b/src/components/utils/logitems.rs
index fb7115d0..b6b113f6 100644
--- a/src/components/utils/logitems.rs
+++ b/src/components/utils/logitems.rs
@@ -1,6 +1,7 @@
use asyncgit::sync::{CommitId, CommitInfo};
use chrono::{DateTime, Duration, Local, NaiveDateTime, Utc};
-use std::{collections::HashSet, slice::Iter};
+use indexmap::IndexSet;
+use std::{rc::Rc, slice::Iter};
#[cfg(feature = "ghemoji")]
use super::emoji::emojifi_string;
@@ -111,7 +112,7 @@ impl ItemBatch {
&mut self,
start_index: usize,
commits: Vec<CommitInfo>,
- highlighted: &Option<HashSet<CommitId>>,
+ highlighted: &Option<Rc<IndexSet<CommitId>>>,
) {
self.items.clear();
self.items.extend(commits.into_iter().map(|c| {
diff --git a/src/tabs/revlog.rs b/src/tabs/revlog.rs
index 0bdb87f5..7c38c850 100644
--- a/src/tabs/revlog.rs
+++ b/src/tabs/revlog.rs
@@ -23,6 +23,7 @@ use asyncgit::{
};
use crossbeam_channel::Sender;
use crossterm::event::Event;
+use indexmap::IndexSet;
use ratatui::{
backend::Backend,
layout::{Alignment, Constraint, Direction, Layout, Rect},
@@ -30,11 +31,10 @@ use ratatui::{
widgets::{Block, Borders, Paragraph},
Frame,
};
-use std::{collections::HashSet, rc::Rc, time::Duration};
+use std::{rc::Rc, time::Duration};
use sync::CommitTags;
struct LogSearchResult {
- commits: usize,
options: LogFilterSearchOptions,
duration: Duration,
}
@@ -280,16 +280,14 @@ impl Revlog {
false
} else {
let results = search.extract_items()?;
- let commits = results.len();
let duration = search.get_last_duration()?;
- self.list.set_highlighting(Some(
- results.into_iter().collect::<HashSet<_>>(),
- ));
+ self.list.set_highlighting(Some(Rc::new(
+ results.into_iter().collect::<IndexSet<_>>(),
+ )));
self.search =
LogSearch::Results(LogSearchResult {
- commits,
options: options.clone(),
duration,
});
@@ -306,22 +304,28 @@ impl Revlog {
}
fn draw_search<B: Backend>(&self, f: &mut Frame<B>, area: Rect) {
- let text = match &self.search {
- LogSearch::Searching(_, options) => {
- format!(
- "'{}' (pending results...)",
- options.search_pattern.clone()
- )
- }
+ let (text, title) = match &self.search {
+ LogSearch::Searching(_, options) => (
+ format!("'{}'", options.search_pattern.clone()),
+ String::from("(pending results...)"),
+ ),
LogSearch::Results(results) => {
- format!(
- "'{}' (hits: {}) (duration: {:?})",
- results.options.search_pattern.clone(),
- results.commits,
- results.duration,
+ let info = self.list.highlighted_selection_info();
+
+ (
+ format!(
+ "'{}' (duration: {:?})",
+ results.options.search_pattern.clone(),
+ results.duration,
+ ),
+ format!(
+ "({}/{})",
+ (info.0 + 1).min(info.1),
+ info.1
+ ),
)
}
- LogSearch::Off => String::new(),
+ LogSearch::Off => (String::new(), String::new()),
};
f.render_widget(
@@ -329,7 +333,11 @@ impl Revlog {
.block(
Block::default()
.title(Span::styled(
- strings::POPUP_TITLE_LOG_SEARCH,
+ format!(
+ "{} {}",
+ strings::POPUP_TITLE_LOG_SEARCH,
+ title
+ ),
self.theme.title(true),
))
.borders(Borders::ALL)