From 4c797bfae9732e3dfc8d2d067428f8aad0d607a8 Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Sat, 25 Apr 2026 20:01:03 -0500 Subject: [PATCH] fix(cli): accept Alt+G as Ctrl+G fallback in VSCode/Cursor terminals Same problem as the TUI: Cursor and VSCode bind Ctrl+G to "Find Next" at the editor level, so the keystroke never reaches the terminal and the prompt_toolkit-driven Hermes CLI sees nothing. Register ('escape', 'g') alongside the existing 'c-g' on the same handler so the editor handoff works inside Cursor/VSCode too. The filter (no clarify/approval/sudo/secret prompt active) is unchanged. --- cli.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/cli.py b/cli.py index 18c9e637f6..0390d47413 100644 --- a/cli.py +++ b/cli.py @@ -4318,7 +4318,7 @@ class HermesCLI: _cprint(f"\n {_DIM}Tip: Just type your message to chat with Hermes!{_RST}") _cprint(f" {_DIM}Multi-line: Alt+Enter for a new line{_RST}") - _cprint(f" {_DIM}Draft editor: Ctrl+G{_RST}") + _cprint(f" {_DIM}Draft editor: Ctrl+G (Alt+G in VSCode/Cursor){_RST}") if _is_termux_environment(): _cprint(f" {_DIM}Attach image: /image {_termux_example_image_path()} or start your prompt with a local image path{_RST}\n") else: @@ -9308,14 +9308,18 @@ class HermesCLI: """Ctrl+Enter (c-j) inserts a newline. Most terminals send c-j for Ctrl+Enter.""" event.current_buffer.insert_text('\n') - @kb.add( - 'c-g', - filter=Condition( - lambda: not self._clarify_state and not self._approval_state and not self._sudo_state and not self._secret_state - ), + # VSCode/Cursor bind Ctrl+G to "Find Next" at the editor level, so + # the keystroke never reaches the embedded terminal. Alt+G is unbound + # in those IDEs and arrives here as ('escape', 'g') — register it as + # a fallback so the editor handoff works inside Cursor/VSCode too. + _editor_filter = Condition( + lambda: not self._clarify_state and not self._approval_state and not self._sudo_state and not self._secret_state ) + + @kb.add('c-g', filter=_editor_filter) + @kb.add('escape', 'g', filter=_editor_filter) def handle_open_in_editor(event): - """Ctrl+G opens the current draft in an external editor.""" + """Ctrl+G (or Alt+G in VSCode/Cursor) opens the current draft in an external editor.""" cli_ref._open_external_editor(event.current_buffer) @kb.add('tab', eager=True)