Add rm, mv, promote, demote, refile, archive, lint, query to ork
Client verbs for the new server capabilities, each a thin wrapper over the base 9P operations: the structural verbs write to /ctl, and query writes to /query and prints the matches.
This commit is contained in:
parent
12869fb9f0
commit
943c05b61c
|
|
@ -3,9 +3,9 @@
|
||||||
//! `ork` is only a 9P client: it connects to a running `ork-server` and
|
//! `ork` is only a 9P client: it connects to a running `ork-server` and
|
||||||
//! operates on its namespace. All org-mode intelligence lives in the server.
|
//! operates on its namespace. All org-mode intelligence lives in the server.
|
||||||
//! The base verbs (ls/read/write/rdwr) speak raw 9P; the friendly verbs
|
//! The base verbs (ls/read/write/rdwr) speak raw 9P; the friendly verbs
|
||||||
//! (docs/sections/todos/agenda/get/set/add/mkdoc/reload/tag/prop/todo/tree)
|
//! (docs/sections/todos/agenda/get/set/add/mkdoc/reload/tag/prop/todo/tree/
|
||||||
//! are thin compositions of those same 9P operations against the exposed
|
//! rm/mv/promote/demote/refile/archive/lint/query) are thin compositions of
|
||||||
//! namespace.
|
//! those same 9P operations against the exposed namespace.
|
||||||
//!
|
//!
|
||||||
//! Address resolution: `--addr` flag, then `$ORK_ADDR`, then
|
//! Address resolution: `--addr` flag, then `$ORK_ADDR`, then
|
||||||
//! `tcp://localhost:5640`. Accepts `tcp://host:port` or `unix:///path/to/sock`.
|
//! `tcp://localhost:5640`. Accepts `tcp://host:port` or `unix:///path/to/sock`.
|
||||||
|
|
@ -172,6 +172,73 @@ enum Commands {
|
||||||
/// Document name
|
/// Document name
|
||||||
doc: String,
|
doc: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Delete a section and its subtree
|
||||||
|
Rm {
|
||||||
|
/// Document name
|
||||||
|
doc: String,
|
||||||
|
/// Section id
|
||||||
|
id: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Reorder a section among its siblings
|
||||||
|
Mv {
|
||||||
|
/// Document name
|
||||||
|
doc: String,
|
||||||
|
/// Section id
|
||||||
|
id: String,
|
||||||
|
/// Direction: up or down
|
||||||
|
dir: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Decrease a section's outline level
|
||||||
|
Promote {
|
||||||
|
/// Document name
|
||||||
|
doc: String,
|
||||||
|
/// Section id
|
||||||
|
id: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Increase a section's outline level
|
||||||
|
Demote {
|
||||||
|
/// Document name
|
||||||
|
doc: String,
|
||||||
|
/// Section id
|
||||||
|
id: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Move a section's subtree to another document (or elsewhere)
|
||||||
|
Refile {
|
||||||
|
/// Source document name
|
||||||
|
doc: String,
|
||||||
|
/// Section id
|
||||||
|
id: String,
|
||||||
|
/// Target document name
|
||||||
|
to: String,
|
||||||
|
/// Place under this section id instead of at top level
|
||||||
|
#[arg(long, short)]
|
||||||
|
parent: Option<String>,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Move a section's subtree to <doc>.org_archive
|
||||||
|
Archive {
|
||||||
|
/// Document name
|
||||||
|
doc: String,
|
||||||
|
/// Section id
|
||||||
|
id: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Validate documents (all, or one)
|
||||||
|
Lint {
|
||||||
|
/// Document name; omit to lint all
|
||||||
|
doc: Option<String>,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Find sections matching a query (tag:X+todo:Y+priority:Z)
|
||||||
|
Query {
|
||||||
|
/// Match expression, e.g. "tag:work+todo:TODO"
|
||||||
|
expr: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Section fields that may be written via `set`.
|
/// Section fields that may be written via `set`.
|
||||||
|
|
@ -499,6 +566,20 @@ fn print_tree(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Send a control command and echo the server's response.
|
||||||
|
fn ctl(client: &mut Client, command: &str) -> io::Result<()> {
|
||||||
|
let resp = client.rdwr("/ctl", command.as_bytes())?;
|
||||||
|
io::stdout().write_all(&resp)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `query <expr>` — write a match expression and print matching sections.
|
||||||
|
fn cmd_query(client: &mut Client, expr: &str) -> io::Result<()> {
|
||||||
|
let resp = client.rdwr("/query", expr.as_bytes())?;
|
||||||
|
io::stdout().write_all(&resp)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn run(cli: Cli) -> io::Result<()> {
|
fn run(cli: Cli) -> io::Result<()> {
|
||||||
let addr = resolve_addr(cli.addr.as_deref());
|
let addr = resolve_addr(cli.addr.as_deref());
|
||||||
let mut client = Client::connect(&addr)
|
let mut client = Client::connect(&addr)
|
||||||
|
|
@ -553,6 +634,25 @@ fn run(cli: Cli) -> io::Result<()> {
|
||||||
cmd_todo(&mut client, &doc, &id, state.as_deref())?
|
cmd_todo(&mut client, &doc, &id, state.as_deref())?
|
||||||
}
|
}
|
||||||
Commands::Tree { doc } => cmd_tree(&mut client, &doc)?,
|
Commands::Tree { doc } => cmd_tree(&mut client, &doc)?,
|
||||||
|
Commands::Rm { doc, id } => ctl(&mut client, &format!("rm {} {}", doc, id))?,
|
||||||
|
Commands::Mv { doc, id, dir } => {
|
||||||
|
ctl(&mut client, &format!("move {} {} {}", doc, id, dir))?
|
||||||
|
}
|
||||||
|
Commands::Promote { doc, id } => ctl(&mut client, &format!("promote {} {}", doc, id))?,
|
||||||
|
Commands::Demote { doc, id } => ctl(&mut client, &format!("demote {} {}", doc, id))?,
|
||||||
|
Commands::Refile { doc, id, to, parent } => {
|
||||||
|
let cmd = match parent {
|
||||||
|
Some(p) => format!("refile {} {} {} {}", doc, id, to, p),
|
||||||
|
None => format!("refile {} {} {}", doc, id, to),
|
||||||
|
};
|
||||||
|
ctl(&mut client, &cmd)?
|
||||||
|
}
|
||||||
|
Commands::Archive { doc, id } => ctl(&mut client, &format!("archive {} {}", doc, id))?,
|
||||||
|
Commands::Lint { doc } => match doc {
|
||||||
|
Some(d) => ctl(&mut client, &format!("lint {}", d))?,
|
||||||
|
None => ctl(&mut client, "lint")?,
|
||||||
|
},
|
||||||
|
Commands::Query { expr } => cmd_query(&mut client, &expr)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue