メインコンテンツへスキップ
  1. Footprints/
  2. Footprints of 2025-12/

2025-12-28

·2 分·

Neovimのclipboardでosc52を使う その2
#

もうちょっと上手く出来ないか,ということで

SSH経由でシステムのClipboardからペーストできないのはまあ良いとして,ローカルで使っている場合はシステムClipboardからペースト出来た方が使い勝手は良いだろう.

ということで,以下のように変更してみた.

-- clipboard
local osc52 = require("vim.ui.clipboard.osc52")

local provider = nil

local paste = {
    ["+"] = nil,
    ["*"] = nil,
}

local paste_unnamed = function()
    return {
        vim.split(vim.fn.getreg(""), "\n"),
        vim.fn.getregtype(""),
    }
end

if not h.is_ssh() then
    if vim.fn.executable("pbpaste") == 1 then
        paste["+"] = { "pbpaste" }
        paste["*"] = { "pbpaste" }
        provider = "osc52-copy-pbpaste"
    elseif vim.fn.executable("wl-paste") == 1 then
        paste["+"] = { "wl-paste", "--no-newline" }
        paste["*"] = { "wl-paste", "--no-newline", "--primary" }
        provider = "osc52-copy-wl-paste"
    elseif vim.fn.executable("waypaste") == 1 then
        paste["+"] = { "waypaste" }
        paste["*"] = { "waypaste", "-p" }
        provider = "osc52-copy-waypaste"
    elseif vim.fn.executable("xclip") == 1 then
        paste["+"] = { "xclip", "-o", "-selection", "clipboard" }
        paste["*"] = { "xclip", "-o", "-selection", "primary" }
        provider = "osc52-copy-xclip"
    elseif vim.fn.executable("xsel") == 1 then
        paste["+"] = { "xsel", "-o", "-b" }
        paste["*"] = { "xsel", "-o", "-p" }
        provider = "osc52-copy-xsel"
	else
	    paste["+"] = paste_unnamed
	    paste["*"] = paste_unnamed
	    provider = "osc52-copy-internal-paste"
    end
else
    paste["+"] = paste_unnamed
    paste["*"] = paste_unnamed
    provider = "osc52-copy-internal-paste"
end

vim.g.clipboard = {
    name = provider,
    copy = {
        ["+"] = osc52.copy("+"),
        ["*"] = osc52.copy("*"),
    },
    paste = {
        ["+"] = paste["+"],
        ["*"] = paste["*"],
    },
}

とりあえず使うことがありそうなClipboard Providerだけ列挙して,executableなものがあればそれを使うようにした.

コマンドはneovimのソースから掘った. 問題無く使えてそう.

Neovimのclipboardでosc52を使う
#

SSH経由のリモートサーバーでNeovimを使うことが多いが,特に明示的にclipboardのproviderを設定していなかったので,度々エラーになっていた. 結局接続元システムのclipboardを使いたいときはnvim-osc52を明示的に使っていたので,あんまり気にしていなかった.

今更ながら,Neovim 10.0でosc52がnativeにサポートされていたと知り設定してみたが,ペーストが上手く機能しない.一定時間ハングして,osc52のリクエストがタイムアウトになる.

原因を調べたところ,そもそもターミナルエミュレータ側がosc52でのペーストをサポートしていない・許可していないケースがあると判明した.(まあセキュリティ的な側面をみれば分からなくはない) Neovimのドキュメントにはシステムのペーストショートカットを使え的な文面があるようだが,それはそれで不便・・・ ということでWorkaroundを探していたところ,pasteのみunnamedregisterから持ってくる手法が紹介されていた.

local osc52 = require("vim.ui.clipboard.osc52")
local paste = function()
    return {
        vim.split(vim.fn.getreg(""), "\n"),
        vim.fn.getregtype(""),
    }
end
vim.opt.clipboard = "unnamedplus"
vim.g.clipboard = {
    name = "osc52-write-only",
    copy = {
        ["+"] = osc52.copy("+"),
        ["*"] = osc52.copy("*"),
    },
    paste = {
        ["+"] = paste,
        ["*"] = paste,
    },
}

neovimの外からペーストするときは基本システムのショートカットを使ってたので,これで今まで通りにはできるだろう.

Myuu
著者
Myuu
CS Researcher