[BUG] CSI u (Fixterms) shifted sequences not recognised
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When using Claude Code inside tmux with extended-keys on, alt+shift+<letter> keybindings (e.g. alt+shift+g) are treated as the unshifted binding (e.g. alt+g).
This is true even when tmux is configured to output CSI u via extended-keys-format csi-u
This is because the tmux's CSI u uses:
- the Fixterms encoding (Alt+Shift+g =
^[[71;3umeaning codepoint 'G', modifier Alt)
but Claude code only seem to understand:
- the Kitty Keyboard Protocol Flag 1 encoding (Alt+Shift+g =
^[[103;4umeaning codepoint 'g', modifier Alt + Shift) - the Kitty Keyboard Protocol Flag 5 encoding (Alt+Shift+g =
^[[103:71;4umeaning the same but with "alternate keys" enabled) - the legacy, non CSI u encoding (Alt+Shift+g =
^[G) - This means that tmux with
extended-keys offwill work, but then we miss out on the whole range of extended key bindings that Claude Code supports
TL;DR Claude Code doesn't seem to support the original CSI u specification (FixTerms) that tmux uses. Causing it to interpret ^[[71;3u as a plain Alt + g (doesn't disambiguate from ^[[103;3u), even though shift is pressed.
What Should Happen?
If Tmux is to be supported by Claude Code, then Alt+Shift+<letter> bindings should work inside Tmux even when extended-keys is set to on.
Tmux by default outputs extended keys in the way that xterm does, but with extended-keys-format csi-u we can have it output in CSI u FixTerms format, both of which currently are not recognized by Claude Code when using Tmux.
Suggested fix: when a CSI u key event arrives without alternate-key data and its codepoint is a shifted character (e.g. 'G' rather than 'g'), treat it as unshifted character (base key) with the Shift bit set.
This makes ESC[71;3u equivalent to ESC[103;4u.
Error Messages/Logs
Steps to Reproduce
Any terminal should work for this example since ^[g and ^[G are distinguishable even in the legacy encoding, it is Tmux that converts the various input encodings into the Fixterms CSI u encoding.
- Claude Code configured to use
alt+shift+gandalt+gkeybinding (actions arbitrarily chosen):
{
"$schema": "https://www.schemastore.org/claude-code-keybindings.json",
"$docs": "https://code.claude.com/docs/en/keybindings",
"bindings": [
{
"context": "Global",
"bindings": {
"alt+g": "chat:cycleMode",
"alt+shift+g": "chat:modelPicker"
}
}
]
}
- Tmux should have the following configuration to enable extended keys to be passed into running programs:
set -as terminal-features ',*xterm*:extkeys'
set -s extended-keys on
set -s extended-keys-format csi-u # Optional, both the default `xterm` and `csi-u` fail to work on Claude Code
- Open Claude with
claude - Notice that the
alt+shift+gbinding performschat:cycleModeinstead ofchat:modelPicker
Bonus peculiar behavior: Spamming Alt+Shift+G immediately after running claude while Claude Code is running will cause the correct keybind to trigger once.
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.295 (Claude Code)
Platform
Anthropic API
Operating System
Other Linux
Terminal/Shell
Other
Additional Information
_No response_