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

Posted

技术标签:

【中文标题】在 Mac OS X 上将代码粘贴到终端窗口中的 vim【英文标题】:Pasting code into terminal window into vim on Mac OS X 【发布时间】:2011-07-31 21:42:46 【问题描述】:

当我将代码粘贴到我的 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 上的this answer。 【参考方案1】:

更新: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 ~) 时,它启用粘贴模式 (set paste) 并在必要时切换到插入模式 ("i")。当它接收到匹配的粘贴结束标记 (ESC [ 201 ~) 时,它会禁用粘贴模式 (pastetoggle) 并保持插入模式。 cmap 命令安排 Vim 命令行忽略转义序列并按原样接受粘贴的文本。

请注意,这仅在 $TERM 值以“xterm…”开头时启用括号粘贴模式;如果您将 $TERM 设置为其他值,您可能需要修改该测试以包含您的 $TERM 值。或者,您可以完全省略测试,因为它不是绝对必要的——它只是要小心不要做一些可能与其他终端类型不兼容的事情。

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

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

【讨论】:

您还应该为命令模式添加一个映射(在您输入时使用冒号)。否则你将失去粘贴到命令行的能力:cmap &lt;Esc&gt;[200~ &lt;nop&gt;cmap &lt;Esc&gt;[201~ &lt;nop&gt; iTerm2 现在支持此功能:iterm2.googlecode.com/svn/trunk/appcasts/testing_changes.html @ChrisPage 增加了一些加速 esc 映射并使其在 tmux 中工作:github.com/aaronjensen/vimfiles/blob/master/vimrc#L449-483 这个答案已经打包成一个插件:github.com/ConradIrwin/vim-bracketed-paste 如果您不使用备用屏幕,您可以通过修改t_SIt_EI 而不是t_tit_te(分别)在(仅)插入模式下启用它。 【参考方案2】:

在 vim 中:

:set paste

将 Vim 置于粘贴模式。如果您想剪切或复制,这很有用 来自一个窗口的一些文本并将其粘贴到 Vim 中。这将避免 意想不到的效果。

【讨论】:

我会把它放在一个开关上;即;我的 vimrc 中有这个... set pastetoggle=【参考方案3】:

另一种方法是这样做,假设你的系统剪贴板设置正确

"+p

这将从系统剪贴板粘贴。

【讨论】:

"*p"+p* 寄存器是 X11 主要选择,+ 是剪贴板。不知道 Mac OS X 是不是和 X11 一样的概念。【参考方案4】:

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

set pastetoggle=<F2>

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

【讨论】:

我也将 pastetoggle 设置为 但通过让 F2 调用函数来实现。那是因为在粘贴模式下我还希望 vim 取消设置“showbreak”,以便我可以从编辑器窗口中清除副本。 注意:我还充分利用了“listchars”(使用 set“list”切换),所以当不处于粘贴模式时,我可以看到不间断的空格、制表符和多余的空格队伍的尽头。这个通常隐藏的字符给我带来了很多 greif,而 listchars 让我知道它们是他们的。还有一些其他隐藏的 unicode 空格字符 vim 不会“显示”。【参考方案5】:

在 vim 中

:设置粘贴

当你想禁用它时

:设置不粘贴

【讨论】:

:set paste! 切换它。【参考方案6】:

在终端中工作时,vim-bracketed-paste vim 插件将自动处理粘贴,而无需在粘贴之前或之后进行任何击键。

这适用于终端、iTerm2 和任何支持括号粘贴模式的“现代”x-term 兼容终端。作为额外的奖励,它也适用于 tmux 会话。我在连接到 linux 服务器并使用 tmux 的 Mac 上通过 iTerm2 成功使用它。

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

【讨论】:

Vim-8 内置了它。但是如果您在命令模式下尝试并过去,它也会执行插入粘贴。那就是你不能再粘贴 vim 命令了!我已经做了 30 多年的事情(从“vi”和“elvis”时代开始) Vim 8 已内置...来自Patch 8.0.0210,但 Debian 当前的稳定版 Stretch 不包含该补丁,仅包含 0197 之后的选定补丁。

以上是关于在 Mac OS X 上将代码粘贴到终端窗口中的 vim的主要内容,如果未能解决你的问题,请参考以下文章

SSH SCP本地文件到终端Mac Os X中的远程

Tkinter 窗口专注于 Mac OS X

在 Mac OS X Mountain Lion Server 中设置 PHP 路径

无法通过终端访问 OS X 中的 adb,“找不到命令”

如何在Mac OS X上将PDF转换为Microsoft Word

Mac OS X 终端中的 Vim:逐字移动光标