我通过 ssh 访问服务器,在该服务器上运行 vim 来编辑文件。当我尝试使用 y 或 "+y 将 vim 中的文本拉到我的 mac(lion)本地的编辑器中时,它不起作用。我最终得到了我最后在本地复制的文本。如果我只在其中使用 p 它确实有效vim 好的。
15 回答
扩展 Ray 的答案……</p>
当您通过 SSH在远程服务器上使用 Vim 时,您在 Vim 中所做的一切都是在远程服务器上完成的。远程服务器和您在其上运行的远程 Vim 对本地计算机及其系统剪贴板的实际知识为零。
因此,y
永远不会将被拉出的文本放在本地剪贴板中。
为了将一段文本从远程 Vim复制到本地机器的剪贴板,你有三个选项:
用鼠标选择文本并像在任何 Mac OS X 应用程序中一样按Cmd+ 。C
显然,它似乎是最简单的,但它至少有三个限制:
它仅限于当前屏幕。如果您要拉出的文本没有完全显示,您将无法复制所有内容。
它不能很好地与
set mouse=a
. 使用此选项,任何使用鼠标选择某些内容的尝试都将导致无法使用+复制的视觉模式选择。作为一种解决方法,您可以使用+mouse 选择文本而不进入可视模式,或者直接从遥控器中删除此设置。CmdCAlt~/.vimrc
行号也会被复制。
将抽出的文本放在一个临时文件中,
scp
将其放到您的本地计算机上,然后用于pbcopy
将其放入系统剪贴板中。这个解决方案似乎有点令人费解,但它确实有效(而且问题本身也有点令人费解)。多年来,我看到了很多不同的实现,从简单的单列到客户端/服务器设置。这是一个,随意谷歌周围的其他人。
如果可用,请使用 X-forwarding 将本地剪贴板连接到远程剪贴板。
我在 stackoverflow 上的第一个答案,但我觉得这是一个很酷(虽然很小)的技巧,值得发布。所以这就是我所做的:
cat <filename>
当文本打印到终端时,我用鼠标选择所有文本(鼠标滚动工作,因为我们在终端窗口上)。Cmd
然后用+复制该文本C
并粘贴到我的本地文本编辑器中。
这个技巧的唯一缺陷是,如果您的文件有数万行长,那么使用它是不切实际的,因为用鼠标选择所有行本身就是一项任务。但是对于约 2k 行的文件,它运行良好。
有这个问题 - 通过 SSH 从 OSX 登录到 linux 机器,无法从用 vim 打开的文件中复制文本。
我的解决方法是:set mouse=i
默认情况下,鼠标在所有模式下都启用。当您将其设置为仅在插入模式下启用时,您可以在不编辑时滚动和复制(正常模式)但是当您开始编辑(通过按 I 或插入键)并进入插入模式时,鼠标充当光标放置你不能从终端复制。
您可以在 ~/.vimrc 中设置该选项
有关可以设置的值和模式的更多信息,请参阅 :help mouse。
我的首选解决方案是通过 scp 从本地计算机使用 vim 编辑文件。
:e scp://remoteuser@server.tld//path/to/document
这使您的缓冲区保持在本地,并可以轻松复制到本地剪贴板。
另一个优点是您可以使用本地 vim 设置(.vimrc 设置、插件等)
在vi
您 ssh 进入的终端中拉动,将这些行复制到远程机器上 vi 的内部缓冲区中,而不是复制到 Mac 的剪贴板中。
用你的鼠标。:)
在 MacOS 上,当从机器 A SSH 到机器 B 并在机器 B 中使用 vim 时,我将其添加到.vimrc
机器 B 中:
nmap yr :call system("ssh $machineA_IP pbcopy", @*)<CR>
这样,在正常模式下,如果您将某些内容复制到 * register,然后键入yr
,则 vim@machine_B 中 register 的内容将*
复制到机器 A 的本地剪贴板,假设您已正确设置 Vim+clipboard
并*
注册
这是来自 romainl 的解决方案 #2 的更新。它创建 ssh 命令的别名,并在 remotecopyserver 未运行时启动它,并将 remotecopy(rclip) 安装在远程服务器中。简而言之,除了将下面的代码片段粘贴到您的 bash_profile 之外,您无需执行任何操作。
######################## For SSH Remote Copy #########################
export LC_SETUP_RC='command -v rclip >/dev/null 2>&1 || { echo "executing"; mkdir -p /usr/local/bin; if [ ! -f /usr/local/bin/rclip ];then wget https://raw.githubusercontent.com/justone/remotecopy/master/remotecopy -P /usr/local/bin/; ln -s /usr/local/bin/remotecopy /usr/local/bin/rclip; chmod +x /usr/local/bin/remotecopy; fi; if [[ \":\$PATH:\" == *\"/usr/local/bin:\"* ]]; then export PATH=/usr/local/bin:$PATH; fi } > /var/log/rclip.log 2>&1 || echo "Some error occured in setting up rclip. check /var/log/rclip.log"'
ssh_function() {
count="`ps -eaf | grep remotecopyserver | grep -v grep | wc -l`";
if [ "$count" -eq "0" ]; then
mkdir -p $HOME/bin;
if [ ! -f $HOME/bin/remotecopyserver ]; then
wget https://raw.githubusercontent.com/justone/remotecopy/master/remotecopyserver -P $HOME/bin;
chmod +x $HOME/bin/remotecopyserver;
fi;
nohup $HOME/bin/remotecopyserver &
fi;
ssh_cmd=`which ssh`
PARAMS=""
for PARAM in "$@"
do
PARAMS="${PARAMS} \"${PARAM}\""
done
bash -c "ssh ${PARAMS} -R 12345:localhost:12345 -t 'echo \$LC_SETUP_RC | sudo bash; bash -l'"
}
alias ssho=`which ssh`
alias ssh=ssh_function
alias ssh2=ssh_function
vssh_function() {
ssh_config=`vagrant ssh-config`;
if [ "$?" -eq "1" ]; then
echo "Problem with Vagrant config. run 'vagrant ssh-config' to debug"
return 1
fi
PORT=`echo "$ssh_config" | grep Port | grep -o "[0-9]\+"`;
ID_FILE=`echo "$ssh_config" | grep IdentityFile | awk '{print $2}'`
ssh2 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PasswordAuthentication=no -i $ID_FILE vagrant@localhost -p $PORT "$@"
}
alias vssh=vssh_function
激活别名后,您通常可以使用 ssh 并且当您需要从 vim 复制到本地剪贴板时,请使用
:w !rclip
将整个文件复制到剪贴板
:'<,'> !rclip
从视觉模式复制选定的行。每当它要求提供密钥时,您都必须按“Cmd+V”或“Ctrl+V”。
奖金
对于那些在 Vagrant 上工作的人,有一个包装器vssh它将执行vagrant ssh但也会启动和安装必要的组件。
参考
最新代码片段在这里 - https://gist.github.com/ningsuhen/7933b206b92fc57364b2
http://endot.org/2011/12/04/remotecopy-copy-from-remote-terminals-into-your-local-clipboard/
https://github.com/justone/remotecopy
注意事项
别名包装了 ssh 命令,可能会出现一些意想不到的问题。ssho
如果您需要在没有整个 remotecopyserver 的情况下执行 ssh,则可用。或者,您可以使用别名 ssh2 并保持 ssh 命令不变。
如果行数很少溢出我的屏幕,我在使用鼠标复制 vim 文本期间经常使用的一个技巧是最小化(Cmd + '-') 文本。:) 尽量减少到您无法用眼睛看到的程度,但您可以一次性复制所有文本。
或者,从终端写入less [filename]
以将其写入终端。然后在按住 - 键的同时开始用鼠标进行选择down-arrow
。然后你可以选择整个一堆。
https://github.com/ojroques/vim-oscyank + iTerm2 + tmux 在我的情况下工作,这是我的工作流程:
- ssh 进入远程主机
- 打开一个新的 tmux 会话
- 打开 vim(或 neovim),并按照文档所述安装并配置https://github.com/ojroques/vim-oscyank
我的 .vimrc 的某些部分
Plug 'ojroques/vim-oscyank' " clipboard over ssh through tmux
" yank operation don't need to use the *" register (system clipboard)
set clipboard+=unnamedplus
autocmd TextYankPost * if v:event.operator is 'y' && v:event.regname is '' | OSCYankReg " | endif
我希望在这里改进我的解决方案,但会分享它,因为它似乎与其他一些解决方案相当。
在 Mac 上使用 iTerm2,连接到机器,运行 tmux,然后使用 Vim 编辑时,我在 Mac 上有一个垂直拆分的 iTerm2 窗口,我将它一直拉到一边以使其尽可能瘦。
然后,当我想从 Vim 复制文本时,我将单击 iTerm2 窗口的一小部分,然后返回并突出显示,然后从 Vim 复制文本。这对单行文本最有效。
如果有 tmux 垂直分割,高亮显示 Vim 缓冲区中的多行将无法正确换行,并将从另一个 tmux 窗口复制文本,但否则这对于复制我需要的 90% 非常有用,而无需退出 Vim , cat 文件,或做其他事情。
我也有充足的水平窗口空间,使小的 iTerm2 窗口不占空间。
只需使用 MobaXterm。
我尝试了很多方法,但没有一个是容易的。所以我能找到的唯一解决方案是使用 MobaXterm。您可以查看所有文件并以任何您想要的方式打开它们。
复制到本地机器最简单的方法是通过鼠标选择然后CMD + c
复制。正如在另一个答案中指出的那样,这有一些限制/缺点。因此,我寻找了替代方案,但在尝试了几个小时(未成功)使 X11 转发工作后,我想出了以下简单的解决方法(至少对于行号警告)来帮助鼠标复制。
添加以下内容以.vimrc
轻松切换行号以进行鼠标复制:
nnoremap L :set invnumber <CR>
您可以轻松地将 更改为L
您希望成为快捷键的任何键。
尝试其他剪贴板寄存器 - "*y
.