Skip to content

fix(widget): system Cmd+V paste no longer lands at cursor+1 in vim mode - #27

Merged
LikeSundayLikeRain merged 1 commit into
mainfrom
fix/vim-cmd-v-system-paste
Jun 11, 2026
Merged

fix(widget): system Cmd+V paste no longer lands at cursor+1 in vim mode#27
LikeSundayLikeRain merged 1 commit into
mainfrom
fix/vim-cmd-v-system-paste

Conversation

@LikeSundayLikeRain

Copy link
Copy Markdown
Owner

Summary

  • @replit/codemirror-vim 6.3.0 attaches a bubble-phase paste listener on view.contentDOM that, in normal/visual mode, advances the cursor by +1 and forces insert mode (collapsing visual selection) before the native paste insert runs — so Cmd+V/Ctrl+V land at cursor+1 in normal mode and never replace a visual selection.
  • New src/widget/systemPasteExtension.ts (createSystemPasteExtension()) — a ViewPlugin that attaches a capture-phase paste listener on contentDOM, reads clipboardData.getData('text/plain'), dispatches replaceSelection(text) with userEvent: 'input.paste', and calls preventDefault() + stopImmediatePropagation() to pre-empt vim's bubble handler. After insert it routes to insert mode via the public Vim.handleKey API.
  • Wired into buildExtensions immediately after vimCompartment.of(...) so it's always-on (vim ON or OFF — when vim is off the capture handler produces the same result as the native default).
  • Vim register-based p/P/yy/]p paste keys go through vim's internal command dispatcher (not the DOM paste event) and are untouched.

Root-cause artifacts: .planning/debug/vim-cmd-v-paste-offset.md.

Test plan

Automated (CI):

  • npm run build — clean
  • npm run lint — 0 errors
  • npm test — 2965 passed / 8 skipped / 0 failures

Manual UAT (cannot be unit-tested without a live Obsidian instance, per CLAUDE.md):

  • Visual mode replace: enter widget, v + extend, Cmd+V → selection replaced, editor in insert mode.
  • Normal mode insert at cursor: cursor on a char, Cmd+V → clipboard inserted at cursor (not cursor+1).
  • Vim register paste regression: yy then p → line duplicates after-cursor (unchanged).
  • Cmd+V works the same with vim mode OFF (always-on extension shouldn't regress non-vim users).

`@replit/codemirror-vim` 6.3.0 attaches a bubble-phase paste DOM listener
on contentDOM that, when vim is in normal/visual mode, advances the
cursor by +1 and forces insert mode (collapsing the visual selection)
before the native paste insert runs. Result: Cmd+V inserts the clipboard
at cursor+1 in normal mode and never replaces visual selections.

Add `systemPasteExtension` — a capture-phase paste listener on the child
editor's contentDOM that reads `clipboardData.getData('text/plain')`,
dispatches `replaceSelection(text)` with `userEvent: 'input.paste'`,
calls `preventDefault() + stopImmediatePropagation()` to pre-empt vim's
bubble handler, and routes to insert mode via the public `Vim.handleKey`
API. Wired into `buildExtensions` immediately after `vimCompartment.of`.

Vim's register-based `p`/`P`/`yy`/`]p` etc. go through vim's internal
command dispatcher (not the DOM paste event) and are untouched.

Debug session: .planning/debug/vim-cmd-v-paste-offset.md
@LikeSundayLikeRain
LikeSundayLikeRain merged commit eeae3b7 into main Jun 11, 2026
1 check passed
@LikeSundayLikeRain
LikeSundayLikeRain deleted the fix/vim-cmd-v-system-paste branch June 11, 2026 02:40
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