Simplify remote clipboard and share Neovim yanks over OSC 52 inside tmux

Sessions inside tmux used to skip the clipboard provider entirely, so
yanks only reached the machine's own Wayland clipboard and never
traveled over OSC 52 to clients attached via SSH. Now every copy also
emits OSC 52, which tmux turns into a buffer and rebroadcasts to all
attached clients. Paste prefers wl-paste when a display is available.

This also drops the private-file fallback clipboard and its regtype
sidecar: Neovim's built-in clipboard layer already restores the register
type when pasted content matches its cache, and OSC 52 queries answered
by tmux cover the display-less paste case.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-07-15 10:39:30 -07:00
co-authored by Claude Fable 5
parent 515b566cb9
commit b4e9935951
2 changed files with 45 additions and 221 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# Maintainer: Ryan Hughes <ryan@omarchy.org> # Maintainer: Ryan Hughes <ryan@omarchy.org>
pkgname=omarchy-nvim pkgname=omarchy-nvim
pkgver=2026.6.17 pkgver=2026.7.15
pkgrel=1 pkgrel=1
pkgdesc="Pre-built LazyVim configuration with cached plugins" pkgdesc="Pre-built LazyVim configuration with cached plugins"
arch=('any') arch=('any')
@@ -1,69 +1,10 @@
-- 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.
local M = {} local M = {}
local uv = vim.uv or vim.loop
local function secure_runtime_dir()
local uid = uv.getuid()
local candidates = {}
local function add(path)
if path and path ~= "" then
candidates[#candidates + 1] = path
end
end
add(vim.env.XDG_RUNTIME_DIR)
if uid then
add("/run/user/" .. uid)
add("/dev/shm/nvim-remote-clipboard-" .. uid)
end
for _, dir in ipairs(candidates) do
if dir:sub(1, 9) == "/dev/shm/" then
pcall(vim.fn.mkdir, dir, "p", 448)
pcall(vim.fn.setfperm, dir, "rwx------")
end
local stat = uv.fs_stat(dir)
if stat and stat.type == "directory" and stat.uid == uid and stat.mode % 512 == 448 then
return dir
end
end
end
local function wayland_connection(runtime_dir)
if vim.fn.executable("wl-copy") ~= 1 or vim.fn.executable("wl-paste") ~= 1 then
return nil
end
local function valid_socket(path)
local stat = uv.fs_stat(path)
return stat and stat.type == "socket"
end
if vim.env.WAYLAND_DISPLAY and vim.env.WAYLAND_DISPLAY ~= "" then
local display = vim.env.WAYLAND_DISPLAY
local socket_path = display:sub(1, 1) == "/" and display or (runtime_dir .. "/" .. display)
if valid_socket(socket_path) then
return display
end
end
for _, path in ipairs(vim.fn.glob(runtime_dir .. "/wayland-*", false, true)) do
local display = vim.fn.fnamemodify(path, ":t")
if not display:match("%.lock$") and valid_socket(path) then
return display
end
end
end
local function write_private_file(path, payload)
local tmp_path = path .. "." .. vim.fn.getpid() .. ".tmp"
vim.fn.writefile({ payload }, tmp_path, "b")
vim.fn.setfperm(tmp_path, "rw-------")
vim.fn.rename(tmp_path, path)
vim.fn.setfperm(path, "rw-------")
end
local function proc_lines(pid, file) local function proc_lines(pid, file)
local ok, lines = pcall(vim.fn.readfile, "/proc/" .. pid .. "/" .. file) local ok, lines = pcall(vim.fn.readfile, "/proc/" .. pid .. "/" .. file)
@@ -99,177 +40,60 @@ local function ancestor_process_named(name)
return false return false
end end
local function copy_to_client_clipboard(register, lines)
if vim.g.omarchy_remote_clipboard_osc52 == false then
return
end
local ok, osc52 = pcall(require, "vim.ui.clipboard.osc52")
if ok then
pcall(osc52.copy(register), lines)
end
end
function M.setup() function M.setup()
local in_tmux = vim.env.TMUX ~= nil local in_tmux = vim.env.TMUX ~= nil
local has_display = vim.env.WAYLAND_DISPLAY or vim.env.DISPLAY local in_ssh = vim.env.SSH_TTY ~= nil or vim.env.SSH_CONNECTION ~= nil
local in_remote_session = vim.env.SSH_TTY or vim.env.SSH_CONNECTION
local in_herdr = vim.env.HERDR_PANE_ID ~= nil or ancestor_process_named("herdr") local in_herdr = vim.env.HERDR_PANE_ID ~= nil or ancestor_process_named("herdr")
local needs_remote_clipboard = not in_tmux and (in_herdr or (in_remote_session and not has_display))
if not needs_remote_clipboard then if not (in_tmux or in_ssh or in_herdr) then
return return
end end
local runtime_dir = secure_runtime_dir() local osc52 = require("vim.ui.clipboard.osc52")
if not runtime_dir then local has_wayland = vim.env.WAYLAND_DISPLAY ~= nil
return and vim.fn.executable("wl-copy") == 1
end and vim.fn.executable("wl-paste") == 1
local wayland_display = wayland_connection(runtime_dir) local function copy(register)
local ttl_seconds = 10 * 60 local emit = osc52.copy(register)
local function empty_clipboard() return function(lines)
return { {}, "v" } if has_wayland then
end local cmd = { "wl-copy", "--sensitive", "--type", "text/plain" }
local function read_regtype(path)
local stat = uv.fs_stat(path)
if not stat or stat.uid ~= uv.getuid() or stat.mode % 512 ~= 384 then
return "v"
end
local ok, file_lines = pcall(vim.fn.readfile, path)
if not ok or #file_lines == 0 then
return "v"
end
local ok_decode, data = pcall(vim.fn.json_decode, table.concat(file_lines, "\n"))
if not ok_decode or type(data) ~= "table" then
return "v"
end
if type(data.created_at) == "number" and os.time() - data.created_at > ttl_seconds then
vim.fn.delete(path)
return "v"
end
return type(data.regtype) == "string" and data.regtype or "v"
end
if wayland_display then
local regtype_path = runtime_dir .. "/nvim-remote-clipboard-regtype.json"
local env = {
"env",
"XDG_RUNTIME_DIR=" .. runtime_dir,
"WAYLAND_DISPLAY=" .. wayland_display,
}
local function write_regtype(regtype)
write_private_file(regtype_path, vim.fn.json_encode({
regtype = regtype,
created_at = os.time(),
}))
end
local function copy(register)
return function(lines, regtype)
write_regtype(regtype)
local cmd = vim.list_extend(vim.deepcopy(env), {
"wl-copy",
"--sensitive",
"--type",
"text/plain",
})
if register == "*" then if register == "*" then
cmd[#cmd + 1] = "--primary" cmd[#cmd + 1] = "--primary"
end end
vim.fn.system(cmd, lines) vim.fn.system(cmd, lines)
copy_to_client_clipboard(register, lines) end
if vim.g.omarchy_remote_clipboard_osc52 ~= false then
emit(lines)
end end
end end
local function paste(register)
return function()
local cmd = vim.list_extend(vim.deepcopy(env), { "wl-paste", "--no-newline" })
if register == "*" then
cmd[#cmd + 1] = "--primary"
end
local lines = vim.fn.systemlist(cmd, "", 1)
if vim.v.shell_error ~= 0 then
return empty_clipboard()
end
return { lines, read_regtype(regtype_path) }
end
end
vim.g.clipboard = {
name = "OmarchyWaylandClipboard",
copy = {
["+"] = copy("+"),
["*"] = copy("*"),
},
paste = {
["+"] = paste("+"),
["*"] = paste("*"),
},
cache_enabled = 0,
}
else
local clipboard_path = runtime_dir .. "/nvim-remote-clipboard.json"
local function copy(register)
return function(lines, regtype)
write_private_file(clipboard_path, vim.fn.json_encode({
lines = lines,
regtype = regtype,
created_at = os.time(),
}))
copy_to_client_clipboard(register, lines)
end
end
local function read_clipboard()
local stat = uv.fs_stat(clipboard_path)
if not stat or stat.uid ~= uv.getuid() or stat.mode % 512 ~= 384 then
return empty_clipboard()
end
local ok, file_lines = pcall(vim.fn.readfile, clipboard_path)
if not ok or #file_lines == 0 then
return empty_clipboard()
end
local ok_decode, data = pcall(vim.fn.json_decode, table.concat(file_lines, "\n"))
if not ok_decode or type(data) ~= "table" or type(data.lines) ~= "table" then
return empty_clipboard()
end
if type(data.created_at) == "number" and os.time() - data.created_at > ttl_seconds then
vim.fn.delete(clipboard_path)
return empty_clipboard()
end
return { data.lines, data.regtype or "v" }
end
vim.g.clipboard = {
name = "RemoteRuntimeClipboard",
copy = {
["+"] = copy("+"),
["*"] = copy("*"),
},
paste = {
["+"] = read_clipboard,
["*"] = read_clipboard,
},
cache_enabled = 0,
}
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"
end
local lines = vim.fn.systemlist(cmd, "", 1)
return vim.v.shell_error == 0 and lines or {}
end
end
vim.g.clipboard = {
name = "OmarchyRemoteClipboard",
copy = { ["+"] = copy("+"), ["*"] = copy("*") },
paste = { ["+"] = paste("+"), ["*"] = paste("*") },
cache_enabled = 0,
}
end end
return M return M