aboutsummaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/ts/tskm/src/cli.rs
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/by-name/ts/tskm/src/cli.rs')
-rw-r--r--pkgs/by-name/ts/tskm/src/cli.rs75
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);
}
}