Skip to content

feat: add a command palette and move panes from it - #2299

Closed
cameronsjo wants to merge 1 commit into
herdrdev:masterfrom
cameronsjo:feat/command-palette
Closed

feat: add a command palette and move panes from it#2299
cameronsjo wants to merge 1 commit into
herdrdev:masterfrom
cameronsjo:feat/command-palette

Conversation

@cameronsjo

Copy link
Copy Markdown

Follows up on discussion #2283.

Opening this for visibility rather than to jump the queue. It exceeds the
automated intake budget (21 files, ~1400 lines, feat: title), so it will close
automatically. The branch is there if the idea is worth pursuing, and I am happy
to cut it down, split it, or drop it entirely on a maintainer's word.

What this adds

A command palette on prefix+/. Its own overlay, listing every runnable
action alongside that action's shortcut. Typing filters; arrows move the
selection, enter runs it, esc closes, and clicking a row runs it.

Matches rank by quality (exact name, then prefix, then word start, then
substring), so typing new tab resolves to the command actually named that
rather than to a longer command containing it. Ordering by source position would
get that right only by accident.

Three commands that relocate the focused pane, to an existing space, a new
space, or a new tab. pane move already existed in the JSON API and the CLI,
but had no keyboard path.

Choosing an existing space arms the session navigator as a destination picker:

Row Result
+ new space the pane gets a space of its own
a space the pane arrives in a new tab there
a tab the pane splits into that tab

Panes are not offered as destinations. A pane is where a move lands, not
somewhere to send one, and which pane it splits beside is layout rather than a
destination. The line above the footer states what accepting the selected row
will do, since nothing else on screen distinguishes a space row from a tab row.

Notes for review

  • The keybind reference is untouched. Its entries gained the action they
    describe so the palette can source one inventory, which means a new keybind
    appears in both without a second list to maintain. ? itself renders and
    behaves exactly as before.
  • PROTOCOL_VERSION is unchanged. Mode and NavigatorTarget carry no
    Serialize derive, so neither crosses the wire, and pane.move is the
    existing API method.
  • The three move commands ship unbound, reachable only from the palette. No
    default keys are claimed beyond prefix+/ itself.
  • A move that changes nothing now reports it. Moving a pane into the tab it
    already occupies returns a success carrying changed: false; the only caller
    reading these responses was looking for an error member and found none, so
    nothing reached the user.
  • The palette's initial selection is seeded after the move is armed. Arming
    changes which rows exist, so seeding first picked an index against a list that
    then changed underneath it.

Verification

just check equivalent in a Linux container, since the dev machine is on macOS
26 where libghostty-vt's pinned Zig 0.15.2 cannot link its build runner (#285):
cargo fmt --check, cargo clippy --all-targets --locked -D warnings, and
cargo nextest run under the macOS CI filter (not binary(live_handoff)).
3177 passing.

All nine scripts/test_* maintenance modules pass, split across host and
container by tooling (two need cargo, two need node; no single environment
has both).

Docs updated under docs/next/ in en/ja/zh-cn, plus two docs/next/CHANGELOG.md
entries and the config-reference.json keybinding entry.

Opens with prefix+/ as its own overlay, listing every runnable action
alongside its shortcut. Typing filters the list, and matches rank by
quality so a query naming one command exactly wins over a longer command
that merely contains it. Arrows move the selection, enter runs it, esc
closes, and clicking a row runs it.

Three of the commands relocate the focused pane and have no shortcut of
their own: to an existing space, to a new space, or to a new tab.
Choosing an existing space arms the session navigator as a destination
picker offering a new space, each space as a new tab there, and each tab
to split into. Panes are not offered, since a pane is where a move lands
rather than somewhere to send one. The line above the footer says what
accepting the selected row will do.

The keybind reference is unchanged. Its rows carry the action they
describe so the palette can source a single inventory, which means a new
keybind shows up in both without a second list to maintain.

A move that changes nothing now says so. The server reports "already
there" as a success carrying changed: false, which the only caller
reading these responses was not looking for.
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • ai-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 43f184a4-cfa3-48ee-b7c6-49b90b463b63

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

@kangal-bot

Copy link
Copy Markdown
Collaborator

Hi @cameronsjo, thanks for your interest in contributing!

Herdr automatically admits focused bug fixes from contributors who are not maintainers when the title uses fix: ... or fix(scope): ... and the patch changes no more than 20 files and 1,000 total added or deleted lines.

Contributors who are not maintainers may submit only focused bug fixes. If this pull request fixes a bug, rename it to use a conventional fix: ... or fix(scope): ... title, then tag a maintainer to review and reopen it.

Feature requests, behavior changes, and other proposals belong in GitHub Discussions and require maintainer approval before a pull request.

If this gate classified the pull request incorrectly, reply and tag a maintainer listed in .github/MAINTAINERS. A verified maintainer can reopen it; reopening by anyone else will be closed again automatically.

Patch size: 21 changed files, 1534 changed lines.

See https://github.com/herdrdev/herdr/blob/master/CONTRIBUTING.md for the contribution policy.

@kangal-bot kangal-bot closed this Aug 4, 2026
cameronsjo added a commit to cameronsjo/herdr that referenced this pull request Aug 4, 2026
Local fork build of herdrdev#2299, which the
contribution gate closes automatically as an over-budget feature.
@cameronsjo

cameronsjo commented Aug 4, 2026

Copy link
Copy Markdown
Author

@ogulcancelik - Opened a discussion, and I'm kind of sort of just over the line. I know the bot gave me a smack down, but would appreciate some human eyes. Thanks for the consideration. I'd really not like to maintain my own fork, and the plugin architecture wouldn't support this fully. 😞

Not so ninja edit: the big win here is that it really just gives the user an easy way to not have to use the cli commands to do this, and makes it so that I don't have to bloat my agents' context with me throwing darts at an unfamiliar dartboard when we're working on something else.

@ogulcancelik

Copy link
Copy Markdown
Collaborator

@cameronsjo bot did the correct thing here, since this is a big feature request. not gigantic but still not a simple bug fix. discussions exist for me to triage, so let's see how much attention your idea gets. if it gets enough upvotes and comments i'll consider it.

@cameronsjo

Copy link
Copy Markdown
Author

@ogulcancelik Agreed, not saying the bot did the wrong thing. And I expected it based on the AGENTS.md and CONTRIBUTING.md.

Appreciate the human eyes regardless.

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.

3 participants