为什么 Vim 错误地缩进粘贴的代码?

为什么 Vim 错误地缩进粘贴的代码?

在 Vim 中,如果我粘贴此脚本:

#!/bin/sh
VAR=1
while ((VAR <  10))
    do
        echo "VAR1 is now $VAR"
        ((VAR = VAR +2))
    done
    echo "finish"

我得到这些奇怪的结果:

#!/bin/sh
#VAR=1
#while ((VAR <  10))
#       do
#                       echo "VAR1 is now $VAR"
#                                       ((VAR = VAR +2))
#                                               done
#                                                       echo "finish"
#                                                       

井号 (#) 和制表符已出现。为什么?

答案1

有两个原因:

vim要在启用自动缩进的情况下粘贴,您必须更改为粘贴模式通过输入:

:set paste

然后您可以更改为插入模式并粘贴代码。粘贴完成后,输入:

:set nopaste

关闭粘贴模式。由于这是常见且频繁的操作,因此vim提供切换粘贴模式:

set pastetoggle=<F2>

您可以更改F2为您想要的任何键,现在您可以轻松地打开和关闭粘贴。


要关闭自动插入注释,您可以将这些行添加到您的vimrc:

augroup auto_comment
    au!
    au FileType * setlocal formatoptions-=c formatoptions-=r formatoptions-=o
augroup END

vim还提供了一个粘贴寄存器供您从系统剪贴板粘贴文本。您可以使用"*p或 ,"+p具体取决于您的系统。在没有 X11 的系统上,例如 OSX 或 Windows,您必须使用寄存器*。在 X11 系统(例如 Linux)上,您可以同时使用两者。

进一步阅读

答案2

使用 vim 粘贴。你想要的是粘贴剪贴板缓冲区上的内容 "+p

这将选择+并将其粘贴到位。

如果您使用的是 Linux,则*是 X/中键单击缓冲区(最后选择的文本)。

然后 vim 就知道这是一个粘贴。

否则,vim 认为您已经键入了要粘贴的键,并执行自己的自动缩进(在复制的缩进之上)一直到粘贴的末尾。

请注意,要通过 SSH 进行此操作,您需要设置共享剪贴板的选项-Y

请参阅man ssh了解更多详情。

答案3

插入选项卡是因为您打开了自动缩进,并且您可以:set noai在粘贴到终端之前通过关闭自动缩进 ( ) 来禁用该行为。

注释行是由自动注释生成的,可以通过关闭它来禁用。

除了这些之外,您还应该使用切换来获得所需的行为 :set paste,粘贴格式化的代码并:set nopaste恢复正常行为。

答案4

至于原因,其他博主已经解释得很清楚了。在这里我想提供一个自动处理这种情况的解决方案。

在您的以下内容中~\.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

您可以自由粘贴,无需担心自动缩进。

如果你在 tmux 中工作,那么你必须编写以下内容

function! WrapForTmux(s)
  if !exists('$TMUX')
    return a:s
  endif

  let tmux_start = "\<Esc>Ptmux;"
  let tmux_end = "\<Esc>\\"

  return tmux_start . substitute(a:s, "\<Esc>", "\<Esc>\<Esc>", 'g') . tmux_end
endfunction

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

function! XTermPasteBegin()
  set pastetoggle=<Esc>[201~
  set paste
  return ""
endfunction

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

来源是编码者沃尔如果您想阅读更多内容。

如果您使用screen等效的换行功能,则为:

function! WrapForScreen(s)
  if exists('$TMUX') || match($TERM, "screen")==-1
    return a:s
  endif

  let screen_start = "\<Esc>P"
  let screen_end = "\<Esc>\\"

  return screen_start . a:s . screen_end
endfunction

在发现斯塔佩尔伯格的.vimrc.

相关内容