1378

我正在努力学习 Vim。

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

line
  line
    line

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

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

set expandtab  
set tabstop=2  
set shiftwidth=2  
set autoindent  
set smartindent  
set bg=dark  
set nowrap  
4

25 回答 25

2419

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

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

类型

:set paste

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

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

:set nopaste

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

set pastetoggle=<F3>
于 2010-03-25T10:02:14.307 回答
281

为避免粘贴时出现不良影响,需要设置一个选项:

set paste

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

于 2010-03-25T10:15:21.297 回答
141

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

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

于 2010-03-30T12:50:15.110 回答
92

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

"+p

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

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

于 2011-11-05T07:45:24.880 回答
73

虽然设置粘贴模式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

现在您可以在不显式打开/关闭粘贴模式的情况下粘贴 - 它会自动为您处理。

资料来源:编码墙

注意:此解决方案不适用于 WSL(适用于 Linux 的 Windows 10 子系统)。如果有人有 WSL 的解决方案,请更新此答案或将其添加到评论中。

Tmux如果使用 tmux,则需要对声明进行双重转义。代码也在Coderwall中

于 2016-07-08T04:00:35.113 回答
38

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

:r !pbpaste
于 2013-08-28T12:58:25.740 回答
20

这是某人的帖子,他想出了如何重新映射粘贴事件以自动打开粘贴模式然后再关闭。在 MacOSX 上的 tmux/iTerm 中为我工作。

于 2014-02-08T20:30:22.837 回答
17

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

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

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

于 2015-01-20T11:15:37.357 回答
17

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

set pastetoggle=<F2>
于 2015-03-22T17:27:05.853 回答
11

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

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

于 2016-04-09T03:53:21.310 回答
9

把它放在你的 ~/.vimrc 中,然后开心:

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

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

于 2013-06-07T21:25:37.997 回答
7

我是一名 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

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

于 2020-07-19T15:34:14.460 回答
6

虽然:pastetoggleor:paste并且:nopaste应该可以正常工作(如果实施 - 它们并不总是如我们从讨论中看到的那样),我强烈建议使用直接方法粘贴或使用"+por"*p阅读:"+r"*r

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

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

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

请注意,对于 X11 系统,只有 "* 和 "+ 之间存在区别。

:help x11-selection进一步阐明 和 的*区别+

                                                  quoteplus quote+

有 3 个记录在案的 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 的文本。请注意,“+”寄存器中的文本在进行可视选择时仍然可用,这使得“* 寄存器中的其他文本可用。这允许覆盖选定的文本。
于 2017-04-18T06:20:48.730 回答
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.

于 2017-04-15T06:09:14.697 回答
5

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

:se paste noai
于 2019-05-25T19:10:16.023 回答
4

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

imap <silent> <S-Insert> <C-O>:set noai<CR><C-R>+<C-O>:set ai<CR>
于 2012-06-01T15:53:47.503 回答
3

来自 vim:]p

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

于 2018-07-22T16:55:04.807 回答
2

如果您使用的是 mac,macvim 似乎可以很好地处理它而无需切换粘贴。

brew install macvim --override-system-vim

于 2014-05-18T14:05:27.010 回答
1

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

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

nnoremap <F2> :set invpaste paste?<CR>
set pastetoggle=<F2>
set showmode
于 2015-07-01T11:18:44.427 回答
1

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

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

  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
于 2020-09-18T02:06:27.923 回答
1

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

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

于 2015-08-13T21:00:21.553 回答
1

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

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

    vim --version | head -1

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


测试

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

    echo -e '\ta\n\tb'

  2. 使用自动缩进启动干净的 vim 8+:

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

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

  4. 现在尝试旧方法,它会用一个额外的选项卡自动缩进第二行:按i插入模式。ctrl+shift+V然后使用or粘贴cmd+Va和现在b错位了。


安装 Vim 8

  • Ubuntu 18.04 -默认带有 Vim 8

  • Ubuntu 16.04 -从 PPA 安装

    sudo add-apt-repository ppa:jonathonf/vim
    sudo apt update
    sudo apt install vim
    
  • 苹果电脑:brew install vim
于 2019-06-26T22:38:56.727 回答
0

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

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

于 2020-09-05T17:53:09.067 回答
0

可悲的是,我发现提到的 vim 插件不能与 iTerm2 3.0.15 一起使用(公平地说,我不知道这是否在旧版本上损坏) - 但我发现了这个 hack。

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

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

:inoremap jk

在你的 .vimrc 中。

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

在此处输入图像描述

于 2017-09-16T01:05:46.027 回答
0

如果你使用上面的 vim v8.2,你可以用: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-color
    let &termguicolors = v:true
    let &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-paste
    let &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-event
    let &t_fe = "\<Esc>[?1004h"
    let &t_fd = "\<Esc>[?1004l"

    " Enable modified arrow keys, see  :help xterm-modifier-keys
    execute "silent! set <xUp>=\<Esc>[@;*A"
    execute "silent! set <xDown>=\<Esc>[@;*B"
    execute "silent! set <xRight>=\<Esc>[@;*C"
    execute "silent! set <xLeft>=\<Esc>[@;*D"
endif
于 2021-11-17T01:44:32.450 回答