[Bug] Ctrl-G and other keybindings hardcoded in TUI surfaces, bypassing keybindings.json registry

Status Open
Reported on v2.1.235
Maintainer reply None cached
Activity 0 comments · opened Aug 25, 2026

Bug Description

Ctrl-G is hardcoded in several TUI surfaces and ignores keybindings.json

Version: 2.1.235 (native, macOS arm64, Darwin 25.5.0, iTerm2)

What I expected

Rebinding ctrl+g in ~/.claude/keybindings.json should apply everywhere the key is used. I have emacs habits, so I want C-g to quit/cancel instead of opening $EDITOR:

{
  "bindings": [
    { "context": "Chat", "bindings": { "ctrl+g": "chat:cancel" } }
  ]
}

What happens

That works in the main chat REPL. It has no effect in three other places, which still open $EDITOR on Ctrl-G:

  1. claude agents (FleetView) input
  2. The plan-mode feedback input
  3. The workflow-script editor in the Workflow permission dialog

Cause

Those surfaces don't go through the keybinding registry. They test the raw key event. In FleetView:

if (ct.ctrl && ct.key === "g" && !Ye && !E) { /* opens external editor */ }

FleetView does the same for Ctrl-S and Ctrl-T, so those are presumably unrebindable too. The plan input and the workflow dialog use the same pattern (the plan one logs tengu_plan_external_editor_used). The hint chords in those views are hardcoded as literal "ctrl+g" strings rather than resolved through the registry, which lines up.

Ask

Route these through the keybinding registry so keybindings.json covers them. A Fleet (or similar) context for the agents view would also let people rebind its Ctrl-S / Ctrl-T. Failing that, documenting which keys are non-rebindable would help, since the current failure is silent.

Workaround

Remap Ctrl-G to a bare ESC (hex 0x1b) in the terminal emulator. That works because the app never sees ctrl+g, but it's terminal-wide, so it breaks C-g in actual emacs and readline.

Environment Info

  • Platform: darwin
  • Terminal: xterm-256color
  • Version: 2.1.235
  • Feedback ID: 01b54444-e3a1-42a1-9c7a-32d2cf480857

Errors

[]

View original on GitHub ↗