Fixed
- Which-key overlay no longer opens on a literal-argument leader key —
r<leader>, and any other command awaiting a literal<character>argument (f,t,m,q,"), opened the leader overlay when the leader key was used as that argument. The fork signalsvim-keypressonly after it has consumed the argument, so the key was indistinguishable from a standalone leader press; the overlay now carries the previous key'sexpectLiteralNextstate across the event and skips leader handling when the key was consumed as an argument. (#186)- Plugin:
src/ui/which-key.ts,src/types/vim-api.d.ts
- Plugin:
:obcommandno longer loses a charwise selection — a mapping such asvim.keymap.set("v", "<C-n>", ":obcommand templater-obsidian:create-new-note-from-template<CR>")ran the Obsidian command with no selection, so Templater and every other selection-dependent command saw nothing; the same command from the command palette, which never goes through the fork, saw it. The fork prefills'<,'>when:is pressed in visual mode, so the dispatcher received'<,'>obcommand …withselectionLine === selectionLineEndfor a selection inside one line — a case the #161 line-range restore skipped outright, while it widened a two-line charwise selection to both whole lines. The handler now rebuilds the range in document offsets from the'</'>marks andlastSelection, which surviveexitVisualModeand carry columns, so charwise, linewise, and blockwise selections each restore as themselves. A typed numeric or%range keeps expanding to whole lines. (#192)- Plugin:
src/workspace/commands.ts
- Plugin:
- Callouts no longer stay highlighted after a linewise yank — a callout the visual-line selection passed through kept a selection-coloured background forever, surviving the yank, further motions, and editing the block. Live Preview renders a callout the cursor is outside of as a block widget, which no CodeMirror mark decoration can reach, so linewise selection paints those widgets by toggling a class on their DOM element; the clearing loops skipped any element that was not
isConnected. That is exactly the element that needs clearing — the moment the selection head enters the callout, Obsidian swaps the widget for source lines and caches the detached element, so the skipped class came back with the element on re-attach, and the element had already been dropped from the plugin's tracking set by then. Both clearing loops now remove the class unconditionally. (#190)- Plugin:
src/vim/linewise-widget-highlight.ts
- Plugin:
- Yank highlight now covers rendered blocks —
yGover a callout flashed every line around it and left the callout itself untouched, and the same held for embedded notes, images, and tables. A block that Live Preview renders is a CodeMirror block widget, and no mark decoration can reach one:ContentBuilder.pointdrops the active marks when it emits a block point. Those blocks are painted through their DOM element instead, on the same timer as the decorations, and a block is painted when the yank touches any line it stands in for — it is opaque, so there is no partial state to show. The painting is derived from the highlight state on every view update rather than applied once, because a linewise yank leaves the CodeMirror selection spanning the range, which makes Live Preview reveal the blocks it touches as source lines; they only return as widgets a transaction later, when the cursor collapses. The fade mode animatesbackground-colorrather than the decorations'opacity, which on a block would take its rendered content down with it. (#190)- Plugin:
src/vim/yank-highlight.ts,src/vim/block-widgets.ts(new — shared withlinewise-widget-highlight.ts) - Styles:
styles.css
- Plugin:
Kon a wikilink now opens a page preview that stays open — the preview either did nothing at all or flashed up for well under a second before vanishing, which made keyword lookup unusable. The action synthesised a barenew MouseEvent('mouseover'), and Obsidian's page preview reads two things off that event. Every hover-link source can be configured to require Ctrl/Cmd, and a modifier-less event does not open the preview — it only arms a document listener that waits for a real Mod keydown, which is whyKlooked inert until Cmd was pressed afterwards. Separately, page preview records the event's client coordinates as the pointer position, and the popover then re-checks every 500ms thatelementFromPoint()there still resolves inside its target element, hiding itself when it does not; an event at (0, 0) resolves to the top-left corner of the window, so the preview hid itself about a second after showing. The event now carries the Mod flag — a deliberateKpress is the explicit request that modifier exists to confirm — and the cursor's own viewport coordinates fromcoordsAtPos, which also anchors the popover to the link rather than to the corner. (#188)- Plugin:
src/workspace/navigation.ts
- Plugin:
Tests
- 5 e2e tests in
test/specs/yank-highlight-widgets.e2e.tsfor #190 —yGpainting a callout and an embedded note, release when the highlight expires, a yank that stops short of the callout leaving it alone, and fade mode keeping the callout's computed opacity at1. Each was negative-controlled against a deliberate break: dropping the coverage filter painted the untouched callout (0 → 1), a no-op unpaint left it lit past expiry (0 → 1), reusing the decorations' opacity fade dropped the callout to opacity0.646399 - 3 e2e tests in
test/specs/linewise-widget-selection-issue190.e2e.tsfor #190 — two drive the stale highlight through the transition that causes it (selection head enters the callout, widget detaches) and assert the re-attached widget is clean after a yank and after<Esc>; the third selects past the callout without ever entering it and asserts the widget is highlighted, because "nothing is highlighted" would otherwise pass for a build that highlights nothing at all. The suite waits on the widget actually rendering, so it cannot pass on an editor that never produced one. Each test strips the class on entry: Obsidian's widget cache outliveseditor.setValue(), so without it the leak fails the following test instead of the one that caused it - 4 e2e tests in
test/specs/obcommand-visual-mode.e2e.tsfor #192 — two drive a real<C-n>mapping and readeditor.getSelection()from inside the dispatched command (single-line and two-line charwise), one runseditor:toggle-boldover a selection straddling two words, one holds:1,2obcommandto whole lines while a charwise selection sits in the marks. The straddle is deliberate: the first version of that test selected a whole word and passed against the unfixed build, becauseeditor:toggle-boldfalls back to the word under the cursor when it sees no selection - 2 e2e tests in
test/specs/keyword-lookup.e2e.tsfor #188 — one forces every registered hover-link source to require Ctrl/Cmd, reproducing the reporter's configuration, and assertsKalone still opens the preview; the other asserts the preview is still on screen 2.5s later, past the 500ms watchdog and the 300ms hide timer it starts. Both assert the popover's text containsTarget.md's body, so a popover from any other surface cannot satisfy them. The first version of the require-Ctrl/Cmd test omitted the configuration step and passed against the unfixed build, because thepreviewsource does not require the modifier by default. Both then failed red (presentfalse in each case), and each half of the fix was controlled in isolation against the finished code: droppingctrlKey/metaKeyfailed only the first test, and pinning the coordinates back to (0, 0) failed only the second
Documentation
CHANGELOG.mdKNOWN_LIMITATIONS.md: extended the ex command path entry in the Obsidian command passthrough section with the charwise restoreCONTRIBUTING.md: addedsrc/vim/block-widgets.tsto the codebase structure treedocs/features/quality-of-life.md: recorded that yank highlight covers rendered blocks wholedocs/features/quality-of-life.md: recorded thatKopens the page preview regardless of the Page preview core plugin's per-source Ctrl/Cmd requirement, and that the preview stays open
Full Changelog: 1.0.0...1.0.1