在Mac OS X上将代码粘贴到终端窗口到vim中


69

当我将代码粘贴到Mac OS X终端窗口中的vim中时,它会将每行缩进。每行添加一个缩进,因此文本看起来像这样...

"ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud        
   ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
        reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
             Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
                    deserunt mollit anim id est laborum."

我当前的解决方法是先将文本粘贴到textmate文本编辑器中,以保持正确的格式。然后我保存该文件并在vim中打开它。然后我用vim yank粘贴它。
.vimrc中是否存在可以更改此行为的设置?还是这是一个终端问题?


括号内的粘贴可解决此问题,而无需调用其他命令:set paste。带括号的粘贴在vim 8中是默认可用的。但是只有在vim认为您在Xterm兼容终端中时,才会启用。有多种方法可以使其在vi.stackexchange上看到此答案
Paul Rougieux

Answers:


86

在vim中:

:set paste

将Vim置于粘贴模式。如果要从一个窗口中剪切或复制一些文本并将其粘贴到Vim中,这将很有用。这样可以避免意外的影响。


1
我把它拨动一下;即 我在vimrc中有此文件... set pastetoggle = <F4>
wom

112

更新:Vim 8包括对括号粘贴模式的本地支持。默认情况下启用。请参阅Vim的xterm-bracketed-paste帮助主题。用户不再需要做任何事情来配置Vim来支持它。

从Mac OS X Lion 10.7开始,终端支持“括号内粘贴模式”,当用户粘贴文本时,终端仿真器使终端仿真器可以告诉连接到tty的程序,这样程序就不会将其解释为编辑命令。支持它的程序向终端发送一个转义序列以启用此模式,在该模式下,终端将粘贴的文本用一对标识开始和结束的转义序列包围。

要在Vim中启用此功能,请将以下代码放入〜/ .vimrc文件中:

if &term =~ "xterm.*"
    let &t_ti = &t_ti . "\e[?2004h"
    let &t_te = "\e[?2004l" . &t_te
    function! XTermPasteBegin(ret)
        set pastetoggle=<Esc>[201~
        set paste
        return a:ret
    endfunction
    map <expr> <Esc>[200~ XTermPasteBegin("i")
    imap <expr> <Esc>[200~ XTermPasteBegin("")
    vmap <expr> <Esc>[200~ XTermPasteBegin("c")
    cmap <Esc>[200~ <nop>
    cmap <Esc>[201~ <nop>
endif

这样一来,当Vim将终端切换到备用屏幕†(t_ti,t_te)时,它将启用/禁用方括号粘贴模式(ESC [?2004 h,ESC [?2004 l])。当它收到表示粘贴开始的转义序列(ESC [200〜)时,它将启用“粘贴”模式(设置粘贴),并在必要时切换到“插入”模式(“ i”)。当它收到匹配的粘贴结束标记(ESC [201〜])时,它将禁用粘贴模式(pastetoggle),并保持在插入模式。这些cmap命令使Vim命令行忽略转义序列并按原样接受粘贴的文本。

注意,只有在$ TERM值以“ xterm…”开头时,才启用方括号粘贴模式。如果将$ TERM设置为其他值,则可能需要修改该测试以包含$ TERM值。或者,您可以完全省略该测试,因为它不是严格必要的,它只是在尝试小心不要执行某些可能与某些其他终端类型不兼容的操作。

在终端中,这适用于所有各种粘贴命令以及拖放操作。

†终端有一个主屏幕和一个“备用”屏幕。每个屏幕都有其自己的内容和状态。备用屏幕中的文本不会向上滚动到回滚日志中。它通常由接管整个屏幕的程序使用,因此被称为“全屏”程序。例如,这包括vim,emacs,less和top。


2
您还应该为命令模式添加一个映射(使用冒号输入)。否则,您将失去粘贴到命令行的能力: cmap <Esc>[200~ <nop> cmap <Esc>[201~ <nop>
raimue 2011年


@ChrisPage进行了一些补充,以加快esc映射并使其在tmux中工作:github.com/aaronjensen/vimfiles/blob/master/vimrc#L449-483
Aaron Jensen

6
这个答案已经打包到一个插件中:github.com/ConradIrwin/vim-bracketed-paste
DenilsonSáMaia

1
如果不使用备用屏幕,则可以通过修改t_SIt_EI而不是t_tit_te(分别)在(只是)插入模式下启用它。

9

除了其他答案外,如果您想快速切换粘贴模式,请添加

set pastetoggle=<F2>

到您的.vimrc。现在,您可以通过按F2(或选择的任何键)来切换粘贴模式。


我也将pastetoggle设置为<F2>,但是可以通过让F2调用函数来实现。那是因为在粘贴模式下,我还希望vim取消设置“ showbreak”,以便可以从编辑器窗口中清除副本。
安东尼

注意:我也很好地利用了“ listchars”(使用set“ list”进行切换),因此当不处于粘贴模式时,我可以在行尾看到不间断空格,制表符和多余的空格。这些通常隐藏的字符使我感到非常高兴,而listchars让我知道它们就是它们。vim还没有显示其他许多隐藏的unicode空格字符。
安东尼

9

假设您正确设置了系统剪贴板,另一种方法是

"+p

这将从系统剪贴板粘贴。


3
"*p"+p。该*寄存器是X11主选择,并且+是剪贴板。我不知道Mac OS X是否具有与X11相同的概念。
DenilsonSáMaia 2014年


5

在终端中操作时,vim括号粘贴的vim插件将自动处理粘贴,而无需在粘贴之前或之后进行任何击键。

这可以在Terminal,iTerm2和支持括号粘贴模式的任何“现代” x-term兼容终端中使用。作为额外的好处,它也适用于tmux会话。我在连接到Linux服务器并使用tmux的Mac上与iTerm2一起成功使用了它。

该插件基本上是@Chris Page在其答案中列出的功能的打包版本。


Vim-8内置了它。如果您在命令模式下尝试过去,BUT也会执行插入粘贴操作。那就是您不能再粘贴vim命令!我已经做了30多年的事(从“ vi”和“ elvis”时代开始)
安东尼

Vim 8内置了它……来自补丁8.0.0210,但是Debian当前的稳定版Stretch没有包含该补丁,仅包含0197之后的选定补丁。
Martin Dorey
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.