Skip to content

feat(editor): command palette (Ctrl+K) — every command searchable, with its live keybinding - #265

Merged
byrongamatos merged 4 commits into
mainfrom
feat/editor-command-palette
Jul 14, 2026
Merged

feat(editor): command palette (Ctrl+K) — every command searchable, with its live keybinding#265
byrongamatos merged 4 commits into
mainfrom
feat/editor-command-palette

Conversation

@ChrisBeWithYou

@ChrisBeWithYou ChrisBeWithYou commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

What

The biggest discoverability lever available: two testers in one night reported features as missing that already existed (Resnap, bulk barline moves). The palette makes every feature findable by typing what you want.

  • Ctrl+K (the registry id and keybinding were already reserved — this replaces the stub that opened the shortcut panel) opens a centered overlay: type-to-filter, ↑/↓ select, Enter runs, Esc or backdrop-click closes.
  • Entries = every status: 'ready' registry command with its live keybinding for the active shortcut profile, plus every menu action that dispatches a window-fn (the dialog-openers — Scan for tempo zones, Replace audio, User Guide…). cmd: menu rows are skipped as registry duplicates; separators/headers never leak.
  • Ranking: word-start match beats mid-substring beats spread subsequence; the search haystack includes the group/menu title, so "tempo" surfaces the Tempo/Grid actions.
  • Registry commands execute through _editorRunEofCommand — the exact dispatcher the keyboard uses — and menu actions through window[fn], exactly as the menu bar dispatches them. Both arrive as init hooks so command-palette.js imports neither input.js nor menu-bar.js (each would close an import cycle).
  • Digit-family metas (set fret, bookmarks) run through the dispatcher's existing explain-path, so selecting them shows the how-to status rather than doing nothing.

Tests

tests/command_palette.test.mjs (4, fail on main — the module doesn't exist): entry building (ready-only, live keys, menu-fn inclusion, dupe/chrome exclusion), the three-tier ranking, group-aware search, browse/limit/no-match. screen_markup.test.mjs extended to pin the overlay's nesting. Full suite 147 green, lint 0 errors, routes.py untouched.

Live-verified

Real pak: Ctrl+K opens focused with a 12-row browse list; typing "resnap" surfaces "Resnap selection to grid — Shift+R" and Enter dispatches the real command (status "Select notes first"); "user guide" + Enter opens the Help ▸ User Guide modal through the window-fn path; Esc closes clean. Zero page errors.

Note

Song Fit isn't listed — it has no registry id and no menu row (it lives on the tempo-inspector button). The upcoming keybind-profiles PR is the natural place to registry-register it so it becomes palette-findable.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EBQCHCNA81E9tHmSDHSe2Q

Summary by CodeRabbit

  • New Features
    • Added a Command palette accessible with Ctrl+K.
    • Search editor commands and menu actions with fuzzy matching and live keyboard shortcuts.
    • Use ↑/↓ to navigate, Enter to run, and Esc to close the palette.
  • Documentation
    • Added Command palette details to the Unreleased changelog.
  • Tests
    • Added automated coverage for command discovery, filtering/ranking behavior, keyboard shortcuts, and result limiting.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@byrongamatos, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 25 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4311bab4-504a-4f7c-b8f5-20eeedeb25a8

📥 Commits

Reviewing files that changed from the base of the PR and between b96975c and f09713a.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • screen.html
  • src/command-palette.js
  • src/input.js
  • src/main.js
  • tests/command_palette.test.mjs
  • tests/screen_markup.test.mjs
📝 Walkthrough

Walkthrough

The editor gains a Ctrl+K command palette with searchable shortcut and menu actions, keyboard selection, command execution, startup wiring, tests for filtering and entry construction, and changelog documentation.

Changes

Command palette

Layer / File(s) Summary
Palette entries, filtering, and runtime behavior
screen.html, src/command-palette.js
Adds the palette overlay, normalized shortcut/menu entries, ranked fuzzy filtering, result rendering, keyboard navigation, click selection, and command execution.
Editor startup and command dispatch
src/input.js, src/main.js
Routes openCommandPalette to the new palette and initializes it with the editor command runner and menu model.
Behavior validation and documentation
tests/command_palette.test.mjs, tests/screen_markup.test.mjs, CHANGELOG.md
Tests entry construction, ranking, menu-text matching, limits, and empty/non-matching queries; documents the new palette behavior.

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

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Editor as _editorRunEofCommand
  participant Palette as command-palette.js
  participant DOM as Palette DOM
  User->>Editor: Press Ctrl+K
  Editor->>Palette: Open command palette
  Palette->>DOM: Render filtered commands
  User->>Palette: Type query and select result
  Palette->>Editor: Run command or menu function
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the new Ctrl+K command palette and its searchable commands with live keybindings.
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
  • Commit unit tests in branch feat/editor-command-palette

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 `@CHANGELOG.md`:
- Around line 39-45: Update the Command palette changelog entry to reference the
Help ▸ Command palette menu path instead of View ▸ Command palette, leaving the
remaining description unchanged.

In `@src/command-palette.js`:
- Around line 177-182: Update the keydown handler on the command palette input
to handle the Tab key by preventing its default behavior and stopping
propagation, keeping focus trapped within the open palette while preserving the
existing Escape, arrow-key, and Enter 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 59da4ca8-459a-4cfd-ab96-51ae980d136b

📥 Commits

Reviewing files that changed from the base of the PR and between a866705 and 539318a.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • screen.html
  • src/command-palette.js
  • src/input.js
  • src/main.js
  • tests/command_palette.test.mjs
  • tests/screen_markup.test.mjs

Comment thread CHANGELOG.md
Comment thread src/command-palette.js
@byrongamatos
byrongamatos force-pushed the feat/editor-command-palette branch from abfdd8d to af04447 Compare July 14, 2026 18:16
@byrongamatos

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

ChrisBeWithYou and others added 4 commits July 14, 2026 21:08
New src/command-palette.js: fuzzy-searchable entries over the ready
registry rows (live keybinding per active profile) plus menu window-fn
actions; word-start > substring > subsequence ranking. Dispatcher and
menu model arrive as init hooks (no input.js/menu-bar.js cycles).
Replaces the openCommandPalette stub that opened the shortcut panel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBQCHCNA81E9tHmSDHSe2Q
_editorLoadShortcutProfile() returns nothing — passing its result pinned
the palette's displayed keys to the FeedBack profile regardless of the
active one. Use the live editorShortcutProfile binding instead.
The palette is a CLICK on a command, not a keypress, so it belongs on
`editorRunShortcutCommand` — the same by-id path the shortcut panel's
buttons already use — not on `_editorRunEofCommand`, the raw keyboard
switch underneath it.

Going straight to the raw switch left the three digit-RANGE registry rows
silently inert: "Set selected fret 0-9", "Jump to bookmark 1-9" and "Set /
clear bookmark 1-9 at cursor" are all `status: 'ready'`, so the palette
listed them, but `_editorRunEofCommand` only knows the per-digit forms
(`setFretDigit:<n>`, `gotoBookmark:<n>`, …). The bare id fell through to
`default: return false` — palette closes, nothing happens, no status. The
explain-hint that turns those rows into "Press 0-9 to set the selected
note fret" lives in `editorRunShortcutCommand`, which is exactly the path
the panel takes and the palette now takes too.

Also:
- The palette no longer lists itself. `openCommandPalette` is a ready
  registry row (and a View menu row), so it surfaced as a hit that closed
  the palette and immediately reopened it.
- Escape closes from anywhere. The backdrop only covers
  #editor-canvas-wrap, so a click on the menu bar or a toolbar moved focus
  out while the overlay stayed up — and the input's keydown handler, the
  only Escape path, could no longer see the key. main.js's global dialog
  listener now closes it, as it does for the other overlays.
- Close restores the element that had focus before the palette took it,
  rather than blurring whatever happens to be active.
- Drop the unused `_paletteOpen` export.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- The changelog pointed at "View ▸ Command palette"; the `openCommandPalette`
  row actually lives in the HELP menu (menu-bar.js). "View" is its registry
  *group* (the shortcut-panel heading), not its menu.
- Trap Tab. The input is the palette's only focusable node, so Tab walked
  focus into the page behind the open overlay; swallow it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@byrongamatos
byrongamatos force-pushed the feat/editor-command-palette branch from d46ac81 to f09713a Compare July 14, 2026 19:09
@byrongamatos
byrongamatos merged commit 9904e28 into main Jul 14, 2026
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