‹ 指南

把 vim 里复制的内容送到手机剪贴板

在服务器上的 vim 里按 y,内容只留在 vim 里,到不了手机。这里讲清楚原因,以及一个小插件,让每次复制(yank)都送到手机剪贴板——在 tmux 里、走 mosh 也行。

撰写于

为什么 y 到不了手机

在 vim 里,y 是复制到 vim 自己的寄存器。这个寄存器在 vim 里,在服务器上,不会被送到任何别的地方。在同一个 vim 里可以用 p 粘回来,但手机完全不知道。

系统剪贴板寄存器 "+ 和 "* 也帮不上忙。在服务器上,它们指的是服务器自己桌面的剪贴板,而服务器没有桌面。大多数服务器上的 vim 直接就是这样编译的:vim --version 里显示 -clipboard,"+y 什么也不做。就算 vim 带剪贴板,复制到的也是服务器的剪贴板,不是手机的。SSH 在两台机器之间传的是按键和屏幕,不是剪贴板。

手机上的 Term 里,vim 打开 deploy-notes.txt,按 V、j、j、y 之后:vim 提示 3 lines yanked,鸿蒙输入法上没有出现 From clipboard(来自剪贴板)一栏。
普通的 vim:3 lines yanked——复制进了 vim。输入法的剪贴板一栏对此一无所知。

能从服务器到达手机的,是一个叫 OSC 52 的转义序列。程序把它打印出来,终端就把其中的文字放进它所在设备的剪贴板。Term 支持它:文字直接进入手机剪贴板。vim 自己不会发送 OSC 52,所以需要一个插件来做这件事。

安装 vim-oscyank

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 里加上:

~/.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 就能粘贴——见终端里的复制与粘贴。

手机上的 Term 里,装了 vim-oscyank 的 vim 按 V、j、j、y 之后,提示 [oscyank] 61 characters copied,鸿蒙输入法在 From clipboard 一栏里给出 server: prod-web-01 deploy: 2026-10-09。
装了插件:同样的复制这次到了手机上,输入法在 From clipboard(来自剪贴板)一栏里给出这段文字。
两张图:Term 的粘贴窗口里显示复制的三行和一个粘贴按钮;然后 shell 提示符上是粘贴进来的同样三行,处于高亮状态,还没有执行。
回到提示符:长按、粘贴,vim 里复制的三行——先在粘贴窗口里确认,再停在提示符上等你执行。

删除(d、x)和复制到命名寄存器("ay)仍然只留在 vim 里,和以前一样。如果只想有意复制某一段,而不是每次复制都发送,插件的 README 里给了一个映射:选中后按 <leader>c。

在 tmux 里:加一行

tmux 会截住里面程序发出的 OSC 52。默认设置(set-clipboard external)下它把复制留给自己,于是 vim 提示 copied,手机上却什么也没有。让 tmux 把它传出去:

~/.tmux.conf
set -s set-clipboard on

然后用 tmux source-file ~/.tmux.conf 重新加载。

走 mosh 时,tmux 还要再加一行。mosh 只转发 52;c; 这种形式的复制,而 tmux 写出来的是 52;;,所以在 tmux 里复制的内容会在路上被丢掉:

~/.tmux.conf
set -ag terminal-overrides ',*:Ms=\E]52;%p1%sc;%p2%s\a'

不经过 tmux 时,vim-oscyank 本身写出来的就是 52;c; 形式,所以 mosh 下直接用 vim 不需要额外设置。

Neovim

同一个插件在 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 下的长内容

mosh 最多传 16 KB 的剪贴板内容。更长的复制会被截断,而且不会报错。走 SSH 时上限是几 MB。