diff options
| author | lukeflo | 2024-10-24 12:53:09 +0200 |
|---|---|---|
| committer | lukeflo | 2024-10-24 12:53:09 +0200 |
| commit | f32b6a19851b8b103ac843503ab008197f0639cd (patch) | |
| tree | 49216019cf71b4c3161eb5b1a74d9ee7e06eceb0 | |
| parent | 66402a9c23e0975a8a3d8c2707b689b9cde98ccf (diff) | |
| download | bibiman-f32b6a19851b8b103ac843503ab008197f0639cd.tar.gz bibiman-f32b6a19851b8b103ac843503ab008197f0639cd.zip | |
rearrange code again, prepare for command-action setup
| -rw-r--r-- | Cargo.lock | 34 | ||||
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/app.rs | 75 | ||||
| -rw-r--r-- | src/bib.rs | 21 | ||||
| -rw-r--r-- | src/bibiman.rs (renamed from src/tui/app.rs) | 58 | ||||
| -rw-r--r-- | src/bibiman/bibisetup.rs (renamed from src/bib/bibmain.rs) | 4 | ||||
| -rw-r--r-- | src/bibiman/entries.rs (renamed from src/bib/entries.rs) | 2 | ||||
| -rw-r--r-- | src/bibiman/keywords.rs (renamed from src/bib/keywords.rs) | 0 | ||||
| -rw-r--r-- | src/bibiman/search.rs (renamed from src/bib/search.rs) | 0 | ||||
| -rw-r--r-- | src/main.rs | 5 | ||||
| -rw-r--r-- | src/tui.rs | 21 | ||||
| -rw-r--r-- | src/tui/command.rs | 10 | ||||
| -rw-r--r-- | src/tui/commandnew.rs | 178 | ||||
| -rw-r--r-- | src/tui/handler.rs | 97 | ||||
| -rw-r--r-- | src/tui/ui.rs | 22 |
15 files changed, 381 insertions, 147 deletions
@@ -82,11 +82,12 @@ dependencies = [ "hayagriva", "itertools", "nucleo-matcher", - "ratatui", + "ratatui 0.29.0", "sarge", "signal-hook", "tokio", "tokio-util", + "tui-input", ] [[package]] @@ -1133,6 +1134,27 @@ dependencies = [ [[package]] name = "ratatui" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdef7f9be5c0122f890d58bdf4d964349ba6a6161f705907526d891efabba57d" +dependencies = [ + "bitflags 2.6.0", + "cassowary", + "compact_str", + "crossterm", + "instability", + "itertools", + "lru", + "paste", + "strum", + "strum_macros", + "unicode-segmentation", + "unicode-truncate", + "unicode-width 0.1.14", +] + +[[package]] +name = "ratatui" version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" @@ -1540,6 +1562,16 @@ dependencies = [ ] [[package]] +name = "tui-input" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd137780d743c103a391e06fe952487f914b299a4fe2c3626677f6a6339a7c6b" +dependencies = [ + "ratatui 0.28.1", + "unicode-width 0.1.14", +] + +[[package]] name = "unic-langid" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -24,3 +24,4 @@ sarge = "7.2.5" signal-hook = "0.3.17" tokio = { version = "1.39.3", features = ["full"] } tokio-util = "0.7.12" +tui-input = "0.10.1" diff --git a/src/app.rs b/src/app.rs new file mode 100644 index 0000000..e3ba079 --- /dev/null +++ b/src/app.rs @@ -0,0 +1,75 @@ +// bibiman - a TUI for managing BibLaTeX databases +// Copyright (C) 2024 lukeflo +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. +///// + +// use super::Event; +use crate::bibiman::Bibiman; +use crate::cliargs::CLIArgs; +use crate::tui; +use crate::tui::handler::handle_key_events; +use color_eyre::eyre::{Ok, Result}; +use tui::Event; + +// Application. +#[derive(Debug)] +pub struct App { + // Is the application running? + pub running: bool, + // bibimain + pub bibiman: Bibiman, +} + +impl App { + // Constructs a new instance of [`App`]. + pub fn new(args: CLIArgs) -> Result<Self> { + // Self::default() + let running = true; + let bibiman = Bibiman::new(args)?; + Ok(Self { running, bibiman }) + } + + pub async fn run(&mut self) -> Result<()> { + let mut tui = tui::Tui::new()?; + tui.enter()?; + + // Start the main loop. + while self.running { + // Render the user interface. + tui.draw(self)?; + // Handle events. + match tui.next().await? { + Event::Tick => self.tick(), + Event::Key(key_event) => handle_key_events(key_event, self, &mut tui)?, + Event::Mouse(_) => {} + Event::Resize(_, _) => {} + } + } + + // Exit the user interface. + tui.exit()?; + Ok(()) + } + + // Handles the tick event of the terminal. + pub fn tick(&self) {} + + // General commands + + // Set running to false to quit the application. + pub fn quit(&mut self) { + self.running = false; + } +} diff --git a/src/bib.rs b/src/bib.rs deleted file mode 100644 index 8443b9a..0000000 --- a/src/bib.rs +++ /dev/null @@ -1,21 +0,0 @@ -// bibiman - a TUI for managing BibLaTeX databases -// Copyright (C) 2024 lukeflo -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -///// - -pub mod bibmain; -pub mod entries; -pub mod keywords; -pub mod search; diff --git a/src/tui/app.rs b/src/bibiman.rs index b09ae80..3bb731b 100644 --- a/src/tui/app.rs +++ b/src/bibiman.rs @@ -15,15 +15,18 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. ///// -use super::Event; -use crate::bib::{bibmain::*, search::BibiSearch}; +use crate::bibiman::{bibisetup::*, search::BibiSearch}; use crate::cliargs::CLIArgs; -use crate::tui; -use crate::{bib::entries::EntryTable, bib::keywords::TagList, tui::handler::handle_key_events}; +use crate::{bibiman::entries::EntryTable, bibiman::keywords::TagList}; use arboard::Clipboard; use color_eyre::eyre::{Ok, Result}; use std::path::PathBuf; +pub mod bibisetup; +pub mod entries; +pub mod keywords; +pub mod search; + // Areas in which actions are possible #[derive(Debug)] pub enum CurrentArea { @@ -44,13 +47,11 @@ pub enum FormerArea { // Application. #[derive(Debug)] -pub struct App { - // Is the application running? - pub running: bool, +pub struct Bibiman { // main bib file pub main_bibfile: PathBuf, // main bibliography - pub main_biblio: BibiMain, + pub main_biblio: BibiSetup, // search struct: pub search_struct: BibiSearch, // tag list @@ -65,19 +66,16 @@ pub struct App { pub former_area: Option<FormerArea>, } -impl App { +impl Bibiman { // Constructs a new instance of [`App`]. pub fn new(args: CLIArgs) -> Result<Self> { - // Self::default() - let running = true; let main_bibfile = args.bibfilearg; - let main_biblio = BibiMain::new(main_bibfile.clone()); + let main_biblio = BibiSetup::new(main_bibfile.clone()); let tag_list = TagList::new(main_biblio.keyword_list.clone()); let search_struct = BibiSearch::default(); let entry_table = EntryTable::new(main_biblio.entry_list.clone()); let current_area = CurrentArea::EntryArea; Ok(Self { - running, main_bibfile, main_biblio, tag_list, @@ -89,40 +87,8 @@ impl App { }) } - pub async fn run(&mut self) -> Result<()> { - let mut tui = tui::Tui::new()?; - tui.enter()?; - - // Start the main loop. - while self.running { - // Render the user interface. - tui.draw(self)?; - // Handle events. - match tui.next().await? { - Event::Tick => self.tick(), - Event::Key(key_event) => handle_key_events(key_event, self, &mut tui)?, - Event::Mouse(_) => {} - Event::Resize(_, _) => {} - } - } - - // Exit the user interface. - tui.exit()?; - Ok(()) - } - - // Handles the tick event of the terminal. - pub fn tick(&self) {} - - // General commands - - // Set running to false to quit the application. - pub fn quit(&mut self) { - self.running = false; - } - pub fn update_lists(&mut self) { - self.main_biblio = BibiMain::new(self.main_bibfile.clone()); + self.main_biblio = BibiSetup::new(self.main_bibfile.clone()); // self.tag_list = TagList::from_iter(self.main_biblio.keyword_list.clone()); self.tag_list = TagList::new(self.main_biblio.keyword_list.clone()); self.entry_table = EntryTable::new(self.main_biblio.entry_list.clone()); diff --git a/src/bib/bibmain.rs b/src/bibiman/bibisetup.rs index a7df951..abc91e4 100644 --- a/src/bib/bibmain.rs +++ b/src/bibiman/bibisetup.rs @@ -29,7 +29,7 @@ pub enum FileFormat { // Set necessary fields // TODO: can surely be made more efficient/simpler #[derive(Debug)] -pub struct BibiMain { +pub struct BibiSetup { pub bibfile: PathBuf, // path to bibfile pub bibfile_format: FileFormat, // Format of passed file pub bibfilestring: String, // content of bibfile as string @@ -52,7 +52,7 @@ pub struct BibiData { pub filepath: String, } -impl BibiMain { +impl BibiSetup { pub fn new(main_bibfile: PathBuf) -> Self { // TODO: Needs check for config file path as soon as config file is impl let bibfile_format = Self::check_file_format(&main_bibfile); diff --git a/src/bib/entries.rs b/src/bibiman/entries.rs index 41edba8..2c222d1 100644 --- a/src/bib/entries.rs +++ b/src/bibiman/entries.rs @@ -15,7 +15,7 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. ///// -use crate::bib::bibmain::BibiData; +use crate::bibiman::bibisetup::BibiData; use ratatui::widgets::{ScrollbarState, TableState}; #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/src/bib/keywords.rs b/src/bibiman/keywords.rs index 2668323..2668323 100644 --- a/src/bib/keywords.rs +++ b/src/bibiman/keywords.rs diff --git a/src/bib/search.rs b/src/bibiman/search.rs index f6e8d14..f6e8d14 100644 --- a/src/bib/search.rs +++ b/src/bibiman/search.rs diff --git a/src/main.rs b/src/main.rs index eaa9e05..c2c5121 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,12 +15,13 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. ///// +use app::App; use cliargs::CLIArgs; use color_eyre::eyre::Result; use errorsetup::init_error_hooks; -use tui::app::App; -pub mod bib; +pub mod app; +pub mod bibiman; pub mod cliargs; pub mod errorsetup; pub mod tui; @@ -15,12 +15,12 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. ///// -pub mod app; pub mod command; +pub mod commandnew; pub mod handler; pub mod ui; -use crate::tui::app::App; +use crate::App; use crossterm::{ cursor, event::{ @@ -59,9 +59,9 @@ pub struct Tui { /// Interface to the Terminal. pub terminal: ratatui::Terminal<CrosstermBackend<Stdout>>, /// Event sender channel. - sender: mpsc::UnboundedSender<Event>, + evt_sender: mpsc::UnboundedSender<Event>, /// Event receiver channel. - receiver: mpsc::UnboundedReceiver<Event>, + evt_receiver: mpsc::UnboundedReceiver<Event>, /// Event handler thread. handler: tokio::task::JoinHandle<()>, cancellation_token: CancellationToken, @@ -71,13 +71,13 @@ impl Tui { // Constructs a new instance of [`Tui`]. pub fn new() -> Result<Self> { let terminal = ratatui::Terminal::new(CrosstermBackend::new(stdout()))?; - let (sender, receiver) = mpsc::unbounded_channel(); + let (evt_sender, evt_receiver) = mpsc::unbounded_channel(); let handler = tokio::spawn(async {}); let cancellation_token = CancellationToken::new(); Ok(Self { terminal, - sender, - receiver, + evt_sender, + evt_receiver, handler, cancellation_token, }) @@ -88,7 +88,7 @@ impl Tui { self.cancel(); self.cancellation_token = CancellationToken::new(); let event_loop = Self::event_loop( - self.sender.clone(), + self.evt_sender.clone(), self.cancellation_token.clone(), tick_rate, ); @@ -203,7 +203,10 @@ impl Tui { } pub async fn next(&mut self) -> Result<Event> { - self.receiver.recv().await.ok_or_eyre("This is an IO error") + self.evt_receiver + .recv() + .await + .ok_or_eyre("This is an IO error") } } diff --git a/src/tui/command.rs b/src/tui/command.rs index 9f25f5f..8416a3e 100644 --- a/src/tui/command.rs +++ b/src/tui/command.rs @@ -15,9 +15,9 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. ///// -use crate::bib::entries::EntryTableColumn; -use crate::bib::search::BibiSearch; -use crate::tui::app::{App, FormerArea}; +use crate::bibiman::entries::EntryTableColumn; +use crate::bibiman::search::BibiSearch; +use crate::bibiman::{Bibiman, FormerArea}; use crate::tui::Tui; use color_eyre::eyre::{Context, Ok, Result}; use core::panic; @@ -25,7 +25,7 @@ use editor_command::EditorBuilder; use ratatui::widgets::ScrollbarState; use std::process::{Command, Stdio}; -impl App { +impl Bibiman { // Entry Table commands // Movement @@ -260,7 +260,7 @@ impl App { } } -impl App { +impl Bibiman { // Tag List commands // Movement diff --git a/src/tui/commandnew.rs b/src/tui/commandnew.rs new file mode 100644 index 0000000..45b2f52 --- /dev/null +++ b/src/tui/commandnew.rs @@ -0,0 +1,178 @@ +// bibiman - a TUI for managing BibLaTeX databases +// Copyright (C) 2024 lukeflo +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. +///// + +use ratatui::crossterm::event::{ + Event, KeyCode, KeyEvent, KeyModifiers, MouseEvent, MouseEventKind, +}; +use tui_input::Input; + +// Possible scroll areas. +#[derive(Debug, PartialEq, Eq)] +pub enum ScrollType { + Rows, + Cols, + InfoArea, +} + +// Possible ressources to open +#[derive(Debug, PartialEq, Eq)] +pub enum OpenRessource { + PDF, + WebLink, + Note, +} + +/// Application command. +#[derive(Debug, PartialEq, Eq)] +pub enum Command { + // Toggle area + ToggleArea, + // Next + Next(ScrollType, usize), + // Previous. + Previous(ScrollType, usize), + // Go to top. + Top, + // Go to bottom. + Bottom, + // Search list + SearchList, + // Reset lists + ResetList, + // Confirm search/selection + Confirm, + // Sort table/list + SortList, + // Yank selected item + YankItem, + // Edit file + EditFile, + // Open linked ressource + Open(OpenRessource), + // Input command. + Input(InputCommand), + // Hexdump command. + Exit, + // Do nothing. + Nothing, +} + +impl From<KeyEvent> for Command { + fn from(key_event: KeyEvent) -> Self { + match key_event.code { + // Go to first/last entry of selected list/table + KeyCode::Char('g') | KeyCode::Home => Self::Top, + KeyCode::Char('G') | KeyCode::End => Self::Bottom, + // Scroll columns of EntryTable + KeyCode::Right | KeyCode::Char('l') => Self::Next(ScrollType::Cols, 1), + KeyCode::Left | KeyCode::Char('h') => Self::Previous(ScrollType::Cols, 1), + // Scroll table/list vertically by 1 + KeyCode::Down | KeyCode::Char('j') => Self::Next(ScrollType::Rows, 1), + KeyCode::Up | KeyCode::Char('k') => Self::Previous(ScrollType::Rows, 1), + // Scroll table/list vertically by 5 + KeyCode::PageDown => Self::Next(ScrollType::Rows, 5), + KeyCode::PageUp => Self::Previous(ScrollType::Rows, 5), + KeyCode::Char('d') => { + if key_event.modifiers == KeyModifiers::CONTROL { + Self::Next(ScrollType::Rows, 5) + } else { + Self::Nothing + } + } + KeyCode::Char('u') => { + if key_event.modifiers == KeyModifiers::CONTROL { + Self::Previous(ScrollType::Rows, 5) + } else { + Self::Open(OpenRessource::WebLink) + } + } + // Exit App + KeyCode::Char('q') => Self::Exit, + KeyCode::Char('c') | KeyCode::Char('C') => { + if key_event.modifiers == KeyModifiers::CONTROL { + Self::Exit + } else { + Self::Nothing + } + } + // Switch selected area + KeyCode::Tab => Self::ToggleArea, + KeyCode::BackTab => Self::ToggleArea, + // Enter search mode + KeyCode::Char('/') => Self::Input(InputCommand::Enter), + KeyCode::Char('f') => { + if key_event.modifiers == KeyModifiers::CONTROL { + Self::Input(InputCommand::Enter) + } else { + Self::Nothing + } + } + // KeyCode::Backspace => Self::Input(InputCommand::Resume(Event::Key(key_event))), + // Confirm selection + KeyCode::Enter => Self::Confirm, + // Reset lists/tables + KeyCode::Esc => Self::ResetList, + // Open linked ressource + KeyCode::Char('o') => Self::Open(OpenRessource::PDF), + // KeyCode::Char('u') => Self::Open(OpenRessource::WebLink), + // Edit currently selected entry + KeyCode::Char('e') => Self::EditFile, + // Yank selected item/value + KeyCode::Char('y') => Self::YankItem, + // Else do nothing + _ => Self::Nothing, + } + } +} + +impl From<MouseEvent> for Command { + fn from(mouse_event: MouseEvent) -> Self { + match mouse_event.kind { + MouseEventKind::ScrollDown => Self::Next(ScrollType::Rows, 1), + MouseEventKind::ScrollUp => Self::Previous(ScrollType::Rows, 1), + _ => Self::Nothing, + } + } +} + +/// Input mode command. +#[derive(Debug, PartialEq, Eq)] +pub enum InputCommand { + // Handle input. + Handle(Event), + // Enter input mode. + Enter, + // Confirm input. + Confirm, + // Exit input mode + Exit, +} + +impl InputCommand { + /// Parses the event. + pub fn parse(key_event: KeyEvent, input: &Input) -> Self { + if key_event.code == KeyCode::Esc + || (key_event.code == KeyCode::Backspace && input.value().is_empty()) + { + Self::Exit + } else if key_event.code == KeyCode::Enter { + Self::Confirm + } else { + Self::Handle(Event::Key(key_event)) + } + } +} diff --git a/src/tui/handler.rs b/src/tui/handler.rs index 5a196b5..3a4d055 100644 --- a/src/tui/handler.rs +++ b/src/tui/handler.rs @@ -15,12 +15,11 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. ///// -use crate::tui::app::App; +use crate::bibiman::{Bibiman, CurrentArea}; use crate::tui::Tui; -use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; - -use super::app::CurrentArea; +use crate::App; use color_eyre::eyre::Result; +use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; /// Handles the key events and updates the state of [`App`]. pub fn handle_key_events(key_event: KeyEvent, app: &mut App, tui: &mut Tui) -> Result<()> { @@ -37,159 +36,159 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App, tui: &mut Tui) -> R } } KeyCode::PageDown => { - app.scroll_info_down(); + app.bibiman.scroll_info_down(); } KeyCode::PageUp => { - app.scroll_info_up(); + app.bibiman.scroll_info_up(); } _ => {} } // Keycodes for specific areas - match app.current_area { + match app.bibiman.current_area { // Keycodes for the tag area CurrentArea::TagArea => match key_event.code { KeyCode::Down => { - app.select_next_tag(1); + app.bibiman.select_next_tag(1); } KeyCode::Up => { - app.select_previous_tag(1); + app.bibiman.select_previous_tag(1); } KeyCode::Char('j') => { if key_event.modifiers == KeyModifiers::ALT { - app.scroll_info_down(); + app.bibiman.scroll_info_down(); } else { - app.select_next_tag(1); + app.bibiman.select_next_tag(1); } } KeyCode::Char('k') => { if key_event.modifiers == KeyModifiers::ALT { - app.scroll_info_up(); + app.bibiman.scroll_info_up(); } else { - app.select_previous_tag(1); + app.bibiman.select_previous_tag(1); } } KeyCode::Char('d') => { if key_event.modifiers == KeyModifiers::CONTROL { - app.select_next_tag(5) + app.bibiman.select_next_tag(5) } } KeyCode::Char('u') => { if key_event.modifiers == KeyModifiers::CONTROL { - app.select_previous_tag(5) + app.bibiman.select_previous_tag(5) } } KeyCode::Char('g') | KeyCode::Home => { - app.select_first_tag(); + app.bibiman.select_first_tag(); } KeyCode::Char('G') | KeyCode::End => { - app.select_last_tag(); + app.bibiman.select_last_tag(); } KeyCode::Char('/') => { - app.enter_search_area(); + app.bibiman.enter_search_area(); } KeyCode::Char('f') | KeyCode::Char('F') => { if key_event.modifiers == KeyModifiers::CONTROL { - app.enter_search_area(); + app.bibiman.enter_search_area(); } } KeyCode::Tab | KeyCode::BackTab => { - app.toggle_area(); + app.bibiman.toggle_area(); } KeyCode::Esc => { - app.reset_current_list(); + app.bibiman.reset_current_list(); } KeyCode::Enter => { - app.filter_for_tags(); + app.bibiman.filter_for_tags(); } _ => {} }, // Keycodes for the entry area CurrentArea::EntryArea => match key_event.code { KeyCode::Down => { - app.select_next_entry(1); + app.bibiman.select_next_entry(1); } KeyCode::Up => { - app.select_previous_entry(1); + app.bibiman.select_previous_entry(1); } KeyCode::Char('j') => { if key_event.modifiers == KeyModifiers::ALT { - app.scroll_info_down(); + app.bibiman.scroll_info_down(); } else { - app.select_next_entry(1); + app.bibiman.select_next_entry(1); } } KeyCode::Char('k') => { if key_event.modifiers == KeyModifiers::ALT { - app.scroll_info_up(); + app.bibiman.scroll_info_up(); } else { - app.select_previous_entry(1); + app.bibiman.select_previous_entry(1); } } KeyCode::Char('d') => { if key_event.modifiers == KeyModifiers::CONTROL { - app.select_next_entry(5); + app.bibiman.select_next_entry(5); } } KeyCode::Char('u') => { if key_event.modifiers == KeyModifiers::CONTROL { - app.select_previous_entry(5); + app.bibiman.select_previous_entry(5); } else { - app.open_doi_url()?; + app.bibiman.open_doi_url()?; } } KeyCode::Char('g') | KeyCode::Home => { - app.select_first_entry(); + app.bibiman.select_first_entry(); } KeyCode::Char('G') | KeyCode::End => { - app.select_last_entry(); + app.bibiman.select_last_entry(); } KeyCode::Char('h') => { - app.select_prev_column(); + app.bibiman.select_prev_column(); } KeyCode::Char('l') => { - app.select_next_column(); + app.bibiman.select_next_column(); } KeyCode::Char('s') => { - app.entry_table.sort_entry_table(true); + app.bibiman.entry_table.sort_entry_table(true); } KeyCode::Char('y') => { - App::yank_text(&app.get_selected_citekey()); + Bibiman::yank_text(&app.bibiman.get_selected_citekey()); } KeyCode::Char('e') => { - app.run_editor(tui)?; + app.bibiman.run_editor(tui)?; } KeyCode::Char('o') => { - app.open_connected_file()?; + app.bibiman.open_connected_file()?; } KeyCode::Char('/') => { - app.enter_search_area(); + app.bibiman.enter_search_area(); } KeyCode::Char('f') | KeyCode::Char('F') => { if key_event.modifiers == KeyModifiers::CONTROL { - app.enter_search_area(); + app.bibiman.enter_search_area(); } } KeyCode::Tab | KeyCode::BackTab => { - app.toggle_area(); + app.bibiman.toggle_area(); } KeyCode::Esc => { - app.reset_current_list(); + app.bibiman.reset_current_list(); } _ => {} }, // Keycodes for the search area (rendered in footer) CurrentArea::SearchArea => match key_event.code { KeyCode::Esc => { - app.break_search(); + app.bibiman.break_search(); } KeyCode::Enter => { - app.confirm_search(); + app.bibiman.confirm_search(); } KeyCode::Backspace => { - app.search_pattern_pop(); + app.bibiman.search_pattern_pop(); } KeyCode::Char(search_pattern) => { - app.search_pattern_push(search_pattern); + app.bibiman.search_pattern_push(search_pattern); } _ => {} }, @@ -199,8 +198,8 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App, tui: &mut Tui) -> R app.quit(); } KeyCode::Esc => { - app.toggle_area(); - app.former_area = None; + app.bibiman.toggle_area(); + app.bibiman.former_area = None; } _ => {} }, diff --git a/src/tui/ui.rs b/src/tui/ui.rs index 07bc88d..d5571c8 100644 --- a/src/tui/ui.rs +++ b/src/tui/ui.rs @@ -15,10 +15,10 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. ///// -use super::app::{CurrentArea, FormerArea}; -use crate::bib::entries::EntryTableColumn; -use crate::bib::keywords::TagListItem; -use crate::tui::app::App; +use crate::bibiman::entries::EntryTableColumn; +use crate::bibiman::keywords::TagListItem; +use crate::bibiman::{Bibiman, CurrentArea, FormerArea}; +use crate::App; use ratatui::{ buffer::Buffer, layout::{Alignment, Constraint, Layout, Rect}, @@ -87,18 +87,18 @@ impl Widget for &mut App { Layout::horizontal([Constraint::Max(25), Constraint::Min(35)]).areas(item_area); // Render header and footer - App::render_header(header_area, buf); - self.render_footer(footer_area, buf); + Bibiman::render_header(header_area, buf); + self.bibiman.render_footer(footer_area, buf); // Render list area where entry gets selected - self.render_entrytable(entry_area, buf); - self.render_file_info(entry_info_area, buf); + self.bibiman.render_entrytable(entry_area, buf); + self.bibiman.render_file_info(entry_info_area, buf); // Render infos related to selected entry - self.render_taglist(tag_area, buf); - self.render_selected_item(info_area, buf); + self.bibiman.render_taglist(tag_area, buf); + self.bibiman.render_selected_item(info_area, buf); } } -impl App { +impl Bibiman { pub fn render_header(area: Rect, buf: &mut Buffer) { Paragraph::new("BIBIMAN – BibLaTeX manager TUI") .bold() |
