fix(tui): stop stealing Ctrl+E from composer
fix(tui): stop stealing Ctrl+E from composer
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
//! File-tree pane — Ctrl+E toggles a left-side workspace file navigator.
|
||||
//! File-tree pane — Ctrl+Shift+E toggles a left-side workspace file navigator.
|
||||
//!
|
||||
//! Shows the workspace directory tree with expandable directories. Up/Down
|
||||
//! navigate, Enter expands/collapses directories or inserts `@path` for files,
|
||||
|
||||
@@ -1805,10 +1805,9 @@ async fn run_event_loop(
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ctrl+E toggles the file-tree pane. Visible even when other
|
||||
// modals are open (the file tree is part of the body layout,
|
||||
// not a modal overlay).
|
||||
if key.code == KeyCode::Char('e') && key.modifiers.contains(KeyModifiers::CONTROL) {
|
||||
// Shifted shortcuts toggle the file-tree pane. Keep plain Ctrl+E
|
||||
// reserved for the composer end-of-line binding used by shells.
|
||||
if is_file_tree_toggle_shortcut(&key) {
|
||||
if let Some(_state) = app.file_tree.as_mut() {
|
||||
// File tree visible → hide it.
|
||||
app.file_tree = None;
|
||||
@@ -2003,7 +2002,9 @@ async fn run_event_loop(
|
||||
continue;
|
||||
}
|
||||
KeyCode::Char('o')
|
||||
if key.modifiers == KeyModifiers::CONTROL && open_thinking_pager(app) =>
|
||||
if key.modifiers == KeyModifiers::CONTROL
|
||||
&& app.input.is_empty()
|
||||
&& open_thinking_pager(app) =>
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -2562,7 +2563,10 @@ async fn run_event_loop(
|
||||
app.move_cursor_end();
|
||||
}
|
||||
KeyCode::Char('e') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
// Ctrl+E: spawn $EDITOR on the composer contents (#91).
|
||||
app.move_cursor_end();
|
||||
}
|
||||
KeyCode::Char('o') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
// Ctrl+O: spawn $EDITOR on the composer contents (#91).
|
||||
// Only fires when no modal is active (the !view_stack
|
||||
// branch above already returns early in that case) and
|
||||
// the composer is the focused input target. We accept the
|
||||
@@ -7557,6 +7561,25 @@ fn is_copy_shortcut(key: &KeyEvent) -> bool {
|
||||
key.modifiers.contains(KeyModifiers::CONTROL) && key.modifiers.contains(KeyModifiers::SHIFT)
|
||||
}
|
||||
|
||||
fn is_file_tree_toggle_shortcut(key: &KeyEvent) -> bool {
|
||||
let is_shifted_e = matches!(key.code, KeyCode::Char('E'))
|
||||
|| (matches!(key.code, KeyCode::Char('e')) && key.modifiers.contains(KeyModifiers::SHIFT));
|
||||
if !is_shifted_e {
|
||||
return false;
|
||||
}
|
||||
|
||||
let has_forbidden_modifier =
|
||||
key.modifiers.contains(KeyModifiers::ALT) || key.modifiers.contains(KeyModifiers::SUPER);
|
||||
let ctrl_shift_e = key.modifiers.contains(KeyModifiers::CONTROL) && !has_forbidden_modifier;
|
||||
|
||||
let cmd_shift_e = key.modifiers.contains(KeyModifiers::SUPER)
|
||||
&& key.modifiers.contains(KeyModifiers::SHIFT)
|
||||
&& !key.modifiers.contains(KeyModifiers::CONTROL)
|
||||
&& !key.modifiers.contains(KeyModifiers::ALT);
|
||||
|
||||
ctrl_shift_e || cmd_shift_e
|
||||
}
|
||||
|
||||
fn details_shortcut_modifiers(modifiers: KeyModifiers) -> bool {
|
||||
modifiers.is_empty()
|
||||
|| modifiers == KeyModifiers::SHIFT
|
||||
|
||||
@@ -378,6 +378,26 @@ fn copy_shortcut_accepts_cmd_and_ctrl_shift_only() {
|
||||
)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_tree_shortcut_does_not_steal_plain_ctrl_e() {
|
||||
assert!(!is_file_tree_toggle_shortcut(&KeyEvent::new(
|
||||
KeyCode::Char('e'),
|
||||
KeyModifiers::CONTROL,
|
||||
)));
|
||||
assert!(is_file_tree_toggle_shortcut(&KeyEvent::new(
|
||||
KeyCode::Char('E'),
|
||||
KeyModifiers::CONTROL,
|
||||
)));
|
||||
assert!(is_file_tree_toggle_shortcut(&KeyEvent::new(
|
||||
KeyCode::Char('e'),
|
||||
KeyModifiers::CONTROL | KeyModifiers::SHIFT,
|
||||
)));
|
||||
assert!(is_file_tree_toggle_shortcut(&KeyEvent::new(
|
||||
KeyCode::Char('E'),
|
||||
KeyModifiers::SUPER | KeyModifiers::SHIFT,
|
||||
)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_plan_choice_accepts_numbers() {
|
||||
assert_eq!(parse_plan_choice("1"), Some(PlanChoice::AcceptAgent));
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ Bindings are not (yet) user-configurable — tracked for a future release (#436,
|
||||
| `Shift-Tab` | Cycle reasoning effort: off → high → max → off |
|
||||
| `Ctrl-R` | Open the resume-session picker |
|
||||
| `Ctrl-L` | Refresh / clear the screen |
|
||||
| `Ctrl-T` | Toggle the file-tree sidebar |
|
||||
| `Ctrl-Shift-E` / `Cmd-Shift-E` | Toggle the file-tree sidebar |
|
||||
| `Esc` | Close topmost modal · cancel slash menu · dismiss toast |
|
||||
|
||||
## Composer
|
||||
|
||||
Reference in New Issue
Block a user