aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlukeflo2024-10-08 22:48:53 +0200
committerlukeflo2024-10-12 22:41:38 +0200
commit2aaee4d89f7d8ee683a0d50f21723d908dec3e46 (patch)
tree973beeb3d1ff543971b7bca1aa22df361354cc25 /src
parente425c7dcdf444de1151ab3f5347e6503cd0452b9 (diff)
downloadbibiman-2aaee4d89f7d8ee683a0d50f21723d908dec3e46.tar.gz
bibiman-2aaee4d89f7d8ee683a0d50f21723d908dec3e46.zip
open URLs, DOIs and PDFs
+ Implement opening mechanism for URLs, DOIs and PDFs + Adding logic to reset selected item after editing to same entry as before
Diffstat (limited to 'src')
-rw-r--r--src/backend/bib.rs1
-rw-r--r--src/backend/cliargs.rs23
-rw-r--r--src/frontend/entries.rs92
-rw-r--r--src/frontend/handler.rs3
-rw-r--r--src/main.rs6
5 files changed, 95 insertions, 30 deletions
diff --git a/src/backend/bib.rs b/src/backend/bib.rs
index 3e0e844..bfc959d 100644
--- a/src/backend/bib.rs
+++ b/src/backend/bib.rs
@@ -17,7 +17,6 @@
use biblatex::{self, Bibliography};
use biblatex::{ChunksExt, Type};
-use color_eyre::eyre::ErrReport;
use std::{fs, path::PathBuf};
// Set necessary fields
diff --git a/src/backend/cliargs.rs b/src/backend/cliargs.rs
index 31d37f0..d3a4652 100644
--- a/src/backend/cliargs.rs
+++ b/src/backend/cliargs.rs
@@ -15,7 +15,6 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/////
-use core::panic;
use std::path::PathBuf;
use sarge::prelude::*;
@@ -45,7 +44,7 @@ impl CLIArgs {
PathBuf::from(&pos_args[1])
// pos_args[1].to_string()
} else {
- panic!("No path to bibfile provided as argument")
+ PathBuf::new()
};
Self {
helparg: cli_args.help,
@@ -55,26 +54,6 @@ impl CLIArgs {
}
}
-// Struct for positional arguments
-// TODO: Can surely be improved!!
-// pub struct PosArgs {
-// pub bibfilearg: PathBuf,
-// }
-
-// impl PosArgs {
-// pub fn parse_pos_args() -> Self {
-// let (_, pos_args) = ArgumentsCLI::parse().expect("Could not parse positional arguments");
-// Self {
-// bibfilearg: if pos_args.len() > 1 {
-// PathBuf::from(&pos_args[1])
-// // pos_args[1].to_string()
-// } else {
-// panic!("No path to bibfile provided as argument")
-// }, // bibfilearg: pos_args[1].to_string(),
-// }
-// }
-// }
-
pub fn help_func() -> String {
let help = format!(
"\
diff --git a/src/frontend/entries.rs b/src/frontend/entries.rs
index b1312ec..1f79bf4 100644
--- a/src/frontend/entries.rs
+++ b/src/frontend/entries.rs
@@ -19,13 +19,11 @@ use super::app::App;
use super::tui::Tui;
use crate::backend::search::BibiSearch;
use color_eyre::eyre::{Context, Ok, Result};
+use core::panic;
use editor_command::EditorBuilder;
use itertools::Itertools;
use ratatui::widgets::TableState;
-use std::{
- io::Stderr,
- process::{Command, Stdio},
-};
+use std::process::{Command, Stdio};
impl FromIterator<Vec<String>> for EntryTable {
fn from_iter<T: IntoIterator<Item = Vec<String>>>(iter: T) -> Self {
@@ -156,6 +154,8 @@ impl App {
pub fn run_editor(&mut self, tui: &mut Tui) -> Result<()> {
// get filecontent and citekey for calculating line number
let citekey = self.get_selected_citekey();
+ // create independent copy of citekey for finding entry after updating list
+ let saved_key = citekey.to_owned();
let filepath = self.main_biblio.bibfile.display().to_string();
let filecontent = self.main_biblio.bibfilestring.clone();
let mut line_count = 0;
@@ -197,6 +197,23 @@ impl App {
// Update the database and the lists to show changes
self.update_lists();
+
+ // Search for entry, selected before editing, by matching citekeys
+ // Use earlier saved copy of citekey to match
+ let mut idx_count = 0;
+ loop {
+ if self.entry_table.entry_table_items[idx_count]
+ .citekey
+ .contains(&saved_key)
+ {
+ break;
+ }
+ idx_count = idx_count + 1
+ }
+
+ // Set selected entry to vec-index of match
+ self.entry_table.entry_table_state.select(Some(idx_count));
+
Ok(())
}
@@ -224,10 +241,19 @@ impl App {
let filepath = &self.entry_table.entry_table_items[idx].filepath.clone();
// Build command to execute pdf-reader. 'xdg-open' is Linux standard
- // TODO: need to implement for MacOS ('opener'). Windows, I don't know...
- let _ = Command::new("xdg-open")
+ let cmd = {
+ match std::env::consts::OS {
+ "linux" => String::from("xdg-open"),
+ "macos" => String::from("open"),
+ "windows" => String::from("start"),
+ _ => panic!("Couldn't detect OS for setting correct opener"),
+ }
+ };
+
+ // Pass filepath as argument, pipe stdout and stderr to /dev/null
+ // to keep the TUI clean (where is it piped on Windows???)
+ let _ = Command::new(&cmd)
.arg(&filepath)
- // Pipe output produced by opener to /dev/null
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
@@ -235,4 +261,56 @@ impl App {
Ok(())
}
+
+ pub fn open_doi_url(&mut self) -> Result<()> {
+ let idx = self.entry_table.entry_table_state.selected().unwrap();
+ let web_adress = self.entry_table.entry_table_items[idx].doi_url.clone();
+
+ // Resolve strings using the resolving function of dx.doi.org, so the
+ // terminal is not blocked by the resolving process
+ let url = if web_adress.starts_with("10.") {
+ let prefix = "https://doi.org/".to_string();
+ prefix + &web_adress
+ } else if web_adress.starts_with("www.") {
+ let prefix = "https://".to_string();
+ prefix + &web_adress
+ } else {
+ web_adress
+ };
+
+ // Build command to execute browser. 'xdg-open' is Linux standard
+ let cmd = {
+ match std::env::consts::OS {
+ "linux" => String::from("xdg-open"),
+ "macos" => String::from("open"),
+ "windows" => String::from("start"),
+ _ => panic!("Couldn't detect OS for setting correct opener"),
+ }
+ };
+
+ // Pass filepath as argument, pipe stdout and stderr to /dev/null
+ // to keep the TUI clean (where is it piped on Windows???)
+ let _ = Command::new(&cmd)
+ .arg(url)
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .spawn()
+ .wrap_err("Opening file not possible");
+
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn check_os() {
+ let os = std::env::consts::OS;
+ assert_eq!(
+ os,
+ "linux",
+ "You're not coding on linux, but on {}... Switch to linux, now!",
+ std::env::consts::OS
+ )
+ }
}
diff --git a/src/frontend/handler.rs b/src/frontend/handler.rs
index 5bb52d5..9a27b3a 100644
--- a/src/frontend/handler.rs
+++ b/src/frontend/handler.rs
@@ -102,6 +102,9 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App, tui: &mut Tui) -> R
KeyCode::Char('o') => {
app.open_connected_file()?;
}
+ KeyCode::Char('u') => {
+ app.open_doi_url()?;
+ }
KeyCode::Char('/') => {
app.enter_search_area();
}
diff --git a/src/main.rs b/src/main.rs
index 9ff24c8..74e1252 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -15,6 +15,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/////
+use core::panic;
+
use backend::cliargs::{self, CLIArgs};
use color_eyre::eyre::Result;
use frontend::app::App;
@@ -39,6 +41,10 @@ async fn main() -> Result<()> {
std::process::exit(0);
}
+ if !parsed_args.bibfilearg.is_file() {
+ panic!("No \'.bib\' file passed, aborting")
+ }
+
// Create an application.
let mut app = App::new(parsed_args)?;