将文本粘贴到vim时关闭自动缩进

Rim*_*ian 1119 vim configuration editor indentation auto-indent

我正在努力学习Vim.

当我从剪贴板将代码粘贴到我的文档中时,我会在每个新行的开头添加额外的空格:

line
  line
    line
Run Code Online (Sandbox Code Playgroud)

我知道你可以关闭自动缩进但我无法让它工作,因为我有一些其他设置冲突或某事(在我的.vimrc中看起来非常明显,但是当我把它们取出时似乎并不重要).

当我粘贴代码时如何关闭自动缩进但在编写代码时仍然有自动缩进?这是我的.vimrc档案:

set expandtab  
set tabstop=2  
set shiftwidth=2  
set autoindent  
set smartindent  
set bg=dark  
set nowrap  
Run Code Online (Sandbox Code Playgroud)

P S*_*ved 1971

更新:更好的答案:https://stackoverflow.com/a/38258720/62202

要在粘贴代码时关闭自动注册,需要使用特殊的"粘贴"模式.

类型

:set paste
Run Code Online (Sandbox Code Playgroud)

然后粘贴您的代码.请注意,工具提示中的文字现在说明了-- INSERT (paste) --.

粘贴代码后,请关闭粘贴模式,以便在键入时自动缩进再次正常工作.

:set nopaste
Run Code Online (Sandbox Code Playgroud)

但是,我总觉得那很累赘.这就是为什么我映射<F3>这样它可以在编辑文本时在粘贴和nopaste模式之间切换! 我加上这个.vimrc

set pastetoggle=<F3>
Run Code Online (Sandbox Code Playgroud)

  • 我认为`set paste`更容易.它比"noai"甚至"noautoindent"更具语义性,当输入"noai"时,更重要的是"noai"和"paste"在你作为触摸打字员足够熟练的时候花费大约相同的时间. (63认同)
  • `:set noai`并不总是有效,具体取决于如何根据OP配置其他与缩进相关的设置.`:set paste`似乎是一次几个设置的简写. (49认同)
  • 这并不比`:set noai`然后``set ai`更容易.建议`:r!猫`更短. (38认同)
  • `:set paste`还禁用其他功能,如大括号完成,粘贴代码时也不需要. (28认同)
  • 晚会,但`set copyindent`将无缝地为您处理. (13认同)
  • @jvriesem:有一个插件:https://github.com/ConradIrwin/vim-bracketed-paste (3认同)
  • 在DD-WRT构建中使用`vim`,`:set paste`不起作用,但`:set noai`可以.谢谢@Leopd,带我永远想出来. (2认同)
  • @helvete,例如[here](/sf/answers/2555878391/)。 (2认同)

Jac*_*ask 258

为了避免在粘贴时产生不良影响,需要设置一个选项:

set paste
Run Code Online (Sandbox Code Playgroud)

在.vimrc中有一个有用的命令set pastetoggle=<F10>或其他按钮,可以轻松地在粘贴和nopaste之间切换.

  • 最后!我一直在打字:设置粘贴/:设置nopaste,多么愚蠢!谢谢. (12认同)
  • 另一个选择是在你的vimrc中添加一个宏:`nmap <silent> <leader> p:set paste <CR>"*p:set nopaste <CR>` (8认同)
  • 从实际的角度来看,你的答案比接受的答案更有用 (4认同)

the*_*eek 128

我经常使用:r! cat然后粘贴( shift + insert )内容,和CTRL+D.

无需启用和禁用,直接使用.

  • @KErlandsson,`:r`将文件的内容插入到当前文档中.`!cat`说,运行cat本质上打开stdin(*nix shells)`(shift + insert)`或者对于某些终端,右键单击会将剪贴板的内容粘贴到终端`CTRL + D`结束 - of-file,所以关闭`:r!cat`会话. (9认同)
  • 这个答案对于有关为什么以及如何`:r的信息更有帮助!猫`工作. (7认同)
  • 在默认的Linux Mint环境中运行良好,谢谢. (2认同)

tho*_*ter 85

如果您在本地工作,则可以使用键序列从系统剪贴板粘贴:

"+p

这是一个正确的vim命令,因此无需担心首先进入插入模式或关闭自动注册.

当然,如果您正在远程工作(例如通过SSH控制台),那么这将无法工作,您应该进入:set noai插入模式,粘贴到控制台,保留插入模式,:set ai路由,如其他地方所述.

  • 我很久以前就写过这个答案.现在我使用`:set paste`和`:set nopaste`而不是因为它更长,它更容易记住,我不必每次都查找它! (9认同)
  • 在一些嵌入式系统中(主要基于busybox)`:set paste`没有实现,所以应该使用`:set noai`代替. (6认同)

thd*_*oan 42

虽然设置粘贴模式paste/nopaste/pastetoggle非常精细,但您仍需要在粘贴之前手动启用粘贴模式,并在粘贴后禁用粘贴模式.作为我的懒人,下面是我到目前为止找到的最佳解决方案,它会在您粘贴时自动切换粘贴模式.

这是一个小技巧,使用终端的括号粘贴模式在粘贴时自动设置/取消设置Vim的粘贴模式.将以下内容放在.vimrc中:

let &t_SI .= "\<Esc>[?2004h"
let &t_EI .= "\<Esc>[?2004l"

inoremap <special> <expr> <Esc>[200~ XTermPasteBegin()

function! XTermPasteBegin()
  set pastetoggle=<Esc>[201~
  set paste
  return ""
endfunction
Run Code Online (Sandbox Code Playgroud)

现在您可以粘贴而无需明确打开/关闭粘贴模式 - 它会自动为您处理.

资料来源:Coderwall

注意:此解决方案在WSL(Windows 10 Subsystem for Linux)中不起作用.如果有人有WSL解决方案,请更新此答案或将其添加到评论中.

Tmux如果使用tmux,那么声明需要双重转义.这个代码也在Coderwall中

  • 如果你更懒,将上面的代码复制粘贴到 .vimrc 中,请注意函数 XTermPasteBegin() 的缩进。 (4认同)
  • 我很好奇这是如何工作的,所以我搜索了 Paste Bracketing 并找到了 https://gitlab.com/gnachman/iterm2/-/wikis/Paste-Bracketing ,它解释了 `t_SI` 和 `t_EI` 变量正在启用粘贴包围并禁用它。当粘贴括号打开时,粘贴的文本以“esc[200~”为前缀,后跟“esc[201~”。 (3认同)

man*_*bot 37

Mac用户可以通过以下方式直接从粘贴板中读取来避免自动格式化:

:r !pbpaste
Run Code Online (Sandbox Code Playgroud)

  • BTW在linux上,等效命令是`:r!xsel -p` (10认同)
  • 这是一个很棒的回应.但是,当我这样做时,它隐藏了文档(看起来我回到了命令行),但是我的剪贴板上有文本.它提示我按Enter键,所以我这样做,它会将我返回到我的文档而不做任何更改.发生了什么事,我怎么做你说的话? (3认同)

B.M*_*.W. 23

我是一名 Python 用户,有时会复制并粘贴到 Vim 中。(我从 Mac 切换到 Windows WSL),这是困扰我的故障之一。

如果您触摸 ascript.py然后vi script.py,Vi 将检测到它是一个 Python 脚本并尝试提供帮助、自动缩进、粘贴额外缩进等。如果您不告诉它是一个 Python 脚本,则不会发生这种情况。

但是,如果这种情况已经发生在您身上,那么当您粘贴已经完全缩进的代码时,默认的自动缩进可能是一场噩梦(请参阅下面的倾斜梯子形状)。

我尝试了三种选择,结果如下

set paste        # works perfect 
set noai         # still introduced extra whitespace
set noautoindent # still introduced extra whitespace
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述 在此输入图像描述

  • @aadibajpai 我把 `setastetoggle=&lt;F2&gt;` 放在我的 `.vimrc` 中,所以按 F2 可以打开和关闭粘贴。 (2认同)

Von*_*Von 19

以下是有人发现如何重新映射粘贴事件以自动打开粘贴模式然后退出的帖子.适用于MacOSX上的tmux/iTerm.


sja*_*jas 14

另一个我直到现在才看到的答案:

:se paste noai
Run Code Online (Sandbox Code Playgroud)


anh*_*ng8 13

将此添加到您的~/.vimrc,您只需在粘贴之前和之后按F2:

set pastetoggle=<F2>
Run Code Online (Sandbox Code Playgroud)


Sor*_*ren 10

我刚放入set clipboard=unnamed我的.vimrc.这使得默认的粘贴缓冲区映射到X的剪贴板.

所以,如果我在终端上标记了一些文字,我只需按下p即可将其粘贴到vim中.类似地,我可以在vim中抓取东西(例如YY,将当前行拉入缓冲区)并在任何窗口中间单击以粘贴它.

不知道.我发现它非常方便.


stu*_*eek 9

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

它的工作原理是检测括号中的粘贴模式,它是由"现代"x-term兼容终端(如iTerm2,gnome-terminal和其他使用libvte的终端)发送的转义序列.作为额外奖励,它也适用于tmux会话.我在连接Linux服务器和使用tmux的Mac上成功使用iTerm2.


Der*_*hev 8

把它粘在你的〜/ .vimrc中并开心:

" enables :Paste to just do what you want
command Paste execute 'set noai | insert | set ai'
Run Code Online (Sandbox Code Playgroud)

编辑:反思,:r !cat是一个更好的方法,因为它很短,语义,并且不需要自定义vimrc.改用它!


cod*_*ave 6

虽然:pastetoggle还是:paste:nopaste应工作正常(如果实现的话-他们并不总是如我们可以从讨论中看到)我非常重评粘贴使用直接的方法"+p"*p与阅读"+r"*r

Vim 可以访问 10 种类型的寄存器 ( :help registers) 并且提问者感兴趣quotestarquoteplus来自部分

  1. 选择和删除寄存器"*"+以及“~

使用这些寄存器来存储和检索 GUI 的选定文本。见quotestarquoteplus。当剪贴板不可用或不工作时,将使用未命名的寄存器。对于 Unix 系统,剪贴板仅在存在 +xterm_clipboard 功能时可用。{不在 Vi}

请注意,对于 X11 系统,只有“*”和“+”之间的区别。

:help x11-selection进一步明确的差异*+

                                                  quoteplus quote+
Run Code Online (Sandbox Code Playgroud)

有三个文档化的 X 选择:PRIMARY(预期代表当前的视觉选择——就像在 Vim 的视觉模式中一样)、SECONDARY(定义不明确)和 CLIPBOARD(预期用于剪切、复制和粘贴操作)。

在这三个中,Vim 在读写 "* 寄存器时使用 PRIMARY(因此当 X11 选项可用时,Vim 为 "autoselect" 的 'clipboard' 设置默认值),在读写 "+ 寄存器时使用 CLIPBOARD。Vim 不访问 SECONDARY 选择。

示例:(假设默认选项值)

  • 在 Vim 的可视模式下选择一个 URL。转到您的浏览器并在 URL 文本字段中单击鼠标中键。所选文本将被插入(希望如此!)。注意:在 Firefox 中,您可以在 about:config 中将 middlemouse.contentLoadURL 首选项设置为 true,然后在窗口中的大多数位置按下鼠标中键时将使用选定的 URL。

  • 通过用鼠标拖动在浏览器中选择一些文本。转到 Vim 并按鼠标中键:插入选定的文本。

  • 在 Vim 中选择一些文本并执行“+y。转到您的浏览器,通过用鼠标拖动在文本字段中选择一些文本。现在使用鼠标右键并从弹出菜单中选择“粘贴”。选定的文本被覆盖来自 Vim 的文本。请注意,“+”寄存器中的文本在进行可视化选择时仍然可用,这使得“*”寄存器中的其他文本可用。这允许覆盖选定的文本。


The*_*tan 5

另一种粘贴方法是通过<C-r>插入模式并删除寄存器的内容(这里是全局寄存器)。见::h i_ctrl-rh i_CTRL-R_CTRL-O

来自 vim 帮助文档:

按字面插入寄存器的内容,不要自动缩进。与使用鼠标粘贴相同。不替换字符!这 '。' 注册(最后插入的文本)仍按输入方式插入。{Vi 无此功能}

所以要将内容粘贴到 vim 而不自动缩进,请<C-r><C-o>*在大多数 unix 系统中使用。

您可以在 vimrc 中添加映射,inoremap <C-r> <C-r><C-o>以便您可以*使用<C-r>*.

注意:这仅在 vim 使用clipboard.


Bru*_*uno 5

来自维姆:]p

从外部:"*]p"+]p