aboutsummaryrefslogtreecommitdiff
path: root/cmd.ha
diff options
context:
space:
mode:
Diffstat (limited to 'cmd.ha')
-rw-r--r--cmd.ha151
1 files changed, 106 insertions, 45 deletions
diff --git a/cmd.ha b/cmd.ha
index ff37c79..dd267b3 100644
--- a/cmd.ha
+++ b/cmd.ha
@@ -6,101 +6,162 @@ use io;
use path;
use os::exec;
use strconv;
+use ascii;
-type error = !(io::error | path::error | exec::error);
+type error = !(!str | io::error | path::error | exec::error | strconv::error);
-type func = fn(tasks: []task, args: str...) (void | task | error);
+type func = fn(tasks: []task, args: arguments) (void | task | error);
type command = struct {
names: []str,
+ help: []getopt::help,
func: *func,
};
+type arguments = *getopt::command;
+
const PADDING: size = 30z;
const commands: [_]command = [
command {
names = ["f", "filter"],
+ help = ["<name>"],
func = &filter,
},
command {
names = ["s", "show"],
+ help = ["<id>"],
func = &show,
},
command {
names = ["w", "write"],
+ help = ["<id>"],
func = &write,
},
];
-fn execcommand(name: str, tasks: []task, args: str...) (void | error) = {
+fn execcommand(name: str, tasks: []task, args: arguments) (void | error) = {
for (const c .. commands) {
for (const n .. c.names) {
if (n == name) {
- c.func(tasks, args...)?;
+ c.func(tasks, args)?;
};
};
};
};
-fn write(tasks: []task, args: str...) (void | task | error) = {
- const cmdname = "task write";
- const cmdhelp: []getopt::help = ["write a task", "<name>"];
- if (len(args) == 0z) {
- getopt::printhelp(os::stderr, cmdname, cmdhelp)?;
- return;
- };
- const cmd = getopt::parse(args,
- cmdname: getopt::help,
- cmdhelp[0],
- cmdhelp[1],
- );
- defer getopt::finish(&cmd);
-
+fn write(tasks: []task, a: arguments) (void | task | error) = {
+ const args = a.args;
if (len(args) != 1z) {
- getopt::printhelp(os::stderr, cmdname, cmdhelp)?;
+ getopt::printhelp(os::stderr, "write", a.help)?;
return;
};
- let buf = path::init()?;
- const p = path::push(&buf, "tasks", args[0])?;
- const c = exec::cmd("vim", p)?;
+ const id = strconv::stoz(args[0])?;
+ const t = if (len(tasks) > id) {
+ yield tasks[id];
+ } else {
+ return "No such task";
+ };
+ const c = exec::cmd("vim", t.path)?;
exec::exec(&c);
};
-fn show(tasks: []task, args: str...) (void | task | error) = {
- for (const t .. tasks) {
- for (const s .. args) {
- if (t.name == s) {
- fmt::println(t.content)!;
- };
- };
+fn show(tasks: []task, a: arguments) (void | task | error) = {
+ const args = a.args;
+ const id = strconv::stoz(args[0])?;
+ const t = if (len(tasks) > id) {
+ yield tasks[id];
+ } else {
+ return "No such task";
};
+ fmt::println(t.content)!;
};
-fn printtask(t: task) (void | error) = {
- const pad = PADDING - len(t.name) + len(strconv::utos(t.priority));
- fmt::printfln("{}{%}", t.name, t.priority, &fmt::mods {
- pad = ' ',
- width = pad, ...
- })!;
+fn printtask(t: task, id: size) (void | error) = {
+ let name = strings::dup(t.name);
+ defer free(name);
+ if (len(t.name) > PADDING - 4) {
+ name = strings::concat(strings::sub(t.name, 0z, PADDING - 4),
+ "...");
+ };
+ const pad = PADDING - len(name) + len(strconv::utos(t.priority));
+ const namepad = 10 - len(strconv::ztos(id)) + len(name);
+ fmt::printfln("{}{%}{%}", id, name, &fmt::mods {
+ pad = ' ',
+ width = namepad,
+ ...
+ },
+ t.priority, &fmt::mods {
+ pad = ' ',
+ width = pad,
+ ...
+ },
+ )!;
};
-fn filter(tasks: []task, args: str...) (void | task | error) = {
+fn filter(tasks: []task, a: arguments) (void | task | error) = {
const headpad = PADDING - len("name") + len("priority");
- fmt::printfln("name{%}", "priority", &fmt::mods {
- pad = ' ',
- width = headpad,
- ...
- })!;
- for (const t .. tasks) {
+ const namepad = 10 - len("id") + len("name");
+ fmt::printfln("id{%}{%}",
+ "name", &fmt::mods {
+ pad = ' ',
+ width = namepad,
+ ...
+ },"priority", &fmt::mods {
+ pad = ' ',
+ width = headpad,
+ ...
+ },
+ )!;
+ const args = a.args;
+ for (let i = 0z; i < len(tasks); i += 1) {
+ const t = tasks[i];
if (len(args) == 0z) {
- printtask(t)?;
+ printtask(t, i)?;
};
for (const s .. args) {
- if (strings::contains(t.name, s)) {
- printtask(t)?;
+ const lname = ascii::strlower(t.name);
+ defer free(lname);
+ const ls = ascii::strlower(s);
+ defer free(ls);
+ if (strings::contains(lname, ls)) {
+ printtask(t, i)?;
};
};
};
};
+
+fn listall(tasks: []task) void = {
+ const headpad = PADDING - len("name") + len("priority");
+ const namepad = 10 - len("id") + len("name");
+ fmt::printfln("id{%}{%}",
+ "name", &fmt::mods {
+ pad = ' ',
+ width = namepad,
+ ...
+ },"priority", &fmt::mods {
+ pad = ' ',
+ width = headpad,
+ ...
+ },
+ )!;
+ for (let i = 0z; i < len(tasks); i += 1) {
+ printtask(tasks[i], i)!;
+ };
+};
+
+fn strerror(e: error) str = {
+ match (e) {
+ case let e: !str =>
+ return e;
+ case let e: io::error =>
+ return io::strerror(e);
+ case let e: path::error =>
+ return path::strerror(e);
+ case let e: exec::error =>
+ return exec::strerror(e);
+ case let e: strconv::error =>
+ return strconv::strerror(e);
+ };
+};