aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlukeflo2024-10-04 12:55:21 +0200
committerlukeflo2024-10-04 12:55:21 +0200
commite7b755ceeff4c8662c78d0ba0289e8007c297820 (patch)
treeb03c971a8801d43286d2f3765ad2f040bc8140dc /src
parent2b5802ead34af39a5786ce6dba92949793ee52f7 (diff)
downloadbibiman-e7b755ceeff4c8662c78d0ba0289e8007c297820.tar.gz
bibiman-e7b755ceeff4c8662c78d0ba0289e8007c297820.zip
impl opening editor for editing file and update lists afterwards
Diffstat (limited to 'src')
-rw-r--r--src/backend/search.rs59
-rw-r--r--src/frontend/app.rs69
-rw-r--r--src/frontend/ui.rs15
-rw-r--r--src/main.rs7
4 files changed, 62 insertions, 88 deletions
diff --git a/src/backend/search.rs b/src/backend/search.rs
index d09dd04..6afb791 100644
--- a/src/backend/search.rs
+++ b/src/backend/search.rs
@@ -87,62 +87,3 @@ impl BibiSearch {
filtered_list
}
}
-// // Stringify inner Vec<String> by joining/concat
-// fn convert_to_string(inner_vec: &Vec<String>) -> String {
-// inner_vec.join(" ")
-// }
-
-// // Return a filtered entry list
-// pub fn search_entry_list(search_pattern: &str, orig_list: Vec<Vec<String>>) -> Vec<Vec<String>> {
-// // Create a hashmap to connect stingified entry with entry vec
-// let mut entry_string_hm: HashMap<String, Vec<String>> = HashMap::new();
-
-// // Convert all entries to string and insert them into the hashmap
-// // next to the original inner Vec<String> of the entry list
-// for entry in orig_list {
-// entry_string_hm.insert(convert_to_string(&entry), entry);
-// }
-
-// // Set up matcher (TODO: One time needed only, move to higher level)
-// let mut matcher = Matcher::new(Config::DEFAULT);
-
-// // Filter the stringified entries and collect them into a vec
-// let filtered_matches: Vec<String> = {
-// let matches = Pattern::parse(search_pattern, CaseMatching::Ignore, Normalization::Smart)
-// .match_list(entry_string_hm.keys(), &mut matcher);
-// matches.into_iter().map(|f| f.0.to_string()).collect()
-// };
-
-// // 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();
-// for m in filtered_matches {
-// filtered_list.push(entry_string_hm[&m].to_owned());
-// }
-// filtered_list
-// }
-
-// pub fn search_tag_list(search_pattern: &str, orig_list: Vec<String>) -> Vec<String> {
-// // Set up matcher (TODO: One time needed only)
-// let mut matcher = Matcher::new(Config::DEFAULT);
-
-// // Filter the list items by search pattern
-// let filtered_matches: Vec<String> = {
-// let matches = Pattern::parse(search_pattern, CaseMatching::Ignore, Normalization::Smart)
-// .match_list(orig_list, &mut matcher);
-// matches.into_iter().map(|f| f.0.to_string()).collect()
-// };
-// 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();
-
-// for e in orig_list {
-// if e[4].contains(keyword) {
-// filtered_list.push(e.to_owned());
-// }
-// }
-
-// filtered_list
-// }
diff --git a/src/frontend/app.rs b/src/frontend/app.rs
index faa54a1..8950202 100644
--- a/src/frontend/app.rs
+++ b/src/frontend/app.rs
@@ -15,17 +15,15 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/////
-use std::io;
+use std::process::Command;
-use crate::backend::cliargs::{self, CLIArgs};
-use ratatui::{backend::CrosstermBackend, Terminal};
+use editor_command::EditorBuilder;
use crate::backend::{bib::*, search::BibiSearch};
use crate::{
frontend::handler::handle_key_events,
frontend::tui::{Event, Tui},
};
-use std::{error, net::SocketAddr};
use arboard::Clipboard;
use color_eyre::eyre::{Ok, Result};
@@ -34,9 +32,6 @@ use ratatui::widgets::{ListState, TableState};
use super::tui;
-// Application result type.
-// pub type AppResult<T> = std::result::Result<T, Box<dyn error::Error>>;
-
// Areas in which actions are possible
#[derive(Debug)]
pub enum CurrentArea {
@@ -59,8 +54,6 @@ pub enum FormerArea {
pub struct App {
// Is the application running?
pub running: bool,
- // // tui initialization
- // pub tui: Tui,
// main bibliography
pub main_biblio: BibiMain,
// bibliographic data
@@ -77,8 +70,6 @@ pub struct App {
pub current_area: CurrentArea,
// mode for popup window
pub former_area: Option<FormerArea>,
- // search string
- // pub search_string: String,
}
// Define the fundamental List
@@ -149,7 +140,6 @@ pub struct EntryTableItem {
pub pubtype: String,
pub keywords: String,
pub citekey: String,
- // pub year: u16,
}
impl EntryTableItem {
@@ -227,7 +217,6 @@ impl App {
pub fn new() -> Result<Self> {
// Self::default()
let running = true;
- // let tui = Tui::new()?;
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());
@@ -236,7 +225,6 @@ impl App {
let current_area = CurrentArea::EntryArea;
Ok(Self {
running,
- // tui,
main_biblio,
biblio_data,
tag_list,
@@ -245,15 +233,10 @@ impl App {
scroll_info: 0,
current_area,
former_area: None,
- // search_string: String::new(),
})
}
pub async fn run(&mut self) -> Result<()> {
- // Initialize the terminal user interface.
- // let backend = CrosstermBackend::new(io::stdout());
- // let terminal = Terminal::new(backend)?;
- // let events = EventHandler::new(250);
let mut tui = tui::Tui::new()?;
tui.enter()?;
@@ -285,6 +268,14 @@ impl App {
self.running = false;
}
+ pub fn update_lists(&mut self) {
+ self.main_biblio = BibiMain::new();
+ 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());
+ self.entry_table = EntryTable::from_iter(self.biblio_data.entry_list.bibentries.clone());
+ }
+
// Toggle moveable list between entries and tags
pub fn toggle_area(&mut self) {
if let CurrentArea::EntryArea = self.current_area {
@@ -519,15 +510,49 @@ 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();
+ 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()?;
- let cmd = String::from("hx");
- let args: Vec<String> = vec!["test.bib".into()];
- let status = std::process::Command::new(&cmd).args(&args).status()?;
+ // 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(())
}
}
diff --git a/src/frontend/ui.rs b/src/frontend/ui.rs
index 0e7c219..cd39bda 100644
--- a/src/frontend/ui.rs
+++ b/src/frontend/ui.rs
@@ -15,6 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/////
+use color_eyre::owo_colors::OwoColorize;
use ratatui::{
buffer::Buffer,
layout::{Constraint, Layout, Rect},
@@ -125,11 +126,23 @@ impl App {
.render(area, buf);
}
_ => {
+ let style_emph = Style::new().bold();
let block = Block::bordered()
.title(Line::raw(" Basic Commands ").centered())
.border_set(symbols::border::ROUNDED);
Paragraph::new(
- "Use j/k to move, g/G to go top/bottom, y to yank the current citekey",
+ Line::from(vec![
+ Span::styled("j/k: ", style_emph),
+ Span::raw("to move | "),
+ Span::styled("g/G: ", style_emph),
+ Span::raw("go top/bottom | "),
+ Span::styled("TAB: ", style_emph),
+ Span::raw("switch fields | "),
+ Span::styled("y: ", style_emph),
+ Span::raw("yank citekey | "),
+ Span::styled("e: ", style_emph),
+ Span::raw("edit entry"),
+ ]), // "Use j/k to move, g/G to go top/bottom, y to yank the current citekey, e to edit the current entry",
)
.block(block)
.centered()
diff --git a/src/main.rs b/src/main.rs
index ba242b7..5a7c538 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -15,14 +15,9 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/////
-use std::io;
-
use backend::cliargs::{self, CLIArgs};
-use ratatui::{backend::CrosstermBackend, Terminal};
-
-use crate::{frontend::app::App, frontend::handler::handle_key_events, frontend::tui::Tui};
-
use color_eyre::eyre::Result;
+use frontend::app::App;
pub mod backend;
pub mod frontend;