Skip to content

feat(tui): Ctrl+X leader chords and emacs menu navigation#699

Open
lfaoro wants to merge 3 commits into
Gitlawb:mainfrom
lfaoro:feat/tui-shortcuts
Open

feat(tui): Ctrl+X leader chords and emacs menu navigation#699
lfaoro wants to merge 3 commits into
Gitlawb:mainfrom
lfaoro:feat/tui-shortcuts

Conversation

@lfaoro

@lfaoro lfaoro commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Adds two related TUI keyboard improvements:

  1. Ctrl+X leader chords for common slash commands (type less, keep the draft)
  2. Emacs-style Ctrl+P / Ctrl+N for previous/next selection in menus

Both are discoverable via the ? help overlay, README controls table, idle composer hints, and (for leader chords) a dedicated Ctrl+X ? modal styled like the keyboard-shortcut overlay.

Motivation

  • High-frequency slash commands (/model, /provider, /resume, …) still required typing /… + Enter mid-session.
  • Menu navigation was arrow-only; Emacs muscle memory expects Ctrl+P / Ctrl+N.

Ctrl+X leader (slash shortcuts)

Chord Action
Ctrl+X then letter Run the mapped builtin slash command
Ctrl+X ? Open bordered Ctrl+X Shortcuts chord map
Esc / second Ctrl+X / ~2s timeout Cancel pending leader
Pending leader Composer draft is not cleared; chord never types into the input
Key Command Key Command
m /model p /provider
P /plan M /stt-model
v /voice c /clear
C /context s /stop
i /image r /resume
u /rewind t /tools
e /edit R /retry
  • Shared executeSlash / dispatchCommand path so chords behave like submitting the slash command.
  • Leader chords do not wipe mid-type composer text.
  • Chord map reuses the same frame chrome as the ? overlay (styledBlockFillTitle + panel fill).

Emacs Ctrl+P / Ctrl+N (menu navigation)

Chord Action
Ctrl+P Previous item (same as ↑)
Ctrl+N Next item (same as ↓)

Surfaces: model/theme/effort/session/skill pickers, slash & file suggestions, permission prompts, ask_user option lists, provider/MCP wizards & managers, onboarding setup lists.

Precedence: while a selection surface is active, Ctrl+P/N move the highlight and do not toggle the plan panel. Idle Ctrl+P still expands/collapses the plan when no menu is open. Idle Ctrl+N remains a no-op (remapped bindings like toggleSidebar: ctrl+n still work).

shared moveModalSelection(delta) used by arrows and Ctrl+P/N.

Follow up if merged:

  • Configurable leader map / remappable leader key (phase 2)
  • Binding every slash command (only the curated table)
  • User-defined / skill slash commands via leader
  • Changing global Ctrl+P default away from plan toggle

Summary by CodeRabbit

  • New Features
    • Added Ctrl+X leader-chord shortcuts for common wired slash commands, plus Ctrl+X ? to show all Ctrl+X chords; incomplete sequences cancel via Esc, a second Ctrl+X, or timeout.
    • Added Emacs-style Ctrl+P / Ctrl+N navigation across menu and picker flows (including suggestions). When no menu is open, Ctrl+P toggles the plan panel; idle Ctrl+N is a no-op.
  • Documentation
    • Updated the interactive controls reference and the in-app shortcut help overlay for the new chords and navigation keys.
  • Bug Fixes
    • Prevents leader-key follow-ups from inserting text while a leader chord is pending.

Add Ctrl+X leader shortcuts for common slash commands (with Ctrl+X ?
chord map), and Ctrl+P/N previous/next selection in modals and pickers.
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1c05326c-fb43-4a69-907a-091196190590

📥 Commits

Reviewing files that changed from the base of the PR and between fd8fa8e and b2cd45e.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • internal/tui/keybinding_help_test.go
  • internal/tui/leader.go
  • internal/tui/model.go
💤 Files with no reviewable changes (1)
  • internal/tui/leader.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • CHANGELOG.md
  • internal/tui/model.go

Walkthrough

The TUI adds timed Ctrl+X leader chords for builtin slash commands and a chord-help overlay. Ctrl+P and Ctrl+N provide Emacs-style navigation across selection surfaces and onboarding, with context-sensitive plan-panel behavior.

Changes

TUI keyboard interactions

Layer / File(s) Summary
Leader chord execution
internal/tui/leader.go, internal/tui/model.go, internal/tui/leader_test.go
Adds timed Ctrl+X chord handling, cancellation, key normalization, builtin slash-command execution, composer preservation, and coverage for mapped, unmapped, stale-timeout, and picker-active states.
Leader help and overlay presentation
internal/tui/leader.go, internal/tui/model.go, internal/tui/keybinding_help.go, internal/tui/sidebar.go, README.md, CHANGELOG.md, internal/tui/*test.go
Adds the Ctrl+X chord map overlay, integrates it into overlay rendering and sidebar suppression, updates help text and documentation, and verifies its content and dismissal behavior.
Emacs-style selection navigation
internal/tui/modal_selection.go, internal/tui/model.go, internal/tui/onboarding.go, internal/tui/modal_selection_test.go, internal/tui/keybinding_help.go
Routes Ctrl+P/Ctrl+N and arrow movement through shared modal selection handling across pickers, suggestions, permissions, wizards, themes, onboarding, and plan-panel states.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant TUI
  participant ModalSelection
  participant PickerOrPrompt
  User->>TUI: Ctrl+P or Ctrl+N
  TUI->>ModalSelection: moveModalSelection(delta)
  ModalSelection->>PickerOrPrompt: move active selection
  PickerOrPrompt-->>TUI: updated cursor or selected item
Loading

Possibly related PRs

  • Gitlawb/zero#83 — overlaps the TUI command-routing and slash-command execution paths.
  • Gitlawb/zero#300 — overlaps sidebar gating for full-width overlays.
  • Gitlawb/zero#417 — overlaps configurable keybinding resolution and help labeling.

Suggested reviewers: gnanam1990, vasanthdev2004, kevincodex1, euxaristia

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two main TUI changes: Ctrl+X leader chords and Emacs-style menu navigation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/tui/leader.go`:
- Line 31: Remove the 'e' to "/edit" entry from the leader mappings in leader.go
so Ctrl+X e no longer exposes a command that replaces the composer and discards
an in-progress draft. Preserve the remaining draft-preserving mappings
unchanged.

In `@internal/tui/model.go`:
- Around line 1268-1280: Update the Ctrl+N handling around moveModalSelection so
that, when no modal selection surface handles the key, idle Ctrl+N is consumed
as a no-op instead of falling through to configurable global bindings; preserve
modal navigation behavior and existing Ctrl+P handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2c2e5d22-6ad0-4dae-8288-b1af225c3d9f

📥 Commits

Reviewing files that changed from the base of the PR and between 75a78e7 and fd8fa8e.

📒 Files selected for processing (11)
  • CHANGELOG.md
  • README.md
  • internal/tui/keybinding_help.go
  • internal/tui/keybinding_help_test.go
  • internal/tui/leader.go
  • internal/tui/leader_test.go
  • internal/tui/modal_selection.go
  • internal/tui/modal_selection_test.go
  • internal/tui/model.go
  • internal/tui/onboarding.go
  • internal/tui/sidebar.go

Comment thread internal/tui/leader.go Outdated
Comment thread internal/tui/model.go
lfaoro added 2 commits July 16, 2026 01:14
/edit replaces the composer and would discard an in-progress draft; leave
it unbound so leader shortcuts stay draft-preserving.
Reserve Ctrl+N for emacs menu navigation so it never falls through to
remapped global bindings when no selection surface is open.

@Vasanthdev2004 Vasanthdev2004 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice work this is clean and well-tested. The leader-chord and Ctrl+P/Ctrl+N refactor is behavior-preserving (the Shift+arrow suggestion break is kept, plain arrows route through moveModalSelection), it builds, vets, and gofmts clean, and the new leader/modal tests pass in the worktree. One thing worth a gut-check before merge: idle Ctrl+N is now a reserved no-op that never reaches configurable global bindings, so anyone who remapped a binding (e.g. toggleSidebar) to Ctrl+N silently loses it the CHANGELOG calls this out, just confirm you're fine burning that binding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants