feat: filter channel category tagging

This commit is contained in:
2026-10-11 19:37:52 +02:00
parent 766fef625c
commit 6afe229406
3 changed files with 394 additions and 102 deletions
+18 -4
View File
@@ -17,6 +17,7 @@ pub enum Context {
SelectorNormal,
SelectorInput,
TagList,
TagFilter,
TagInput,
Help,
}
@@ -29,6 +30,7 @@ const ALL: &[Context] = &[
Context::SelectorNormal,
Context::SelectorInput,
Context::TagList,
Context::TagFilter,
Context::TagInput,
Context::Help,
];
@@ -36,6 +38,7 @@ const VIEW: &[Context] = &[Context::Normal, Context::Info, Context::Description]
const TEXT: &[Context] = &[
Context::SearchInput,
Context::SelectorInput,
Context::TagFilter,
Context::TagInput,
];
const NON_TEXT: &[Context] = &[
@@ -78,7 +81,7 @@ actions! {
Interrupt, "app.interrupt", "Exit immediately", ALL, ["ctrl+c"];
Quit, "app.quit", "Quit the application", &[Context::Normal, Context::Info, Context::Description, Context::Help], ["q"];
Help, "help.toggle", "Open or close keyboard help", NON_TEXT, ["?"];
InputSubmit, "input.submit", "Submit search, selector filter or new tag", TEXT, ["enter"];
InputSubmit, "input.submit", "Submit search, browse selector, leave tag filter or stage new tag", TEXT, ["enter"];
InputCancel, "input.cancel", "Leave text input without submitting", TEXT, ["escape"];
DeleteCharacter, "input.delete.character", "Delete the previous character", TEXT, ["backspace"];
DeleteWord, "input.delete.word", "Delete the previous word", TEXT, ["alt+backspace", "ctrl+w"];
@@ -112,6 +115,9 @@ actions! {
SelectorClose, "selector.close", "Close the category or channel picker", &[Context::SelectorNormal], ["escape"];
TagNext, "tags.select.next", "Select the next category tag", &[Context::TagList], ["j", "down"];
TagPrevious, "tags.select.previous", "Select the previous category tag", &[Context::TagList], ["k", "up"];
TagEdit, "tags.edit", "Edit the category tag filter", &[Context::TagList], ["i"];
TagInputNext, "tags.input.next", "Select the next tag while editing the filter", &[Context::TagFilter], ["down", "ctrl+j"];
TagInputPrevious, "tags.input.previous", "Select the previous tag while editing the filter", &[Context::TagFilter], ["up", "ctrl+k"];
TagToggle, "tags.toggle", "Toggle the selected category tag", &[Context::TagList], ["space"];
TagNew, "tags.new", "Enter a new category tag name", &[Context::TagList], ["n"];
TagSave, "tags.save", "Save category tag changes", &[Context::TagList], ["enter"];
@@ -262,7 +268,7 @@ impl Key {
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Bindings {
labels: Vec<Vec<String>>,
contexts: [Vec<(Key, Action)>; 9],
contexts: [Vec<(Key, Action)>; ALL.len()],
}
impl Default for Bindings {
@@ -378,7 +384,7 @@ impl Bindings {
}
fn build(keys: Vec<Vec<Key>>) -> io::Result<Self> {
let mut contexts: [Vec<(Key, Action)>; 9] = std::array::from_fn(|_| Vec::new());
let mut contexts: [Vec<(Key, Action)>; ALL.len()] = std::array::from_fn(|_| Vec::new());
for definition in DEFINITIONS {
for &context in definition.contexts {
let entries = &mut contexts[context as usize];
@@ -483,6 +489,12 @@ impl Bindings {
"CHANNEL TAGS",
&[
(&[TagNext, TagPrevious], "Move between tags"),
(&[TagEdit], "Enter filter INSERT mode"),
(&[TagInputNext, TagInputPrevious], "Move while filtering"),
(
&[InputSubmit, InputCancel],
"Leave tag filter without saving",
),
(&[TagToggle], "Toggle a tag"),
(&[TagNew], "Enter a new tag name"),
(&[TagSave], "Save tags"),
@@ -565,7 +577,9 @@ impl Bindings {
}
if matches!(
actions,
[DescriptionNext, DescriptionPrevious] | [SelectorInputNext, SelectorInputPrevious]
[DescriptionNext, DescriptionPrevious]
| [SelectorInputNext, SelectorInputPrevious]
| [TagInputNext, TagInputPrevious]
) && matches(actions[0], &["↓", "Ctrl+j"])
&& matches(actions[1], &["↑", "Ctrl+k"])
{