Add support for annotations

This matches the taskwarrior task model for annotations.
This commit is contained in:
Dustin J. Mitchell
2021-10-26 22:33:14 -04:00
parent 7fe5553093
commit 4314b8bc2d
8 changed files with 173 additions and 11 deletions

View File

@@ -48,6 +48,9 @@ pub struct Modification {
/// Remove tags
pub remove_tags: HashSet<Tag>,
/// Add annotation
pub annotate: Option<String>,
}
/// A single argument that is part of a modification, used internally to this module
@@ -128,12 +131,12 @@ impl Modification {
pub(super) fn get_usage(u: &mut usage::Usage) {
u.modifications.push(usage::Modification {
syntax: "DESCRIPTION",
summary: "Set description",
summary: "Set description/annotation",
description: "
Set the task description. Multiple arguments are combined into a single
space-separated description. To avoid surprises from shell quoting, prefer
to use a single quoted argument, for example `ta 19 modify \"return library
books\"`",
Set the task description (or the task annotation for `ta annotate`). Multiple
arguments are combined into a single space-separated description. To avoid
surprises from shell quoting, prefer to use a single quoted argument, for example
`ta 19 modify \"return library books\"`",
});
u.modifications.push(usage::Modification {
syntax: "+TAG",

View File

@@ -207,6 +207,13 @@ impl Modify {
"start" => modification.active = Some(true),
"stop" => modification.active = Some(false),
"done" => modification.status = Some(Status::Completed),
"annotate" => {
// what would be parsed as a description is, here, used as the annotation
if let DescriptionMod::Set(s) = modification.description {
modification.description = DescriptionMod::None;
modification.annotate = Some(s);
}
}
_ => {}
}
@@ -225,6 +232,7 @@ impl Modify {
arg_matching(literal("start")),
arg_matching(literal("stop")),
arg_matching(literal("done")),
arg_matching(literal("annotate")),
)),
Modification::parse,
)),
@@ -278,6 +286,13 @@ impl Modify {
Mark all tasks matching the required filter as completed, additionally applying any given
modifications.",
});
u.subcommands.push(usage::Subcommand {
name: "annotate",
syntax: "<filter> annotate [modification]",
summary: "Mark tasks as completed",
description: "
Add an annotation to all tasks matching the required filter.",
});
}
}
@@ -652,6 +667,23 @@ mod test {
);
}
#[test]
fn test_annotate() {
let subcommand = Subcommand::Modify {
filter: Filter {
conditions: vec![Condition::IdList(vec![TaskId::WorkingSetId(123)])],
},
modification: Modification {
annotate: Some("sent invoice".into()),
..Default::default()
},
};
assert_eq!(
Subcommand::parse(argv!["123", "annotate", "sent", "invoice"]).unwrap(),
(&EMPTY[..], subcommand)
);
}
#[test]
fn test_report() {
let subcommand = Subcommand::Report {