aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/app.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/app.rs')
-rw-r--r--src/frontend/app.rs324
1 files changed, 12 insertions, 312 deletions
diff --git a/src/frontend/app.rs b/src/frontend/app.rs
index 8950202..4bd46be 100644
--- a/src/frontend/app.rs
+++ b/src/frontend/app.rs
@@ -15,22 +15,16 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/////
-use std::process::Command;
-
-use editor_command::EditorBuilder;
-
+use super::tui;
+use crate::backend::cliargs::CLIArgs;
use crate::backend::{bib::*, search::BibiSearch};
use crate::{
- frontend::handler::handle_key_events,
- frontend::tui::{Event, Tui},
+ frontend::entries::EntryTable, frontend::handler::handle_key_events,
+ frontend::keywords::TagList, frontend::tui::Event,
};
-
use arboard::Clipboard;
use color_eyre::eyre::{Ok, Result};
-use itertools::Itertools;
-use ratatui::widgets::{ListState, TableState};
-
-use super::tui;
+use std::path::PathBuf;
// Areas in which actions are possible
#[derive(Debug)]
@@ -54,6 +48,8 @@ pub enum FormerArea {
pub struct App {
// Is the application running?
pub running: bool,
+ // main bib file
+ pub main_bibfile: PathBuf,
// main bibliography
pub main_biblio: BibiMain,
// bibliographic data
@@ -72,152 +68,13 @@ pub struct App {
pub former_area: Option<FormerArea>,
}
-// Define the fundamental List
-#[derive(Debug)]
-pub struct TagList {
- pub tag_list_items: Vec<TagListItem>,
- pub tag_list_state: ListState,
-}
-
-// Structure of the list items.
-#[derive(Debug)]
-pub struct TagListItem {
- pub keyword: String,
-}
-
-// Function to process inputed characters and convert them (to string, or more complex function)
-impl TagListItem {
- pub fn new(info: &str) -> Self {
- Self {
- keyword: info.to_string(),
- }
- }
-}
-
-impl FromIterator<String> for TagList {
- fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> Self {
- let tag_list_items = iter
- .into_iter()
- .map(|info| TagListItem::new(&info))
- .collect();
- let tag_list_state = ListState::default(); // for preselection: .with_selected(Some(0));
- Self {
- tag_list_items,
- tag_list_state,
- }
- }
-}
-
-// // Also possible with vector.
-impl FromIterator<Vec<String>> for EntryTable {
- fn from_iter<T: IntoIterator<Item = Vec<String>>>(iter: T) -> Self {
- let entry_table_items = iter
- .into_iter()
- .sorted()
- .map(|i| EntryTableItem::new(&i[0], &i[1], &i[2], &i[3], &i[4], &i[5]))
- .collect();
- let entry_table_state = TableState::default().with_selected(0);
- Self {
- entry_table_items,
- entry_table_state,
- }
- }
-}
-
-// Define list containing entries as table
-#[derive(Debug)]
-pub struct EntryTable {
- pub entry_table_items: Vec<EntryTableItem>,
- pub entry_table_state: TableState,
-}
-
-// Define contents of each entry table row
-#[derive(Debug)]
-pub struct EntryTableItem {
- pub authors: String,
- pub title: String,
- pub year: String,
- pub pubtype: String,
- pub keywords: String,
- pub citekey: String,
-}
-
-impl EntryTableItem {
- pub fn new(
- authors: &str,
- title: &str,
- year: &str,
- pubtype: &str,
- keywords: &str,
- citekey: &str,
- ) -> Self {
- Self {
- authors: authors.to_string(),
- title: title.to_string(),
- year: year.to_string(),
- pubtype: pubtype.to_string(),
- keywords: keywords.to_string(),
- citekey: citekey.to_string(),
- }
- }
-
- // This functions decides which fields are rendered in the entry table
- // Fields which should be usable but not visible can be left out
- pub fn ref_vec(&self) -> Vec<&String> {
- vec![&self.authors, &self.title, &self.year, &self.pubtype]
- }
-
- pub fn authors(&self) -> &str {
- &self.authors
- }
-
- pub fn title(&self) -> &str {
- &self.title
- }
-
- pub fn year(&self) -> &str {
- &self.year
- }
-
- pub fn pubtype(&self) -> &str {
- &self.pubtype
- }
-
- pub fn citekey(&self) -> &str {
- &self.citekey
- }
-}
-
-// impl Default for App {
-// fn default() -> Self {
-// let running = true;
-// let main_biblio = BibiMain::new();
-// let biblio_data = BibiData::new(&main_biblio.bibliography, &main_biblio.citekeys);
-// let tag_list = TagList::from_iter(main_biblio.keyword_list.clone());
-// let search_struct = BibiSearch::default();
-// let entry_table = EntryTable::from_iter(biblio_data.entry_list.bibentries.clone());
-// let current_area = CurrentArea::EntryArea;
-// Self {
-// running,
-// main_biblio,
-// biblio_data,
-// tag_list,
-// search_struct,
-// entry_table,
-// scroll_info: 0,
-// current_area,
-// former_area: None,
-// // search_string: String::new(),
-// }
-// }
-// }
-
impl App {
// Constructs a new instance of [`App`].
- pub fn new() -> Result<Self> {
+ pub fn new(args: CLIArgs) -> Result<Self> {
// Self::default()
let running = true;
- let main_biblio = BibiMain::new();
+ let main_bibfile = args.bibfilearg;
+ let main_biblio = BibiMain::new(main_bibfile.clone());
let biblio_data = BibiData::new(&main_biblio.bibliography, &main_biblio.citekeys);
let tag_list = TagList::from_iter(main_biblio.keyword_list.clone());
let search_struct = BibiSearch::default();
@@ -225,6 +82,7 @@ impl App {
let current_area = CurrentArea::EntryArea;
Ok(Self {
running,
+ main_bibfile,
main_biblio,
biblio_data,
tag_list,
@@ -269,7 +127,7 @@ impl App {
}
pub fn update_lists(&mut self) {
- self.main_biblio = BibiMain::new();
+ self.main_biblio = BibiMain::new(self.main_bibfile.clone());
self.biblio_data =
BibiData::new(&self.main_biblio.bibliography, &self.main_biblio.citekeys);
self.tag_list = TagList::from_iter(self.main_biblio.keyword_list.clone());
@@ -285,34 +143,6 @@ impl App {
self.current_area = CurrentArea::EntryArea;
self.tag_list.tag_list_state.select(None)
}
- // match self.current_area {
- // CurrentArea::EntryArea => {
- // self.current_area = CurrentArea::TagArea;
- // self.tag_list.tag_list_state.select(Some(0))
- // }
- // CurrentArea::TagArea => {
- // self.current_area = CurrentArea::EntryArea;
- // self.tag_list.tag_list_state.select(None)
- // }
- // CurrentArea::SearchArea => {
- // if let Some(former_area) = &self.former_area {
- // match former_area {
- // FormerArea::EntryArea => self.current_area = CurrentArea::EntryArea,
- // FormerArea::TagArea => self.current_area = CurrentArea::TagArea,
- // _ => {}
- // }
- // }
- // }
- // CurrentArea::HelpArea => {
- // if let Some(former_area) = &self.former_area {
- // match former_area {
- // FormerArea::EntryArea => self.current_area = CurrentArea::EntryArea,
- // FormerArea::TagArea => self.current_area = CurrentArea::TagArea,
- // FormerArea::SearchArea => self.current_area = CurrentArea::SearchArea,
- // }
- // }
- // }
- // }
}
pub fn reset_current_list(&mut self) {
@@ -425,134 +255,4 @@ impl App {
self.search_tags();
}
}
-
- // Tag List commands
-
- // Movement
- pub fn select_next_tag(&mut self) {
- self.tag_list.tag_list_state.select_next();
- }
-
- pub fn select_previous_tag(&mut self) {
- self.tag_list.tag_list_state.select_previous();
- }
-
- pub fn select_first_tag(&mut self) {
- self.tag_list.tag_list_state.select_first();
- }
-
- pub fn select_last_tag(&mut self) {
- self.tag_list.tag_list_state.select_last();
- }
-
- pub fn get_selected_tag(&self) -> &str {
- let idx = self.tag_list.tag_list_state.selected().unwrap();
- let keyword = &self.tag_list.tag_list_items[idx].keyword;
- keyword
- }
-
- pub fn search_tags(&mut self) {
- let orig_list = &self.main_biblio.keyword_list;
- let filtered_list =
- BibiSearch::search_tag_list(&self.search_struct.search_string, orig_list.clone());
- self.tag_list = TagList::from_iter(filtered_list)
- }
-
- // Filter the entry list by tags
- // 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;
- orig_list
- } else {
- let orig_list = &self.biblio_data.entry_list.bibentries;
- orig_list
- }
- };
- let keyword = self.get_selected_tag();
- let filtered_list = BibiSearch::filter_entries_by_tag(&keyword, &orig_list);
- self.search_struct.filtered_entry_list = filtered_list;
- self.entry_table = EntryTable::from_iter(self.search_struct.filtered_entry_list.clone());
- self.toggle_area();
- self.former_area = Some(FormerArea::TagArea);
- }
-
- // Entry Table commands
-
- // Movement
- pub fn select_next_entry(&mut self) {
- self.scroll_info = 0;
- self.entry_table.entry_table_state.select_next();
- }
-
- pub fn select_previous_entry(&mut self) {
- self.scroll_info = 0;
- self.entry_table.entry_table_state.select_previous();
- }
-
- pub fn select_first_entry(&mut self) {
- self.scroll_info = 0;
- self.entry_table.entry_table_state.select_first();
- }
-
- pub fn select_last_entry(&mut self) {
- self.scroll_info = 0;
- self.entry_table.entry_table_state.select_last();
- }
-
- // Get the citekey of the selected entry
- pub fn get_selected_citekey(&self) -> &str {
- let idx = self.entry_table.entry_table_state.selected().unwrap();
- let citekey = &self.entry_table.entry_table_items[idx].citekey;
- citekey
- }
-
- pub fn run_editor(&mut self, tui: &mut Tui) -> Result<()> {
- // get filecontent and citekey for calculating line number
- let citekey = self.get_selected_citekey();
- let filepath = self.main_biblio.bibfile.display().to_string();
- let filecontent = self.main_biblio.bibfilestring.clone();
- let mut line_count = 0;
-
- for line in filecontent.lines() {
- line_count = line_count + 1;
- // if reaching the citekey break the loop
- // if reaching end of lines without match, reset to 0
- if line.contains(&citekey) {
- break;
- } else if line_count == filecontent.len() {
- eprintln!(
- "Citekey {} not found, opening file {} at line 1",
- &citekey, &filepath
- );
- line_count = 0;
- break;
- }
- }
-
- // Exit TUI to enter editor
- tui.exit()?;
- // Use VISUAL or EDITOR. Set "vi" as last fallback
- let mut cmd: Command = EditorBuilder::new()
- .environment()
- .source(Some("vi"))
- .build()
- .unwrap();
- // Prepare arguments to open file at specific line
- let args: Vec<String> = vec![format!("+{}", line_count), filepath];
- let status = cmd.args(&args).status()?;
- if !status.success() {
- eprintln!("Spawning editor failed with status {}", status);
- }
-
- // Enter TUI again
- tui.enter()?;
- tui.terminal.clear()?;
-
- // Update the database and the lists to show changes
- self.update_lists();
- Ok(())
- }
}