diff options
Diffstat (limited to 'src/app.rs')
| -rw-r--r-- | src/app.rs | 188 |
1 files changed, 106 insertions, 82 deletions
@@ -17,15 +17,18 @@ use crate::bibiman::{CurrentArea, FormerArea}; use color_eyre::eyre::{Context, Ok, Result}; +use regex::Regex; // use super::Event; use crate::cliargs::CLIArgs; use crate::tui::commands::InputCmdAction; use crate::tui::popup::PopupKind; use crate::tui::{self, Tui}; use crate::{bibiman::Bibiman, tui::commands::CmdAction}; -use ratatui::crossterm::event::KeyCode; +use core::panic; use std::ffi::OsStr; -use std::path::PathBuf; +use std::fs::{File, OpenOptions}; +use std::io::Write; +use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use tui::Event; use tui_input::backend::crossterm::EventHandler; @@ -59,7 +62,7 @@ impl App { }) } - pub async fn run(&mut self, args: &CLIArgs) -> Result<()> { + pub async fn run(&mut self, args: &mut CLIArgs) -> Result<()> { let mut tui = tui::Tui::new()?; tui.enter()?; @@ -80,72 +83,13 @@ impl App { { self.bibiman.close_popup() } - // else if let Some(PopupKind::AddEntry) = self.bibiman.popup_area.popup_kind { - // // Handle key events for AddEntry popup - // match key_event.code { - // KeyCode::Char(c) => { - // let index = self.bibiman.popup_area.add_entry_cursor_position; - // self.bibiman.popup_area.add_entry_input.insert(index, c); - // self.bibiman.popup_area.add_entry_cursor_position += 1; - // } - // KeyCode::Backspace => { - // if self.bibiman.popup_area.add_entry_cursor_position > 0 { - // self.bibiman.popup_area.add_entry_cursor_position -= 1; - // let index = self.bibiman.popup_area.add_entry_cursor_position; - // self.bibiman.popup_area.add_entry_input.remove(index); - // } - // } - // KeyCode::Left => { - // if self.bibiman.popup_area.add_entry_cursor_position > 0 { - // self.bibiman.popup_area.add_entry_cursor_position -= 1; - // } - // } - // KeyCode::Right => { - // if self.bibiman.popup_area.add_entry_cursor_position - // < self.bibiman.popup_area.add_entry_input.len() - // { - // self.bibiman.popup_area.add_entry_cursor_position += 1; - // } - // } - // KeyCode::Enter => { - // // Handle submission of the new entry - // self.bibiman.handle_new_entry_submission(args, &self.input); - // self.bibiman.close_popup(); - // self.input_mode = false; - // } - // KeyCode::Esc => { - // // Close the popup without saving - // self.bibiman.close_popup(); - // self.input_mode = false; - // } - // _ => {} - // } - // } - else { - let command = if self.input_mode { - CmdAction::Input(InputCmdAction::parse(key_event, &self.input)) - } else { - CmdAction::from(key_event) - }; - self.run_command(command, args, &mut tui)? - } + let command = if self.input_mode { + CmdAction::Input(InputCmdAction::parse(key_event, &self.input)) + } else { + CmdAction::from(key_event) + }; + self.run_command(command, args, &mut tui)? } - // Event::Key(key_event) => { - // // Automatically close message popups on next keypress - // if let Some(PopupKind::MessageConfirm) = self.bibiman.popup_area.popup_kind { - // self.bibiman.close_popup() - // } else if let Some(PopupKind::MessageError) = self.bibiman.popup_area.popup_kind - // { - // self.bibiman.close_popup() - // } - - // let command = if self.input_mode { - // CmdAction::Input(InputCmdAction::parse(key_event, &self.input)) - // } else { - // CmdAction::from(key_event) - // }; - // self.run_command(command, args, &mut tui)? - // } Event::Mouse(mouse_event) => { self.run_command(CmdAction::from(mouse_event), args, &mut tui)? } @@ -169,7 +113,7 @@ impl App { self.running = false; } - pub fn run_command(&mut self, cmd: CmdAction, args: &CLIArgs, tui: &mut Tui) -> Result<()> { + pub fn run_command(&mut self, cmd: CmdAction, args: &mut CLIArgs, tui: &mut Tui) -> Result<()> { match cmd { CmdAction::Input(cmd) => match cmd { InputCmdAction::Nothing => {} @@ -191,8 +135,19 @@ impl App { } else if let CurrentArea::PopupArea = self.bibiman.current_area { match self.bibiman.popup_area.popup_kind { Some(PopupKind::AddEntry) => { - self.bibiman.handle_new_entry_submission(args, &self.input); + let doi = self.input.value(); self.bibiman.close_popup(); + self.input_mode = false; + // Check if the DOI pattern is valid. If not, show warning and break + if doi.starts_with("10.") || doi.starts_with("http") { + self.bibiman.handle_new_entry_submission(args, doi); + } else { + self.bibiman.popup_area.popup_message( + "No valid DOI pattern: ", + doi, + false, + ); + } } _ => {} } @@ -218,13 +173,15 @@ impl App { CurrentArea::TagArea => { self.bibiman.select_next_tag(amount); } - CurrentArea::PopupArea => { - if let Some(PopupKind::Help) = self.bibiman.popup_area.popup_kind { + CurrentArea::PopupArea => match self.bibiman.popup_area.popup_kind { + Some(PopupKind::Help) => { self.bibiman.popup_area.popup_scroll_down(); - } else if let Some(PopupKind::Selection) = self.bibiman.popup_area.popup_kind { + } + Some(PopupKind::SelectRes) | Some(PopupKind::SelectFile) => { self.bibiman.popup_area.popup_state.scroll_down_by(1) } - } + _ => {} + }, _ => {} }, CmdAction::SelectPrevRow(amount) => match self.bibiman.current_area { @@ -235,13 +192,15 @@ impl App { CurrentArea::TagArea => { self.bibiman.select_previous_tag(amount); } - CurrentArea::PopupArea => { - if let Some(PopupKind::Help) = self.bibiman.popup_area.popup_kind { + CurrentArea::PopupArea => match self.bibiman.popup_area.popup_kind { + Some(PopupKind::Help) => { self.bibiman.popup_area.popup_scroll_up(); - } else if let Some(PopupKind::Selection) = self.bibiman.popup_area.popup_kind { + } + Some(PopupKind::SelectRes) | Some(PopupKind::SelectFile) => { self.bibiman.popup_area.popup_state.scroll_up_by(1) } - } + _ => {} + }, _ => {} }, CmdAction::SelectNextCol => { @@ -290,8 +249,10 @@ impl App { if let Some(PopupKind::Help) = self.bibiman.popup_area.popup_kind { self.bibiman.popup_area.popup_scroll_pos = 0; self.bibiman.close_popup() - } else if let Some(PopupKind::Selection) = self.bibiman.popup_area.popup_kind { + } else if let Some(PopupKind::SelectRes) = self.bibiman.popup_area.popup_kind { self.bibiman.close_popup() + } else if let Some(PopupKind::SelectFile) = self.bibiman.popup_area.popup_kind { + self.bibiman.close_popup(); } } else { self.bibiman.reset_current_list(); @@ -303,7 +264,7 @@ impl App { } else if let CurrentArea::PopupArea = self.bibiman.current_area { if let Some(PopupKind::Help) = self.bibiman.popup_area.popup_kind { self.bibiman.close_popup(); - } else if let Some(PopupKind::Selection) = self.bibiman.popup_area.popup_kind { + } else if let Some(PopupKind::SelectRes) = self.bibiman.popup_area.popup_kind { // Index of selected entry let entry_idx = self .bibiman @@ -330,6 +291,55 @@ impl App { }; // run command to open file/Url self.bibiman.close_popup() + } else if let Some(PopupKind::SelectFile) = self.bibiman.popup_area.popup_kind { + // Index of selected popup field + let popup_idx = self.bibiman.popup_area.popup_state.selected().unwrap(); + + // regex pattern to match citekey in fetched bibtexstring + let pattern = Regex::new(r"\{([^\{\},]*),").unwrap(); + + let citekey = PathBuf::from( + pattern + .captures(&self.bibiman.popup_area.popup_sel_item) + .unwrap() + .get(1) + .unwrap() + .as_str(), + ); + + // Check if new file or existing file was choosen + let mut file = if self.bibiman.popup_area.popup_list[popup_idx] + .contains("Create new file") + { + // Get path of current files + let path: PathBuf = if args.files[0].is_file() { + args.files[0].parent().unwrap().to_owned() + } else { + dirs::home_dir().unwrap() // home dir as fallback + }; + + let citekey = citekey.with_extension("bib"); + + let newfile = path.join(citekey); + + args.files.push(newfile.clone()); + + File::create_new(newfile).unwrap() + } else { + let file_path = &args.files[popup_idx - 1]; + OpenOptions::new().append(true).open(file_path).unwrap() + }; + // Optionally, add a newline before the content + file.write_all(b"\n")?; + // Write content to file + file.write_all(self.bibiman.popup_area.popup_sel_item.as_bytes())?; + // Update the database and the lists to reflect the new content + self.bibiman.update_lists(args); + self.bibiman.close_popup(); + + // Select newly created entry + self.bibiman + .select_entry_by_citekey(citekey.to_str().unwrap()); } } } @@ -378,6 +388,7 @@ impl App { if entry.filepath.is_some() { items.push("File (PDF/EPUB)".to_owned()) } + self.bibiman.popup_area.popup_kind = Some(PopupKind::SelectRes); self.bibiman.popup_area.popup_selection(items); self.bibiman.former_area = Some(FormerArea::EntryArea); self.bibiman.current_area = CurrentArea::PopupArea; @@ -392,8 +403,10 @@ impl App { } } CmdAction::AddEntry => { - self.input_mode = true; - self.bibiman.add_entry(); + if let CurrentArea::EntryArea = self.bibiman.current_area { + self.input_mode = true; + self.bibiman.add_entry(); + } } CmdAction::ShowHelp => { self.bibiman.show_help(); @@ -498,4 +511,15 @@ mod test { assert_eq!(path, PathBuf::from(full_path)) } + + #[test] + fn regex_capture_citekey() { + let re = Regex::new(r"\{([^\{\},]*),").unwrap(); + + let bibstring = String::from("@article{citekey77_2001:!?, author = {Hanks, Tom}, title = {A great book}, year = {2001}}"); + + let result = re.captures(&bibstring).unwrap(); + + assert_eq!(result.get(1).unwrap().as_str(), "citekey77_2001:!?") + } } |
