zudo-text

検索したい単語を入力

いつでも検索バーを開ける

Vim Clipboard Sync — Manual Regression Checklist

Caution

This is the canonical Vim clipboard regression checklist. Parts A–C preserve the original coverage from epics#2043 and#2913; Part D covers the installed macOS external-refresh regression from #5019. The plugin-leg steps require a human verifier with a real installed app.

This checklist covers the regression test for epic #2043 (Vim Clipboard Sync Fix).

Background

tauri-app/renderer/lib/vim-clipboard.ts is now host-aware:

  • Tauri host (installed .app): clipboard I/O routes through @tauri-apps/plugin-clipboard-manager (Rust → NSPasteboard). This is the plugin leg.

  • Browser / dev:mock: clipboard I/O routes through navigator.clipboard. This is the fallback leg.

Installed Tauri builds refresh from the clipboard on Tauri's native window-focus event, with a low-frequency native-plugin polling backstop for macOS activation paths that do not deliver a focus event. Browser builds use the DOM window focus event and never poll the clipboard. Editor focusin only re-asserts the Vim register binding and performs no clipboard read, because a WebKit clipboard read on editor focus can open macOS's native Paste-permission menu.

An automated e2e spec (e2e/vim-clipboard-sync.spec.ts) exercises the fallback leg. The plugin leg requires a human verifier with a freshly installed text app.


Part A — Plugin leg (installed .app)

Run these steps against a freshly installed text app built from the fixed source (post-#2046).

A1 — Yank → external paste

StepActionExpected resultPass / Fail
1Open a generated text app (e.g. modmsg.app). Vim mode must be enabled in Settings → Editor.App opens normally.
2Click the editor, press i, type hello plugin leg, press Escape.Text is visible in the editor.
3Press gg to jump to line 1, then press yy to yank the line.No visible error; cursor stays on line 1.
4Switch to another app (e.g. TextEdit or Notes).App switch completes.
5Press Cmd+V to paste.The yanked text hello plugin leg appears.

A2 — External copy → vim paste

StepActionExpected resultPass / Fail
1In an external app (TextEdit, Notes, etc.), type or select external content. Copy it with Cmd+C.Clipboard holds external content. Confirm via pbpaste in Terminal if needed.
2Switch back to the text app.Window regains focus. (The focus event triggers clipboard sync into the vim register.)
3In the editor in vim normal mode, press p to paste.external content appears in the editor.

Verifier note: run pbpaste in Terminal after each yank step and record the raw output in the PR/issue comment to confirm NSPasteboard received the text.


Part B — Fallback leg (dev:mock browser)

Run these steps against pnpm dev:mock (port 1421, no Tauri host — navigator.clipboard path).

The automated e2e spec (e2e/vim-clipboard-sync.spec.ts) covers the same flow under WebKit headless where clipboard permissions allow it. These manual steps complement the spec for environments where headless clipboard access is blocked.

B1 — Yank → external paste (browser fallback)

StepActionExpected resultPass / Fail
1Run pnpm dev:mock and open http://localhost:1421 in a browser.App loads.
2Click the editor, press i, type hello fallback leg, press Escape.Text visible in editor.
3Press gg then yy.No error.
4Open the browser DevTools console and run: await navigator.clipboard.readText().Returns hello fallback leg.

B2 — External copy → vim paste (browser fallback)

StepActionExpected resultPass / Fail
1In the browser DevTools console, run: await navigator.clipboard.writeText('external fallback').No error.
2Click back to the editor. In vim normal mode, press p.external fallback appears in the editor. (Note: the sync-from-clipboard fires on window focus — clicking back counts as a focus event.)

Part C — Lifecycle race / self-healing guard rail (epic #2913)

This part covers the intermittent "yank stops copying to the clipboard until I relaunch the app" bug. Root cause: vim-clipboard.ts was a module-level singleton with no ownership, and multiple concurrent editor instances (main editor, archive editor, external-file-editor tabs) all shared it. A non-owning instance's teardownVimClipboard() on unmount/re-render could detach the binding from the still-focused editor, which never re-installed it.

The fix makes the singleton ownership-aware (single-owner, last-setup-wins; teardown is a no-op unless the caller is the current owner) and self-healing (re-asserts the binding on window focus + editor focusin — identity-only, zero clipboard I/O — plus a low-frequency interval backstop).

Run against an installed .app (plugin leg) for the authoritative verdict. Vim mode + Clipboard Sync must both be on (Settings → Editor / Vim).

C1 — Yank survives multi-editor churn

StepActionExpected resultPass / Fail
1Open a text app. In the main editor, type some text and yank a line (yy); paste into an external app (Cmd+V).Yanked text pastes.
2Open an external file in the external-file-editor (a second editor instance), then close that tab / switch focus back to the main editor.Focus returns to the main editor.
3In the main editor, yank a different line (yy) and paste into an external app.The new line pastes — yank still copies to the clipboard (pre-fix: this silently pasted the old/wrong text or nothing).
4Change any editor/vim setting (forces an editor rebuild), then yank again and paste.Yank still copies to the clipboard.

C2 — Self-heal after drift

StepActionExpected resultPass / Fail
1With vim + Clipboard Sync on, switch to another app and back (window blur → focus).On regaining focus the binding is re-asserted (and the external clipboard is synced in for p).
2Yank a line and paste into an external app.Yanked text pastes. No relaunch ever required.

Part D — Installed macOS external refresh (#5019)

Run this part against a freshly installed .app, not dev:mock. Keep Vim mode and Clipboard Sync enabled. Use distinct strings in each cycle so an old register value cannot look like a pass.

D1 — External ownership refresh and focus-menu guard

StepActionExpected resultPass / Fail
1In the Vim editor, create a line containing zudo yank 1, press Escape, then yy. Switch to TextEdit and press Cmd+V.TextEdit receives zudo yank 1.
2In TextEdit, copy the distinct text textedit copy 1, then switch back to the installed app and wait 2.5 seconds.The app regains focus without showing the native Paste-permission menu; the polling backstop has had time to run even if macOS omitted both focus signals.
3Without using Cmd+V, press p in Vim normal mode.Vim inserts textedit copy 1, not zudo yank 1.
4Click between the editor, preview, and editor again several times.Merely focusing the editor never shows the native Paste-permission menu.

D2 — Refresh survives editor lifecycle changes

StepActionExpected resultPass / Fail
1Open an external-file-editor tab, focus its editor, then close the tab and return to the main Vim editor. In TextEdit copy textedit after tab, return to the app, and press p.Vim inserts textedit after tab; the closed editor did not leave a stale or duplicate listener.
2Change an editor or Vim setting that rebuilds/reconfigures the editor. In TextEdit copy textedit after rebuild, return to the app, and press p.Vim inserts textedit after rebuild without relaunching.
3Repeat a full app blur → focus cycle with textedit after blur, then press p.Vim inserts textedit after blur.
4Immediately after returning from TextEdit, yank a new Vim line before an earlier clipboard read could reasonably finish, then paste into TextEdit.The new yank remains authoritative; a stale async read does not overwrite it.

Pass criteria

All rows in Parts A and B (the original eight), Part C, and Part D must show Pass for the fix to be considered verified. Record any Fail rows with the actual observed behavior in the relevant issue. Post Part D evidence to #2916, but keep that tracker open until its integrated confirmation sub-issue passes.

Automation coverage

WhatWhereLeg covered
Unit tests (adapter contract, native/DOM focus, stale-read guards, ownership/guard rail)tauri-app/renderer/lib/vim-clipboard.test.tsBoth legs (mocked)
E2E spec (browser, WebKit)e2e/vim-clipboard-sync.spec.tsFallback (navigator.clipboard); guard-rail focus-cycle regression
This manual checklist (Part A)Human + installed .appPlugin (@tauri-apps/plugin-clipboard-manager)
This manual checklist (Part B)Human + dev:mockFallback (navigator.clipboard)