diff --git a/CHANGELOG.md b/CHANGELOG.md index 5610820c..9ca14fd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed * parallelise log search - performance gain ~100% ([#1869](https://github.com/extrawurst/gitui/issues/1869)) +* search message body/summary separately ([#1875](https://github.com/extrawurst/gitui/issues/1875)) + ## [0.24.2] - 2023-09-03 diff --git a/asyncgit/src/sync/commit_filter.rs b/asyncgit/src/sync/commit_filter.rs index a105c085..7fdb7818 100644 --- a/asyncgit/src/sync/commit_filter.rs +++ b/asyncgit/src/sync/commit_filter.rs @@ -35,11 +35,13 @@ bitflags! { /// pub struct SearchFields: u32 { /// - const MESSAGE = 1 << 0; + const MESSAGE_SUMMARY = 1 << 0; /// - const FILENAMES = 1 << 1; + const MESSAGE_BODY = 1 << 1; /// - const AUTHORS = 1 << 2; + const FILENAMES = 1 << 2; + /// + const AUTHORS = 1 << 3; //TODO: // const COMMIT_HASHES = 1 << 3; // /// @@ -51,7 +53,7 @@ bitflags! { impl Default for SearchFields { fn default() -> Self { - Self::MESSAGE + Self::MESSAGE_SUMMARY } } @@ -159,12 +161,22 @@ pub fn filter_commit_by_search( -> Result { let commit = repo.find_commit((*commit_id).into())?; - let msg_match = filter + let msg_summary_match = filter .options .fields - .contains(SearchFields::MESSAGE) + .contains(SearchFields::MESSAGE_SUMMARY) .then(|| { - commit.message().map(|msg| filter.match_text(msg)) + commit.summary().map(|msg| filter.match_text(msg)) + }) + .flatten() + .unwrap_or_default(); + + let msg_body_match = filter + .options + .fields + .contains(SearchFields::MESSAGE_BODY) + .then(|| { + commit.body().map(|msg| filter.match_text(msg)) }) .flatten() .unwrap_or_default(); @@ -203,7 +215,9 @@ pub fn filter_commit_by_search( }) .unwrap_or_default(); - Ok(msg_match || file_match || authors_match) + Ok(msg_summary_match + || msg_body_match + || file_match || authors_match) }, )) } diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs index aeaa4174..b13a9e5a 100644 --- a/asyncgit/src/sync/logwalker.rs +++ b/asyncgit/src/sync/logwalker.rs @@ -249,7 +249,7 @@ mod tests { let log_filter = filter_commit_by_search( LogFilterSearch::new(LogFilterSearchOptions { - fields: SearchFields::MESSAGE, + fields: SearchFields::MESSAGE_SUMMARY, options: SearchOptions::FUZZY_SEARCH, search_pattern: String::from("my msg"), }), diff --git a/src/components/log_search_popup.rs b/src/components/log_search_popup.rs index 564a0097..3f90a0d0 100644 --- a/src/components/log_search_popup.rs +++ b/src/components/log_search_popup.rs @@ -29,7 +29,8 @@ enum Selection { EnterText, FuzzyOption, CaseOption, - MessageSearch, + SummarySearch, + MessageBodySearch, FilenameSearch, AuthorsSearch, } @@ -173,8 +174,16 @@ impl LogSearchPopupComponent { } fn get_text_options(&self) -> Vec { - let x_message = - if self.options.0.contains(SearchFields::MESSAGE) { + let x_summary = + if self.options.0.contains(SearchFields::MESSAGE_SUMMARY) + { + "X" + } else { + " " + }; + + let x_body = + if self.options.0.contains(SearchFields::MESSAGE_BODY) { "X" } else { " " @@ -225,11 +234,21 @@ impl LogSearchPopupComponent { ), )]), Line::from(vec![Span::styled( - format!("[{x_message}] messages",), + format!("[{x_summary}] summary",), self.theme.text( matches!( self.selection, - Selection::MessageSearch + Selection::SummarySearch + ), + false, + ), + )]), + Line::from(vec![Span::styled( + format!("[{x_body}] message body",), + self.theme.text( + matches!( + self.selection, + Selection::MessageBodySearch ), false, ), @@ -254,14 +273,6 @@ impl LogSearchPopupComponent { false, ), )]), - // Line::from(vec![Span::styled( - // "[ ] changes (soon)", - // theme, - // )]), - // Line::from(vec![Span::styled( - // "[ ] hashes (soon)", - // theme, - // )]), ] } @@ -278,8 +289,17 @@ impl LogSearchPopupComponent { Selection::CaseOption => { self.options.1.toggle(SearchOptions::CASE_SENSITIVE); } - Selection::MessageSearch => { - self.options.0.toggle(SearchFields::MESSAGE); + Selection::SummarySearch => { + self.options.0.toggle(SearchFields::MESSAGE_SUMMARY); + + if self.options.0.is_empty() { + self.options + .0 + .set(SearchFields::MESSAGE_BODY, true); + } + } + Selection::MessageBodySearch => { + self.options.0.toggle(SearchFields::MESSAGE_BODY); if self.options.0.is_empty() { self.options.0.set(SearchFields::FILENAMES, true); @@ -296,7 +316,9 @@ impl LogSearchPopupComponent { self.options.0.toggle(SearchFields::AUTHORS); if self.options.0.is_empty() { - self.options.0.set(SearchFields::MESSAGE, true); + self.options + .0 + .set(SearchFields::MESSAGE_SUMMARY, true); } } } @@ -309,16 +331,26 @@ impl LogSearchPopupComponent { Selection::EnterText => Selection::AuthorsSearch, Selection::FuzzyOption => Selection::EnterText, Selection::CaseOption => Selection::FuzzyOption, - Selection::MessageSearch => Selection::CaseOption, - Selection::FilenameSearch => Selection::MessageSearch, + Selection::SummarySearch => Selection::CaseOption, + Selection::MessageBodySearch => { + Selection::SummarySearch + } + Selection::FilenameSearch => { + Selection::MessageBodySearch + } Selection::AuthorsSearch => Selection::FilenameSearch, }; } else { self.selection = match self.selection { Selection::EnterText => Selection::FuzzyOption, Selection::FuzzyOption => Selection::CaseOption, - Selection::CaseOption => Selection::MessageSearch, - Selection::MessageSearch => Selection::FilenameSearch, + Selection::CaseOption => Selection::SummarySearch, + Selection::SummarySearch => { + Selection::MessageBodySearch + } + Selection::MessageBodySearch => { + Selection::FilenameSearch + } Selection::FilenameSearch => Selection::AuthorsSearch, Selection::AuthorsSearch => Selection::EnterText, };