Changed
- Picker modal Telescope-style presentation — the unified fuzzy picker now uses a terminal-inspired visual style matching the which-key overlay aesthetic. All text elements use
var(--font-monospace)at compact sizes (11–13px). Items are denser (3px vertical padding, no minimum height). The selected item uses an accent-tinted background (hsla(var(--interactive-accent-hsl), 0.15)) instead of the generic hover color. The modal itself has minimal border-radius (2px), a subtle box-shadow, and an accent-colored border on the input and results panels. The result count bar usesvar(--text-faint)at 11px with a border separator. Preview pane font sizes are unified at 12px. All colors use Obsidian CSS variables for full theme compatibility. (telescope.nvim-inspired)- Plugin:
styles.css(picker CSS section rewritten)
- Plugin:
- Picker floating border titles — each picker section (prompt, results, preview) now displays a centered title label that overlays the top border, matching telescope.nvim's
─── Files ───presentation. The prompt shows the source name (e.g. "Files", "Buffers", "Commands", "Livegrep"), the results list shows "Results", and the preview pane shows "Preview". Titles use monospace font at 11px withvar(--text-muted)color and avar(--modal-background)background to mask the border behind them.- Plugin:
src/picker/picker.ts(formatTitlehelper,.vim-motions-picker-sectionwrapper divs with.vim-motions-picker-titlespans for input, results, and preview sections),styles.css(.vim-motions-picker-section,.vim-motions-picker-titlerules, updated flex layout for preview body wrappers)
- Plugin:
- Picker positional previews use raw text — positional previews (grep, live grep, headings, marks) now render as monospace plain text instead of rendered markdown. This ensures uniform line heights so the line-number gutter stays perfectly aligned with the content —
MarkdownRenderer.render()produces variable-height elements (headings, block elements) that caused the gutter and content to drift apart. Non-positional previews (full file preview without line numbers) continue to use markdown rendering.- Plugin:
src/picker/picker.ts(renderMarkdownPreviewpositional branch rewritten to emit<pre>with per-line<div>elements),styles.css(.vim-motions-picker-preview-code,.vim-motions-picker-preview-code-linerules)
- Plugin:
Fixed
- Neovim golden recorder produced incorrect results for visual-block operations — the
NeovimClient.input()method usednvim_feedkeyswith'tx'flags, which does not fully execute block-insert replication (where<C-v>I/A+ text +<Esc>applies the inserted text to all selected lines) or visual mode-switch + operator combos within a single RPC call. Block insert operations only appeared on the last selected line, and<C-v>→v/Vmode switches produced incorrect deletion scopes. Fixed by using:execute "normal ..."(vianvim.command()) for key sequences containing<C-v>, which processes synchronously within Neovim's command loop. Non-block sequences still usenvim_feedkeys(needed for macro recording/replay which:normaldoesn't support). AddedescapeForNormal()helper to convert control characters to Vim\<...>notation.- Plugin:
test/neovim/client.ts(hybridinput()method,escapeForNormalfunction) - Golden data:
upstream-gaps.json(4 cases corrected),visual-block.json(15 cases corrected — block I/A/c/C/x/~ now correctly affect all selected lines),select-mode.jsonandselect-mode-extended.json(minor corrections from improved key processing)
- Plugin:
- Picker preview gutter misaligned on files with frontmatter — positional previews (grep, live grep, headings, marks) showed line numbers for YAML frontmatter lines, but
MarkdownRenderer.render()silently strips frontmatter from the output. This caused the rendered text to shift up relative to the gutter by the number of frontmatter lines. Fixed by detecting----delimited frontmatter inreadLinesAroundPositionand clamping the preview slice to start after the frontmatter block, so both the gutter and content exclude frontmatter lines.- Plugin:
src/picker/sources/preview-utils.ts(getFrontmatterEndhelper,effectiveStartclamping inreadLinesAroundPosition)
- Plugin:
Added
- Picker matching engine setting — selectable fuzzy matching engine for the picker (Settings → Vim Motions → Picker matching engine). Four options:
ufuzzy(default),nucleo,obsidian,auto. The setting takes effect immediately on the next picker invocation without restarting Obsidian.- uFuzzy (default): Pure JavaScript matcher with filename-aware ranking — prefers exact filename prefix matches over partial path matches (e.g.,
Header.tsxranks aboveheader/utils.tsfor query"Header"). Fastest engine in benchmarks across all query types. Supports typo tolerance. - nucleo (opt-in): WASM-compiled matcher from the Helix editor (~193KB binary). Provides fzf-compatible scoring with optimal Smith-Waterman alignment and path-aware matching. Fork at saberzero1/nucleo-matcher-wasm adds
matchLiteralIndexedWithIndicesandmatchPatternIndexedWithIndicesmethods for efficient WASM boundary crossing. - obsidian (opt-in): Obsidian's built-in
prepareFuzzySearchAPI. Zero bundle cost. May be slower on large vaults. - auto: nucleo on desktop, uFuzzy on mobile. Falls back to uFuzzy if WASM initialization fails.
- Plugin:
src/picker/matcher.ts(factory),src/picker/matcher-ufuzzy.ts(enhanced sort),src/picker/matcher-nucleo.ts(WASM adapter),src/picker/matcher-obsidian.ts(Obsidian API adapter),src/picker/matcher-utils.ts(shared utilities),src/settings.ts(pickerMatcherEnginesetting),esbuild.config.mjs(WASM binary loader plugin)
- uFuzzy (default): Pure JavaScript matcher with filename-aware ranking — prefers exact filename prefix matches over partial path matches (e.g.,
- Enhanced uFuzzy file-picker sort — the uFuzzy matcher now uses a filename-aware ranking algorithm instead of the default sort. The sort prefers: (1) exact filename prefix matches, (2) shorter basenames among prefix matches, (3) filename matches over path-only matches, (4) more exact term boundaries, (5) tighter fuzzy matches, (6) shorter paths. The info phase is capped at 500 items with filename-prefix candidates prioritized, keeping sort overhead bounded for broad queries. Benchmarks show this produces the same #1 result as nucleo's Smith-Waterman scoring for 7 out of 8 test queries at ~25% overhead vs the default sort.
- Plugin:
src/picker/matcher-ufuzzy.ts(filePickerSortfunction, 3-phasefilter()→info()→ custom sort pipeline)
- Plugin:
- Matcher benchmark suite —
npm run test:benchruns a vitest benchmark comparing all three matching engines (uFuzzy, nucleo, obsidian) across 8 query patterns at 1K/5K/10K item counts. Uses realistic file path data (16 directories × 50 filenames × 6 extensions).- Plugin:
test/bench/matcher.bench.ts,vitest.config.ts(benchmark configuration),package.json(test:benchscript)
- Plugin:
- Picker engine switching e2e test — validates that all three engines (ufuzzy, nucleo, obsidian) can be switched at runtime via settings and produce results in the picker.
- Plugin:
test/specs/picker.e2e.ts(matcher engine switching section)
- Plugin:
- Matcher unit tests expanded — parameterized test suite runs 18 shared test cases across all three engines (54 tests total). Nucleo-specific tests cover fzf syntax chars as literals, emoji UTF-32/UTF-16 index correction, CJK characters, and 10K-item performance. Matcher-utils tests cover
indicesToRangesandutf32ToUtf16Indices.- Plugin:
test/unit/picker/matcher.test.ts(68 tests, up from 18)
- Plugin:
- 3 Neovim golden comparison cases for
gkcolumn preservation across headings (gk over heading preserves column,gk over heading then above preserves column,gk gj round-trip preserves column), recorded against Neovim 0.12.2 - 2 spike test suites:
spike-gk-font-variations.e2e.ts(11 tests: CSS theme stress-testing with varying font sizes, line heights, heading sizes, editor widths, padding/margins),spike-gk-column-drift.e2e.ts(4 tests: column drift measurement per heading level with Neovim comparison data)
Documentation
KNOWN_LIMITATIONS.md: updated picker section with four-engine description, filename-aware ranking, bundle size impact; added "gk/gjcolumn drift on heading lines" section documenting the pixel-vs-character column deviation from Neovim with measurement data table; addedgj/gkcolumn row to behavioral deviations table with "Pixel drift" status; updated golden test coverage note (7 → 10 heading tests, 3 golden comparison cases)docs/configuration/settings.md: added picker matching engine setting row with four options and notes sectionAGENTS.md: added nucleo-matcher-wasm fork section (dependency URL, build instructions, WASM binary size, fork API additions, license)ACKNOWLEDGEMENTS.md: added third-party attribution for nucleo-matcher-wasm (MPL-2.0), codemirror-vim (MIT), fengari (MIT)test/neovim/deviations.ts: registered 2 known deviations forgkcolumn preservation across heading lines (pixel-basedposAtCoordsvs Neovim's character-basedcurswant)- Fork
DIFFERENCES.md: updated "Widget-aware vertical navigation" section with clamp-all-jumps approach andposAtCoordscolumn fixup relaxation
Full Changelog: 0.43.0...0.44.0