Skip to content

Add a Cmd/Ctrl+K command palette that searches everything - #91

Merged
danipen merged 6 commits into
mainfrom
command-palette
Sep 25, 2026
Merged

danipen merged 6 commits into
mainfrom
command-palette

Conversation

@danipen

@danipen danipen commented Sep 25, 2026

Copy link
Copy Markdown
Owner

Summary

A Cmd/Ctrl+K command palette: one box that searches commands, branches, files, tags, stashes, worktrees, recent repositories and pasted commit ids. Also reachable from the new Search everything field in the toolbar and View ▸ Search Everything….

  • Enter reveals, never switches. A branch or tag is selected and framed in the Graph. A changed file opens in Changes, any other file opens its history, a stash opens its review, and a commit id opens in History.
  • Act without revealing. Tab, right-click or the row's ⋯ opens the object's own menu — the same builders the branch switcher, History and file lists use.
  • Scopes: > commands, @ branches & tags, / files. Sections always appear in the same order and expand with "N more". Every row highlights what matched.

How it stays fast on huge repos

  • Files are fuzzy-ranked in main (main/search/file-index.ts). The ls-files list is cached per repo, keyed to the git index's mtime and size, and scanned in yielding chunks. Only the best 50 matches cross IPC, and a newer query from the same window abandons the older scan. Changed and untracked files merge in from the snapshot.
  • Refs come from one for-each-ref, with annotated tags peeled to their commits.
  • Matching uses a shared fzf-style matcher (shared/fuzzy.ts), so main and the renderer rank identically.

Refactors along the way

  • Command registry (shared/commands.ts): the native menu builds its items from it, and useAppCommands runs them for both the menu and the palette. Open Repository and About now travel as regular menu commands. Reveal in Finder, Open in Terminal, Copy Repository Path and View on Remote now run from the window through the existing IPC calls.
  • ContextMenu is keyboard-drivable (arrows, Home/End, ←/→ for submenus, focus ring only via :focus-visible) and can hang from a trigger button.
  • Branch menu extracted into common/branchMenuItems.tsx. The switcher's remote-branch menu gains a Checkout item; like clicking a remote row already does, it runs git checkout origin/foo and leaves HEAD detached (existing behaviour, worth a separate decision).
  • GraphView gains revealRequest / onRevealMissed. A miss clears the session's temporary filters and retries; commits fall back to History.
  • New delete-tag confirmation dialog, a <Shortcut> key-cap component, and a .kbd primitive.

Testing

  • Unit tests for the fuzzy matcher, command registry and availability, palette ranking/scoping/limits, graph reveal resolution and position highlighting.
  • Integration tests against real git for getRefs and searchFiles, including cache invalidation and query cancellation.
  • bun run lint, bun run typecheck and bun test (955 tests) pass.
  • Checked in the running app with Playwright in both themes: search, arrow navigation, the Tab-opened menu, branch reveal in the Graph, and commit-id lookup, with no console errors.
  • Not yet checked: the Cmd+K accelerator itself, since key presses sent through the browser debugging protocol never reach the native menu. Needs one manual press.

🤖 Generated with Claude Code

fzf-v1 style subsequence scoring (word-boundary, camelCase and run
bonuses, gap penalties) with a file-name-first path variant and a
bounded top-K collector. Lives in shared so main (file index) and
renderer (commands, refs) rank and highlight identically.
- shared/commands.ts: one list of named app commands (title, shortcut,
  repo gate). The native menu builds its items from it; the renderer's
  useAppCommands runs them, for the menu today and the palette next.
  Open Repository and About now travel as regular menu commands, and
  the folder/terminal/copy/remote items run through the renderer's
  existing IPC.
- getRefs: every branch and tag (annotated tags peeled) in one
  for-each-ref.
- searchFiles: tracked paths cached per repo in main, keyed to the git
  index's mtime+size, fuzzy-ranked in yielding chunks so only the best
  matches cross IPC; a newer query from the same window abandons the
  older scan.
ContextMenu focuses its first item on open (ring only via
:focus-visible), moves with arrows/Home/End, opens and closes
submenus with right/left, and can hang from a trigger button.
The branch switcher's local/remote/GitHub menu items move into a
shared builder so the command palette can offer the same menu;
remote rows gain the Checkout their click already performs.
…icon

highlightPositions marks fuzzy-match positions (with an offset for
showing one slice of a path); acceleratorKeys + <Shortcut> draw a
shortcut as one key cap per key (⌘ K, Ctrl Shift F) on the shared
.kbd primitive.
One box that searches commands, branches, files, tags, stashes,
worktrees, recent repositories and pasted commit ids, in fixed-order
sections with "N more" expansion and >, @, / scope prefixes.

- Enter reveals: a branch or tag is selected and framed in the Graph
  (GraphView.revealRequest; a miss clears the session's own filters
  and retries, commits fall back to History), a changed file opens in
  Changes, any other file its history, a stash its review.
- Tab, right-click or the row's ⋯ open the object's own menu (shared
  branch/commit/file builders), so acting never needs the reveal.
- Files are fuzzy-ranked in main; changed and untracked files merge in
  from the snapshot. Ranking, scoping and limits are pure and tested.
- A quiet Search field with the shortcut in the toolbar for discovery;
  new delete-tag confirmation for the tag menu.
@danipen
danipen merged commit f8a1068 into main Sep 25, 2026
9 checks passed
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.

1 participant