✨ Fuzzy search for command palette + Cmd+P project switcher (#34, #35)#38
✨ Fuzzy search for command palette + Cmd+P project switcher (#34, #35)#38
Conversation
Replace prefix/substring-only FuzzyMatcher with non-contiguous character matching. Scoring rewards consecutive matches, word boundary matches, and prefix matches while penalizing gaps. Also fix duplicate 'Set Worktree Status' block in CommandPaletteDataSource and add itemFilter support for filtered palette modes.
Add showProjectsOnly() to CommandPaletteController that opens the palette filtered to projects only with a 'Switch project...' placeholder. Bind Cmd+P in AppDelegate key monitor. Reuses existing palette infrastructure with a filter-based approach rather than a separate controller.
- Replace recursive FuzzyMatcher with O(qLen*cLen) DP approach to eliminate exponential worst-case - Clamp scores to >= 1 (never return negative for valid matches) - Cap consecutive bonus at 5 to prevent unbounded growth - Extract presentPalette() helper to deduplicate show/showProjectsOnly
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 65b0ead691
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if prevRow[c - 1].score > bestPrevScore { | ||
| bestPrevScore = prevRow[c - 1].score | ||
| bestPrevIndex = c - 1 |
There was a problem hiding this comment.
Consider gap penalty when choosing predecessor state
The DP optimization keeps only the maximum previous score (bestPrevScore) and reuses its index for option A, but option A’s transition cost includes a gap-dependent penalty, so the best predecessor is actually argmax(prevScore - gapPenalty) for each c, not simply argmax(prevScore). This can produce suboptimal fuzzy scores and mis-rank results (e.g., a closer match can score lower than a farther one when the farther path had a slightly higher prior score), which directly affects command palette ordering.
Useful? React with 👍 / 👎.
Track far predecessors (gap >= maxGap, constant penalty) separately and check near predecessors individually, since the optimal predecessor depends on both score and distance — not just max score. Addresses Codex review comment on PR #38.
When the project-only palette (Cmd+P) is visible and user presses Cmd+Shift+P, switch to full palette instead of dismissing. Also fix stale comment referencing removed variable name.
Summary
Implements two related features:
🐛 Fix: Command palette fuzzy matching (#35)
FuzzyMatcherfrom prefix/substring-only to true non-contiguous character matching with graduated scoringoprnow matchOpen Project,cwmatchesCreate Worktree✨ Feature: Quick project switching with Cmd+P (#34)
Cmd+Popens the command palette filtered to projects only with a "Switch project..." placeholderCmd+Shift+Pcontinues to open the full palette (unchanged)Other improvements
CommandPaletteDataSource.allItems()itemFilterproperty toCommandPaletteDataSourcefor extensible filtered modespresentPalette()helper to deduplicateshow()/showProjectsOnly()Testing
mise run test)MoriandmoriCLItestFuzzyMatcherNonContiguous,testFuzzyMatcherNonContiguousNoMatchCloses #34, closes #35