遠(yuǎn)程主機(jī)及本地主機(jī)之間共享 Clipboard,以及 Neovim 訪問 Clipboard 全解析
時(shí)間:2023-07-14 14:06:02 | 來源:網(wǎng)站運(yùn)營(yíng)
時(shí)間:2023-07-14 14:06:02 來源:網(wǎng)站運(yùn)營(yíng)
遠(yuǎn)程主機(jī)及本地主機(jī)之間共享 Clipboard,以及 Neovim 訪問 Clipboard 全解析:
遠(yuǎn)程主機(jī)及本地主機(jī)之間共享 Clipboard,以及 Neovim 訪問 Clipboard 全解析
前言
從本地主機(jī)登錄到一臺(tái)遠(yuǎn)程服務(wù)器或虛擬主機(jī),并且把遠(yuǎn)程主機(jī)上的某個(gè)文件中的內(nèi)容復(fù)制到本地是一個(gè)比較常見的場(chǎng)景,而我們常見的做法通常是用鼠標(biāo)在命令行中選擇然后復(fù)制(Ctrl + v),比如:
顯然,這種方式在遇到長(zhǎng)文本的時(shí)候非常低效,在 Terminal 中使用鼠標(biāo)滾屏選擇文本可不是一個(gè)很好的體驗(yàn)。這時(shí)候,我們需要一種能直接在 Terminal 中與 System Clipboard 交互的工具。
一、在命令行界面通過標(biāo)準(zhǔn)輸入輸出與 System Clipboard 交互我們知道 Ctrl + C 和 Ctrl + V 是我們最常用的在圖形界面下與 System Clipboard 交互的方式,幸運(yùn)的是,Windows, MacOS 及 Linux 也都提供了在命令行界面中使用 stdio/stdout 與 System Clipboard 交互的工具。比如:
(1) WindowsWindows 自帶
clip.exe
,可以在 WSL 中使用:
clip.exe < test.txt
或者可以使用 Powershell 提供的
Set-Clipboard 和
Get-Clipboard 工具來訪問
ls | Set-ClipboardGet-Clipboard > file.txt
還可以使用第三方工具 win32yank,它是使用 Rust 語言開發(fā)的:
win32yank.exe -o --lf
注:--lf 選項(xiàng)的作用是使用 unix 格式
(2) MacOSmacOS 提供了
pbcopy 和
pbpaste 用于在命令行訪問 clipboard 中的內(nèi)容,比如
cat file.txt | pbcopypbpaste
另外,iTerm2 還提供了一個(gè)叫
it2copy 的工具,可以把來自 stdin 的內(nèi)容導(dǎo)入 clipboard,然后我們 CMD + V 可以粘貼出來。
cat file.txt | it2copyit2copy file.txt
(3) Linux使用 xclip/xsel, wl-copy/wl-paste 等。比如:
cat file.txt | xclip -i -sel c
-i 選項(xiàng)就是?—?input, 它的作用就是接受 stdin 的 input。
-o 就是?—?output,同理,我們可以使用:
xclip -o -sel clipboard
另外,pbcopy 原本是 macOS 中的一個(gè)工具,但有人在 Linux 中也實(shí)現(xiàn)了一個(gè)同樣的(見:https://github.com/skaji/remote-pbcopy-iterm2),因此,我們?cè)?remote machine 上也可以用 pbcopy 代替 xclip 來使用。
不過,由于安全的原因, iTerm2 不允許遠(yuǎn)程讀取 pbpaste,因此也就沒有相應(yīng)的 Linux 下的 pbpaste 了,當(dāng)然,這個(gè)并不影響我們粘貼內(nèi)容,我們依然可以使用 CMD + V 來進(jìn)行 paste。
二、把一臺(tái)主機(jī)的 Clipboard 中的內(nèi)容發(fā)送給另一臺(tái)主機(jī)假設(shè)我們需要把本地主機(jī) Clipboard 中的內(nèi)容發(fā)送給另一臺(tái)遠(yuǎn)程主機(jī),那太容易了,登錄遠(yuǎn)程主機(jī),然后在命令行中直接 Ctrl + V 就行了。
但是,如果我們想把遠(yuǎn)程主機(jī) Clipboard 中的內(nèi)容發(fā)送給本地主機(jī),那可就得費(fèi)點(diǎn)周章了。因?yàn)椋?br>
- 1)遠(yuǎn)程主機(jī)可能根本就沒有 Clipboard 這個(gè)東西,比如 Linux 系統(tǒng)本身就沒有 Clipboard 這個(gè)概念,clipboard 只有圖形界面才有,而圖形界面并不是 Linux 系統(tǒng)的一部分,只是一個(gè) GUI 程序而已。也就是說,如果我們?cè)L問的是一個(gè)只有命令行界面而沒有桌面環(huán)境的 Linux Server,那么它是沒有 Clipboard,我們自然也就無從訪問。
- 2)即便遠(yuǎn)程主機(jī)具有圖形界面并且我們通過 VNC 共享桌面, VMWare, VirtualBox 或 ParalellDesktop 等方式連接到到遠(yuǎn)程主機(jī)的 GUI 界面,我們也無法把其 Clipboard 中的內(nèi)容共享到本地。
那怎么辦?方法一:TCP 通信假設(shè)我們現(xiàn)在訪問的是只有命令行界面的 Linux Server,我們可以在本地主機(jī)(比如 MacOS)上啟動(dòng)一個(gè) TCP Server 偵聽,然后在遠(yuǎn)端的 Linux Server 上連接到這個(gè) TCP Server(比如通過 nc 命令),連接成功后,直接發(fā)送數(shù)據(jù)即可 (
cat file.txt | nc localhost 9997
)。本地主機(jī)的 TCP Server 收到數(shù)據(jù)后,可以通過調(diào)用 pbcopy 等工具把收到的數(shù)據(jù)導(dǎo)入到本地主機(jī)中的 System clipboard 中,這樣我們就可以直接訪問來自遠(yuǎn)端 Linux 主機(jī)上的數(shù)據(jù)了。
下面是兩個(gè)實(shí)施這種方法的例子:
案例 1:- 遠(yuǎn)程主機(jī):Ubuntu Server (Headless 無桌面環(huán)境)
- 本地主機(jī):MacOS
- 目標(biāo)需求:把 Linux server 上的 clipboard 內(nèi)容拷貝到本地主機(jī) MacOS 上
步驟一:在本地主機(jī) MacOS 上啟動(dòng)一個(gè) server,把從連接中所接收到的所有內(nèi)容導(dǎo)入到本地的 System Clipboard 中去。建立一個(gè) plist 服務(wù)文件:
local.pbcopy.9999.plist
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict> <key>Label</key> <string>local.pbcopy.9999</string> <key>UserName</key> <string>user1</string> <key>Program</key> <string>/usr/bin/pbcopy</string> <key>StandardOutPath</key> <string>/tmp/pb9999.out</string> <key>StandardErrorPath</key> <string>/tmp/pb9999.err</string> <key>Sockets</key> <dict> <key>Listeners</key> <dict> <key>SockNodeName</key> <string>localhost</string> <key>SockServiceName</key> <string>9999</string> </dict> </dict> <key>inetdCompatibility</key> <dict> <key>Wait</key> <false/> </dict></dict></plist>
啟動(dòng)該服務(wù):
launchctl load local.pbcopy.9999.plist
步驟二:在遠(yuǎn)端主機(jī) Ubuntu 上,發(fā)起一個(gè)連接到本地主機(jī)。把本地主機(jī) MacOS 作為一個(gè) Server,由遠(yuǎn)端主機(jī)向本機(jī)發(fā)起連接。但由于本地主機(jī)通常是在一個(gè) LAN 中,不具有公網(wǎng) IP,因此遠(yuǎn)端的主機(jī) Ubuntu 通常沒辦法主動(dòng)向其發(fā)起連接。
我們可以利用 SSH 從 MacOS 主機(jī)中主動(dòng)向 遠(yuǎn)端的 Ubuntu 主機(jī)發(fā)起一個(gè)反向隧道連接(Reverse Tunnel),如下:
ssh -R 9997:localhost:9999 user@remote.com
解釋:
其中
9997
是 Ubuntu 上的 port,
localhost:9999
則是 macOS 中的 IP:Port。
如果不想每次都打這么一長(zhǎng)串,我們可以在
~/.ssh/config
中配置:
Host ubun* RemoteForward 9997 localhost:9999
這樣,每次我們連接 host name 以 ubun 開頭的 server 都會(huì)自動(dòng)建立反向隧道。
步驟三:遠(yuǎn)端主機(jī) Ubuntu 向 tunnel 中發(fā)送數(shù)據(jù)現(xiàn)在有了 tunnel,我們只需要在 Ubuntu 中向 tunnel 所使用的端口(即 9997)發(fā)送數(shù)據(jù)即可,比如:
cat test.txt | nc localhost 9997
或者,復(fù)雜一點(diǎn)的:
nc localhost 9997 <<EOF> `ls -ld *`> `date`> EOF
另外,我們?cè)诎l(fā)送數(shù)據(jù)之前還可以先檢查一下端口是否已在偵聽:
#!/bin/bashcnt=`(netstat -lnptu 2>/dev/null) | grep 127.0.0.1:9999 | grep -v grep | wc -l`if [[ $cnt -eq 1 ]]; then date | nc localhost 9999fi
步驟四:在本地主機(jī) MacOS 訪問自身的 Clipboard由于 MacOS 中建立的 Server 會(huì)執(zhí)行 pbcopy 命令把從連接中收到的內(nèi)容導(dǎo)入 system clipboard,我們可以直接使用 CMD + V 或者在命令行執(zhí)行 pbpaste 把內(nèi)容粘貼出來了。
案例 2:上述的純手動(dòng)創(chuàng)建 Client/Server 的方式太過于繁瑣,因此有人開發(fā)了一個(gè)專門的工具來完成這個(gè)事情,這個(gè)工具叫
lemonade。它使用 Go 語言實(shí)現(xiàn),可以跨平臺(tái)使用。有了 lemonade,我們不僅可以方便地啟動(dòng) Client/Server,而且不再需要使用其他工具(比如 pbcopy/pbpaste, xclip 等)來訪問 clipboard 了。
下面是使用 lemonade 來完成共享粘貼板的一個(gè)具體方法(非常簡(jiǎn)單)
步驟一:在本地主機(jī)(MacOS) 上啟動(dòng)一個(gè) Serverlemonade server
server 的配置文件
~/.config/lemonade.toml
可以指定 port:
port = 1234allow = '192.168.0.0/24'line-ending = 'crlf'
步驟二:在遠(yuǎn)程主機(jī) Ubuntu Server 上向 MacOS 發(fā)起一個(gè)連接同樣,由于本地的 MacOS 通常是在局域網(wǎng)中的,沒有公網(wǎng) IP,如果遠(yuǎn)程主機(jī)不在同一個(gè)內(nèi)網(wǎng)就不可直接訪問,我們同樣需要使用上面介紹的 SSH Revserve Tunnel 來創(chuàng)建連接。
ssh -R 9997:localhost:9999 user@remote.com
建立 Tunnel 后,我們需要在 Ubuntu 這端配置好 lemonade client 所應(yīng)連接的端口(即 9997)。
編輯如下配置
~/.config/lemonade.toml
:
port = 9997host = localhosttrans-loopback = truetrans-localfile = trueline-ending = 'crlf'
注意:如果遠(yuǎn)程主機(jī)與本地主機(jī)在同一個(gè)網(wǎng)段中可以直接訪問,那我們則不需要?jiǎng)?chuàng)建 SSH tunnel,但是由于 lemonade 缺乏 encryption 和 authorization 功能,所以這樣建立的連接會(huì)有不少安全風(fēng)險(xiǎn),因此依然建議建立 SSH tunnel (正向 tunnel) 來提供更多安全性保障。
步驟三:遠(yuǎn)端主機(jī)(Ubuntu)作為 lemonade client 向本地主機(jī)發(fā)送數(shù)據(jù)cat file.txt | lemonade copy
步驟四:在 本地主機(jī)(MacOS)中訪問 clipboard 內(nèi)容lemonade paste
總結(jié):上述方式有幾個(gè)缺陷:
- 如果有多個(gè) local 機(jī)器連接到 remote machine 的同一個(gè) port,只有第一個(gè)會(huì)收到 content。因此,我們需要 tunnel 到不同的 remote port。
- 如果一個(gè) local 機(jī)器被多個(gè) remote machine 連接,那么也是只有第一個(gè)連接有效。
- netcat 和 lemonade 方式都沒有認(rèn)證,因此很容易造成安全風(fēng)險(xiǎn)。雖然可以用 SSH 創(chuàng)建反向隧道連提升安全性,但總歸不方便。
方法二:使用 X11 Forwarding (or Wayland)
上述的方案實(shí)施起來比較麻煩,易用性一般。有沒有更好的辦法?答案是有的,使用 X11 Forwarding。使用 X11 Forward 之前,我們先了解一下什么是 X 協(xié)議,它是 Linux 上 GUI 的通信協(xié)議,所有 GUI 的顯示都是通過這個(gè)協(xié)議來完成。它分為 X server 和 X client 兩部分,X Server 用來顯示,而 X client 則負(fù)責(zé)發(fā)送顯示指令。
如果我們安裝的是 Linux Desktop,那么其已經(jīng)安裝了 X Window,如果我們安裝的是 Headless Linux server(也就是沒有 GUI 只有命令行的版本),那么 X Window 就沒有安裝。通常我們使用的 Linux 服務(wù)器就是 Headless linux server,沒有 GUI 部分,但是有時(shí)我們又需要顯示 GUI 怎么辦?那我們可以在本地主機(jī)(比如 Windows 或 MacOS,它們自帶桌面 GUI)上安裝一個(gè) X Server,然后在 Linux Server 中安裝 X Client,這樣,我們可以通過把兩者建立連接從而把 Linux Server 中的 GUI 內(nèi)容通過本地主機(jī)上的 X Server 顯示出來。比如,我們?cè)诎惭b了 X Client 的只有命令行界面的 Ubuntu Server 中執(zhí)行 firefox,可以在本地主機(jī)中打開 firebox 瀏覽器界面。
Linux 自身既沒有圖形界面也沒有 system clipboard 這個(gè)概念的,因此你沒辦法在一個(gè) Headless server 中使用 clipboard。只有 X Server (也就是負(fù)責(zé) GUI 顯示的部分)才實(shí)現(xiàn)了 clipboard,比如你在一個(gè)有 GUI 的桌面系統(tǒng)中使用鼠標(biāo)選中文本然后 Ctrl + C 復(fù)制,這時(shí)候文本內(nèi)容就保存在了你 GUI 系統(tǒng)的 clipboard 中了,再執(zhí)行 Ctrl + V 就可以粘貼出來。
因此,現(xiàn)在我們要做的就是,在本地主機(jī)中安裝一個(gè) X Server,在遠(yuǎn)端主機(jī)(Headless Linux Server)中安裝一個(gè) X client (作用就是發(fā)送粘貼文本給 X Server 的 Clipboard)。
我們有如下幾種選擇:
本地主機(jī) (X Server)- Windows: Xming, Vcxsrv, 如果使用 mobaxterm ,其自帶了一個(gè) X Server
- MacOS: XQuartz
- Linux Desktop: 自帶 X Server
遠(yuǎn)端主機(jī) (X Client)- Linux: xclip, xsel, wl-copy/wl-paste
提示:在一個(gè)帶有 Desktop 的 Linux 系統(tǒng)中,X Server 和 X Client 都是在同一個(gè)機(jī)器中的,但是我們這里 X Server 和 X Client 在兩臺(tái)不同的機(jī)器上。
X Server 和 X Client 需要建立通信,通常,我們是使用 SSH 從 X Server 所在的本地主機(jī)登錄到 X Client 所在的遠(yuǎn)端主機(jī)。
這時(shí)候我們就需要用到 SSH 提供的 X11Forwarding 選項(xiàng),在 Ubuntu 中的
/etc/ssh/sshd_config
設(shè)置為 yes 把它開啟之后,就允許在 SSH 連接中轉(zhuǎn)發(fā)基于 X 協(xié)議的通信,簡(jiǎn)單來說就是允許轉(zhuǎn)發(fā) X Client 與 X Server 之間通信的指令,使得它們可以在基于 SSH Tunnel 的連接中通信。比如 xclip 作為 X Client,需要把來自 stdin 的文本內(nèi)容發(fā)送給 X Server 的 clipboard,反過來,X Server 也具有訪問 X Client 的權(quán)限。
這里,我們以 MacOS 為本地主機(jī),Ubuntu/CentOS (headless) 為遠(yuǎn)端主機(jī)作為例子
第一步:在 Ubuntu上安裝 xclip# Ubuntuapt-get install -y xsel xclip # CentOSyum -y install xclip
第二步:SSH server 端(即 Ubuntu)上開啟 X11Forwarding# on Ubuntu/etc/ssh/sshd_config X11Forwarding yes
開啟后,重啟 sshd 服務(wù)
sudo systemctl restart sshd
第三步:SSH Client 端(即本地主機(jī) MacOS 或 Windows)上,也需要開啟 ForwardX11,用于主動(dòng)建立一條 X11 Forward Session。在 ssh client 的配置文件
~/.ssh/config
中如下配置:
# on macOS~/.ssh/configHost * ForwardAgent yes ForwardX11 yes ForwardX11Trusted yes XAuthLocation /opt/X11/bin/xauth
解釋:
- MacOS 端作為 SSH 連接發(fā)起方,需要啟用 ForwardAgent,并且啟用 ForwardX11 或 ForwardX11Trusted 來使用一個(gè)可信的 X11 forward session。
- xauth 程序是用于 X11 通信的認(rèn)證程序,安裝 XQuartz 時(shí)會(huì)自動(dòng)安裝(默認(rèn)安裝路徑是
/opt/X11/bin/xauth
) - 可以直接在命令行使用 -X 或 -Y 選項(xiàng),其中 -X 表示 ForwardX11,-Y 表示 ForwardX11Trusted,如下:
ssh user@ubuntu -Xssh user@ubuntu -Y
-X
和 -Y
的區(qū)別在于:-X
方式是 Untrusted 模式,Xauth cookie 有時(shí)間限制。如果 ssh 時(shí)間過長(zhǎng),會(huì)出現(xiàn)
Error: Can't open display: localhost:10.0) 的情況。而
-Y
則是 trusted 模式,Xauth cookie 沒有時(shí)間限制。我們可以根據(jù)自身需要來進(jìn)行選擇,通常,由于我們是本地環(huán)境,使用 -Y 更加方便,不會(huì)因?yàn)?cookie 過期而導(dǎo)致頻繁掉線。
第四步:在 MacOS 中安裝 XQuartz,前面已經(jīng)介紹了,它是一個(gè) X11 Server。
注:XQuartz 安裝完成時(shí)會(huì)要求我們重新登錄 MacOS 才能生效。
如果是在 Windows 中,我們可以安裝 xming 或 vcxsrv,或者使用 mobaxterm,它自帶一個(gè) X Server。
安裝完成后,我們啟用 XQuartz,然后到 Terminal 中使用 SSH 命令登錄到 Ubuntu Server。
ssh user@ubuntu -Y
登錄后,我們檢查一下 X Server 和 X Client 是否已經(jīng)成功建立連接。
在 macOS 和 linux 中分別查看環(huán)境變量
$DISPLAY
的值:
echo $DISPLAY
如果連接成功,會(huì)得到如下結(jié)果:
# on macOSecho $DISPLAY /private/tmp/com.apple.launchd.aOF9gd84Om/org.xquartz:0# on Ubuntuecho $DISPLAYlocalhost:10.0
解釋:DISPLAY 是 X Server 提供給 X Client 訪問的地址,X Client 通過往這個(gè)地址發(fā)送指令來控制 X Server 的 GUI app 的顯示。如果 $DISPLAY 沒有值,說明連接沒成功,這時(shí)應(yīng)該檢查
/etc/ssh/sshd_config
中是否已開啟 X11Forwarding,并重啟 sshd 服務(wù)。
第五步:在 Ubuntu 命令行中使用 xclip。
現(xiàn)在一切就緒,我們可以用 xclip 把內(nèi)容復(fù)制到 X Server 的 clipboard 中了。
方法如下:
在 Ubuntu 中執(zhí)行如下命令:
# copyls | xclip -ils | xclip -sel c
執(zhí)行上述命令之后,內(nèi)容就已經(jīng)通過 X11 Forward 到了 X Server 的 clipboard 中;也就是說,它已經(jīng)在 MacOS 的 system clipboard 中了,這時(shí),我們就可以在 MacOS 中像正常訪問一樣訪問 system clipboard 了,比如 CMD + V 把內(nèi)容粘貼出來,或者在命令行中使用 pbpaste 把內(nèi)容粘貼出來。
同樣,你在 MacOS 中選中文本 CMD + C 或 pbcopy,回到 Ubuntu 中,你可以直接使用
xclip -o
把內(nèi)容 paste 出來。
# paste content from selections (by default it is primary)xclip -oxclip -o -sel second
至此,我們就已經(jīng)完成了兩個(gè)主機(jī)的 clipboard 共享了。三、在 Neovim 中訪問 System ClipboardNeovim 重新實(shí)現(xiàn)了 Vim 的 clipboard 功能,具體來說就是,它通過調(diào)用第三方工具(也叫 provider)來實(shí)現(xiàn)訪問 system clipboard。
打開 Neovim,執(zhí)行
:checkhealth
- 當(dāng)沒有檢測(cè)到可用的第三方 clipboard 工具時(shí),顯示如下:
顯然,此時(shí) clipboard 功能不可用。
- 當(dāng)檢測(cè)到可用的第三方 clipboard 工具,顯示如下:
此時(shí),clipboard 功能可用。
所以,我們想要使用 Neovim 的 clipboard 功能,一定要先確保類似 xclip/xsel, wl-copy/wl-paste 或 pbcopy/pbpaste 這樣的工具已經(jīng)存在。
另外,如果你系統(tǒng)中已經(jīng)安裝了上述工具,但
:checkhealth
依然提示
"No clipboard tool found" 錯(cuò)誤的話,那是因?yàn)槟銢]有成功連接 X Server,也就是你的
$DISPLAY
沒有顯示正確或沒有值。要解決這個(gè)問題請(qǐng)確保已經(jīng)在 SSH 中開啟 X11Forwarding 并連接成功。
那 Neovim 中的 clipboard 怎么使用,原理又是如何?首先,我們需要設(shè)置:
:set clipboard=unnamed# or:set clipboard=unnamedplus
這條語句的作用是把 clipboard 關(guān)聯(lián)到一個(gè) Neovim 中的寄存器,unamed 寄存器是
*
,而 unnamedplus 寄存器是
+
。
也就是說當(dāng)我們?cè)L問
*
或
+
這兩個(gè)寄存器的時(shí)候,訪問的就是 system clipboard。
*
和
+
沒什么區(qū)別,都是 system clipboard,唯一區(qū)別就是在 Linux 中
*
表示 selection clipboard,而在其他 OS 中,unnamedplus 都表示 system clipboard。如果你設(shè)置了 unnamedplus,那么你所有的操作都會(huì)自動(dòng)被粘貼進(jìn) system clipboard 中。而設(shè)置的是 unnamed 的話,想要訪問 clipboard,就必須手動(dòng)執(zhí)行
"+y
或
"+p
等操作。
在 Vim 中訪問寄存器的方式我們很熟悉。比如,往寄存器
+
中存入數(shù)據(jù),我們可以這樣
# in normal mode"+diw"+yy"+yG# in visual mode"+y
把寄存器 + 中的內(nèi)容粘貼出來:
# in normal mode"+p# in insert mode@=<c-r>+
建議:不建議設(shè)置 clipboard=unnamedplus,因?yàn)楹苋菀着c system clipboard 中的內(nèi)容誤覆蓋,比如你在 Vim 外進(jìn)行操作時(shí)(瀏覽網(wǎng)頁(yè)時(shí)拷貝了一段話),然后你在 Vim 中又執(zhí)行了 x, d 等會(huì)覆蓋 clipboard 內(nèi)容的操作,那么你之前在瀏覽器中拷貝的一段話就被覆蓋了,很可能這并不是你想要的。
因此,建議僅使用 unnamed,如果確實(shí)需要在 Vim 中訪問系統(tǒng)粘貼板,我們?cè)偻ㄟ^手動(dòng)的方式 yank/paste system clipboard。這樣的話,你相當(dāng)于有了兩個(gè) clipboards,一個(gè)是 vim only clipboard 的,一個(gè)是 system clipboard,兩者之間還互不影響。
最后,為了簡(jiǎn)化手動(dòng)復(fù)制的操作,我們綁定一個(gè)快捷鍵即可:
vnoremap <c-c> "+y
上面介紹到 Neovim clipboard 工作方式就是關(guān)聯(lián)到寄存器 +,寄存器 + 又通過第三方工具訪問到 system clipboard。
至此 ,我們就打通了從 Neovim 到 OS clipboard 的互相訪問。Neovim clipboard 的實(shí)現(xiàn)原理我們通過查看
:h clipboard
和
runtime/autoload/clipboard.vim
源碼可以得到如下信息:
The presence of a working clipboard tool implicitly enables the ‘+’ and ‘*’ registers. Nvim looks for these clipboard tools, in order of priority:
- |g:clipboard|
- pbcopy, pbpaste (macOS)
- wl-copy, wl-paste (if $WAYLAND_DISPLAY is set)
- In Arch I found that the package for Wayland is called wl-clipboard, which includes both wl-copy and wl-paste. Thanks for the tip!
- xclip (if $DISPLAY is set)
- xsel (if $DISPLAY is set)
- lemonade (for SSH) https://github.com/pocke/lemonade
- doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/
- win32yank (Windows)
- termux (via termux-clipboard-set, termux-clipboard-set)
- tmux (if $TMUX is set)
解釋:- 首先判斷是否定義了 g:clipboard 變量,如果定義了,那么就調(diào)用該變量所定義的程序。
- 然后判斷 OS 是否是 mac,那么就執(zhí)行 pbcopy 或 pbpaste
- 繼續(xù)判斷是否已定義環(huán)境變量
$WAYLAND_DISPLAY
,如果定義了,就使用 wl-copy/wl-past - 繼續(xù)判斷是否已定義環(huán)境變量
$DISPLAY
,如果定義了,就是用 xclip/xsel - 。。。
總結(jié):簡(jiǎn)單來說,在 Ubuntu 中的 Neovim 執(zhí)行
"+<action>
時(shí),執(zhí)行的就是 xclip,在 MacOS 中的 Neovim 中執(zhí)行
"+<action>
時(shí),執(zhí)行的就是 pbcopy。
前面已經(jīng)介紹過,我們通過 X11Forwarding 把 X Server 和 X Client 建立了連接,因此,在 Neovim 中就可以直接訪問 X Server 的 clipboard 了,我們也就打通了從 Neovim 到 remote machine 再到 local machine 之間的 clipboard 訪問了。
最后,附上一個(gè)示意圖:參考:https://stackoverflow.com/questions/30691466/what-is-difference-between-vims-clipboard-unnamed-and-unnamedplus-settingshttps://superuser.com/questions/407218/why-does-ssh-x-forwarding-timeout-after-a-whilehttps://github.com/lemonade-command/lemonadehttps://developpaper.com/how-to-output-contents-to-the-clipboard-in-windows-mac-linux/https://vim.fandom.com/wiki/Accessing/_the/_system/_clipboard
如果你覺得我的文章對(duì)你有幫助,歡迎留言或者關(guān)注我的專欄。
微信公眾號(hào):“知輝”
搜索“deliverit”或
掃描二維碼
關(guān)鍵詞:主機(jī),訪問,本地,遠(yuǎn)程