ChatGPT解决这个技术问题 Extra ChatGPT

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

当我将代码粘贴到我的 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

C
Chris Page

更新: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。

正如@DenilsonSáMaia 所指出的,这个答案已被打包到一个插件中;不过,从 Vim 8 开始它已经过时了:https://github.com/ConradIrwin/vim-bracketed-paste


您还应该为命令模式添加一个映射(使用冒号输入)。否则,您将无法粘贴到命令行:cmap <Esc>[200~ <nop> cmap <Esc>[201~ <nop>
@ChrisPage 增加了一些加速 esc 映射并使其在 tmux 中工作的附加功能:github.com/aaronjensen/vimfiles/blob/master/vimrc#L449-483
此答案已打包到插件中:github.com/ConradIrwin/vim-bracketed-paste
如果您不使用备用屏幕,您可以通过修改 t_SIt_EI 而不是 t_tit_te(分别)在(仅)插入模式下启用它。
J
John Bachir

在 vim 中:

:set paste

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


我会把它放在一个开关上;即;我的 vimrc 中有这个... set pastetoggle=
D
Denilson Sá Maia

假设您正确设置了系统剪贴板,另一种方法是执行此操作

"+p

这将从系统剪贴板粘贴。


"*p"+p* 寄存器是 X11 主要选择,+ 是剪贴板。我不知道 Mac OS X 是否和 X11 有相同的概念。
d
dancavallaro

除了其他答案之外,如果您想要一种快速切换粘贴模式的方法,请添加

set pastetoggle=<F2>

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


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

在 vim 中

:设置粘贴

当你想禁用它时

:set nopaste


:set paste! 进行切换。
C
Community

在终端中工作时,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 之后的选定补丁。

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅