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

问题描述 投票:1067回答:21

我正在努力学习Vim。

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

line
  line
    line

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

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

set expandtab  
set tabstop=2  
set shiftwidth=2  
set autoindent  
set smartindent  
set bg=dark  
set nowrap  
vim configuration editor indentation auto-indent
21个回答
1934
投票

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

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

类型

:set paste

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

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

:set nopaste

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

set pastetoggle=<F3>

9
投票

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

它的工作原理是检测bracketed paste mode,这是一个由“现代”x-term兼容终端发送的转义序列,如iTerm2,gnome-terminal和其他使用libvte的终端。作为额外奖励,它也适用于tmux会话。我在连接Linux服务器和使用tmux的Mac上成功使用iTerm2。


7
投票

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

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

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


4
投票

这适用于我(+寄存器的情况,我使用的像aps之间的交换缓冲区):

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

3
投票

虽然: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的可视模式),SECONDARY(定义不明确)和CLIPBOARD(预计用于剪切,复制和粘贴操作) )。

在这三个中,Vim在读取和写入“*寄存器时使用PRIMARY(因此当X11选项可用时,Vim为”自动选择“的'剪贴板'设置默认值),以及在读取和写入”+寄存器时CLIPBOARD。 Vim不访问SECONDARY选择。

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

  • 在Vim中以可视模式选择一个URL。转到浏览器并在URL文本字段中单击鼠标中键。将插入所选文本(希望!)。注意:在Firefox中,您可以在about:config中将middlemouse.contentLoadURL首选项设置为true,然后在窗口中的大多数位置按鼠标中键时将使用所选的URL。
  • 通过拖动鼠标在浏览器中选择一些文本。转到Vim并按下鼠标中键:插入所选文本。
  • 在Vim中选择一些文本并执行“+ y。转到浏览器,通过拖动鼠标在文本字段中选择一些文本。现在使用鼠标右键并从弹出菜单中选择”粘贴“。所选文本被覆盖来自Vim的文本。请注意,“+寄存器中的文本在进行可视选择时仍然可用,这使得其他文本在”*寄存器中可用。这允许覆盖所选文本。

2
投票

如果你在Mac上,macvim似乎无需切换粘贴就可以很好地处理它。

brew install macvim --override-system-vim


2
投票

vim 8(2016年发布)以来,原生糊状/方括号粘贴是最好和最简单的方法。它甚至适用于ssh! (括号粘贴适用于Linux和Mac,但不适用于Windows Git Bash)

  1. 确保你有vim 8+(你不需要+clipboard+xterm_clipboard选项)。 vim --version | head -1
  2. 只需在普通模式下使用OS本机粘贴命令(例如ctrl+shift+Vcmd+V)。不要按i进行插入模式。

测试

  1. 将(ctrl+shift+Ccmd+C)的输出(带有制表符缩进的2行)复制到系统剪贴板: echo -e '\ta\n\tb'
  2. 使用autoindent启动干净的vim 8+: vim -u NONE --noplugin -c 'set autoindent'
  3. 在普通模式下从系统剪贴板(ctrl+shift+Vcmd+V)粘贴。不要按i进行插入模式。 ab应与单个制表符缩进对齐。您甚至可以在连接到远程计算机时执行此操作(远程计算机将需要vim 8+)。
  4. 现在尝试旧方法,它将使用额外的选项卡自动添加第二行:按i进行插入模式。然后使用ctrl+shift+Vcmd+V粘贴。 ab现在未对齐。

安装Vim 8


1
投票

请阅读这篇文章:Toggle auto-indenting for code paste

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

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

1
投票

我知道快速进入一次性粘贴的粘贴插入模式的最快方法是tpope的unimpaired,它具有yoyO,可能是“你打开”的助记符。他们只记录在他的vimdoc中,如:

没有为“粘贴”提供切换,因为包装单独插入的典型用例非常浪费:您切换两次,但只粘贴一次(YOPO)。相反,按y或yO以调用已设置“粘贴”的o或O.离开插入模式会自动设置'nopaste'。


1
投票

来自vim:]p

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


0
投票

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

从vim帮助文档: Insert the contents of a register literally and don't auto-indent. Does the same as pasting with the mouse<MiddleMouse>. Does not replace characters! The '.' register (last inserted text) is still inserted as typed.{not in Vi}

因此,要将内容粘贴到vim而不进行自动缩进,请在大多数unix系统中使用<CR><CO>*

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


256
投票

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

set paste

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


0
投票

可悲的是,我发现提到的vim插件不能与iTerm2 3.0.15一起使用(公平地说我不知道​​这是否在旧版本中出现了) - 但我发现这个黑客而已。

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

这个怎么运作。我使用“jk”进入转义模式,因此您还需要:

:theoremap jk

在你的.vimrc中。

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

enter image description here


0
投票

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

:se paste noai

125
投票

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

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


85
投票

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

"+p

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

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


37
投票

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

:r !pbpaste

34
投票

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

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

资料来源:Coderwall

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

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


19
投票

Here is a post是一个想出如何重新映射粘贴事件以自动打开粘贴模式然后退出的人。适用于MacOSX上的tmux / iTerm。


12
投票

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

set pastetoggle=<F2>

9
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.