Skip to content

fix(cli): preserve Ctrl-J newline on macOS - #27688

Open
ForgedFinancial wants to merge 1 commit into
NousResearch:mainfrom
ForgedFinancial:fix/macos-ctrl-j-newline-2026-05-17
Open

fix(cli): preserve Ctrl-J newline on macOS#27688
ForgedFinancial wants to merge 1 commit into
NousResearch:mainfrom
ForgedFinancial:fix/macos-ctrl-j-newline-2026-05-17

Conversation

@ForgedFinancial

Copy link
Copy Markdown

Summary

  • Preserves Ctrl+J as a multiline newline shortcut on macOS instead of binding it to prompt submit
  • Updates the startup/tips copy to surface Ctrl+J first, while keeping Alt+Enter as a forwarded-terminal option
  • Adds focused regression coverage for macOS keybinding behavior and the multiline tip

Test plan

  • .venv/bin/python -m pytest -o addopts="-m 'not integration'" -q tests/cli/test_ctrl_enter_newline.py tests/cli/test_cli_init.py tests/hermes_cli/test_tips.py
  • direct keybinding assertion: macos_ctrl_j_preserve_and_keybinding_assertion=PASS
  • git diff --check

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard labels May 18, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #25111 (same author, same approach, 3rd resubmission). The most comprehensive open fix for the Ctrl-J/c-j macOS keybinding issue is #22911, which also handles Warp terminal. Root issue: #22908.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused fix. I verified the underlying bug still exists on current main: _preserve_ctrl_enter_newline() has no native macOS branch at cli.py:2716-2751, so _bind_prompt_submit_keys() still binds c-j to submit at cli.py:2768-2770, and the newline handler only registers when that predicate is true at cli.py:11308-11322.

Problems

  • The handle_ctrl_enter_newline docstring is still Windows/WSL/SSH/Windows Terminal-specific at cli.py:11311-11320; after adding macOS, that inline documentation would be stale.
  • The PR diff for cli.py around _preserve_ctrl_enter_newline() includes user-specific wording (On Danny's MacBook). That should be generalized to the platform/terminal behavior and root issue [Bug]: Shift+Enter no longer inserts a newline in classic Hermes CLI #22908.

Suggested changes

  • Preserve the current main Ghostty detection branches at cli.py:2735-2740 while adding the macOS behavior, since those were merged after this PR was opened.
  • Update the newline-handler docstring at cli.py:11311-11320 to mention native macOS once darwin is included.
  • Replace the user-specific comment with neutral wording such as native macOS terminals that deliver the multiline shortcut as bare LF/c-j.

This is an automated hermes-sweeper review.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused classic-CLI regression coverage. The macOS premise still holds on current main: local macOS falls through _preserve_ctrl_enter_newline() at cli.py:3149-3171, so _bind_prompt_submit_keys() binds c-j to submit at cli.py:3189-3190, while the newline handler is conditional at cli.py:13583-13597.

Problems

  • Current main added Ghostty preservation at cli.py:3155-3159 in cf8862cfa; this PR branch predates those checks. Preserve them while adding darwin, or Ghostty/tmux newline behavior would regress.
  • Adding macOS also requires updating the Windows-only descriptions at cli.py:3181-3186 and cli.py:13586-13595.
  • The PR-head predicate docstring at cli.py:2141-2142 refers to “Danny's MacBook”; use neutral platform/terminal wording instead.

Suggested changes

  • Salvage the darwin branch into the current predicate without dropping the Ghostty branches from cf8862cfa.
  • Update both current inline keybinding docstrings to name native macOS.
  • Generalize the user-specific wording.

This is an automated hermes-sweeper review.

Comment thread cli.py
See issue #22379.
"""
if sys.platform == "win32":
if sys.platform in {"darwin", "win32"}:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When salvaging this onto current main, retain the later Ghostty checks added by cf8862cfa (current cli.py:3155-3159). This branch predates them, and replacing the predicate wholesale would make Ghostty/tmux c-j submit again.

Comment thread cli.py
some thin PTYs without SSH) still need c-j bound to submit, so we keep
that binding for those.
Native macOS, native Windows, WSL, SSH sessions, and Windows Terminal all
need c-j kept free for the newline handler. On Danny's MacBook, Ctrl+J is

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace the user-specific “Danny's MacBook” explanation with neutral wording about native macOS terminals and bare LF/c-j delivery.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants