diff --git a/Cargo.lock b/Cargo.lock index a1e9314..daca859 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,7 +118,7 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "c3" -version = "0.8.0" +version = "0.9.0" dependencies = [ "chrono", "clap", diff --git a/Cargo.toml b/Cargo.toml index 39123e1..82185e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "c3" -version = "0.8.0" +version = "0.9.0" edition = "2021" [dependencies] diff --git a/README.md b/README.md index faa13ef..a00415e 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,9 @@ The default mode of the app is TUI mode. Keybinds are vim-like. Here they are: | y | yank todo to clipboard | | p | paste todo from clipboard | | P | enable module | -| / | search todo | +| / | search current list for todo | +| ? | search the whole tree for todo | +| O | open nnn file picker for choosing a file to append to current list | n | search next | | N | search previous | | w | write changes to file | diff --git a/src/cli_app.rs b/src/cli_app.rs index 157e0a0..b245761 100644 --- a/src/cli_app.rs +++ b/src/cli_app.rs @@ -23,6 +23,9 @@ impl <'a>CliApp <'a>{ for message in app.args.prepend_todo.clone() { app.prepend(message); } + if let Some(path) = app.args.append_file.clone() { + app.append_list_from_path(path) + } app.do_commands_on_selected(); if !app.args.append_todo.is_empty() || !app.args.prepend_todo.is_empty() || app.is_changed(){ let _ = app.write(); diff --git a/src/fileio.rs b/src/fileio.rs index e6d0158..7f3b10b 100644 --- a/src/fileio.rs +++ b/src/fileio.rs @@ -27,11 +27,16 @@ pub fn get_todo_path() -> io::Result { #[inline(always)] pub fn temp_note_path() -> PathBuf{ + temp_path("note") +} + +#[inline(always)] +pub fn temp_path(name: &str) -> PathBuf{ let time = match SystemTime::now().duration_since(UNIX_EPOCH) { Err(_)=>12345, Ok(some) => some.as_secs(), }; - let filename = format!("c3-note.{time}"); + let filename = format!("c3-{name}.{time}"); let path = home_dir().unwrap().join(filename); path.to_path_buf() } diff --git a/src/main.rs b/src/main.rs index 0e2c552..343b636 100644 --- a/src/main.rs +++ b/src/main.rs @@ -67,14 +67,18 @@ pub struct Args { #[command(flatten)] display_args: DisplayArgs, - /// Append todo + /// A todo message to append #[arg(short='a', long)] append_todo: Vec, - /// Prepend todo + /// A todo message to prepend #[arg(short='A', long)] prepend_todo: Vec, + /// A todo file to append to current list + #[arg(long)] + append_file: Option, + /// Minimal tree with no tree graphics #[arg(short='M', long)] minimal_tree: bool, @@ -99,7 +103,7 @@ pub struct Args { impl Args { pub fn is_cli(&self) -> bool { self.stdout || self.minimal_tree || self.list || - !self.search_and_select.is_empty() || !self.prepend_todo.is_empty() || !self.append_todo.is_empty() + !self.search_and_select.is_empty() || !self.prepend_todo.is_empty() || !self.append_todo.is_empty() || self.append_file.is_some() } } diff --git a/src/todo_app.rs b/src/todo_app.rs index 3074c12..d6bf35d 100644 --- a/src/todo_app.rs +++ b/src/todo_app.rs @@ -62,6 +62,17 @@ impl App { app } + #[inline] + pub fn append_list_from_path(&mut self, path: PathBuf) { + let todo_list = TodoList::read(&path, !self.args.no_tree, true); + self.append_list(todo_list) + } + + #[inline] + pub fn append_list(&mut self, todo_list: TodoList) { + self.mut_current_list().append_list(todo_list) + } + pub fn do_commands_on_selected(&mut self) { let mut index_shift = 0; for (iter_index, sel_index) in self.selected.clone().iter().enumerate() { diff --git a/src/todo_app/todo_list.rs b/src/todo_app/todo_list.rs index ec41431..134c414 100644 --- a/src/todo_app/todo_list.rs +++ b/src/todo_app/todo_list.rs @@ -198,6 +198,13 @@ impl TodoList { } } + pub fn append_list(&mut self, mut todo_list: TodoList) { + self.undone.todos.append(&mut todo_list.undone.todos); + self.done.todos.append(&mut todo_list.done.todos); + self.done.sort(); + self.undone.sort(); + } + pub fn remove(&mut self, index: usize) -> Todo { let size = self.undone.len(); diff --git a/src/tui_app.rs b/src/tui_app.rs index 5a2fff0..7ed4441 100644 --- a/src/tui_app.rs +++ b/src/tui_app.rs @@ -1,6 +1,7 @@ // vim:fileencoding=utf-8:foldmethod=marker // std {{{ -use std::{io::{self, stdout}, rc::Rc}; +use std::{fs::{read_to_string, remove_file}, io::{self, stdout}, path::PathBuf, rc::Rc}; +use std::process::Command; // }}} // lib {{{ use crossterm::{ @@ -19,7 +20,7 @@ use modules::{ potato::Potato, }; use super::todo_app::{App, Todo}; -use crate::{date, todo_app::PriorityType}; +use crate::{date, fileio::temp_path, todo_app::PriorityType}; // }}} pub fn default_block<'a, T>(title: T) -> Block<'a> @@ -197,6 +198,21 @@ impl<'a>TuiApp<'a>{ self.set_text_mode(Self::on_reminder, "Date reminder", ""); } + #[inline] + pub fn nnn_append_todo(&mut self) { + let path = temp_path("nnn-file-picker"); + if Command::new("nnn").args(["-p", path.to_str().unwrap_or("")]).status().is_err(){ + return + } + let mut output_str = match read_to_string(&path) { + Ok(value) => value, + Err(_) => return, + }; + output_str.pop(); + self.todo_app.append_list_from_path(PathBuf::from(output_str)); + let _ = remove_file(path); + } + #[inline] fn on_reminder(&mut self,str:String) { if let Ok(date) = date::parse_user_input(&str) { @@ -369,6 +385,10 @@ impl<'a>TuiApp<'a>{ Char('p') => self.todo_app.paste_todo(), Char('i') => self.todo_app.increase_day_done(), Char('o') => self.todo_app.decrease_day_done(), + Char('O') => { + self.nnn_append_todo(); + return Ok(Operation::Restart) + } KeyCode::Down | Char('j') => self.todo_app.increment(), KeyCode::Up |Char('k') => self.todo_app.decrement(), KeyCode::Right | Char('l') => self.todo_app.add_dependency_traverse_down(),