diff options
Diffstat (limited to 'pkgs/by-name/ts/tskm/src/cli.rs')
| -rw-r--r-- | pkgs/by-name/ts/tskm/src/cli.rs | 75 |
1 files changed, 59 insertions, 16 deletions
diff --git a/pkgs/by-name/ts/tskm/src/cli.rs b/pkgs/by-name/ts/tskm/src/cli.rs index a347f5ce..3dc1181d 100644 --- a/pkgs/by-name/ts/tskm/src/cli.rs +++ b/pkgs/by-name/ts/tskm/src/cli.rs @@ -8,11 +8,12 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -use std::{ffi::OsStr, path::PathBuf}; +use std::{ffi::OsStr, path::PathBuf, thread}; -use anyhow::{Result, bail}; -use clap::{ArgAction, Parser, Subcommand, ValueEnum, builder::StyledStr}; +use anyhow::{bail, Result}; +use clap::{builder::StyledStr, ArgAction, Parser, Subcommand, ValueEnum}; use clap_complete::{ArgValueCompleter, CompletionCandidate}; +use tokio::runtime::Runtime; use crate::{ interface::{ @@ -23,6 +24,43 @@ use crate::{ state, task, }; +macro_rules! as_sync { + ( + wrap $old_name_1:ident($($arg_name_1:ident : $arg_type_1:ty),*) -> $output_1:ty => $new_name_1:ident; + $( + wrap $old_name:ident($($arg_name:ident : $arg_type:ty),*) -> $output:ty => $new_name:ident; + )+ + ) => { + as_sync!( + wrap $old_name_1($($arg_name_1 : $arg_type_1),*) -> $output_1 => $new_name_1; + ); + as_sync!( + $( + wrap $old_name($($arg_name : $arg_type),*) -> $output => $new_name; + )+ + ); + }; + ( + wrap $old_name:ident($($arg_name:ident : $arg_type:ty),*) -> $output:ty => $new_name:ident $(;)? + ) => { + fn $new_name($($arg_name: $arg_type),*) -> $output { + $( + let $arg_name = $arg_name.to_owned(); + ),* + + let handle: std::thread::JoinHandle<$output> = thread::spawn(move || { + let rt = Runtime::new().expect("No runtime issue"); + + let output = rt.block_on($old_name($($arg_name.as_ref()),*)); + + output + }); + + handle.join().expect("The thread should be joinable") + } + }; +} + #[derive(Parser, Debug)] #[command(author, version, about, long_about, verbatim_doc_comment)] /// This is the core interface to the system-integrated task management @@ -94,16 +132,21 @@ pub enum NeorgCommand { /// Open the `neorg` project associated with id of the task. Task { /// The working set id of the task - #[arg(value_name = "ID", value_parser = task_from_working_set_id, add = ArgValueCompleter::new(complete_task_id))] + #[arg(value_name = "ID", value_parser = task_from_working_set_id_sync, add = ArgValueCompleter::new(complete_task_id_sync))] task: task::Task, }, } -fn task_from_working_set_id(id: &str) -> Result<task::Task> { +as_sync!( + wrap task_from_working_set_id(id: &str) -> Result<task::Task> => task_from_working_set_id_sync; + wrap complete_task_id(current: &OsStr) -> Vec<CompletionCandidate> => complete_task_id_sync; +); + +async fn task_from_working_set_id(id: &str) -> Result<task::Task> { let id: usize = id.parse()?; - let mut state = state::State::new_ro()?; + let mut state = state::State::new_ro().await?; - let Some(task) = task::Task::from_working_set(id, &mut state)? else { + let Some(task) = task::Task::from_working_set(id, &mut state).await? else { bail!("Working set id '{id}' is not valid!") }; Ok(task) @@ -201,14 +244,14 @@ pub enum InputCommand { Tags {}, } -fn complete_task_id(current: &OsStr) -> Vec<CompletionCandidate> { - fn format_task( +async fn complete_task_id(current: &OsStr) -> Vec<CompletionCandidate> { + async fn format_task( task: task::Task, current: &str, state: &mut state::State, ) -> Option<CompletionCandidate> { let id = { - let Ok(base) = task.working_set_id(state) else { + let Ok(base) = task.working_set_id(state).await else { return None; }; base.to_string() @@ -219,7 +262,7 @@ fn complete_task_id(current: &OsStr) -> Vec<CompletionCandidate> { } let description = { - let Ok(base) = task.description(state) else { + let Ok(base) = task.description(state).await else { return None; }; StyledStr::from(base) @@ -234,11 +277,11 @@ fn complete_task_id(current: &OsStr) -> Vec<CompletionCandidate> { return output; }; - let Ok(mut state) = state::State::new_ro() else { + let Ok(mut state) = state::State::new_ro().await else { return output; }; - let Ok(pending) = state.replica().pending_tasks() else { + let Ok(pending) = state.replica().pending_tasks().await else { return output; }; @@ -249,9 +292,9 @@ fn complete_task_id(current: &OsStr) -> Vec<CompletionCandidate> { if let Some(current_project) = current_project { for t in pending { let task = task::Task::from(&t); - if let Ok(project) = task.project(&mut state) { + if let Ok(project) = task.project(&mut state).await { if project == current_project { - if let Some(out) = format_task(task, current, &mut state) { + if let Some(out) = format_task(task, current, &mut state).await { output.push(out); } } @@ -260,7 +303,7 @@ fn complete_task_id(current: &OsStr) -> Vec<CompletionCandidate> { } else { for t in pending { let task = task::Task::from(&t); - if let Some(out) = format_task(task, current, &mut state) { + if let Some(out) = format_task(task, current, &mut state).await { output.push(out); } } |
