use crossterm::event::KeyCode;
use crate::tui::store::{TaskOrder, TaskView};
use super::Action;
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum CommandLifecycle {
Implemented,
Planned { reason: &'static str },
Disabled { reason: &'static str },
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct KeySequence {
pub(crate) codes: &'static [KeyCode],
pub(crate) label: &'static str,
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct CommandSpec {
pub(crate) name: &'static str,
pub(crate) aliases: &'static [&'static str],
pub(crate) description: &'static str,
pub(crate) section: &'static str,
pub(crate) keys: &'static [KeySequence],
pub(crate) action: Action,
pub(crate) lifecycle: CommandLifecycle,
}
pub(crate) const PROJECT_PATH_FLOW_REASON: &str = "requires a multi-step project/path picker flow";
impl CommandSpec {
pub(crate) const fn implemented(
name: &'static str,
description: &'static str,
section: &'static str,
keys: &'static [KeySequence],
action: Action,
) -> Self {
Self::implemented_with_aliases(name, &[], description, section, keys, action)
}
pub(crate) const fn implemented_with_aliases(
name: &'static str,
aliases: &'static [&'static str],
description: &'static str,
section: &'static str,
keys: &'static [KeySequence],
action: Action,
) -> Self {
Self {
name,
aliases,
description,
section,
keys,
action,
lifecycle: CommandLifecycle::Implemented,
}
}
const fn planned(
name: &'static str,
description: &'static str,
section: &'static str,
keys: &'static [KeySequence],
reason: &'static str,
) -> Self {
Self {
name,
aliases: &[],
description,
section,
keys,
action: Action::Planned { name, reason },
lifecycle: CommandLifecycle::Planned { reason },
}
}
#[allow(dead_code)]
const fn disabled(
name: &'static str,
description: &'static str,
section: &'static str,
keys: &'static [KeySequence],
reason: &'static str,
) -> Self {
Self {
name,
aliases: &[],
description,
section,
keys,
action: Action::Disabled { name, reason },
lifecycle: CommandLifecycle::Disabled { reason },
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum CommandContext {
Normal,
Detail,
}
impl CommandContext {
pub(crate) const fn commands(self) -> &'static [CommandSpec] {
match self {
Self::Normal => COMMANDS,
Self::Detail => DETAIL_COMMANDS,
}
}
pub(crate) const fn sections(self) -> &'static [&'static str] {
match self {
Self::Normal => NORMAL_HELP_SECTIONS,
Self::Detail => DETAIL_HELP_SECTIONS,
}
}
}
pub(crate) const NORMAL_HELP_SECTIONS: &[&str] = &[
"General",
"Navigation",
"Tasks",
"Projects",
"Labels",
"Views",
"Filters",
"Order",
"Conflicts",
"Config",
];
pub(crate) const DETAIL_HELP_SECTIONS: &[&str] = &["General", "Task detail", "Tasks"];
pub(crate) const COMMANDS: &[CommandSpec] = &[
CommandSpec::implemented(
"quit",
"quit the TUI",
"General",
&[KeySequence {
codes: &[KeyCode::Char('q')],
label: "q",
}],
Action::Quit,
),
CommandSpec::implemented(
"command",
"open the command panel",
"General",
&[KeySequence {
codes: &[KeyCode::Char(':')],
label: ":",
}],
Action::BeginCommand,
),
CommandSpec::implemented(
"help",
"toggle shortcut help",
"General",
&[KeySequence {
codes: &[KeyCode::Char('?')],
label: "?",
}],
Action::ToggleHelp,
),
CommandSpec::implemented(
"welcome",
"show the getting-started guide",
"General",
&[],
Action::ShowWelcome,
),
CommandSpec::implemented(
"refresh",
"reload tasks",
"General",
&[KeySequence {
codes: &[KeyCode::Char('r')],
label: "r",
}],
Action::Refresh,
),
CommandSpec::implemented(
"update",
"check for and install an aven update",
"General",
&[],
Action::BeginUpdate,
),
CommandSpec::implemented(
"undo",
"undo last TUI mutation",
"General",
&[KeySequence {
codes: &[KeyCode::Char('u')],
label: "u",
}],
Action::Undo,
),
CommandSpec::implemented(
"search",
"search all tasks",
"General",
&[KeySequence {
codes: &[KeyCode::Char('/')],
label: "/",
}],
Action::BeginSearch,
),
CommandSpec::implemented(
"move-down",
"move selection down",
"Navigation",
&[
KeySequence {
codes: &[KeyCode::Char('j')],
label: "j",
},
KeySequence {
codes: &[KeyCode::Down],
label: "Down",
},
],
Action::MoveDown,
),
CommandSpec::implemented(
"move-up",
"move selection up",
"Navigation",
&[
KeySequence {
codes: &[KeyCode::Char('k')],
label: "k",
},
KeySequence {
codes: &[KeyCode::Up],
label: "Up",
},
],
Action::MoveUp,
),
CommandSpec::implemented(
"move-left",
"move focus left",
"Navigation",
&[
KeySequence {
codes: &[KeyCode::Char('h')],
label: "h",
},
KeySequence {
codes: &[KeyCode::Left],
label: "Left",
},
],
Action::MoveLeft,
),
CommandSpec::implemented(
"move-right",
"move focus right",
"Navigation",
&[
KeySequence {
codes: &[KeyCode::Char('l')],
label: "l",
},
KeySequence {
codes: &[KeyCode::Right],
label: "Right",
},
],
Action::MoveRight,
),
CommandSpec::implemented(
"move-column-left",
"move selected or marked tasks to the previous column",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('<')],
label: "<",
}],
Action::MoveColumnLeft,
),
CommandSpec::implemented(
"move-column-right",
"move selected or marked tasks to the next column",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('>')],
label: ">",
}],
Action::MoveColumnRight,
),
CommandSpec::implemented(
"move-to-column",
"move selected or marked tasks to a column",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('m')],
label: "m",
}],
Action::BeginMoveToColumn,
),
CommandSpec::implemented(
"previous-item",
"select previous item in flow",
"Navigation",
&[KeySequence {
codes: &[KeyCode::Char('[')],
label: "[",
}],
Action::PreviousItem,
),
CommandSpec::implemented(
"next-item",
"select next item in flow",
"Navigation",
&[KeySequence {
codes: &[KeyCode::Char(']')],
label: "]",
}],
Action::NextItem,
),
CommandSpec::implemented(
"first",
"jump to the first item",
"Navigation",
&[
KeySequence {
codes: &[KeyCode::Char('g'), KeyCode::Char('g')],
label: "g g",
},
KeySequence {
codes: &[KeyCode::Home],
label: "Home",
},
],
Action::First,
),
CommandSpec::implemented(
"last",
"jump to the last item",
"Navigation",
&[
KeySequence {
codes: &[KeyCode::Char('G')],
label: "G",
},
KeySequence {
codes: &[KeyCode::End],
label: "End",
},
],
Action::Last,
),
CommandSpec::implemented(
"focus",
"switch between views and tasks",
"Navigation",
&[
KeySequence {
codes: &[KeyCode::Tab],
label: "Tab",
},
KeySequence {
codes: &[KeyCode::BackTab],
label: "Shift+Tab",
},
],
Action::ToggleFocus,
),
CommandSpec::implemented(
"back",
"return to the previous navigation state",
"Navigation",
&[KeySequence {
codes: &[KeyCode::Char('g'), KeyCode::Char('[')],
label: "g [",
}],
Action::GoBack,
),
CommandSpec::implemented(
"toggle-sidebar",
"toggle the sidebar",
"Navigation",
&[KeySequence {
codes: &[KeyCode::Char('g'), KeyCode::Char('s')],
label: "g s",
}],
Action::ToggleSidebar,
),
CommandSpec::implemented(
"detail",
"select a view or toggle task detail",
"Navigation",
&[KeySequence {
codes: &[KeyCode::Enter],
label: "Enter",
}],
Action::ToggleDetail,
),
CommandSpec::implemented(
"toggle-columns-preview",
"toggle the selected-task preview in columns view",
"Navigation",
&[KeySequence {
codes: &[KeyCode::Char('g'), KeyCode::Char('d')],
label: "g d",
}],
Action::ToggleColumnsPreview,
),
CommandSpec::implemented(
"delete",
"confirm deleting selected task",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('D')],
label: "t D",
}],
Action::Delete,
),
CommandSpec::implemented(
"status-picker",
"open task status picker",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('s')],
label: "t s",
},
KeySequence {
codes: &[KeyCode::Char('s')],
label: "s",
},
],
Action::BeginStatusPicker,
),
CommandSpec::implemented(
"restore",
"restore selected task",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('R')],
label: "t R",
}],
Action::Restore,
),
CommandSpec::implemented(
"status-inbox",
"set status to inbox",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('i')],
label: "t i",
}],
Action::SetStatus("inbox"),
),
CommandSpec::implemented(
"status-backlog",
"set status to backlog",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('b')],
label: "t b",
}],
Action::SetStatus("backlog"),
),
CommandSpec::implemented_with_aliases(
"status-todo",
&["todo"],
"set status to todo",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('t')],
label: "t t",
}],
Action::SetStatus("todo"),
),
CommandSpec::implemented(
"status-active",
"set status to active",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('a')],
label: "t a",
}],
Action::SetStatus("active"),
),
CommandSpec::implemented(
"status-done",
"set status to done",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('d')],
label: "t d",
},
KeySequence {
codes: &[KeyCode::Char('d')],
label: "d",
},
],
Action::SetStatus("done"),
),
CommandSpec::implemented(
"status-canceled",
"set status to canceled",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('x')],
label: "t x",
},
KeySequence {
codes: &[KeyCode::Char('x')],
label: "x",
},
],
Action::SetStatus("canceled"),
),
CommandSpec::implemented(
"view-queue",
"show queue view",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('q')],
label: "v q",
}],
Action::ShowView(TaskView::Queue),
),
CommandSpec::implemented(
"view-columns",
"show configurable column view",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('l')],
label: "v l",
}],
Action::ShowView(TaskView::Columns),
),
CommandSpec::implemented(
"view-open",
"show open task view",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('o')],
label: "v o",
}],
Action::ShowView(TaskView::Open),
),
CommandSpec::implemented(
"view-epics",
"show epics view",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('e')],
label: "v e",
}],
Action::ShowView(TaskView::Epics),
),
CommandSpec::implemented(
"view-recent",
"show recent actions",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('r')],
label: "v r",
}],
Action::ShowView(TaskView::RecentActions),
),
CommandSpec::implemented(
"view-inbox",
"show inbox view",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('i')],
label: "v i",
}],
Action::ShowView(TaskView::Inbox),
),
CommandSpec::implemented(
"view-backlog",
"show backlog view",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('b')],
label: "v b",
}],
Action::ShowView(TaskView::Backlog),
),
CommandSpec::implemented(
"view-todo",
"show todo view",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('t')],
label: "v t",
}],
Action::ShowView(TaskView::Todo),
),
CommandSpec::implemented(
"view-active",
"show active view",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('a')],
label: "v a",
}],
Action::ShowView(TaskView::Active),
),
CommandSpec::implemented(
"view-done",
"show done view",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('d')],
label: "v d",
}],
Action::ShowView(TaskView::Done),
),
CommandSpec::implemented(
"view-conflicts",
"show conflicts view",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('c')],
label: "v c",
}],
Action::ShowView(TaskView::Conflicts),
),
CommandSpec::implemented(
"view-search",
"show search results",
"Views",
&[KeySequence {
codes: &[KeyCode::Char('v'), KeyCode::Char('s')],
label: "v s",
}],
Action::ShowView(TaskView::Search),
),
CommandSpec::implemented(
"scope-all",
"show all projects in current workspace",
"Navigation",
&[KeySequence {
codes: &[KeyCode::Char('g'), KeyCode::Char('a')],
label: "g a",
}],
Action::ShowWorkspaceScope,
),
CommandSpec::implemented(
"scope-project",
"scope to a project",
"Navigation",
&[KeySequence {
codes: &[KeyCode::Char('g'), KeyCode::Char('p')],
label: "g p",
}],
Action::BeginScopeProject,
),
CommandSpec::implemented(
"workspace-switch",
"switch active workspace",
"Navigation",
&[KeySequence {
codes: &[KeyCode::Char('g'), KeyCode::Char('w')],
label: "g w",
}],
Action::BeginSwitchWorkspace,
),
CommandSpec::implemented(
"add-task",
"add a new task",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('n')],
label: "t n",
},
KeySequence {
codes: &[KeyCode::Char('a')],
label: "a",
},
],
Action::BeginAddTask,
),
CommandSpec::implemented(
"add-note",
"add a note to selected task",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('N')],
label: "t N",
},
KeySequence {
codes: &[KeyCode::Char('n')],
label: "n",
},
],
Action::BeginAddNote,
),
CommandSpec::implemented(
"add-project",
"create a new project",
"Projects",
&[KeySequence {
codes: &[KeyCode::Char('p'), KeyCode::Char('a')],
label: "p a",
}],
Action::BeginAddProject,
),
CommandSpec::implemented(
"add-label",
"create a new label",
"Labels",
&[KeySequence {
codes: &[KeyCode::Char('L'), KeyCode::Char('n')],
label: "L n",
}],
Action::BeginAddLabel,
),
CommandSpec::implemented(
"rename-project",
"rename a project and display prefix",
"Projects",
&[KeySequence {
codes: &[KeyCode::Char('p'), KeyCode::Char('r')],
label: "p r",
}],
Action::BeginRenameProject,
),
CommandSpec::implemented(
"delete-project",
"delete a project",
"Projects",
&[KeySequence {
codes: &[KeyCode::Char('p'), KeyCode::Char('D')],
label: "p D",
}],
Action::BeginDeleteProject,
),
CommandSpec::planned(
"add-project-path",
"add a path to a project",
"Projects",
&[KeySequence {
codes: &[KeyCode::Char('p'), KeyCode::Char('n')],
label: "p n",
}],
PROJECT_PATH_FLOW_REASON,
),
CommandSpec::planned(
"remove-project-path",
"remove a path from a project",
"Projects",
&[KeySequence {
codes: &[KeyCode::Char('p'), KeyCode::Char('x')],
label: "p x",
}],
PROJECT_PATH_FLOW_REASON,
),
CommandSpec::implemented(
"edit-title",
"edit selected task title",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('t')],
label: "e t",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('t')],
label: "t e t",
},
],
Action::BeginEditTitle,
),
CommandSpec::implemented(
"edit-description",
"edit selected task description",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('d')],
label: "e d",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('d')],
label: "t e d",
},
],
Action::BeginEditDescription,
),
CommandSpec::implemented(
"edit-project",
"edit selected task project",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('j')],
label: "e j",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('j')],
label: "t e j",
},
],
Action::BeginEditProject,
),
CommandSpec::implemented(
"edit-priority",
"edit selected task priority",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('p')],
label: "e p",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('p')],
label: "t e p",
},
],
Action::BeginEditPriority,
),
CommandSpec::implemented(
"edit-availability",
"edit selected task availability",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('a')],
label: "e a",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('a')],
label: "t e a",
},
],
Action::BeginEditAvailability,
),
CommandSpec::implemented(
"edit-due",
"edit selected task due date",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('u')],
label: "e u",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('u')],
label: "t e u",
},
],
Action::BeginEditDue,
),
CommandSpec::implemented(
"edit-labels",
"edit selected task labels",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('l')],
label: "e l",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('l')],
label: "t e l",
},
],
Action::BeginEditLabels,
),
CommandSpec::implemented(
"copy-ref",
"copy selected task display ref",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('r')],
label: "y r",
}],
Action::CopyShortRef,
),
CommandSpec::implemented(
"copy-id",
"copy selected task id",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('i')],
label: "y i",
}],
Action::CopyDurableRef,
),
CommandSpec::implemented(
"copy-title",
"copy selected task title",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('t')],
label: "y t",
}],
Action::CopyTaskTitle,
),
CommandSpec::implemented(
"copy-description",
"copy selected task description",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('d')],
label: "y d",
}],
Action::CopyTaskDescription,
),
CommandSpec::implemented(
"copy-text",
"copy selected task title and description",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('a')],
label: "y a",
}],
Action::CopyTaskText,
),
CommandSpec::implemented(
"copy-notes",
"copy selected task notes",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('n')],
label: "y n",
}],
Action::CopyTaskNotes,
),
CommandSpec::implemented(
"priority-none",
"set priority to none",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('0')],
label: "t 0",
}],
Action::SetPriority("none"),
),
CommandSpec::implemented(
"priority-low",
"set priority to low",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('l')],
label: "t l",
}],
Action::SetPriority("low"),
),
CommandSpec::implemented(
"priority-medium",
"set priority to medium",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('m')],
label: "t m",
}],
Action::SetPriority("medium"),
),
CommandSpec::implemented(
"priority-high",
"set priority to high",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('h')],
label: "t h",
}],
Action::SetPriority("high"),
),
CommandSpec::implemented(
"priority-urgent",
"set priority to urgent",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('u')],
label: "t u",
}],
Action::SetPriority("urgent"),
),
CommandSpec::implemented(
"toggle-mark",
"toggle mark on selected task",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char(' ')],
label: "Space",
}],
Action::ToggleMarkSelected,
),
CommandSpec::implemented(
"toggle-mark-all",
"toggle marks on visible tasks",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('V')],
label: "t V",
}],
Action::ToggleMarkAllInView,
),
CommandSpec::implemented(
"clear-marks",
"clear task marks",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('C')],
label: "t C",
}],
Action::ClearMarks,
),
CommandSpec::implemented(
"add-dependency",
"add blocker to selected task",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('B')],
label: "t B",
}],
Action::BeginAddDependency,
),
CommandSpec::implemented(
"remove-dependency",
"remove blocker from selected task",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('U')],
label: "t U",
}],
Action::BeginRemoveDependency,
),
CommandSpec::implemented(
"task-epic-toggle",
"toggle epic parent expand/collapse",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('c'), KeyCode::Char('t')],
label: "t c t",
}],
Action::ToggleEpicExpanded,
),
CommandSpec::implemented(
"task-child-detach",
"detach selected child from its epic parent",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('c'), KeyCode::Char('d')],
label: "t c d",
}],
Action::DetachEpicChild,
),
CommandSpec::implemented(
"task-child-promote",
"promote selected child by removing its epic parent edge",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('c'), KeyCode::Char('p')],
label: "t c p",
}],
Action::PromoteEpicChild,
),
CommandSpec::implemented(
"filter-label",
"filter by label",
"Filters",
&[KeySequence {
codes: &[KeyCode::Char('f'), KeyCode::Char('l')],
label: "f l",
}],
Action::BeginFilterLabel,
),
CommandSpec::implemented(
"filter-priority",
"filter by priority",
"Filters",
&[KeySequence {
codes: &[KeyCode::Char('f'), KeyCode::Char('p')],
label: "f p",
}],
Action::BeginFilterPriority,
),
CommandSpec::implemented(
"filter-clear",
"clear all filters",
"Filters",
&[KeySequence {
codes: &[KeyCode::Char('f'), KeyCode::Char('c')],
label: "f c",
}],
Action::ClearFilters,
),
CommandSpec::implemented(
"filter-deleted",
"cycle deleted task visibility",
"Filters",
&[KeySequence {
codes: &[KeyCode::Char('f'), KeyCode::Char('x')],
label: "f x",
}],
Action::ToggleDeletedFilter,
),
CommandSpec::implemented(
"order-due",
"sort by due date",
"Order",
&[KeySequence {
codes: &[KeyCode::Char('o'), KeyCode::Char('d')],
label: "o d",
}],
Action::SetOrder(crate::tui::store::TaskOrder::DueOn),
),
CommandSpec::implemented(
"order-created",
"sort by created date",
"Order",
&[KeySequence {
codes: &[KeyCode::Char('o'), KeyCode::Char('c')],
label: "o c",
}],
Action::SetOrder(TaskOrder::Created),
),
CommandSpec::implemented(
"order-updated",
"sort by updated date",
"Order",
&[KeySequence {
codes: &[KeyCode::Char('o'), KeyCode::Char('u')],
label: "o u",
}],
Action::SetOrder(TaskOrder::Updated),
),
CommandSpec::implemented(
"order-priority",
"sort by priority",
"Order",
&[KeySequence {
codes: &[KeyCode::Char('o'), KeyCode::Char('p')],
label: "o p",
}],
Action::SetOrder(TaskOrder::Priority),
),
CommandSpec::implemented(
"order-project",
"sort by project",
"Order",
&[KeySequence {
codes: &[KeyCode::Char('o'), KeyCode::Char('j')],
label: "o j",
}],
Action::SetOrder(TaskOrder::Project),
),
CommandSpec::implemented(
"order-title",
"sort by title",
"Order",
&[KeySequence {
codes: &[KeyCode::Char('o'), KeyCode::Char('t')],
label: "o t",
}],
Action::SetOrder(TaskOrder::Title),
),
CommandSpec::implemented(
"order-reverse",
"reverse sort direction",
"Order",
&[KeySequence {
codes: &[KeyCode::Char('o'), KeyCode::Char('r')],
label: "o r",
}],
Action::ReverseSort,
),
CommandSpec::implemented(
"conflict-list",
"list or filter conflicts",
"Conflicts",
&[KeySequence {
codes: &[KeyCode::Char('c'), KeyCode::Char('l')],
label: "c l",
}],
Action::BeginConflictList,
),
CommandSpec::implemented(
"conflict-show",
"show conflict details",
"Conflicts",
&[KeySequence {
codes: &[KeyCode::Char('c'), KeyCode::Char('s')],
label: "c s",
}],
Action::ShowConflictDetails,
),
CommandSpec::implemented(
"conflict-next",
"jump to next conflict",
"Conflicts",
&[KeySequence {
codes: &[KeyCode::Char('c'), KeyCode::Char('n')],
label: "c n",
}],
Action::NextConflict,
),
CommandSpec::implemented(
"conflict-prev",
"jump to previous conflict",
"Conflicts",
&[KeySequence {
codes: &[KeyCode::Char('c'), KeyCode::Char('p')],
label: "c p",
}],
Action::PreviousConflict,
),
CommandSpec::implemented(
"conflict-use-local",
"resolve with local value",
"Conflicts",
&[KeySequence {
codes: &[KeyCode::Char('c'), KeyCode::Char('a')],
label: "c a",
}],
Action::AcceptConflictLocal,
),
CommandSpec::implemented(
"conflict-use-remote",
"resolve with remote value",
"Conflicts",
&[KeySequence {
codes: &[KeyCode::Char('c'), KeyCode::Char('r')],
label: "c r",
}],
Action::AcceptConflictRemote,
),
CommandSpec::implemented(
"conflict-manual-merge",
"resolve with manual value",
"Conflicts",
&[KeySequence {
codes: &[KeyCode::Char('c'), KeyCode::Char('m')],
label: "c m",
}],
Action::BeginManualConflictMerge,
),
CommandSpec::implemented(
"config-status",
"show sync and daemon status",
"Config",
&[KeySequence {
codes: &[KeyCode::Char('C'), KeyCode::Char('s')],
label: "C s",
}],
Action::ShowConfigStatus,
),
CommandSpec::implemented(
"config-show",
"show configuration",
"Config",
&[KeySequence {
codes: &[KeyCode::Char('C'), KeyCode::Char('c')],
label: "C c",
}],
Action::ShowConfigInfo,
),
CommandSpec::implemented(
"config-paths",
"show data paths",
"Config",
&[KeySequence {
codes: &[KeyCode::Char('C'), KeyCode::Char('d')],
label: "C d",
}],
Action::ShowConfigPaths,
),
CommandSpec::implemented(
"database-stats",
"show database statistics",
"Config",
&[KeySequence {
codes: &[KeyCode::Char('C'), KeyCode::Char('D')],
label: "C D",
}],
Action::ShowDatabaseStats,
),
CommandSpec::implemented(
"config-init",
"initialize configuration",
"Config",
&[KeySequence {
codes: &[KeyCode::Char('C'), KeyCode::Char('i')],
label: "C i",
}],
Action::BeginConfigInit,
),
];
pub(crate) const DETAIL_COMMANDS: &[CommandSpec] = &[
CommandSpec::implemented(
"detail-back",
"return to the task list",
"General",
&[KeySequence {
codes: &[KeyCode::Char('g'), KeyCode::Char('[')],
label: "g [",
}],
Action::GoBack,
),
CommandSpec::implemented(
"detail-edit-title",
"edit selected task title",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('t')],
label: "t e t",
},
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('t')],
label: "e t",
},
],
Action::BeginEditTitle,
),
CommandSpec::implemented(
"detail-edit-description",
"edit selected task description",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('d')],
label: "t e d",
},
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('d')],
label: "e d",
},
],
Action::BeginEditDescription,
),
CommandSpec::implemented(
"detail-edit-project",
"edit selected task project",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('j')],
label: "e j",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('j')],
label: "t e j",
},
],
Action::BeginEditProject,
),
CommandSpec::implemented(
"detail-edit-priority",
"edit selected task priority",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('p')],
label: "e p",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('p')],
label: "t e p",
},
],
Action::BeginEditPriority,
),
CommandSpec::implemented(
"detail-edit-availability",
"edit selected task availability",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('a')],
label: "e a",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('a')],
label: "t e a",
},
],
Action::BeginEditAvailability,
),
CommandSpec::implemented(
"detail-edit-due",
"edit selected task due date",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('u')],
label: "e u",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('u')],
label: "t e u",
},
],
Action::BeginEditDue,
),
CommandSpec::implemented(
"detail-edit-labels",
"edit selected task labels",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('e'), KeyCode::Char('l')],
label: "t e l",
},
KeySequence {
codes: &[KeyCode::Char('e'), KeyCode::Char('l')],
label: "e l",
},
],
Action::BeginEditLabels,
),
CommandSpec::implemented(
"detail-add-note",
"add a note to selected task",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('n')],
label: "n",
},
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('N')],
label: "t N",
},
],
Action::BeginAddNote,
),
CommandSpec::implemented(
"detail-status-picker",
"open task status picker",
"Tasks",
&[
KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('s')],
label: "t s",
},
KeySequence {
codes: &[KeyCode::Char('s')],
label: "s",
},
],
Action::BeginStatusPicker,
),
CommandSpec::implemented(
"detail-status-done",
"set status to done",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('d')],
label: "t d",
}],
Action::SetStatus("done"),
),
CommandSpec::implemented(
"detail-delete",
"confirm deleting selected task",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('D')],
label: "t D",
}],
Action::Delete,
),
CommandSpec::implemented(
"detail-copy-ref",
"copy selected task display ref",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('r')],
label: "y r",
}],
Action::CopyShortRef,
),
CommandSpec::implemented(
"detail-copy-id",
"copy selected task id",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('i')],
label: "y i",
}],
Action::CopyDurableRef,
),
CommandSpec::implemented(
"detail-copy-title",
"copy task title",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('t')],
label: "y t",
}],
Action::CopyTaskTitle,
),
CommandSpec::implemented(
"detail-copy-description",
"copy task description",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('d')],
label: "y d",
}],
Action::CopyTaskDescription,
),
CommandSpec::implemented(
"detail-copy-text",
"copy task title and description",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('a')],
label: "y a",
}],
Action::CopyTaskText,
),
CommandSpec::implemented(
"detail-copy-notes",
"copy task notes",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('y'), KeyCode::Char('n')],
label: "y n",
}],
Action::CopyTaskNotes,
),
CommandSpec::implemented(
"detail-undo",
"undo last TUI mutation",
"General",
&[KeySequence {
codes: &[KeyCode::Char('u')],
label: "u",
}],
Action::Undo,
),
CommandSpec::implemented(
"detail-add-dependency",
"add blocker to selected task",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('B')],
label: "t B",
}],
Action::BeginAddDependency,
),
CommandSpec::implemented(
"detail-remove-dependency",
"remove blocker from selected task",
"Tasks",
&[KeySequence {
codes: &[KeyCode::Char('t'), KeyCode::Char('U')],
label: "t U",
}],
Action::BeginRemoveDependency,
),
];
#[cfg_attr(not(test), allow(dead_code))]
#[derive(Debug, Clone, Copy)]
pub(crate) struct CommandDomain {
pub(crate) section: &'static str,
}
#[cfg_attr(not(test), allow(dead_code))]
impl CommandDomain {
pub(crate) fn commands(self) -> Vec<&'static CommandSpec> {
COMMANDS
.iter()
.filter(|command| command.section == self.section)
.collect()
}
}
#[cfg_attr(not(test), allow(dead_code))]
pub(crate) const COMMAND_DOMAINS: &[CommandDomain] = &[
CommandDomain { section: "General" },
CommandDomain {
section: "Navigation",
},
CommandDomain { section: "Tasks" },
CommandDomain {
section: "Projects",
},
CommandDomain { section: "Labels" },
CommandDomain { section: "Views" },
CommandDomain { section: "Filters" },
CommandDomain { section: "Order" },
CommandDomain {
section: "Conflicts",
},
CommandDomain { section: "Config" },
];