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

我正在努力学习Vim。

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

linelineline

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

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

set expandtabset tabstop=2set shiftwidth=2set autoindentset smartindentset bg=darkset nowrap
552033 次浏览

更新时间:最好在这里回答:https://stackoverflow.com/a/38258720/62202

要在粘贴代码时关闭自动缩进,有一种特殊的“粘贴”模式。

类型

:set paste

然后粘贴您的代码。请注意,工具提示中的文本现在显示-- INSERT (paste) --

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

:set nopaste

然而,我总是觉得这很麻烦。这就是为什么我映射<F3>,这样它就可以在粘贴和不粘贴模式之间切换在编辑文本时!我将它添加到.vimrc

set pastetoggle=<F3>

为了避免粘贴时出现不希望的效果,需要设置一个选项:

set paste

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

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

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

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

"+p

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

当然,如果您是远程工作(例如,通过SSH控制台),那么这将不起作用,您应该转到:set noai,插入模式,粘贴到控制台,离开插入模式,:set ai路由,如其他地方所述。

这适用于我(案例+寄存器,我使用的是ap之间的交换缓冲区):

imap <silent> <S-Insert> <C-O>:set noai<CR><C-R>+<C-O>:set ai<CR>

把这个贴在你的~/. vimrc上,快乐起来:

" enables :Paste to just do what you wantcommand Paste execute 'set noai | insert | set ai'

编辑:经过反思,:r !cat是一种更好的方法,因为它简短、语义化,并且不需要自定义vimrc。改用它吧!

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

:r !pbpaste

这是一篇文章由想出如何重新映射粘贴事件以自动打开粘贴模式然后关闭的人创建。在MacOSX上的tmux/iTerm中为我工作。

如果你在Mac上,macvim似乎可以很好地处理它,而不必切换粘贴。

brew install macvim--overrive-sy-vim安装完成后

我只是把set clipboard=unnamed放在我的. vimrc中。这使得默认的粘贴缓冲区映射到X的剪贴板。

因此,如果我在终端中标记了一点文本,我可以简单地按p将其粘贴到vim中。类似地,我可以在vim中猛拉东西(例如YY将当前行猛拉到缓冲区中)并在任何窗口中键单击以粘贴它。

我不知道。我觉得它超级方便。

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

set pastetoggle=<F2>

请阅读这篇文章:切换代码粘贴的自动缩进

有些人喜欢通过以下替代方案在状态行中显示的视觉反馈vimrc

nnoremap <F2> :set invpaste paste?<CR>set pastetoggle=<F2>set showmode

据我所知,快速进入一次性粘贴的粘贴插入模式的最快方法是tpope的未受损,它具有#0#1,大概是“你打开”的助记符。他们只在他的vimdoc中记录如下:

没有为“粘贴”提供切换,因为典型的用例是包装一个单独的插入是如此浪费:你切换两次,但是你只粘贴一次(YOPO)。相反,按yo或yO调用o或O“粘贴”已设置。离开插入模式会自动设置“不粘贴”。

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

它的工作原理是检测括号粘贴方式,这是一个由“现代”x术语兼容终端(如iTerm2、gnome终端和其他使用libvte的终端)发送的转义序列。作为额外的奖励,它也适用于tmux会话。我在连接到linux服务器并使用tmux的Mac上成功地将它与iTerm2一起使用。

虽然使用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 pastereturn ""endfunction

现在您可以粘贴而无需显式打开/关闭粘贴模式-它是为您自动处理。

来源:Coderwall

备注:此解决方案在WSL(Linux的Windows 10子系统)中不起作用。如果有人有WSL的解决方案,请更新此答案或在评论中添加它。

Tmux如果使用tmux,则声明需要双重转义。这方面的代码也在Coderwall

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

从vim帮助留档:

按字面意思插入寄存器的内容,不要自动缩进。与用鼠标粘贴相同。不替换字符!“.”寄存器(最后插入的文本)仍按键入方式插入。{不在Vi}

因此,要在没有自动缩进的情况下将内容粘贴到vim中,请在大多数unix系统中使用<C-r><C-o>*

您可以在vimrcinoremap <C-r> <C-r><C-o>中添加映射,以便您可以使用<C-r>*正常粘贴*寄存器的内容而无需自动缩进。

注意:这仅适用于使用clipboard编译vim的情况。

虽然:pastetoggle:paste:nopaste应该工作得很好(如果实现了-它们并不总是像我们从讨论中看到的那样),但我强烈建议使用直接方法"+p"*p粘贴并使用"+r"*r阅读:

Vim可以访问十种类型的寄存器(:help registers),提问者对部分中的quotestarquoteplus感兴趣

  1. 选择和丢弃寄存器"*"+和"~

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

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

:help x11-selection进一步澄清了*+的区别:

                                                  quoteplus quote+

有三个记录在案的X选择:PRIMary(预计将表示当前可视选择-与Vim的可视模式一样),第二(定义不明确)和CLIPBOARD(预计将用于剪切,复制和粘贴操作)。

在这三者中,Vim在读取和写入"*寄存器时使用PRIMary(因此,当X11选择可用时,Vim会为“自动选择”的“剪贴板”),以及读取和写入“+”时的剪贴板注册。Vim无法访问第二选择。

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

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

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

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

可悲的是,我发现上面提到的vim插件不适用于iTerm2 3.0.15(公平地说,我不知道这是否在旧版本上崩溃)-但我发现了这个黑客。

映射命令-p进行粘贴并使用iTerm2 vim键。显然这只适用于iTerm2。

它是如何工作的。我使用“jk”进入逃逸模式,因此您还需要:

: inoremap jk

在你的. vimrc

然后它只是调用P进入粘贴模式,“+p从剪贴板粘贴,然后P禁用粘贴模式。

在此处输入图片描述

来自vim:]p

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

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

:se paste noai

本机粘贴/括号粘贴是自vim 8(2016年发布)以来最好和最简单的方法。它甚至可以在ssh上工作!(括号粘贴适用于Linux和Mac,但不适用于Windows Git Bash)

  1. 确保你有vim 8+(你不需要+clipboard+xterm_clipboard选项)。

    vim --version | head -1

  2. 只需在正常模式下使用操作系统本机粘贴命令(例如ctrl+shift+Vcmd+V)。不要按i进入插入模式。


测试

  1. 复制(ctrl+shift+Ccmd+C)this的输出(2行带有制表符缩进)到系统剪贴板:

    echo -e '\ta\n\tb'

  2. 使用autoindent启动一个干净的vim 8+:

    vim -u NONE --noplugin -c 'set autoindent'

  3. 以正常模式从系统剪贴板(ctrl+shift+Vcmd+V)粘贴。插入模式不要按iab应该与单个制表符缩进对齐。您甚至可以在ssh到远程机器时执行此操作(远程机器需要vim 8+)。

  4. 现在尝试旧方法,它将使用额外的制表符自动缩进第二行:按i进行插入模式。然后使用ctrl+shift+Vcmd+V粘贴。ab现在不对齐。


安装Vim 8

  • Ubuntu 18.04-默认附带Vim 8

  • Ubuntu 16.04-从PPA安装

    sudo add-apt-repository ppa:jonathonf/vimsudo apt updatesudo apt install vim
  • Mac: brew install vim

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

如果您触摸script.py然后vi script.py,Vi将检测到它是Python脚本并尝试提供帮助,自动缩进,粘贴额外的缩进等。

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

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

set paste        # works perfectset noai         # still introduced extra whitespaceset noautoindent # still introduced extra whitespace

输入图片描述输入图片描述

以下vim插件通过其“括号粘贴”模式自动处理:https://github.com/wincent/terminus

设置“括号粘贴”模式,这意味着您可以忘记手动设置“粘贴”选项,只需继续以任何模式粘贴即可。

这个问题已经得到了回答,但我想我也可以添加自己的解决方案:

如果您只是想禁用自动缩进系统,对于每种文件类型(基本上,完全禁用自动缩进功能),您可以执行以下操作:

  1. 备份indent.vim文件:
    sudo mv /usr/share/vim/vim81/indent.vim /usr/share/vim/vim81/indent.vim.orig
  2. 创建一个新的空indent.vim文件:
    sudo touch /usr/share/vim/vim81/indent.vim

如果您使用v8.2以上的vim,您可以检查:help tmux-integration

如果您在tmux中运行Vim时遇到问题,这里有一些提示。如果某些东西不起作用,您可以注释掉部分(它可能取决于运行tmux的终端):

if !has('gui_running') && &term =~ '^\%(screen\|tmux\)'" Better mouse support, see  :help 'ttymouse'set ttymouse=sgr
" Enable true colors, see  :help xterm-true-colorlet &termguicolors = v:truelet &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
" Enable bracketed paste mode, see  :help xterm-bracketed-pastelet &t_BE = "\<Esc>[?2004h"let &t_BD = "\<Esc>[?2004l"let &t_PS = "\<Esc>[200~"let &t_PE = "\<Esc>[201~"
" Enable focus event tracking, see  :help xterm-focus-eventlet &t_fe = "\<Esc>[?1004h"let &t_fd = "\<Esc>[?1004l"
" Enable modified arrow keys, see  :help xterm-modifier-keysexecute "silent! set <xUp>=\<Esc>[@;*A"execute "silent! set <xDown>=\<Esc>[@;*B"execute "silent! set <xRight>=\<Esc>[@;*C"execute "silent! set <xLeft>=\<Esc>[@;*D"endif