From 6b7b6b91a84c50a2c56b9141e90fa305e5990815 Mon Sep 17 00:00:00 2001 From: xeruf <27jf@pm.me> Date: Thu, 8 Aug 2024 13:04:22 +0300 Subject: [PATCH] feat: hashtag list and quick filter override --- README.md | 5 +++-- src/kinds.rs | 2 +- src/main.rs | 12 +++++++++++- src/tasks.rs | 15 +++++++++++++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6b7bdcb..afe81cf 100644 --- a/README.md +++ b/README.md @@ -110,8 +110,9 @@ Dots can be repeated to move to parent tasks. Property Filters: -- `+TAG` - filter by tag -- `-TAG` - remove filter by tag +- `#TAG` - set tag filter (empty: list all used tags) +- `+TAG` - add tag filter +- `-TAG` - remove tag filters - `?STATE` - filter by state (type or description) - plain `?` to reset State descriptions can be used for example for Kanban columns or review flows. diff --git a/src/kinds.rs b/src/kinds.rs index 3c313e1..6f23a98 100644 --- a/src/kinds.rs +++ b/src/kinds.rs @@ -58,6 +58,6 @@ fn format_tag(tag: &Tag) -> String { pub(crate) fn is_hashtag(tag: &Tag) -> bool { tag.single_letter_tag() - .is_some_and(|sltag| sltag.character == Alphabet::T) + .is_some_and(|letter| letter.character == Alphabet::T) } diff --git a/src/main.rs b/src/main.rs index 9611b8a..e9f572e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -331,7 +331,17 @@ async fn main() { } }, - Some('#') | Some('+') => { + Some('#') => { + match arg { + Some(arg) => tasks.set_tag(arg.to_string()), + None => { + println!("Hashtags of all known tasks:\n{}", tasks.all_hashtags().join(" ")); + continue + } + } + } + + Some('+') => { match arg { Some(arg) => tasks.add_tag(arg.to_string()), None => tasks.clear_filter() diff --git a/src/tasks.rs b/src/tasks.rs index 84b3986..f71c7be 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -102,6 +102,16 @@ impl Tasks { children } + + pub(crate) fn all_hashtags(&self) -> impl Iterator { + self.tasks.values() + .filter(|t| t.pure_state() != State::Closed) + .filter_map(|t| t.tags.as_ref()).flatten() + .filter(|tag| is_hashtag(tag)) + .filter_map(|tag| tag.content().map(|s| s.trim())) + .sorted_unstable() + .dedup() + } /// Total time in seconds tracked on this task by the current user. pub(crate) fn time_tracked(&self, id: EventId) -> u64 { @@ -350,6 +360,11 @@ impl Tasks { info!("Removed all filters"); } + pub(crate) fn set_tag(&mut self, tag: String) { + self.tags.clear(); + self.add_tag(tag); + } + pub(crate) fn add_tag(&mut self, tag: String) { self.view.clear(); info!("Added tag filter for #{tag}");