Allow disabling chat-input edge-of-text history fallback (up/down to history when cursor at first/last line)
Problem
When up / down are unbound (null) in the Chat context via ~/.claude/keybindings.json, the input box correctly uses them for vertical cursor movement in the middle of a multi-line message — but the harness has a separate edge-of-text fallback that still routes the keystrokes to history:previous / history:next when the cursor is on the first line (up) or last line (down).
This fallback cannot be disabled through keybindings.json: setting the key to null removes the explicit action binding, but the edge-of-text behavior is independent code in the input widget itself.
Repro
- Add to
~/.claude/keybindings.json:
``json``
{
"bindings": [
{ "context": "Chat", "bindings": { "up": null, "down": null } }
]
}
- Restart Claude Code.
- In the input box, type a multi-line message (use
ctrl+jfor newlines). - Move the cursor to the first line and press
up— message is replaced with the previous one in history. - Move the cursor to the last line and press
down— message is replaced with an empty input ready for new text.
Impact
Losing typed content to a single misplaced arrow keystroke is a real pain point — users who type long multi-line prompts (which is increasingly common with agentic workflows) routinely hit the edge of the input and lose work. The current workarounds all have downsides:
- Binding
up/downto a no-op action likeapp:redrawprevents the fallback but also kills cursor movement entirely. - Moving history to a chord (e.g.
cmd+up) doesn't help — the fallback still fires regardless of wherehistory:previousis bound. - The macOS-reserved modifier space is crowded, leaving few clean chord options for history.
Proposed solution
Add a setting (in ~/.claude/settings.json) such as chatInputEdgeHistoryFallback: false (default true for back-compat) that suppresses the edge-of-text history routing. When disabled, up at the first line and down at the last line do nothing (or, ideally, behave as Home/End — placing the cursor at line start/end). The current behavior remains the default.
Alternatively, treat unbinding history:previous / history:next (via null on up / down in Chat) as a signal to disable the fallback too — i.e., the fallback only fires when the action is reachable via some bound key in the active context.
Workaround in the meantime
None that does not sacrifice cursor movement.
---
Filed via the Claude Code agent itself on behalf of a user who lost typed content to this fallback and is actively bothered by it.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗