From db5f3791c51b8a73960bcd7610152e8770ac577e Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 12 Sep 2026 16:48:59 +0200 Subject: [PATCH 1/4] Enable automatic clipboard yanks with the remote provider --- pkgbuilds/omarchy-nvim/PKGBUILD | 2 +- pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgbuilds/omarchy-nvim/PKGBUILD b/pkgbuilds/omarchy-nvim/PKGBUILD index d8f64148d..e08f8e5a4 100644 --- a/pkgbuilds/omarchy-nvim/PKGBUILD +++ b/pkgbuilds/omarchy-nvim/PKGBUILD @@ -1,7 +1,7 @@ # Maintainer: Ryan Hughes pkgname=omarchy-nvim pkgver=2026.8.13 -pkgrel=1 +pkgrel=2 pkgdesc="Pre-built LazyVim configuration with cached plugins" arch=('any') url="https://github.com/LazyVim/LazyVim" diff --git a/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua b/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua index b54c54e67..5f3248a6d 100644 --- a/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua +++ b/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua @@ -88,6 +88,9 @@ function M.setup() end end + -- LazyVim disables clipboard syncing over SSH; our provider supports it. + vim.opt.clipboard = "unnamedplus" + vim.g.clipboard = { name = "OmarchyRemoteClipboard", copy = { ["+"] = copy("+"), ["*"] = copy("*") }, From c095aa4ccc84e417e0b29cb4c50181a0c6600740 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 13 Sep 2026 17:46:10 +0200 Subject: [PATCH 2/4] Keep remote clipboard paste fast and cover provider transports --- .../lua/config/remote_clipboard.lua | 66 +++++++--- tests/neovim-remote-clipboard.lua | 123 ++++++++++++++++++ tests/neovim-remote-clipboard.sh | 7 + 3 files changed, 177 insertions(+), 19 deletions(-) create mode 100644 tests/neovim-remote-clipboard.lua create mode 100755 tests/neovim-remote-clipboard.sh diff --git a/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua b/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua index 5f3248a6d..d35d109e1 100644 --- a/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua +++ b/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua @@ -1,9 +1,8 @@ --- Clipboard for sessions whose yanks may need to reach another machine: --- every copy is emitted as OSC 52 (inside tmux this becomes a tmux buffer, --- rebroadcast to every attached client, local or SSH). Paste prefers the --- local Wayland clipboard when one is available, so content copied in other --- apps remains pasteable; without a display, paste is an OSC 52 query that --- tmux (or the terminal) answers. +-- Copies reach the local Wayland clipboard and attached terminals. Reads use +-- Wayland or tmux's buffer, falling back to this Neovim's last copy. Never query +-- the terminal with OSC 52: support for writes does not imply permission to read, +-- and an unanswered query blocks ordinary paste for ten seconds. To insert new +-- text from the host when no readable clipboard exists, use terminal paste. local M = {} local function proc_lines(pid, file) @@ -54,10 +53,15 @@ function M.setup() and vim.fn.executable("wl-copy") == 1 and vim.fn.executable("wl-paste") == 1 + local has_tmux = in_tmux and vim.fn.executable("tmux") == 1 + local last_copy = {} + local function copy(register) local emit = osc52.copy(register) - return function(lines) + return function(lines, regtype) + last_copy[register] = { vim.deepcopy(lines), regtype } + if has_wayland then local cmd = { "wl-copy", "--sensitive", "--type", "text/plain" } if register == "*" then @@ -67,36 +71,60 @@ function M.setup() end if vim.g.omarchy_remote_clipboard_osc52 ~= false then + if has_tmux and register == "+" then + -- Let tmux emit OSC 52, avoiding its input parser's payload size limit. + vim.fn.system({ "tmux", "load-buffer", "-w", "-" }, lines) + if vim.v.shell_error == 0 then + return + end + end emit(lines) end end end local function paste(register) - if not has_wayland then - return osc52.paste(register) - end - return function() - local cmd = { "wl-paste", "--no-newline" } - if register == "*" then - cmd[#cmd + 1] = "--primary" + local cmd + -- tmux's buffer is shared between Neovim instances in the session. Over + -- SSH, prefer it to the remote machine's unrelated graphical clipboard. + if has_tmux and register == "+" and (in_ssh or not has_wayland) + and vim.g.omarchy_remote_clipboard_osc52 ~= false then + cmd = { "tmux", "save-buffer", "-" } + elseif has_wayland then + cmd = { "wl-paste", "--no-newline" } + if register == "*" then + cmd[#cmd + 1] = "--primary" + end + end + + if cmd then + local lines = vim.fn.systemlist(cmd, "", 1) + if vim.v.shell_error == 0 then + -- An empty clipboard is valid; only failed reads use the fallback. + if last_copy[register] and vim.deep_equal(lines, last_copy[register][1]) then + return vim.deepcopy(last_copy[register]) + end + return lines + end end - local lines = vim.fn.systemlist(cmd, "", 1) - return vim.v.shell_error == 0 and lines or {} + return vim.deepcopy(last_copy[register] or { {}, "v" }) end end - -- LazyVim disables clipboard syncing over SSH; our provider supports it. - vim.opt.clipboard = "unnamedplus" - vim.g.clipboard = { name = "OmarchyRemoteClipboard", copy = { ["+"] = copy("+"), ["*"] = copy("*") }, paste = { ["+"] = paste("+"), ["*"] = paste("*") }, cache_enabled = 0, } + + -- LazyVim clears this over SSH. Users can opt out before setup or override + -- the option afterward in config/options.lua. + if vim.g.omarchy_remote_clipboard_sync ~= false then + vim.opt.clipboard:append("unnamedplus") + end end return M diff --git a/tests/neovim-remote-clipboard.lua b/tests/neovim-remote-clipboard.lua new file mode 100644 index 000000000..165ea45fb --- /dev/null +++ b/tests/neovim-remote-clipboard.lua @@ -0,0 +1,123 @@ +local provider = assert(vim.env.TEST_PROVIDER) +local real_system, real_systemlist = vim.fn.system, vim.fn.systemlist +local real_executable, real_readfile = vim.fn.executable, vim.fn.readfile +local writes, reads, emitted, read_result, failed, write_failed + +local function setup(env, options) + for _, key in ipairs({ "SSH_CONNECTION", "SSH_TTY", "TMUX", "HERDR_PANE_ID", "WAYLAND_DISPLAY" }) do + vim.env[key] = nil + end + for key, value in pairs(env) do vim.env[key] = value end + vim.g.clipboard = nil + vim.g.omarchy_remote_clipboard_sync = options and options.sync + vim.g.omarchy_remote_clipboard_osc52 = options and options.osc52 + vim.opt.clipboard = options and options.clipboard or "" + writes, reads, emitted = {}, {}, {} + read_result, failed, write_failed = nil, false, false + vim.fn.readfile = function(path, ...) + if path:match("^/proc/") then return {} end + return real_readfile(path, ...) + end + vim.fn.executable = function(cmd) + if cmd == "tmux" or cmd == "wl-copy" or cmd == "wl-paste" then return 1 end + return real_executable(cmd) + end + vim.fn.system = function(cmd, lines) + writes[#writes + 1] = { cmd, vim.deepcopy(lines) } + real_system({ "sh", "-c", write_failed and "exit 1" or "exit 0" }) + return "" + end + vim.fn.systemlist = function(cmd) + reads[#reads + 1] = cmd + real_system({ "sh", "-c", failed and "exit 1" or "exit 0" }) + return vim.deepcopy(read_result or {}) + end + vim.api.nvim_ui_send = function(data) emitted[#emitted + 1] = data end + -- A clipboard read must never reach Neovim's synchronous OSC 52 query. + require("vim.ui.clipboard.osc52").paste = function() error("OSC 52 read attempted") end + dofile(provider).setup() + vim.cmd("unlet! g:loaded_clipboard_provider") + vim.cmd("runtime autoload/provider/clipboard.vim") +end + +local function equal(actual, expected) + assert(vim.deep_equal(actual, expected), vim.inspect(actual) .. " != " .. vim.inspect(expected)) +end +local function put_yank() + vim.api.nvim_buf_set_lines(0, 0, -1, false, { "probe" }) + vim.cmd("normal! gg0yy") + -- Unnamed clipboard writes are deferred until the command loop returns. + vim.cmd("redraw") + local start = vim.uv.hrtime() + vim.cmd("normal! p") + assert((vim.uv.hrtime() - start) / 1e6 < 1000, "paste blocked") + equal(vim.api.nvim_buf_get_lines(0, 0, -1, false), { "probe", "probe" }) +end + +setup({}) +assert(vim.g.clipboard == nil and vim.o.clipboard == "", "local config changed") +for _, env in ipairs({ { SSH_CONNECTION = "test" }, { SSH_TTY = "test" }, { HERDR_PANE_ID = "test" } }) do + setup(env) + assert(vim.o.clipboard == "unnamedplus") + put_yank() + assert(#emitted > 0 and emitted[1]:find("\27]52;c;", 1, true)) + assert(#reads == 0) + equal(vim.g.clipboard.paste["*"](), { {}, "v" }) + for _, regtype in ipairs({ "v", "V", "\22" .. "3" }) do + vim.g.clipboard.copy["*"]({ "abc" }, regtype) + equal(vim.g.clipboard.paste["*"](), { { "abc" }, regtype }) + end +end +print("ok - local, SSH, SSH_TTY and Herdr setup; real yy/p; no OSC 52 reads; register types") + +setup({ SSH_CONNECTION = "test" }, { sync = false, clipboard = "unnamed" }) +assert(vim.o.clipboard == "unnamed") +setup({ SSH_CONNECTION = "test" }, { clipboard = "unnamed" }) +assert(vim.o.clipboard:find("unnamedplus", 1, true) and vim.o.clipboard:find("unnamed,", 1, true)) +vim.opt.clipboard = "" +assert(vim.o.clipboard == "", "user override must win") +setup({ SSH_CONNECTION = "test" }, { osc52 = false }) +put_yank() +assert(#emitted == 0) +print("ok - sync and OSC 52 opt-outs; existing clipboard flags and subsequent overrides") + +setup({ SSH_CONNECTION = "test", TMUX = "test" }) +local large = { string.rep("x", 1024 * 1024 + 1) } +vim.g.clipboard.copy["+"](large, "v") +equal(writes[1], { { "tmux", "load-buffer", "-w", "-" }, large }) +assert(#emitted == 0) +read_result = { "external buffer" } +equal(vim.g.clipboard.paste["+"](), read_result) +equal(reads[1], { "tmux", "save-buffer", "-" }) +failed = true +equal(vim.g.clipboard.paste["+"](), { large, "v" }) +write_failed = true +vim.g.clipboard.copy["+"]({ "retry" }, "v") +assert(#emitted == 1) +print("ok - tmux large yanks, shared buffer reads, failed read and write fallbacks") + +setup({ TMUX = "test" }, { osc52 = false }) +put_yank() +assert(#writes == 0 and #reads == 0 and #emitted == 0) +setup({ TMUX = "test" }) +failed = true +put_yank() +print("ok - tmux-only yanks and paste; opt-out does not read a stale tmux buffer") + +setup({ HERDR_PANE_ID = "test", WAYLAND_DISPLAY = "test" }) +vim.g.clipboard.copy["*"]({ "primary" }, "v") +equal(writes[1][1], { "wl-copy", "--sensitive", "--type", "text/plain", "--primary" }) +read_result = { "from another app" } +equal(vim.g.clipboard.paste["*"](), read_result) +equal(reads[1], { "wl-paste", "--no-newline", "--primary" }) +read_result = {} +equal(vim.g.clipboard.paste["*"](), {}) +failed = true +equal(vim.g.clipboard.paste["*"](), { { "primary" }, "v" }) +setup({ SSH_CONNECTION = "test", WAYLAND_DISPLAY = "test", TMUX = "test" }) +vim.g.clipboard.copy["+"]({ "both" }, "v") +assert(#writes == 2) +read_result = { "both" } +equal(vim.g.clipboard.paste["+"](), { { "both" }, "v" }) +equal(reads[1], { "tmux", "save-buffer", "-" }) +print("ok - Wayland primary, external, empty and failed reads; SSH prefers tmux") diff --git a/tests/neovim-remote-clipboard.sh b/tests/neovim-remote-clipboard.sh new file mode 100755 index 000000000..50e089abc --- /dev/null +++ b/tests/neovim-remote-clipboard.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -euo pipefail +root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) +export TEST_PROVIDER="$root/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua" +export NVIM_LOG_FILE=$(mktemp) +trap 'rm -f "$NVIM_LOG_FILE"' EXIT +nvim --clean -n --headless -i NONE -l "$root/tests/neovim-remote-clipboard.lua" From 3bfc327f8f94809558104584aebe5c2e3b6828c0 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 13 Sep 2026 17:49:36 +0200 Subject: [PATCH 3/4] Run Neovim clipboard regression tests in CI --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3d0a68e6a..bb8d24894 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,9 +39,10 @@ jobs: -w /workspace \ archlinux:base-devel bash -lc ' set -euo pipefail - pacman -Syu --noconfirm git jq + pacman -Syu --noconfirm git jq neovim ./bin/sync-upstream self-test ./bin/sync-rebuilds --self-test ./bin/omarchy-pkgs self-test ./bin/omarchy-release self-test + ./tests/neovim-remote-clipboard.sh ' From 0022e278c6041f7455c320b22c3bcc93acf4fe86 Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Sun, 13 Sep 2026 19:48:41 -0400 Subject: [PATCH 4/4] Respect tmux clipboard policy and preserve empty reads --- .github/workflows/test.yml | 3 +- .../lua/config/remote_clipboard.lua | 34 +++- tests/neovim-clipboard-tmux.py | 148 ++++++++++++++++++ tests/neovim-remote-clipboard.lua | 12 +- 4 files changed, 191 insertions(+), 6 deletions(-) create mode 100644 tests/neovim-clipboard-tmux.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bb8d24894..a84333dd6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,10 +39,11 @@ jobs: -w /workspace \ archlinux:base-devel bash -lc ' set -euo pipefail - pacman -Syu --noconfirm git jq neovim + pacman -Syu --noconfirm git jq neovim tmux python ./bin/sync-upstream self-test ./bin/sync-rebuilds --self-test ./bin/omarchy-pkgs self-test ./bin/omarchy-release self-test ./tests/neovim-remote-clipboard.sh + python tests/neovim-clipboard-tmux.py ' diff --git a/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua b/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua index d35d109e1..f287de6e2 100644 --- a/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua +++ b/pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua @@ -56,6 +56,11 @@ function M.setup() local has_tmux = in_tmux and vim.fn.executable("tmux") == 1 local last_copy = {} + local function tmux_export_enabled() + local setting = vim.fn.systemlist({ "tmux", "show-options", "-sv", "set-clipboard" }) + return vim.v.shell_error == 0 and (setting[1] == "on" or setting[1] == "external") + end + local function copy(register) local emit = osc52.copy(register) @@ -72,8 +77,21 @@ function M.setup() if vim.g.omarchy_remote_clipboard_osc52 ~= false then if has_tmux and register == "+" then + -- tmux ignores zero-byte loads. Record the current buffer's identity + -- instead: all Neovim instances see empty until a new buffer arrives, + -- without deleting the user's shared tmux clipboard history. + if #lines == 0 or (#lines == 1 and lines[1] == "") then + vim.fn.system({ "tmux", "set-option", "-sF", "@omarchy-nvim-cleared-buffer", "#{buffer_name}" }) + return + end -- Let tmux emit OSC 52, avoiding its input parser's payload size limit. - vim.fn.system({ "tmux", "load-buffer", "-w", "-" }, lines) + -- Explicit -w bypasses set-clipboard, so honor the user's policy first. + local cmd = { "tmux", "load-buffer" } + if tmux_export_enabled() then + cmd[#cmd + 1] = "-w" + end + cmd[#cmd + 1] = "-" + vim.fn.system(cmd, lines) if vim.v.shell_error == 0 then return end @@ -86,11 +104,21 @@ function M.setup() local function paste(register) return function() local cmd - -- tmux's buffer is shared between Neovim instances in the session. Over + -- tmux's buffer is shared between Neovim instances on the server. Over -- SSH, prefer it to the remote machine's unrelated graphical clipboard. if has_tmux and register == "+" and (in_ssh or not has_wayland) and vim.g.omarchy_remote_clipboard_osc52 ~= false then - cmd = { "tmux", "save-buffer", "-" } + local buffers = vim.fn.systemlist({ "tmux", "display-message", "-p", + "#{buffer_name}\n#{@omarchy-nvim-cleared-buffer}" }) + if vim.v.shell_error ~= 0 then + return vim.deepcopy(last_copy[register] or { {}, "v" }) + end + if not buffers[1] or buffers[1] == "" or buffers[1] == buffers[2] then + return { {}, "v" } + end + -- Pin the buffer selected above: a concurrent copy must not change + -- which payload we read after checking its identity against the marker. + cmd = { "tmux", "save-buffer", "-b", buffers[1], "-" } elseif has_wayland then cmd = { "wl-paste", "--no-newline" } if register == "*" then diff --git a/tests/neovim-clipboard-tmux.py b/tests/neovim-clipboard-tmux.py new file mode 100644 index 000000000..6dd7220fd --- /dev/null +++ b/tests/neovim-clipboard-tmux.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +"""Exercise the provider against real, isolated tmux buffers and fake terminals.""" +import base64 +import fcntl +import json +import os +from pathlib import Path +import pty +import select +import struct +import subprocess +import tempfile +import termios +import time + +ROOT = Path(__file__).resolve().parents[1] +PROVIDER = ROOT / "pkgbuilds/omarchy-nvim/lua/config/remote_clipboard.lua" + + +def drain(fd, seconds=0.1): + data = b"" + deadline = time.monotonic() + seconds + while time.monotonic() < deadline: + if select.select([fd], [], [], max(0, deadline - time.monotonic()))[0]: + try: + data += os.read(fd, 65536) + except OSError: + break + return data + + +with tempfile.TemporaryDirectory(prefix="nvim-tmux-test-") as directory: + root = Path(directory) + command = ["tmux", "-S", str(root / "socket"), "-f", "/dev/null"] + clients = [] + + def tmux(*args): + return subprocess.check_output(command + list(args), text=True) + + driver = root / "driver.lua" + driver.write_text(r''' +local request = vim.json.decode(table.concat(vim.fn.readfile(vim.env.TEST_REQUEST), "\n")) +dofile(vim.env.TEST_PROVIDER).setup() +if request.operation == "copy" then + vim.fn.setreg("+", request.lines, request.regtype or "v") +else + local value = vim.g.clipboard.paste["+"]() + local lines = type(value[1]) == "table" and value[1] or value + io.write(vim.json.encode(lines)) +end +''') + + def nvim(operation, lines=None, regtype="v"): + request = root / "request.json" + request.write_text(json.dumps(dict(operation=operation, lines=lines, regtype=regtype))) + env = dict(os.environ) + for key in ("WAYLAND_DISPLAY", "DISPLAY", "HERDR_PANE_ID", "SSH_TTY"): + env.pop(key, None) + env.update( + TMUX=tmux("display-message", "-p", "#{socket_path},#{pid},0").strip(), + TMUX_PANE=tmux("display-message", "-p", "-t", "A:0.0", "#{pane_id}").strip(), + SSH_CONNECTION="test", TEST_PROVIDER=str(PROVIDER), + TEST_REQUEST=str(request), + ) + result = subprocess.run( + ["nvim", "--clean", "-n", "--headless", "-i", "NONE", "-l", str(driver)], + env=env, cwd=root, capture_output=True, text=True, timeout=15, + ) + assert result.returncode == 0, result.stderr + if operation == "paste": + return json.loads(result.stdout) + + try: + tmux("new-session", "-d", "-s", "A") + tmux("new-session", "-d", "-s", "B") + tmux("set-option", "-s", "terminal-features", "xterm*:clipboard") + tmux("set-option", "-g", "set-clipboard", "off") + # Every nvim() call is a separate instance: clearing must be shared. + nvim("copy", [""]) + assert nvim("paste") == [], "empty server clipboard did not stay empty" + tmux("set-buffer", "older history") + nvim("copy", ["private previous value"]) + assert nvim("paste") == ["private previous value"] + history = tmux("list-buffers") + for _ in range(2): + nvim("copy", [""]) + assert nvim("paste") == [], "clear returned stale clipboard text" + assert tmux("list-buffers") == history, "clear destroyed tmux history" + tmux("set-buffer", "external copy") + assert nvim("paste") == ["external copy"], "new copy did not supersede clear" + nvim("copy", [""]) + nvim("copy", ["new Neovim copy"]) + assert nvim("paste") == ["new Neovim copy"] + print("ok - shared empty clipboard, preserved history, and subsequent copies") + + for lines, regtype in [(["line"], "V"), (["a", "b"], "v"), + (["x" * (1024 * 1024 + 1)], "v"), + (["$(touch NEVER) `id`; quotes ' \"", "λ\u001b\n"], "v")]: + nvim("copy", lines, regtype) + # Neovim represents embedded NUL bytes as newline inside a list item. + expected = list(lines) + if regtype == "V": + expected.append("") + actual = nvim("paste") + assert actual == expected, ("transport changed clipboard bytes", repr(actual)[:200], repr(expected)[:200]) + assert not (root / "NEVER").exists(), "clipboard content executed as shell code" + print("ok - real transport: linewise, multiline, large and literal/control payloads") + + # Attach three PTYs, never the developer's terminal or clipboard. + for session in ("A", "A", "B"): + master, slave = pty.openpty() + fcntl.ioctl(slave, termios.TIOCSWINSZ, struct.pack("HHHH", 24, 80, 0, 0)) + + def controlling_tty(): + os.setsid() + fcntl.ioctl(0, termios.TIOCSCTTY, 0) + + env = dict(os.environ, TERM="xterm-256color") + env.pop("TMUX", None) + env.pop("TMUX_PANE", None) + process = subprocess.Popen( + command + ["attach-session", "-t", session], stdin=slave, + stdout=slave, stderr=slave, env=env, preexec_fn=controlling_tty, + ) + os.close(slave) + clients.append((master, process)) + drain(master) + for policy in ("off", "on", "external", "off"): + tmux("set-option", "-s", "set-clipboard", policy) + for fd, _ in clients: + drain(fd) + payload = "synthetic-export-" + policy + nvim("copy", [payload]) + outputs = [drain(fd, 0.3) for fd, _ in clients] + exports = [b"\x1b]52;" in output for output in outputs] + assert not exports[2], "clipboard escaped into an unrelated session" + if policy == "off": + assert not any(exports), "set-clipboard off leaked OSC 52" + else: + assert sum(exports[:2]) == 1, "expected one selected tmux client" + assert any(base64.b64encode(payload.encode()) in output for output in outputs[:2]) + assert nvim("paste") == [payload], "export policy broke internal paste" + print("ok - real clients: export policy, policy changes, selected-client isolation") + finally: + subprocess.run(command + ["kill-server"], capture_output=True) + for fd, process in clients: + process.wait(timeout=5) + os.close(fd) diff --git a/tests/neovim-remote-clipboard.lua b/tests/neovim-remote-clipboard.lua index 165ea45fb..478d44502 100644 --- a/tests/neovim-remote-clipboard.lua +++ b/tests/neovim-remote-clipboard.lua @@ -28,6 +28,14 @@ local function setup(env, options) return "" end vim.fn.systemlist = function(cmd) + if cmd[2] == "show-options" then + real_system({ "sh", "-c", "exit 0" }) + return { "on" } + end + if cmd[2] == "display-message" then + real_system({ "sh", "-c", failed and "exit 1" or "exit 0" }) + return { "buffer-test", "" } + end reads[#reads + 1] = cmd real_system({ "sh", "-c", failed and "exit 1" or "exit 0" }) return vim.deepcopy(read_result or {}) @@ -88,7 +96,7 @@ equal(writes[1], { { "tmux", "load-buffer", "-w", "-" }, large }) assert(#emitted == 0) read_result = { "external buffer" } equal(vim.g.clipboard.paste["+"](), read_result) -equal(reads[1], { "tmux", "save-buffer", "-" }) +equal(reads[1], { "tmux", "save-buffer", "-b", "buffer-test", "-" }) failed = true equal(vim.g.clipboard.paste["+"](), { large, "v" }) write_failed = true @@ -119,5 +127,5 @@ vim.g.clipboard.copy["+"]({ "both" }, "v") assert(#writes == 2) read_result = { "both" } equal(vim.g.clipboard.paste["+"](), { { "both" }, "v" }) -equal(reads[1], { "tmux", "save-buffer", "-" }) +equal(reads[1], { "tmux", "save-buffer", "-b", "buffer-test", "-" }) print("ok - Wayland primary, external, empty and failed reads; SSH prefers tmux")