在伺服器上的 vim 裏按 y,內容只留在 vim 裏,到不了手機。這裏講清楚原因,以及一個小外掛,讓每次複製(yank)都送到手機剪貼簿——在 tmux 裏、走 mosh 也行。
撰寫於
在 vim 裏,y 是複製到 vim 自己的暫存器。這個暫存器在 vim 裏,在伺服器上,不會被送到任何別的地方。在同一個 vim 裏可以用 p 貼回來,但手機完全不知道。
系統剪貼簿暫存器 "+ 和 "* 也幫不上忙。在伺服器上,它們指的是伺服器自己桌面的剪貼簿,而伺服器沒有桌面。大多數伺服器上的 vim 直接就是這樣編譯的:vim --version 裏顯示 -clipboard,"+y 甚麼也不做。就算 vim 帶剪貼簿,複製到的也是伺服器的剪貼簿,不是手機的。SSH 在兩部機器之間傳的是按鍵和畫面,不是剪貼簿。
能從伺服器到達手機的,是一個叫 OSC 52 的跳脫序列。程式把它印出來,終端機就把其中的文字放進它所在裝置的剪貼簿。Term 支援它:文字直接進入手機剪貼簿。vim 自己不會傳送 OSC 52,所以需要一個外掛來做這件事。
vim-oscyank 是一個小外掛,把複製的內容以 OSC 52 送出去。在伺服器上把它裝成 vim 的 package,不需要外掛管理器:
mkdir -p ~/.vim/pack/plugins/start git clone https://github.com/ojroques/vim-oscyank ~/.vim/pack/plugins/start/vim-oscyank
如果用 vim-plug,就在 ~/.vimrc 裏加上 Plug 'ojroques/vim-oscyank', {'branch': 'main'},再執行 :PlugInstall。
外掛只在被呼叫時才運作。要讓平常的每次複製也送到手機,在 ~/.vimrc 裏加上:
" Copy every yank to the phone's clipboard (vim-oscyank, OSC 52) autocmd TextYankPost * \ if v:event.operator is 'y' && v:event.regname is '' | \ execute 'OSCYankRegister "' | \ endif
之後 yy、yw、V 再 y——任何複製到預設暫存器的操作——都會同時到達手機,vim 也會提示:[oscyank] 61 characters copied。文字馬上出現在輸入法的 From clipboard(來自剪貼簿)一欄裏,在手機上任何地方都能貼上。回到 Term 裏,在游標旁長按或按 Ctrl+Shift+V 就能貼上——見終端機裏的複製與貼上。
刪除(d、x)和複製到具名暫存器("ay)仍然只留在 vim 裏,和以前一樣。如果只想有意複製某一段,而不是每次複製都傳送,外掛的 README 裏給了一個對應鍵:選取後按 <leader>c。
tmux 會截住裏面程式發出的 OSC 52。預設設定(set-clipboard external)下它把複製留給自己,於是 vim 提示 copied,手機上卻甚麼也沒有。讓 tmux 把它傳出去:
set -s set-clipboard on然後用 tmux source-file ~/.tmux.conf 重新載入。
走 mosh 時,tmux 還要再加一行。mosh 只轉發 52;c; 這種形式的複製,而 tmux 寫出來的是 52;;,所以在 tmux 裏複製的內容會在路上被丟掉:
set -ag terminal-overrides ',*:Ms=\E]52;%p1%sc;%p2%s\a'不經過 tmux 時,vim-oscyank 本身寫出來的就是 52;c; 形式,所以 mosh 下直接用 vim 不需要額外設定。
同一個外掛在 Neovim 裏也能用:複製到 ~/.local/share/nvim/site/pack/plugins/start/,把同樣的幾行放進 ~/.config/nvim/init.vim。
Neovim 0.10 及以後的版本也內建了 OSC 52(let g:clipboard = 'osc52')。它能複製到手機,但貼上時也用 OSC 52,會向終端機索取剪貼簿內容。Term 不會回應這個請求(見下文),所以 "+p 會停在 Waiting for OSC 52 response from the terminal,然後放棄。外掛只負責複製,所以從不需要等待。貼上請用 Term 自己的貼上。
這是單向的。伺服器上的程式可以把文字放進手機剪貼簿,但 Term 不允許它讀回剪貼簿。這是出於安全考慮:剪貼簿裏常常是密碼、驗證碼和私人訊息,而讀取請求可能來自你連線的任何伺服器上的任何程式——一個指令碼、一個相依套件、別人的機器。所以這個功能目前不開放。要從手機貼上到 vim 裏,在插入模式下用 Term 的貼上:貼上甚麼由你決定,文字會插入到游標處。
mosh 最多傳 16 KB 的剪貼簿內容。更長的複製會被截斷,而且不會報錯。走 SSH 時上限是幾 MB。