mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-18 04:41:56 +00:00
fix(cli): make Ctrl+Enter insert newline on WSL/SSH/Windows Terminal (#22777)
Native Windows, WSL, SSH sessions, and Windows Terminal all send Ctrl+Enter as bare LF (c-j). Hermes was binding c-j as submit on every POSIX platform, so Ctrl+Enter submitted instead of inserting a newline on those terminals. Reported in #22379. Add _preserve_ctrl_enter_newline() predicate that detects the environments where Ctrl+Enter must produce a newline (sys.platform == 'win32', SSH_CONNECTION/SSH_CLIENT/SSH_TTY env, WT_SESSION, WSL_DISTRO_NAME, /proc/version 'microsoft' marker). Gate the c-j-as-submit binding off in those environments and gate the c-j-as-newline handler on. Local POSIX TTYs without those markers (docker exec, plain ssh from a Mac) keep c-j as submit so plain Enter still works on thin PTYs. Add install_ctrl_enter_alias() in hermes_cli/pt_input_extras.py mapping the three CSI-u / modifyOtherKeys variants of Ctrl+Enter ('\x1b[13;5u', '\x1b[27;5;13~', '\x1b[27;5;13u') to the (Escape, ControlM) tuple Alt+Enter produces. This lets Kitty / mintty / xterm-with-modifyOtherKeys users over SSH get a Ctrl+Enter newline through the existing Alt+Enter handler. 9 new tests + extended existing test_lf_enter_binds_to_submit_handler_posix to cover bare-local vs SSH branches. Closes #22379.
This commit is contained in:
parent
2124ad72a2
commit
70bc52e408
4 changed files with 210 additions and 24 deletions
|
|
@ -166,13 +166,14 @@ class TestPromptToolkitTerminalCompatibility:
|
|||
def test_lf_enter_binds_to_submit_handler_posix(self):
|
||||
"""Some thin PTYs deliver Enter as LF/c-j instead of CR/enter.
|
||||
|
||||
On POSIX we keep the c-j → submit binding so Enter works on thin
|
||||
PTYs (docker exec, certain SSH configurations). On Windows c-j is
|
||||
reclaimed as the newline keystroke because Windows Terminal
|
||||
delivers Ctrl+Enter as LF, and we want an Enter-involving newline
|
||||
without requiring terminal-settings changes.
|
||||
On a bare local POSIX TTY (no SSH/WSL/WT) we keep c-j → submit so
|
||||
Enter works on thin PTYs (docker exec, certain ssh configurations).
|
||||
On Windows, WSL, SSH sessions, and Windows Terminal we leave c-j
|
||||
unbound here so it can be used as the Ctrl+Enter newline keystroke
|
||||
without conflicting with submit. See issue #22379.
|
||||
"""
|
||||
import sys as _sys
|
||||
import os as _os
|
||||
from unittest.mock import patch as _patch
|
||||
from prompt_toolkit.key_binding import KeyBindings
|
||||
|
||||
|
|
@ -181,14 +182,27 @@ class TestPromptToolkitTerminalCompatibility:
|
|||
def submit_handler(event):
|
||||
return None
|
||||
|
||||
# POSIX: both enter and c-j submit
|
||||
with _patch.object(_sys, "platform", "linux"):
|
||||
# Bare local POSIX (no SSH/WSL markers): both enter and c-j submit.
|
||||
with _patch.object(_sys, "platform", "linux"), \
|
||||
_patch.dict(_os.environ, {}, clear=True), \
|
||||
_patch("builtins.open", side_effect=OSError("no /proc")):
|
||||
kb = KeyBindings()
|
||||
_bind_prompt_submit_keys(kb, submit_handler)
|
||||
bindings = {tuple(key.value for key in binding.keys): binding.handler for binding in kb.bindings}
|
||||
assert bindings[("c-m",)] is submit_handler
|
||||
assert bindings[("c-j",)] is submit_handler
|
||||
|
||||
# POSIX over SSH: c-j stays free so Ctrl+Enter (sent as LF by
|
||||
# Windows Terminal / Kitty / mintty over SSH) inserts a newline.
|
||||
with _patch.object(_sys, "platform", "linux"), \
|
||||
_patch.dict(_os.environ, {"SSH_CONNECTION": "1.2.3.4 5 6.7.8.9 22"}, clear=True), \
|
||||
_patch("builtins.open", side_effect=OSError("no /proc")):
|
||||
kb = KeyBindings()
|
||||
_bind_prompt_submit_keys(kb, submit_handler)
|
||||
bindings = {tuple(key.value for key in binding.keys): binding.handler for binding in kb.bindings}
|
||||
assert bindings[("c-m",)] is submit_handler
|
||||
assert ("c-j",) not in bindings
|
||||
|
||||
# Windows: only enter submits; c-j is free for the newline binding
|
||||
# added separately in the prompt setup.
|
||||
with _patch.object(_sys, "platform", "win32"):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue