mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
Generate keymap descriptors and binding accessors from one catalog (#54151)
## Why The `/keymap` action catalog and root-config binding lookup duplicated the same action inventory, requiring both to be maintained together. ## What changed Use `define_keymap_actions!` to generate `KEYMAP_ACTIONS` and `binding_slot` from a single declaration grouped by context. Preserve the existing action order, descriptions, feature gates, and binding mappings. GitOrigin-RevId: 182e937d9642a8b5a4aa787691da793712f29010
This commit is contained in:
committed by
copyberry
parent
4ca84a1069
commit
ac9db7d8b5
@@ -1,13 +1,13 @@
|
||||
//! Catalog and accessors for keymap actions shown by `/keymap`.
|
||||
//!
|
||||
//! The descriptor table is the single UI-facing inventory of configurable
|
||||
//! actions. Each descriptor ties together the config path segment, user-facing
|
||||
//! context label, stable action name, and short description used by the picker
|
||||
//! and action menu.
|
||||
//! The catalog declaration generates both the UI-facing descriptors and the
|
||||
//! matching root-config accessors. Each entry ties together the config path,
|
||||
//! user-facing context label, stable action name, short description, and
|
||||
//! optional feature gate used by the picker and action menu.
|
||||
//!
|
||||
//! Root-config accessors mirror the descriptor table, while runtime lookups
|
||||
//! reuse the inventory owned by [`crate::keymap`]. A catalog action must remain
|
||||
//! both writable in `TuiKeymap` and readable from the shared runtime inventory.
|
||||
//! Runtime lookups reuse the inventory owned by [`crate::keymap`]. A catalog
|
||||
//! action must remain both writable in `TuiKeymap` and readable from the shared
|
||||
//! runtime inventory.
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
@@ -32,37 +32,6 @@ pub(super) struct KeymapActionDescriptor {
|
||||
required_feature: Option<KeymapActionFeature>,
|
||||
}
|
||||
|
||||
const fn action(
|
||||
context: &'static str,
|
||||
context_label: &'static str,
|
||||
action: &'static str,
|
||||
description: &'static str,
|
||||
) -> KeymapActionDescriptor {
|
||||
KeymapActionDescriptor {
|
||||
context,
|
||||
context_label,
|
||||
action,
|
||||
description,
|
||||
required_feature: None,
|
||||
}
|
||||
}
|
||||
|
||||
const fn gated_action(
|
||||
context: &'static str,
|
||||
context_label: &'static str,
|
||||
action: &'static str,
|
||||
description: &'static str,
|
||||
required_feature: KeymapActionFeature,
|
||||
) -> KeymapActionDescriptor {
|
||||
KeymapActionDescriptor {
|
||||
context,
|
||||
context_label,
|
||||
action,
|
||||
description,
|
||||
required_feature: Some(required_feature),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
enum KeymapActionFeature {
|
||||
FastMode,
|
||||
@@ -82,164 +51,245 @@ impl KeymapActionDescriptor {
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub(super) const KEYMAP_ACTIONS: &[KeymapActionDescriptor] = &[
|
||||
action("global", "Global", "open_agents", "Open the shared agent-session overview."),
|
||||
action("global", "Global", "open_transcript", "Open the transcript overlay."),
|
||||
action("global", "Global", "find_transcript", "Find text in the full transcript."),
|
||||
// Keep the new warnings action out of shared-config writes until older strict readers
|
||||
// accept it. Its built-in shortcuts remain available.
|
||||
action("global", "Global", "focus_activity", "Focus transcript activity groups to expand or collapse their details."),
|
||||
action("global", "Global", "open_external_editor", "Open the current draft in an external editor."),
|
||||
action("global", "Global", "copy", "Copy the last agent response to the clipboard."),
|
||||
action("global", "Global", "clear_terminal", "Clear the terminal UI."),
|
||||
action("global", "Global", "toggle_vim_mode", "Turn Vim composer mode on or off."),
|
||||
gated_action("global", "Global", "toggle_fast_mode", "Turn Fast mode on or off.", KeymapActionFeature::FastMode),
|
||||
action("global", "Global", "toggle_raw_output", "Toggle raw scrollback mode."),
|
||||
action("global", "Global", "toggle_side_conversation", "Switch between a side conversation and its parent."),
|
||||
action("global", "Global", "leader", "Set the prefix used by shared leader shortcuts."),
|
||||
action("chat", "Chat", "interrupt_turn", "Interrupt the active turn."),
|
||||
action("chat", "Chat", "decrease_reasoning_effort", "Decrease reasoning effort."),
|
||||
action("chat", "Chat", "increase_reasoning_effort", "Increase reasoning effort."),
|
||||
action("chat", "Chat", "previous_permission_mode", "Switch to the previous available permission mode."),
|
||||
action("chat", "Chat", "next_permission_mode", "Switch to the next available permission mode."),
|
||||
action("chat", "Chat", "edit_queued_message", "Move forward through questions, then edit the last queued message."),
|
||||
action("chat", "Chat", "prompt_stack_back", "Move back through questions toward the composer."),
|
||||
action("chat", "Chat", "skip_question", "Skip the focused question."),
|
||||
action("chat", "Chat", "toggle_voice", "Start or stop a voice conversation."),
|
||||
action("chat", "Chat", "toggle_voice_mute", "Mute or unmute the voice microphone."),
|
||||
action("composer", "Composer", "submit", "Submit the current composer draft."),
|
||||
action("composer", "Composer", "queue", "Queue the draft while a task is running."),
|
||||
action("composer", "Composer", "toggle_shortcuts", "Show or hide the composer shortcut overlay."),
|
||||
action("composer", "Composer", "history_search_previous", "Open history search or move to the previous match."),
|
||||
action("composer", "Composer", "history_search_next", "Move to the next history search match."),
|
||||
action("editor", "Editor", "insert_newline", "Insert a newline in the editor."),
|
||||
action("editor", "Editor", "move_left", "Move the cursor left."),
|
||||
action("editor", "Editor", "move_right", "Move the cursor right."),
|
||||
action("editor", "Editor", "move_up", "Move the cursor up."),
|
||||
action("editor", "Editor", "move_down", "Move the cursor down."),
|
||||
action("editor", "Editor", "move_word_left", "Move to the beginning of the previous word."),
|
||||
action("editor", "Editor", "move_word_right", "Move to the end of the next word."),
|
||||
action("editor", "Editor", "move_line_start", "Move to the beginning of the line."),
|
||||
action("editor", "Editor", "move_line_end", "Move to the end of the line."),
|
||||
action("editor", "Editor", "delete_backward", "Delete one grapheme to the left."),
|
||||
action("editor", "Editor", "delete_forward", "Delete one grapheme to the right."),
|
||||
action("editor", "Editor", "delete_backward_word", "Delete the previous word."),
|
||||
action("editor", "Editor", "delete_forward_word", "Delete the next word."),
|
||||
action("editor", "Editor", "kill_line_start", "Delete from cursor to line start."),
|
||||
action("editor", "Editor", "kill_whole_line", "Delete the current line."),
|
||||
action("editor", "Editor", "kill_line_end", "Delete from cursor to line end."),
|
||||
action("editor", "Editor", "yank", "Paste the kill buffer."),
|
||||
action("vim_normal", "Vim normal", "enter_insert", "Enter insert mode at the cursor."),
|
||||
action("vim_normal", "Vim normal", "append_after_cursor", "Enter insert mode after the cursor."),
|
||||
action("vim_normal", "Vim normal", "append_line_end", "Enter insert mode at end of line."),
|
||||
action("vim_normal", "Vim normal", "insert_line_start", "Enter insert mode at the first non-blank character."),
|
||||
action("vim_normal", "Vim normal", "open_line_below", "Open a new line below and enter insert mode."),
|
||||
action("vim_normal", "Vim normal", "open_line_above", "Open a new line above and enter insert mode."),
|
||||
action("vim_normal", "Vim normal", "enter_replace_mode", "Enter replace mode and overwrite characters."),
|
||||
action("vim_normal", "Vim normal", "move_left", "Move left in Vim normal mode."),
|
||||
action("vim_normal", "Vim normal", "move_right", "Move right in Vim normal mode."),
|
||||
action("vim_normal", "Vim normal", "move_up", "Move up or recall older history in Vim normal mode."),
|
||||
action("vim_normal", "Vim normal", "move_down", "Move down or recall newer history in Vim normal mode."),
|
||||
action("vim_normal", "Vim normal", "move_word_forward", "Move to the start of the next word."),
|
||||
action("vim_normal", "Vim normal", "move_word_backward", "Move to the start of the previous word."),
|
||||
action("vim_normal", "Vim normal", "move_word_end", "Move to the end of the current or next word."),
|
||||
action("vim_normal", "Vim normal", "move_line_start", "Move to the start of the line."),
|
||||
action("vim_normal", "Vim normal", "move_line_end", "Move to the end of the line."),
|
||||
action("vim_normal", "Vim normal", "find_forward", "Find the next character on the current line."),
|
||||
action("vim_normal", "Vim normal", "find_backward", "Find the previous character on the current line."),
|
||||
action("vim_normal", "Vim normal", "till_forward", "Stop before the next character on the current line."),
|
||||
action("vim_normal", "Vim normal", "till_backward", "Stop after the previous character on the current line."),
|
||||
action("vim_normal", "Vim normal", "jump_top", "Jump to the first buffer line."),
|
||||
action("vim_normal", "Vim normal", "jump_bottom", "Jump to the last buffer line."),
|
||||
action("vim_normal", "Vim normal", "delete_char", "Delete the character under the cursor."),
|
||||
action("vim_normal", "Vim normal", "replace_char", "Replace the character under the cursor."),
|
||||
action("vim_normal", "Vim normal", "repeat_last_change", "Repeat the last complete edit."),
|
||||
action("vim_normal", "Vim normal", "substitute_char", "Delete the character under the cursor and enter insert mode."),
|
||||
action("vim_normal", "Vim normal", "delete_to_line_end", "Delete from cursor to end of line."),
|
||||
action("vim_normal", "Vim normal", "change_to_line_end", "Change from cursor to end of line and enter insert mode."),
|
||||
action("vim_normal", "Vim normal", "yank_line", "Yank the entire line."),
|
||||
action("vim_normal", "Vim normal", "paste_after", "Paste after the cursor."),
|
||||
action("vim_normal", "Vim normal", "start_delete_operator", "Begin a delete operator and wait for a motion."),
|
||||
action("vim_normal", "Vim normal", "start_yank_operator", "Begin a yank operator and wait for a motion."),
|
||||
action("vim_normal", "Vim normal", "start_change_operator", "Begin a change operator and wait for a motion or text object."),
|
||||
action("vim_normal", "Vim normal", "undo", "Undo the last complete edit."),
|
||||
action("vim_normal", "Vim normal", "redo", "Redo the last undone edit."),
|
||||
action("vim_normal", "Vim normal", "cancel_operator", "Cancel a pending Vim operator."),
|
||||
action("vim_search", "Vim search", "forward", "Search forward in the active buffer."),
|
||||
action("vim_search", "Vim search", "backward", "Search backward in the active buffer."),
|
||||
action("vim_search", "Vim search", "next", "Repeat the accepted search."),
|
||||
action("vim_search", "Vim search", "previous", "Repeat the search in the opposite direction."),
|
||||
action("vim_operator", "Vim operator", "delete_line", "Repeat delete operator to delete the whole line."),
|
||||
action("vim_operator", "Vim operator", "yank_line", "Repeat yank operator to yank the whole line."),
|
||||
action("vim_operator", "Vim operator", "motion_left", "Operator motion left."),
|
||||
action("vim_operator", "Vim operator", "motion_right", "Operator motion right."),
|
||||
action("vim_operator", "Vim operator", "motion_up", "Operator motion up."),
|
||||
action("vim_operator", "Vim operator", "motion_down", "Operator motion down."),
|
||||
action("vim_operator", "Vim operator", "motion_word_forward", "Operator motion to start of next word."),
|
||||
action("vim_operator", "Vim operator", "motion_word_backward", "Operator motion to start of previous word."),
|
||||
action("vim_operator", "Vim operator", "motion_word_end", "Operator motion to end of word."),
|
||||
action("vim_operator", "Vim operator", "motion_line_start", "Operator motion to line start."),
|
||||
action("vim_operator", "Vim operator", "motion_line_end", "Operator motion to line end."),
|
||||
action("vim_operator", "Vim operator", "motion_find_forward", "Operator motion to the next character on the current line."),
|
||||
action("vim_operator", "Vim operator", "motion_find_backward", "Operator motion to the previous character on the current line."),
|
||||
action("vim_operator", "Vim operator", "motion_till_forward", "Stop before the next character on the current line."),
|
||||
action("vim_operator", "Vim operator", "motion_till_backward", "Stop after the previous character on the current line."),
|
||||
action("vim_operator", "Vim operator", "motion_jump_top", "Operator motion to the first buffer line."),
|
||||
action("vim_operator", "Vim operator", "motion_jump_bottom", "Operator motion to the last buffer line."),
|
||||
action("vim_operator", "Vim operator", "select_inner_text_object", "Select an inner text object."),
|
||||
action("vim_operator", "Vim operator", "select_around_text_object", "Select an around text object."),
|
||||
action("vim_operator", "Vim operator", "cancel", "Cancel the pending operator."),
|
||||
action("vim_text_object", "Vim text object", "word", "Target the current word."),
|
||||
action("vim_text_object", "Vim text object", "big_word", "Target the current WORD."),
|
||||
action("vim_text_object", "Vim text object", "parentheses", "Target enclosing parentheses."),
|
||||
action("vim_text_object", "Vim text object", "brackets", "Target enclosing brackets."),
|
||||
action("vim_text_object", "Vim text object", "braces", "Target enclosing braces."),
|
||||
action("vim_text_object", "Vim text object", "double_quote", "Target enclosing double quotes."),
|
||||
action("vim_text_object", "Vim text object", "single_quote", "Target enclosing single quotes."),
|
||||
action("vim_text_object", "Vim text object", "backtick", "Target enclosing backticks."),
|
||||
action("vim_text_object", "Vim text object", "cancel", "Cancel the pending text object."),
|
||||
action("pager", "Pager", "scroll_up", "Scroll up by one row."),
|
||||
action("pager", "Pager", "scroll_down", "Scroll down by one row."),
|
||||
action("pager", "Pager", "page_up", "Scroll up by one page."),
|
||||
action("pager", "Pager", "page_down", "Scroll down by one page."),
|
||||
action("pager", "Pager", "half_page_up", "Scroll up by half a page."),
|
||||
action("pager", "Pager", "half_page_down", "Scroll down by half a page."),
|
||||
action("pager", "Pager", "jump_top", "Jump to the beginning."),
|
||||
action("pager", "Pager", "jump_bottom", "Jump to the end."),
|
||||
action("pager", "Pager", "close", "Close the pager overlay."),
|
||||
action("pager", "Pager", "close_transcript", "Close the transcript overlay."),
|
||||
action("pager", "Pager", "find", "Find text in a transcript pager."),
|
||||
action("list", "List", "move_up", "Move list selection up."),
|
||||
action("list", "List", "move_down", "Move list selection down."),
|
||||
action("list", "List", "move_left", "Move horizontally left in list pickers."),
|
||||
action("list", "List", "move_right", "Move horizontally right in list pickers."),
|
||||
action("list", "List", "page_up", "Move list selection up by one page."),
|
||||
action("list", "List", "page_down", "Move list selection down by one page."),
|
||||
action("list", "List", "jump_top", "Jump to the first list item."),
|
||||
action("list", "List", "jump_bottom", "Jump to the last list item."),
|
||||
action("list", "List", "accept", "Accept the current list selection."),
|
||||
action("list", "List", "cancel", "Cancel and close selection views."),
|
||||
action("agents", "Agents", "resume", "Open the session resume picker."),
|
||||
action("agents", "Agents", "search", "Search the available agent tasks."),
|
||||
action("agents", "Agents", "new_task", "Open a new session in the selected checkout."),
|
||||
action("agents", "Agents", "new_worktree", "Open a new session in a worktree from the project default branch."),
|
||||
action("agents", "Agents", "fork", "Fork the selected conversation and open the new session."),
|
||||
action("agents", "Agents", "rename", "Rename the selected task."),
|
||||
action("agents", "Agents", "stop", "Stop the selected running task."),
|
||||
action("agents", "Agents", "archive", "Archive the selected task and its child agents."),
|
||||
action("agents", "Agents", "delete", "Permanently delete the selected task and its child agents."),
|
||||
action("agents", "Agents", "hide", "Hide the selected task until explicitly resumed."),
|
||||
action("agents", "Agents", "toggle_grouping", "Cycle task grouping by project, status, or model."),
|
||||
action("approval", "Approval", "open_fullscreen", "Open approval details fullscreen."),
|
||||
action("approval", "Approval", "open_thread", "Open the approval source thread when available."),
|
||||
action("approval", "Approval", "approve", "Approve the primary option."),
|
||||
action("approval", "Approval", "approve_for_session", "Approve for the session when available."),
|
||||
action("approval", "Approval", "approve_for_prefix", "Approve with an exec-policy prefix when available."),
|
||||
action("approval", "Approval", "deny", "Choose the explicit deny option when available."),
|
||||
action("approval", "Approval", "decline", "Decline and provide corrective guidance."),
|
||||
action("approval", "Approval", "cancel", "Cancel an elicitation request."),
|
||||
];
|
||||
macro_rules! required_feature {
|
||||
() => {
|
||||
None
|
||||
};
|
||||
($feature:ident) => {
|
||||
Some(KeymapActionFeature::$feature)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! define_keymap_actions {
|
||||
(
|
||||
$(
|
||||
$context:ident $context_label:literal {
|
||||
$(
|
||||
$action:ident $( [$required_feature:ident] )? => $description:literal,
|
||||
)*
|
||||
}
|
||||
)*
|
||||
) => {
|
||||
pub(super) const KEYMAP_ACTIONS: &[KeymapActionDescriptor] = &[
|
||||
$(
|
||||
$(
|
||||
KeymapActionDescriptor {
|
||||
context: stringify!($context),
|
||||
context_label: $context_label,
|
||||
action: stringify!($action),
|
||||
description: $description,
|
||||
required_feature: required_feature!($($required_feature)?),
|
||||
},
|
||||
)*
|
||||
)*
|
||||
];
|
||||
|
||||
/// Return the mutable root-config binding slot for one catalog action.
|
||||
///
|
||||
/// The returned `Option<KeybindingsSpec>` distinguishes three states that the
|
||||
/// editor must preserve: absent means use fallback/default resolution, `Some`
|
||||
/// with one or more keys is a custom binding, and `Some(Many([]))` is an
|
||||
/// explicit unbind.
|
||||
pub(super) fn binding_slot<'a>(
|
||||
keymap: &'a mut TuiKeymap,
|
||||
context: &str,
|
||||
action: &str,
|
||||
) -> Option<&'a mut Option<KeybindingsSpec>> {
|
||||
match (context, action) {
|
||||
$(
|
||||
$(
|
||||
(stringify!($context), stringify!($action)) => {
|
||||
Some(&mut keymap.$context.$action)
|
||||
}
|
||||
)*
|
||||
)*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
define_keymap_actions! {
|
||||
global "Global" {
|
||||
open_agents => "Open the shared agent-session overview.",
|
||||
open_transcript => "Open the transcript overlay.",
|
||||
find_transcript => "Find text in the full transcript.",
|
||||
// Keep the new warnings action out of shared-config writes until older strict readers
|
||||
// accept it. Its built-in shortcuts remain available.
|
||||
focus_activity => "Focus transcript activity groups to expand or collapse their details.",
|
||||
open_external_editor => "Open the current draft in an external editor.",
|
||||
copy => "Copy the last agent response to the clipboard.",
|
||||
clear_terminal => "Clear the terminal UI.",
|
||||
toggle_vim_mode => "Turn Vim composer mode on or off.",
|
||||
toggle_fast_mode [FastMode] => "Turn Fast mode on or off.",
|
||||
toggle_raw_output => "Toggle raw scrollback mode.",
|
||||
toggle_side_conversation => "Switch between a side conversation and its parent.",
|
||||
leader => "Set the prefix used by shared leader shortcuts.",
|
||||
}
|
||||
chat "Chat" {
|
||||
interrupt_turn => "Interrupt the active turn.",
|
||||
decrease_reasoning_effort => "Decrease reasoning effort.",
|
||||
increase_reasoning_effort => "Increase reasoning effort.",
|
||||
previous_permission_mode => "Switch to the previous available permission mode.",
|
||||
next_permission_mode => "Switch to the next available permission mode.",
|
||||
edit_queued_message => "Move forward through questions, then edit the last queued message.",
|
||||
prompt_stack_back => "Move back through questions toward the composer.",
|
||||
skip_question => "Skip the focused question.",
|
||||
toggle_voice => "Start or stop a voice conversation.",
|
||||
toggle_voice_mute => "Mute or unmute the voice microphone.",
|
||||
}
|
||||
composer "Composer" {
|
||||
submit => "Submit the current composer draft.",
|
||||
queue => "Queue the draft while a task is running.",
|
||||
toggle_shortcuts => "Show or hide the composer shortcut overlay.",
|
||||
history_search_previous => "Open history search or move to the previous match.",
|
||||
history_search_next => "Move to the next history search match.",
|
||||
}
|
||||
editor "Editor" {
|
||||
insert_newline => "Insert a newline in the editor.",
|
||||
move_left => "Move the cursor left.",
|
||||
move_right => "Move the cursor right.",
|
||||
move_up => "Move the cursor up.",
|
||||
move_down => "Move the cursor down.",
|
||||
move_word_left => "Move to the beginning of the previous word.",
|
||||
move_word_right => "Move to the end of the next word.",
|
||||
move_line_start => "Move to the beginning of the line.",
|
||||
move_line_end => "Move to the end of the line.",
|
||||
delete_backward => "Delete one grapheme to the left.",
|
||||
delete_forward => "Delete one grapheme to the right.",
|
||||
delete_backward_word => "Delete the previous word.",
|
||||
delete_forward_word => "Delete the next word.",
|
||||
kill_line_start => "Delete from cursor to line start.",
|
||||
kill_whole_line => "Delete the current line.",
|
||||
kill_line_end => "Delete from cursor to line end.",
|
||||
yank => "Paste the kill buffer.",
|
||||
}
|
||||
vim_normal "Vim normal" {
|
||||
enter_insert => "Enter insert mode at the cursor.",
|
||||
append_after_cursor => "Enter insert mode after the cursor.",
|
||||
append_line_end => "Enter insert mode at end of line.",
|
||||
insert_line_start => "Enter insert mode at the first non-blank character.",
|
||||
open_line_below => "Open a new line below and enter insert mode.",
|
||||
open_line_above => "Open a new line above and enter insert mode.",
|
||||
enter_replace_mode => "Enter replace mode and overwrite characters.",
|
||||
move_left => "Move left in Vim normal mode.",
|
||||
move_right => "Move right in Vim normal mode.",
|
||||
move_up => "Move up or recall older history in Vim normal mode.",
|
||||
move_down => "Move down or recall newer history in Vim normal mode.",
|
||||
move_word_forward => "Move to the start of the next word.",
|
||||
move_word_backward => "Move to the start of the previous word.",
|
||||
move_word_end => "Move to the end of the current or next word.",
|
||||
move_line_start => "Move to the start of the line.",
|
||||
move_line_end => "Move to the end of the line.",
|
||||
find_forward => "Find the next character on the current line.",
|
||||
find_backward => "Find the previous character on the current line.",
|
||||
till_forward => "Stop before the next character on the current line.",
|
||||
till_backward => "Stop after the previous character on the current line.",
|
||||
jump_top => "Jump to the first buffer line.",
|
||||
jump_bottom => "Jump to the last buffer line.",
|
||||
delete_char => "Delete the character under the cursor.",
|
||||
replace_char => "Replace the character under the cursor.",
|
||||
repeat_last_change => "Repeat the last complete edit.",
|
||||
substitute_char => "Delete the character under the cursor and enter insert mode.",
|
||||
delete_to_line_end => "Delete from cursor to end of line.",
|
||||
change_to_line_end => "Change from cursor to end of line and enter insert mode.",
|
||||
yank_line => "Yank the entire line.",
|
||||
paste_after => "Paste after the cursor.",
|
||||
start_delete_operator => "Begin a delete operator and wait for a motion.",
|
||||
start_yank_operator => "Begin a yank operator and wait for a motion.",
|
||||
start_change_operator => "Begin a change operator and wait for a motion or text object.",
|
||||
undo => "Undo the last complete edit.",
|
||||
redo => "Redo the last undone edit.",
|
||||
cancel_operator => "Cancel a pending Vim operator.",
|
||||
}
|
||||
vim_search "Vim search" {
|
||||
forward => "Search forward in the active buffer.",
|
||||
backward => "Search backward in the active buffer.",
|
||||
next => "Repeat the accepted search.",
|
||||
previous => "Repeat the search in the opposite direction.",
|
||||
}
|
||||
vim_operator "Vim operator" {
|
||||
delete_line => "Repeat delete operator to delete the whole line.",
|
||||
yank_line => "Repeat yank operator to yank the whole line.",
|
||||
motion_left => "Operator motion left.",
|
||||
motion_right => "Operator motion right.",
|
||||
motion_up => "Operator motion up.",
|
||||
motion_down => "Operator motion down.",
|
||||
motion_word_forward => "Operator motion to start of next word.",
|
||||
motion_word_backward => "Operator motion to start of previous word.",
|
||||
motion_word_end => "Operator motion to end of word.",
|
||||
motion_line_start => "Operator motion to line start.",
|
||||
motion_line_end => "Operator motion to line end.",
|
||||
motion_find_forward => "Operator motion to the next character on the current line.",
|
||||
motion_find_backward => "Operator motion to the previous character on the current line.",
|
||||
motion_till_forward => "Stop before the next character on the current line.",
|
||||
motion_till_backward => "Stop after the previous character on the current line.",
|
||||
motion_jump_top => "Operator motion to the first buffer line.",
|
||||
motion_jump_bottom => "Operator motion to the last buffer line.",
|
||||
select_inner_text_object => "Select an inner text object.",
|
||||
select_around_text_object => "Select an around text object.",
|
||||
cancel => "Cancel the pending operator.",
|
||||
}
|
||||
vim_text_object "Vim text object" {
|
||||
word => "Target the current word.",
|
||||
big_word => "Target the current WORD.",
|
||||
parentheses => "Target enclosing parentheses.",
|
||||
brackets => "Target enclosing brackets.",
|
||||
braces => "Target enclosing braces.",
|
||||
double_quote => "Target enclosing double quotes.",
|
||||
single_quote => "Target enclosing single quotes.",
|
||||
backtick => "Target enclosing backticks.",
|
||||
cancel => "Cancel the pending text object.",
|
||||
}
|
||||
pager "Pager" {
|
||||
scroll_up => "Scroll up by one row.",
|
||||
scroll_down => "Scroll down by one row.",
|
||||
page_up => "Scroll up by one page.",
|
||||
page_down => "Scroll down by one page.",
|
||||
half_page_up => "Scroll up by half a page.",
|
||||
half_page_down => "Scroll down by half a page.",
|
||||
jump_top => "Jump to the beginning.",
|
||||
jump_bottom => "Jump to the end.",
|
||||
close => "Close the pager overlay.",
|
||||
close_transcript => "Close the transcript overlay.",
|
||||
find => "Find text in a transcript pager.",
|
||||
}
|
||||
list "List" {
|
||||
move_up => "Move list selection up.",
|
||||
move_down => "Move list selection down.",
|
||||
move_left => "Move horizontally left in list pickers.",
|
||||
move_right => "Move horizontally right in list pickers.",
|
||||
page_up => "Move list selection up by one page.",
|
||||
page_down => "Move list selection down by one page.",
|
||||
jump_top => "Jump to the first list item.",
|
||||
jump_bottom => "Jump to the last list item.",
|
||||
accept => "Accept the current list selection.",
|
||||
cancel => "Cancel and close selection views.",
|
||||
}
|
||||
agents "Agents" {
|
||||
resume => "Open the session resume picker.",
|
||||
search => "Search the available agent tasks.",
|
||||
new_task => "Open a new session in the selected checkout.",
|
||||
new_worktree => "Open a new session in a worktree from the project default branch.",
|
||||
fork => "Fork the selected conversation and open the new session.",
|
||||
rename => "Rename the selected task.",
|
||||
stop => "Stop the selected running task.",
|
||||
archive => "Archive the selected task and its child agents.",
|
||||
delete => "Permanently delete the selected task and its child agents.",
|
||||
hide => "Hide the selected task until explicitly resumed.",
|
||||
toggle_grouping => "Cycle task grouping by project, status, or model.",
|
||||
}
|
||||
approval "Approval" {
|
||||
open_fullscreen => "Open approval details fullscreen.",
|
||||
open_thread => "Open the approval source thread when available.",
|
||||
approve => "Approve the primary option.",
|
||||
approve_for_session => "Approve for the session when available.",
|
||||
approve_for_prefix => "Approve with an exec-policy prefix when available.",
|
||||
deny => "Choose the explicit deny option when available.",
|
||||
decline => "Decline and provide corrective guidance.",
|
||||
cancel => "Cancel an elicitation request.",
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a stable action identifier into a display label.
|
||||
///
|
||||
@@ -260,176 +310,6 @@ pub(super) fn action_label(action: &str) -> String {
|
||||
.join(" ")
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
/// Return the mutable root-config binding slot for one catalog action.
|
||||
///
|
||||
/// The returned `Option<KeybindingsSpec>` distinguishes three states that the
|
||||
/// editor must preserve: absent means use fallback/default resolution, `Some`
|
||||
/// with one or more keys is a custom binding, and `Some(Many([]))` is an
|
||||
/// explicit unbind.
|
||||
pub(super) fn binding_slot<'a>(
|
||||
keymap: &'a mut TuiKeymap,
|
||||
context: &str,
|
||||
action: &str,
|
||||
) -> Option<&'a mut Option<KeybindingsSpec>> {
|
||||
match (context, action) {
|
||||
("global", "leader") => Some(&mut keymap.global.leader),
|
||||
("global", "open_agents") => Some(&mut keymap.global.open_agents),
|
||||
("global", "open_transcript") => Some(&mut keymap.global.open_transcript),
|
||||
("global", "find_transcript") => Some(&mut keymap.global.find_transcript),
|
||||
("global", "focus_activity") => Some(&mut keymap.global.focus_activity),
|
||||
("global", "open_external_editor") => Some(&mut keymap.global.open_external_editor),
|
||||
("global", "copy") => Some(&mut keymap.global.copy),
|
||||
("global", "clear_terminal") => Some(&mut keymap.global.clear_terminal),
|
||||
("global", "toggle_vim_mode") => Some(&mut keymap.global.toggle_vim_mode),
|
||||
("global", "toggle_fast_mode") => Some(&mut keymap.global.toggle_fast_mode),
|
||||
("global", "toggle_raw_output") => Some(&mut keymap.global.toggle_raw_output),
|
||||
("global", "toggle_side_conversation") => Some(&mut keymap.global.toggle_side_conversation),
|
||||
("chat", "interrupt_turn") => Some(&mut keymap.chat.interrupt_turn),
|
||||
("chat", "decrease_reasoning_effort") => Some(&mut keymap.chat.decrease_reasoning_effort),
|
||||
("chat", "increase_reasoning_effort") => Some(&mut keymap.chat.increase_reasoning_effort),
|
||||
("chat", "previous_permission_mode") => Some(&mut keymap.chat.previous_permission_mode),
|
||||
("chat", "next_permission_mode") => Some(&mut keymap.chat.next_permission_mode),
|
||||
("chat", "edit_queued_message") => Some(&mut keymap.chat.edit_queued_message),
|
||||
("chat", "prompt_stack_back") => Some(&mut keymap.chat.prompt_stack_back),
|
||||
("chat", "skip_question") => Some(&mut keymap.chat.skip_question),
|
||||
("chat", "toggle_voice") => Some(&mut keymap.chat.toggle_voice),
|
||||
("chat", "toggle_voice_mute") => Some(&mut keymap.chat.toggle_voice_mute),
|
||||
("composer", "submit") => Some(&mut keymap.composer.submit),
|
||||
("composer", "queue") => Some(&mut keymap.composer.queue),
|
||||
("composer", "toggle_shortcuts") => Some(&mut keymap.composer.toggle_shortcuts),
|
||||
("composer", "history_search_previous") => Some(&mut keymap.composer.history_search_previous),
|
||||
("composer", "history_search_next") => Some(&mut keymap.composer.history_search_next),
|
||||
("editor", "insert_newline") => Some(&mut keymap.editor.insert_newline),
|
||||
("editor", "move_left") => Some(&mut keymap.editor.move_left),
|
||||
("editor", "move_right") => Some(&mut keymap.editor.move_right),
|
||||
("editor", "move_up") => Some(&mut keymap.editor.move_up),
|
||||
("editor", "move_down") => Some(&mut keymap.editor.move_down),
|
||||
("editor", "move_word_left") => Some(&mut keymap.editor.move_word_left),
|
||||
("editor", "move_word_right") => Some(&mut keymap.editor.move_word_right),
|
||||
("editor", "move_line_start") => Some(&mut keymap.editor.move_line_start),
|
||||
("editor", "move_line_end") => Some(&mut keymap.editor.move_line_end),
|
||||
("editor", "delete_backward") => Some(&mut keymap.editor.delete_backward),
|
||||
("editor", "delete_forward") => Some(&mut keymap.editor.delete_forward),
|
||||
("editor", "delete_backward_word") => Some(&mut keymap.editor.delete_backward_word),
|
||||
("editor", "delete_forward_word") => Some(&mut keymap.editor.delete_forward_word),
|
||||
("editor", "kill_line_start") => Some(&mut keymap.editor.kill_line_start),
|
||||
("editor", "kill_whole_line") => Some(&mut keymap.editor.kill_whole_line),
|
||||
("editor", "kill_line_end") => Some(&mut keymap.editor.kill_line_end),
|
||||
("editor", "yank") => Some(&mut keymap.editor.yank),
|
||||
("vim_normal", "enter_insert") => Some(&mut keymap.vim_normal.enter_insert),
|
||||
("vim_normal", "append_after_cursor") => Some(&mut keymap.vim_normal.append_after_cursor),
|
||||
("vim_normal", "append_line_end") => Some(&mut keymap.vim_normal.append_line_end),
|
||||
("vim_normal", "insert_line_start") => Some(&mut keymap.vim_normal.insert_line_start),
|
||||
("vim_normal", "open_line_below") => Some(&mut keymap.vim_normal.open_line_below),
|
||||
("vim_normal", "open_line_above") => Some(&mut keymap.vim_normal.open_line_above),
|
||||
("vim_normal", "enter_replace_mode") => Some(&mut keymap.vim_normal.enter_replace_mode),
|
||||
("vim_normal", "move_left") => Some(&mut keymap.vim_normal.move_left),
|
||||
("vim_normal", "move_right") => Some(&mut keymap.vim_normal.move_right),
|
||||
("vim_normal", "move_up") => Some(&mut keymap.vim_normal.move_up),
|
||||
("vim_normal", "move_down") => Some(&mut keymap.vim_normal.move_down),
|
||||
("vim_normal", "move_word_forward") => Some(&mut keymap.vim_normal.move_word_forward),
|
||||
("vim_normal", "move_word_backward") => Some(&mut keymap.vim_normal.move_word_backward),
|
||||
("vim_normal", "move_word_end") => Some(&mut keymap.vim_normal.move_word_end),
|
||||
("vim_normal", "move_line_start") => Some(&mut keymap.vim_normal.move_line_start),
|
||||
("vim_normal", "move_line_end") => Some(&mut keymap.vim_normal.move_line_end),
|
||||
("vim_normal", "find_forward") => Some(&mut keymap.vim_normal.find_forward),
|
||||
("vim_normal", "find_backward") => Some(&mut keymap.vim_normal.find_backward),
|
||||
("vim_normal", "till_forward") => Some(&mut keymap.vim_normal.till_forward),
|
||||
("vim_normal", "till_backward") => Some(&mut keymap.vim_normal.till_backward),
|
||||
("vim_normal", "jump_top") => Some(&mut keymap.vim_normal.jump_top),
|
||||
("vim_normal", "jump_bottom") => Some(&mut keymap.vim_normal.jump_bottom),
|
||||
("vim_normal", "delete_char") => Some(&mut keymap.vim_normal.delete_char),
|
||||
("vim_normal", "replace_char") => Some(&mut keymap.vim_normal.replace_char),
|
||||
("vim_normal", "repeat_last_change") => Some(&mut keymap.vim_normal.repeat_last_change),
|
||||
("vim_normal", "substitute_char") => Some(&mut keymap.vim_normal.substitute_char),
|
||||
("vim_normal", "delete_to_line_end") => Some(&mut keymap.vim_normal.delete_to_line_end),
|
||||
("vim_normal", "change_to_line_end") => Some(&mut keymap.vim_normal.change_to_line_end),
|
||||
("vim_normal", "yank_line") => Some(&mut keymap.vim_normal.yank_line),
|
||||
("vim_normal", "paste_after") => Some(&mut keymap.vim_normal.paste_after),
|
||||
("vim_normal", "start_delete_operator") => Some(&mut keymap.vim_normal.start_delete_operator),
|
||||
("vim_normal", "start_yank_operator") => Some(&mut keymap.vim_normal.start_yank_operator),
|
||||
("vim_normal", "start_change_operator") => Some(&mut keymap.vim_normal.start_change_operator),
|
||||
("vim_normal", "undo") => Some(&mut keymap.vim_normal.undo),
|
||||
("vim_normal", "redo") => Some(&mut keymap.vim_normal.redo),
|
||||
("vim_normal", "cancel_operator") => Some(&mut keymap.vim_normal.cancel_operator),
|
||||
("vim_search", "forward") => Some(&mut keymap.vim_search.forward),
|
||||
("vim_search", "backward") => Some(&mut keymap.vim_search.backward),
|
||||
("vim_search", "next") => Some(&mut keymap.vim_search.next),
|
||||
("vim_search", "previous") => Some(&mut keymap.vim_search.previous),
|
||||
("vim_operator", "delete_line") => Some(&mut keymap.vim_operator.delete_line),
|
||||
("vim_operator", "yank_line") => Some(&mut keymap.vim_operator.yank_line),
|
||||
("vim_operator", "motion_left") => Some(&mut keymap.vim_operator.motion_left),
|
||||
("vim_operator", "motion_right") => Some(&mut keymap.vim_operator.motion_right),
|
||||
("vim_operator", "motion_up") => Some(&mut keymap.vim_operator.motion_up),
|
||||
("vim_operator", "motion_down") => Some(&mut keymap.vim_operator.motion_down),
|
||||
("vim_operator", "motion_word_forward") => Some(&mut keymap.vim_operator.motion_word_forward),
|
||||
("vim_operator", "motion_word_backward") => Some(&mut keymap.vim_operator.motion_word_backward),
|
||||
("vim_operator", "motion_word_end") => Some(&mut keymap.vim_operator.motion_word_end),
|
||||
("vim_operator", "motion_line_start") => Some(&mut keymap.vim_operator.motion_line_start),
|
||||
("vim_operator", "motion_line_end") => Some(&mut keymap.vim_operator.motion_line_end),
|
||||
("vim_operator", "motion_find_forward") => Some(&mut keymap.vim_operator.motion_find_forward),
|
||||
("vim_operator", "motion_find_backward") => Some(&mut keymap.vim_operator.motion_find_backward),
|
||||
("vim_operator", "motion_till_forward") => Some(&mut keymap.vim_operator.motion_till_forward),
|
||||
("vim_operator", "motion_till_backward") => Some(&mut keymap.vim_operator.motion_till_backward),
|
||||
("vim_operator", "motion_jump_top") => Some(&mut keymap.vim_operator.motion_jump_top),
|
||||
("vim_operator", "motion_jump_bottom") => Some(&mut keymap.vim_operator.motion_jump_bottom),
|
||||
("vim_operator", "select_inner_text_object") => Some(&mut keymap.vim_operator.select_inner_text_object),
|
||||
("vim_operator", "select_around_text_object") => Some(&mut keymap.vim_operator.select_around_text_object),
|
||||
("vim_operator", "cancel") => Some(&mut keymap.vim_operator.cancel),
|
||||
("vim_text_object", "word") => Some(&mut keymap.vim_text_object.word),
|
||||
("vim_text_object", "big_word") => Some(&mut keymap.vim_text_object.big_word),
|
||||
("vim_text_object", "parentheses") => Some(&mut keymap.vim_text_object.parentheses),
|
||||
("vim_text_object", "brackets") => Some(&mut keymap.vim_text_object.brackets),
|
||||
("vim_text_object", "braces") => Some(&mut keymap.vim_text_object.braces),
|
||||
("vim_text_object", "double_quote") => Some(&mut keymap.vim_text_object.double_quote),
|
||||
("vim_text_object", "single_quote") => Some(&mut keymap.vim_text_object.single_quote),
|
||||
("vim_text_object", "backtick") => Some(&mut keymap.vim_text_object.backtick),
|
||||
("vim_text_object", "cancel") => Some(&mut keymap.vim_text_object.cancel),
|
||||
("pager", "scroll_up") => Some(&mut keymap.pager.scroll_up),
|
||||
("pager", "scroll_down") => Some(&mut keymap.pager.scroll_down),
|
||||
("pager", "page_up") => Some(&mut keymap.pager.page_up),
|
||||
("pager", "page_down") => Some(&mut keymap.pager.page_down),
|
||||
("pager", "half_page_up") => Some(&mut keymap.pager.half_page_up),
|
||||
("pager", "half_page_down") => Some(&mut keymap.pager.half_page_down),
|
||||
("pager", "jump_top") => Some(&mut keymap.pager.jump_top),
|
||||
("pager", "jump_bottom") => Some(&mut keymap.pager.jump_bottom),
|
||||
("pager", "close") => Some(&mut keymap.pager.close),
|
||||
("pager", "close_transcript") => Some(&mut keymap.pager.close_transcript),
|
||||
("pager", "find") => Some(&mut keymap.pager.find),
|
||||
("list", "move_up") => Some(&mut keymap.list.move_up),
|
||||
("list", "move_down") => Some(&mut keymap.list.move_down),
|
||||
("list", "move_left") => Some(&mut keymap.list.move_left),
|
||||
("list", "move_right") => Some(&mut keymap.list.move_right),
|
||||
("list", "page_up") => Some(&mut keymap.list.page_up),
|
||||
("list", "page_down") => Some(&mut keymap.list.page_down),
|
||||
("list", "jump_top") => Some(&mut keymap.list.jump_top),
|
||||
("list", "jump_bottom") => Some(&mut keymap.list.jump_bottom),
|
||||
("list", "accept") => Some(&mut keymap.list.accept),
|
||||
("list", "cancel") => Some(&mut keymap.list.cancel),
|
||||
("agents", "resume") => Some(&mut keymap.agents.resume),
|
||||
("agents", "search") => Some(&mut keymap.agents.search),
|
||||
("agents", "new_task") => Some(&mut keymap.agents.new_task),
|
||||
("agents", "new_worktree") => Some(&mut keymap.agents.new_worktree),
|
||||
("agents", "fork") => Some(&mut keymap.agents.fork),
|
||||
("agents", "rename") => Some(&mut keymap.agents.rename),
|
||||
("agents", "stop") => Some(&mut keymap.agents.stop),
|
||||
("agents", "archive") => Some(&mut keymap.agents.archive),
|
||||
("agents", "delete") => Some(&mut keymap.agents.delete),
|
||||
("agents", "hide") => Some(&mut keymap.agents.hide),
|
||||
("agents", "toggle_grouping") => Some(&mut keymap.agents.toggle_grouping),
|
||||
("approval", "open_fullscreen") => Some(&mut keymap.approval.open_fullscreen),
|
||||
("approval", "open_thread") => Some(&mut keymap.approval.open_thread),
|
||||
("approval", "approve") => Some(&mut keymap.approval.approve),
|
||||
("approval", "approve_for_session") => Some(&mut keymap.approval.approve_for_session),
|
||||
("approval", "approve_for_prefix") => Some(&mut keymap.approval.approve_for_prefix),
|
||||
("approval", "deny") => Some(&mut keymap.approval.deny),
|
||||
("approval", "decline") => Some(&mut keymap.approval.decline),
|
||||
("approval", "cancel") => Some(&mut keymap.approval.cancel),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Format an action's active single-key and chord alternatives in config order.
|
||||
///
|
||||
/// Duplicate runtime variants that normalize to the same config spec are shown
|
||||
|
||||
Reference in New Issue
Block a user