Skip to content

Commit

Permalink
Index of search result (#1840)
Browse files Browse the repository at this point in the history
  • Loading branch information
extrawurst authored Aug 27, 2023
1 parent c68fa3e commit 2675934
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 37 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ easy-cast = "0.5"
filetreelist = { path = "./filetreelist", version = "0.5" }
fuzzy-matcher = "0.3"
gh-emoji = { version = "1.0", optional = true }
indexmap = "1.9"
itertools = "0.11"
log = "0.4"
notify = "5.1"
Expand Down
44 changes: 30 additions & 14 deletions src/components/commitlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand All @@ -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),
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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();
}

Expand All @@ -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
}
Expand Down Expand Up @@ -318,6 +338,7 @@ impl CommitList {
self.selection = new_selection;

if self.selection_highlighted() {
self.set_highlighted_selection_index();
return Ok(true);
}
}
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/components/utils/logitems.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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| {
Expand Down
50 changes: 29 additions & 21 deletions src/tabs/revlog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ use asyncgit::{
};
use crossbeam_channel::Sender;
use crossterm::event::Event;
use indexmap::IndexSet;
use ratatui::{
backend::Backend,
layout::{Alignment, Constraint, Direction, Layout, Rect},
text::Span,
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,
}
Expand Down Expand Up @@ -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,
});
Expand All @@ -306,30 +304,40 @@ 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(
Paragraph::new(text)
.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)
Expand Down

0 comments on commit 2675934

Please sign in to comment.