如何在运行vim的不同tmux窗格之间复制和粘贴?

72
例子:在一个 tmux 窗格(通过 vim)中复制,然后切换到另一个窗格(运行另一个 vim 实例),并使用 vim 粘贴命令粘贴。我知道可以通过 tmux(使用 prefix+ ] )完成此操作,但如果我只是在不同的运行 vim 的窗格之间切换,使用 vim 绑定复制和粘贴将非常方便。
有什么想法吗?

1
这些 tmux 面板是否在不同的主机上运行 vim?如果不是,我只需运行单个 vim 实例并使用 vim 缓冲区打开 2 个文件并在缓冲区之间粘贴。 - sashang
这可能是由于您的Vim版本未编译支持剪贴板 - 请参见@DmitrySemenov下面的答案。 - JonnyRaa
8个回答

49

抱歉,我试图说服您使用vim内置功能。


为了使复制/粘贴更加容易,您可以在另一个选项卡中打开文件:

:tabe /path/to/another/file

使用gtgT切换选项卡页。


或者分割窗口以编辑另一个文件:

:sp /path/to/another/file

使用 Ctrl-ww 切换窗口。
要垂直分割窗口,请使用 :vsp 文件名


更新:

这是我的 .tmux.conf 文件:

# vim
setw -g mode-keys vi
bind [ copy-mode
bind -t vi-copy v begin-selection
bind -t vi-copy y copy-selection
bind -t vi-copy V rectangle-toggle
bind ] paste-buffer

# buffer
bind Space choose-buffer

我只在需要复制终端输出时才使用它们。

2
有没有办法直接通过tmux来做到这一点?我在不同的目录中打开了不同的窗格,有时使用:tabe或:sp并键入长路径并不方便。更容易切换窗格并粘贴。 - gylaz
这对我没用。它敲了前缀 [, 然后是 v,然后我移动到另一行,然后是 y,然后是前缀 ],但什么也没有发生,即使我重新启动了 tmux。 - Rose Perrone
1
我认为有理由不仅使用一个vim实例。例如,您可能只想在终端中打开三个窗格:一个半屏幕编辑会话,一个四分之一屏幕编辑会话和一个四分之一屏幕终端。我不确定这是否可以通过一个vim实例来实现。 - Zach Conn
1
使用多个Vim实例有合理的理由。例如,如果我有两个显示器,但我想在两个显示器上编辑文件怎么办?或者,如果我有几个完全不同项目的tmux会话,但我想将一个项目中的某些文本复制到另一个项目的文件中怎么办?被限制在单个系统范围内的Vim实例非常不灵活。Vim是一个文本编辑器,而不是操作系统。 - Will Vousden
2
对于更新版本的tmux,应该使用bind-key -T copy-mode-vi ...而不是bind-key -t vi-copy ... - chriad
显示剩余2条评论

24

我已经用了这个方便的绑定工具好几年了 :)

" copy to buffer
vmap <C-c> :w! ~/.vimbuffer<CR>
nmap <C-c> :.w! ~/.vimbuffer<CR>
" paste from buffer
map <C-p> :r ~/.vimbuffer<CR>

3
没错,它没有复制到系统剪贴板。 但它满足了这个问题的要求 :) - chenkaie
有趣的解决方案。您可以使用一个脚本来复制并生成一个基于日期的新文件名,每次都在一个目录中,然后使用另一个脚本从最近的文件名中读取并粘贴。现在您还可以跟踪所有剪贴板。 - NeilG

14

我目前在工作中使用的是运行Windows的笔记本电脑,但是我所有的开发都在运行Linux的服务器上进行,所以我最终会在PuTTY中的tmux会话中工作。

我想要在tmux会话的不同窗口中运行的vim实例之间复制文本。我尝试使用*寄存器来复制到系统剪贴板,但由于我是通过PuTTY连接的,因此我没有X会话,因此即使我启动gVim而不是vim,也没有系统剪贴板。(我可能可以使用x转发或类似方法来解决这个问题,但我不想在Windows上安装x-server。)

我认为应该有一种方法可以在vim中使用tmux的复制/粘贴缓冲区代替系统键盘,果然有人写了一个插件来实现这个功能。

安装fakeclip插件后,添加了一个新寄存器&,它映射到tmux的粘贴缓冲区。由于我的所有vim实例都位于同一个tmux会话中,因此在它们之间复制/粘贴文本变得非常简单。

插件文档说fakeclip也应该适用于gnu screen,但我个人没有测试过。


简而言之

安装fakeclip插件,然后您可以使用"&y来将文本复制到tmux的缓冲区,以及使用"&p从tmux的缓冲区中粘贴


13

虽然我同意最好只使用一个vim实例,但你可以仅使用tmux来实现这一点。它有内置的复制模式。我的tmux.conf设置如下:

  setw -g mode-keys vi
  unbind [
  unbind p
  bind C-y copy-mode
  bind p paste-buffer
  bind -t vi-copy v begin-selection
  bind -t vi-copy y copy-selection
  bind -t vi-copy Escape cancel

所以,您可以使用prefix-<C-y>来激活复制模式,以/search term为例去到您想要的位置,使用v进行可视化选择,使用y将内容复制到tmux中。然后进入其他vim会话并进入插入模式。使用prefix-p粘贴在tmux粘贴缓冲区中的内容。还有一些方法可以将tmux的粘贴缓冲区复制到您的系统剪贴板。


2
为什么最好只使用一个vim实例?这肯定与拥有不同工作区的想法不兼容吧?当我有5个大型、无关的项目要处理时,这似乎并不是很实用。 - Will Vousden
这主要是观点和/或CPU效率的问题。这里有一个视频可以观看:https://vimeo.com/4446112 - Conner

4

您可以使用vim绑定复制内容到剪贴板,然后切换到窗格并粘贴。

以下按键绑定可能会很方便。

noremap ty "+y
noremap tY "+Y  // copy a whole line to the clipboard
noremap tp "+p  // put the text from clipboard after the cursor 
noremap tP "+P  // put the text from clipboard before the cursor 
"+ 寄存器用于在 Vim 中访问系统剪贴板。
一些有用的提示:
1. 您可以按 vVctrl-v 进入可视模式,然后选择要复制的内容,按 ty 将其复制到您的剪贴板中。
2. ty 可以与其他动作组合使用。例如,tyaw 可用于将光标下的单词复制到剪贴板中。tyib 复制括号内的内容。tyi" 复制双引号内的文本,等等...
更多解释请参见如何使 Vim 从(和复制到)系统剪贴板?

为了那些可能不知道这些命令的人,请您添加每个命令的解释,这将使答案更有用! - user4151918
@PetahChristian 我很惊讶我的回答引起了注意!现在我来扩展一下我的回答。如果有什么含糊不清或语法错误(我不是以英语为母语的人),请告诉我 :) - knight42

3

这在neovim中可行。

执行:checkhealth,你会发现类似于以下内容:

## Clipboard (optional)
  - OK: Clipboard tool found: tmux

如果不能,可能需要将tmux升级到最新版本2.9。 然后在“〜/config/nvim/init.vim”中添加以下代码。
set clipboard+=unnamedplus

2

Fedora24的解决方案

您需要使用vimx而不是vim

将其放在您的.bashrc.zshrc

alias vi='vimx'
alias vim='vimx'

然后您可以轻松地在Vim/Tmux面板之间进行复制


$ vim --version | grep clipboard
-clipboard       +insert_expand   +path_extra      -toolbar
+eval            +mouse_dec       +statusline      -xterm_clipboard

$ vimx --version | grep clipboard
+clipboard       +insert_expand   +path_extra      +toolbar
+eval            +mouse_dec       +statusline      +xterm_clipboard

vimx 是 vim-enhanced-2:7.4.1868-1.fc24.x86_64 的一部分,您很可能已经安装了。


-1

控制键+插入键 = 复制

Shift+插入键 = 粘贴


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接