diff --git a/cli.py b/cli.py index 2f2378ed3..d6f01649b 100755 --- a/cli.py +++ b/cli.py @@ -37,10 +37,18 @@ from prompt_toolkit.layout.dimension import Dimension from prompt_toolkit.widgets import TextArea from prompt_toolkit.key_binding import KeyBindings from prompt_toolkit.completion import Completer, Completion +from prompt_toolkit.keys import Keys import threading import queue import tempfile +# Patch prompt_toolkit to recognize Shift+Enter as a distinct key. +# By default, the xterm "disambiguated modified keys" sequence for Shift+Enter +# (\x1b[27;2;13~) is mapped to ControlM (same as plain Enter). We remap it to +# a unique key tuple so we can bind Shift+Enter to insert a newline. +from prompt_toolkit.input.ansi_escape_sequences import ANSI_SEQUENCES +ANSI_SEQUENCES["\x1b[27;2;13~"] = (Keys.Escape, Keys.ControlJ) # Shift+Enter + # Load environment variables first from dotenv import load_dotenv env_path = Path(__file__).parent / '.env' @@ -829,7 +837,7 @@ class HermesCLI: print() print(" Tip: Just type your message to chat with Hermes!") - print(" Multi-line: End a line with \\ to continue on next line") + print(" Multi-line: Shift+Enter for a new line (Alt+Enter as fallback)") print() def show_tools(self): @@ -1549,9 +1557,14 @@ class HermesCLI: self._pending_input.put(text) event.app.current_buffer.reset() - @kb.add('s-enter') + @kb.add('escape', 'c-j') def handle_shift_enter(event): - """Shift+Enter inserts a newline for multi-line input.""" + """Shift+Enter inserts a newline (via patched ANSI sequence).""" + event.current_buffer.insert_text('\n') + + @kb.add('escape', 'enter') + def handle_alt_enter(event): + """Alt+Enter also inserts a newline (fallback for terminals without Shift+Enter).""" event.current_buffer.insert_text('\n') @kb.add('c-c')