aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlukeflo2025-06-28 12:45:21 +0200
committerlukeflo2025-06-28 12:45:21 +0200
commit5700c16b9dd2a964d071dcae4de5baa896bc2d20 (patch)
tree9bf7e4416387839229174476e6c6c35ab6aa022c /src
parent3bc409fa5627cb2fd2dd1bd885f471e4aab21478 (diff)
downloadbibiman-5700c16b9dd2a964d071dcae4de5baa896bc2d20.tar.gz
bibiman-5700c16b9dd2a964d071dcae4de5baa896bc2d20.zip
add shortcuts for opening files/links and yanking citekey
+ `o-o`|`o-l` -> shortcut for opening first file/link of current entry + `y-y` -> shortcut for yanking citekey of current entry
Diffstat (limited to 'src')
-rw-r--r--src/app.rs4
-rw-r--r--src/bibiman.rs71
-rw-r--r--src/tui/ui.rs10
3 files changed, 84 insertions, 1 deletions
diff --git a/src/app.rs b/src/app.rs
index f7e7891..d10e4f8 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -79,6 +79,10 @@ impl App {
} else if let Some(PopupKind::MessageError) = self.bibiman.popup_area.popup_kind
{
self.bibiman.close_popup()
+ } else if let Some(PopupKind::YankItem) | Some(PopupKind::OpenRes) =
+ self.bibiman.popup_area.popup_kind
+ {
+ self.bibiman.fast_selection(cfg, key_event.code)?;
}
let command = if self.input_mode {
CmdAction::Input(InputCmdAction::parse(key_event, &self.input))
diff --git a/src/bibiman.rs b/src/bibiman.rs
index 3341653..71ef07c 100644
--- a/src/bibiman.rs
+++ b/src/bibiman.rs
@@ -26,6 +26,7 @@ use crate::{app, cliargs};
use crate::{bibiman::entries::EntryTable, bibiman::keywords::TagList};
use arboard::Clipboard;
use color_eyre::eyre::{Error, Result};
+use crossterm::event::{KeyCode, KeyEvent};
use editor_command::EditorBuilder;
use ratatui::widgets::ScrollbarState;
use regex::Regex;
@@ -725,6 +726,76 @@ impl Bibiman {
Ok(())
}
+ /// Fast opening/yanking of file/link or citekey through simple keypress in
+ /// the particular popup mode:
+ ///
+ /// **Opening popup**
+ ///
+ /// `o` -> opens the first file of the `filepath` `Vec` for the current entry
+ /// `l` -> opens the link of the current entry
+ ///
+ /// **Yanking popup**
+ ///
+ /// `y` -> yanks the citekey for the current entry
+ pub fn fast_selection(&mut self, cfg: &BibiConfig, key_code: KeyCode) -> Result<()> {
+ if let CurrentArea::PopupArea = self.current_area {
+ let entry_idx = self.entry_table.entry_table_state.selected().unwrap();
+ match self.popup_area.popup_kind {
+ Some(PopupKind::OpenRes) => match key_code {
+ KeyCode::Char('o') => {
+ let file = self.entry_table.entry_table_items[entry_idx]
+ .filepath
+ .clone();
+ if file.is_some() {
+ let file = expand_home(&PathBuf::from(file.unwrap()[0].clone()));
+ // let object: OsString = popup_entry.into();
+ if file.is_file() {
+ app::open_connected_file(cfg, &file.into_os_string())?;
+ self.close_popup();
+ } else {
+ self.open_popup(
+ PopupKind::MessageError,
+ Some("No valid file path: "),
+ Some(file.to_str().unwrap()),
+ None,
+ )?;
+ }
+ }
+ }
+ KeyCode::Char('l') => {
+ if self.entry_table.entry_table_items[entry_idx]
+ .doi_url
+ .is_some()
+ {
+ let object = self.entry_table.entry_table_items[entry_idx].doi_url();
+ let url = app::prepare_weblink(object);
+ app::open_connected_link(cfg, &url)?;
+ self.close_popup();
+ }
+ }
+ _ => {}
+ },
+ Some(PopupKind::YankItem) => match key_code {
+ KeyCode::Char('y') => {
+ let key = self.entry_table.entry_table_items[entry_idx]
+ .citekey
+ .clone();
+ Bibiman::yank_text(&key);
+ self.open_popup(
+ PopupKind::MessageConfirm,
+ Some("Yanked citekey to clipboard: "),
+ Some(&key),
+ None,
+ )?;
+ }
+ _ => {}
+ },
+ _ => {}
+ }
+ }
+ Ok(())
+ }
+
/// Formats a raw BibTeX entry string for better readability.
pub fn format_bibtex_entry(entry: &str, file_path: &str) -> String {
let mut formatted = String::new();
diff --git a/src/tui/ui.rs b/src/tui/ui.rs
index 7a121bf..ebebe4c 100644
--- a/src/tui/ui.rs
+++ b/src/tui/ui.rs
@@ -299,9 +299,17 @@ pub fn render_popup(app: &mut App, cfg: &BibiConfig, frame: &mut Frame) {
" Select "
};
+ let bottom_info = if let Some(PopupKind::OpenRes) = app.bibiman.popup_area.popup_kind {
+ " (j,k|↓,↑) ━ (o,l) ━ (ENTER) ━ (ESC) ".bold()
+ } else if let Some(PopupKind::YankItem) = app.bibiman.popup_area.popup_kind {
+ " (j,k|↓,↑) ━ (y) ━ (ENTER) ━ (ESC) ".bold()
+ } else {
+ " (j,k|↓,↑) ━ (ENTER) ━ (ESC) ".bold()
+ };
+
let block = Block::bordered()
.title_top(title.bold())
- .title_bottom(" (j,k|↓,↑) ━ (ENTER) ━ (ESC) ".bold())
+ .title_bottom(bottom_info)
.title_alignment(Alignment::Center)
.style(
Style::new()