aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/search.rs64
-rw-r--r--src/frontend/app.rs11
-rw-r--r--src/frontend/entries.rs20
-rw-r--r--src/frontend/keywords.rs60
4 files changed, 75 insertions, 80 deletions
diff --git a/src/backend/search.rs b/src/backend/search.rs
index 6757790..bb87416 100644
--- a/src/backend/search.rs
+++ b/src/backend/search.rs
@@ -4,10 +4,13 @@ use nucleo_matcher::{
};
use std::collections::HashMap;
+use crate::frontend::entries::EntryTableItem;
+
#[derive(Debug)]
pub struct BibiSearch {
pub search_string: String, // Search string show in footer, used for search
pub inner_search: bool, // True, if we trigger a search for already filtered list
+ // pub entry_list_at_search_start: Vec<EntryTableItem>,
pub filtered_entry_list_by_search: Vec<Vec<String>>, // Temporary holds entry list filtered by search pattern to refilter it
pub filtered_entry_list_by_tags: Vec<Vec<String>>, // Holds entry list filtered by tag to filter it further by search
pub filtered_tag_list: Vec<String>,
@@ -18,6 +21,7 @@ impl Default for BibiSearch {
Self {
search_string: String::new(),
inner_search: false,
+ // entry_list_at_search_start: Vec::new(),
filtered_entry_list_by_search: Vec::new(),
filtered_entry_list_by_tags: Vec::new(),
filtered_tag_list: Vec::new(),
@@ -26,18 +30,29 @@ impl Default for BibiSearch {
}
impl BibiSearch {
- // Stringify inner Vec<String> by joining/concat
- fn convert_to_string(inner_vec: &Vec<String>) -> String {
- inner_vec[0..6].join(" ")
+ // Stringify EntryTableItem by joining/concat
+ fn convert_to_string(inner_vec: &EntryTableItem) -> String {
+ let entry_table_item_str = {
+ format!(
+ "{} {} {} {} {} {}",
+ &inner_vec.authors,
+ &inner_vec.title,
+ &inner_vec.year,
+ &inner_vec.pubtype,
+ &inner_vec.keywords,
+ &inner_vec.citekey
+ )
+ };
+ entry_table_item_str
}
// Return a filtered entry list
pub fn search_entry_list(
search_pattern: &str,
- orig_list: Vec<Vec<String>>,
- ) -> Vec<Vec<String>> {
+ orig_list: Vec<EntryTableItem>,
+ ) -> Vec<EntryTableItem> {
// Create a hashmap to connect stingified entry with entry vec
- let mut entry_string_hm: HashMap<String, Vec<String>> = HashMap::new();
+ let mut entry_string_hm: HashMap<String, EntryTableItem> = HashMap::new();
// Convert all entries to string and insert them into the hashmap
// next to the original inner Vec<String> of the entry list
@@ -58,10 +73,11 @@ impl BibiSearch {
// Create filtered entry list and push the inner entry vec's to it
// Use the filtered stringified hm-key as index
- let mut filtered_list: Vec<Vec<String>> = Vec::new();
+ let mut filtered_list: Vec<EntryTableItem> = Vec::new();
for m in filtered_matches {
filtered_list.push(entry_string_hm[&m].to_owned());
}
+ filtered_list.sort();
filtered_list
}
@@ -79,11 +95,17 @@ impl BibiSearch {
filtered_matches
}
- pub fn filter_entries_by_tag(keyword: &str, orig_list: &Vec<Vec<String>>) -> Vec<Vec<String>> {
- let mut filtered_list: Vec<Vec<String>> = Vec::new();
+ pub fn filter_entries_by_tag(
+ keyword: &str,
+ orig_list: &Vec<EntryTableItem>,
+ ) -> Vec<EntryTableItem> {
+ let mut filtered_list: Vec<EntryTableItem> = Vec::new();
+ // Loop over the whole given entry table
+ // Check if the selected keyword is present in the current entry
+ // If present, push the entry to the filtered list
for e in orig_list {
- if e[4].contains(keyword) {
+ if e.keywords.contains(keyword) {
filtered_list.push(e.to_owned());
}
}
@@ -98,17 +120,17 @@ mod tests {
#[test]
fn test_vector_join() {
- let bibvec = vec![
- "Author".to_string(),
- "Title".to_string(),
- "1999".to_string(),
- "article".to_string(),
- "hello, bye".to_string(),
- "author_1999".to_string(),
- "An abstract with multiple sentences. Sometimes thats necessary".to_string(),
- "www.bibiman.org".to_string(),
- "/home/file/path.pdf".to_string(),
- ];
+ let bibvec: EntryTableItem = EntryTableItem::new(
+ "Author",
+ "Title",
+ "1999",
+ "article",
+ "hello, bye",
+ "author_1999",
+ "An abstract with multiple sentences. Here is the second",
+ "https://www.bibiman.org",
+ "/home/file/path.pdf",
+ );
let joined_vec = BibiSearch::convert_to_string(&bibvec);
diff --git a/src/frontend/app.rs b/src/frontend/app.rs
index 2f88ff2..3f679bf 100644
--- a/src/frontend/app.rs
+++ b/src/frontend/app.rs
@@ -163,6 +163,7 @@ impl App {
}
self.search_struct.filtered_entry_list_by_search.clear();
self.search_struct.filtered_entry_list_by_tags.clear();
+ self.entry_table.entry_table_at_search_start.clear();
self.search_struct.filtered_tag_list.clear();
self.search_struct.inner_search = false;
self.former_area = None
@@ -176,7 +177,6 @@ impl App {
}
pub fn scroll_info_down(&mut self) {
- // self.entry_table.entry_info_scroll = self.entry_table.entry_info_scroll + 1;
self.entry_table.entry_info_scroll = self.entry_table.entry_info_scroll.saturating_add(1);
self.entry_table.entry_info_scroll_state = self
.entry_table
@@ -185,11 +185,6 @@ impl App {
}
pub fn scroll_info_up(&mut self) {
- // if self.entry_table.entry_info_scroll == 0 {
- // {}
- // } else {
- // self.entry_table.entry_info_scroll = self.entry_table.entry_info_scroll - 1;
- // }
self.entry_table.entry_info_scroll = self.entry_table.entry_info_scroll.saturating_sub(1);
self.entry_table.entry_info_scroll_state = self
.entry_table
@@ -205,6 +200,8 @@ impl App {
if let Some(FormerArea::TagArea) = self.former_area {
self.search_struct.inner_search = true
}
+ self.entry_table.entry_table_at_search_start =
+ self.entry_table.entry_table_items.clone();
self.former_area = Some(FormerArea::EntryArea)
} else if let CurrentArea::TagArea = self.current_area {
self.former_area = Some(FormerArea::TagArea)
@@ -222,6 +219,7 @@ impl App {
}
self.former_area = Some(FormerArea::SearchArea);
self.search_struct.search_string.clear();
+ self.entry_table.entry_table_at_search_start.clear();
}
// Break search: leave search area without filtering list
@@ -239,6 +237,7 @@ impl App {
self.former_area = None;
// If search is canceled, reset default status of struct
self.search_struct.search_string.clear();
+ self.entry_table.entry_table_at_search_start.clear();
}
// Remove last char from search pattern and filter list immidiately
diff --git a/src/frontend/entries.rs b/src/frontend/entries.rs
index ac6d1b0..98604f9 100644
--- a/src/frontend/entries.rs
+++ b/src/frontend/entries.rs
@@ -29,6 +29,7 @@ use std::process::{Command, Stdio};
#[derive(Debug)]
pub struct EntryTable {
pub entry_table_items: Vec<EntryTableItem>,
+ pub entry_table_at_search_start: Vec<EntryTableItem>,
pub entry_table_state: TableState,
pub entry_scroll_state: ScrollbarState,
pub entry_info_scroll: u16,
@@ -54,6 +55,7 @@ impl FromIterator<Vec<String>> for EntryTable {
let entry_info_scroll_state = ScrollbarState::default();
Self {
entry_table_items,
+ entry_table_at_search_start: Vec::new(),
entry_table_state,
entry_scroll_state,
entry_info_scroll: 0,
@@ -63,7 +65,7 @@ impl FromIterator<Vec<String>> for EntryTable {
}
// Define contents of each entry table row
-#[derive(Debug)]
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct EntryTableItem {
pub authors: String,
pub title: String,
@@ -248,20 +250,12 @@ impl App {
// Search entry list
pub fn search_entries(&mut self) {
- let orig_list = {
- if self.search_struct.inner_search {
- let orig_list = &self.search_struct.filtered_entry_list_by_tags;
- orig_list
- } else {
- let orig_list = &self.biblio_data.entry_list.bibentries;
- orig_list
- }
- };
+ // Use snapshot of entry list saved when starting the search
+ // so deleting a char, will show former entries too
+ let orig_list = self.entry_table.entry_table_at_search_start.clone();
let filtered_list =
BibiSearch::search_entry_list(&mut self.search_struct.search_string, orig_list.clone());
- //search::search_entry_list(&self.search_string, orig_list.clone());
- self.search_struct.filtered_entry_list_by_search = filtered_list.clone();
- self.entry_table = EntryTable::from_iter(filtered_list);
+ self.entry_table.entry_table_items = filtered_list;
}
// Open file connected with entry through 'file' or 'pdf' field
diff --git a/src/frontend/keywords.rs b/src/frontend/keywords.rs
index b4cc7e9..0363609 100644
--- a/src/frontend/keywords.rs
+++ b/src/frontend/keywords.rs
@@ -16,7 +16,6 @@
/////
use super::app::{App, FormerArea};
-use super::entries::EntryTable;
use crate::backend::search::BibiSearch;
use ratatui::widgets::{ListState, ScrollbarState};
@@ -105,56 +104,37 @@ impl App {
}
pub fn filter_tags_by_entries(&mut self) {
- if !self.search_struct.filtered_entry_list_by_search.is_empty()
- || !self.search_struct.filtered_entry_list_by_tags.is_empty()
- {
- self.search_struct.filtered_tag_list.clear();
-
- let orig_list = if !self.search_struct.filtered_entry_list_by_search.is_empty() {
- self.search_struct.filtered_entry_list_by_search.clone()
- } else {
- self.search_struct.filtered_entry_list_by_tags.clone()
- };
-
- let mut filtered_keywords: Vec<String> = Vec::new();
-
- for e in orig_list {
- if !e[4].is_empty() {
- let mut key_vec: Vec<String> = e[4]
- .split(',')
- .map(|s| s.trim().to_string())
- .filter(|s| !s.is_empty())
- .collect();
- filtered_keywords.append(&mut key_vec);
- }
+ let mut filtered_keywords: Vec<String> = Vec::new();
+
+ let orig_list = &self.entry_table.entry_table_items;
+
+ for e in orig_list {
+ if !e.keywords.is_empty() {
+ let mut key_vec: Vec<String> = e
+ .keywords
+ .split(',')
+ .map(|s| s.trim().to_string())
+ .filter(|s| !s.is_empty())
+ .collect();
+ filtered_keywords.append(&mut key_vec);
}
+ }
- filtered_keywords.sort_by(|a, b| a.to_lowercase().cmp(&b.to_lowercase()));
- filtered_keywords.dedup();
+ filtered_keywords.sort_by(|a, b| a.to_lowercase().cmp(&b.to_lowercase()));
+ filtered_keywords.dedup();
- self.search_struct.filtered_tag_list = filtered_keywords.clone();
- self.tag_list = TagList::from_iter(filtered_keywords);
- }
+ self.search_struct.filtered_tag_list = filtered_keywords.clone();
+ self.tag_list = TagList::from_iter(filtered_keywords);
}
// Filter the entry list by tags when hitting enter
// If already inside a filtered tag or entry list, apply the filtering
// to the already filtered list only
pub fn filter_for_tags(&mut self) {
- let orig_list = {
- if self.search_struct.inner_search {
- let orig_list = &self.search_struct.filtered_entry_list_by_search;
- orig_list
- } else {
- let orig_list = &self.biblio_data.entry_list.bibentries;
- orig_list
- }
- };
+ let orig_list = &self.entry_table.entry_table_items;
let keyword = self.get_selected_tag();
let filtered_list = BibiSearch::filter_entries_by_tag(&keyword, &orig_list);
- self.search_struct.filtered_entry_list_by_tags = filtered_list;
- self.entry_table =
- EntryTable::from_iter(self.search_struct.filtered_entry_list_by_tags.clone());
+ self.entry_table.entry_table_items = filtered_list;
self.filter_tags_by_entries();
self.toggle_area();
self.former_area = Some(FormerArea::TagArea);