Vim宏很慢

时间:2011-12-05 03:41:49

标签: vim text

我将一个非常简单的vim宏保存到一个键:qa $ pjq然后用40000 @ a执行40000次。这很慢。我一定做错了,因为虽然它确实有效,但需要60-90秒。这和vim一样快吗?是否有一些设置可以加速这个?是否存在使宏执行变慢的插件混合?

我正在使用Mac并使用MacVim。它是一个纯文本文件,它实际上没有比这简单。

5 个答案:

答案 0 :(得分:22)

粘贴40,000行并不需要很长时间,但如果你不断更新屏幕,就像你经常在宏中那样放慢速度。

首先,关于你的宏应该做什么的问题。如果它只是粘贴默认寄存器的内容,那么正确的宏定义只是qapjq。无需将光标定位在前一行的特定位置。 [编辑:抱歉,我假设你正在进行行式粘贴,如果你在行尾贴上字符顺序注册,则需要定位。 。 ..]

其次,您可以通过设置lazyredraw(:set lazyredraw)来加速当前的宏,因此屏幕不会随着更新而更新。可能不会把事情加速很多,像这样的键盘宏不像是直接处理缓冲区。

第三,这是另一种方法,需要大约一秒钟: .,+40000g/.*/normal! $p

答案 1 :(得分:8)

这很正常。正如Herbert Sitz所写,更新屏幕的速度很慢。

您可能只想运行替换命令::.,+40000s/.*/&<c-r>"

  • .,+40000是包含当前行和
  • 之后的40000的范围 模式中的
  • .*匹配整行
  • 字符串中的
  • &是匹配的行
  • <c-r>"粘贴未命名寄存器的内容

答案 2 :(得分:3)

我建议使用&#39; vim -u NONE&#39;开始一个空白的vim。 插件通常会减慢速度。 你会发现它以这种方式运行得更快。 然后你需要找出哪个插件导致这种减速。 另请参阅How to see which plugins are making Vim slow?

答案 3 :(得分:1)

原因

<块引用>

然后用 40000@a 执行 40000 次。这是非常缓慢的。我一定是做错了什么,因为虽然它确实有效,但需要 60-90 秒。

其他答案都没有针对主要原因。宏运行缓慢主要受插件影响粘贴,而不是屏幕重绘。

filetype 语法和 lazyredraw 只有非常非常非常最小的影响。正确的解决方案应该是找出并禁用那些在插入模式下会减慢编辑速度的插件。

宏只是将寄存器中存储的操作重播到所选区域。运行宏的环境和你录制宏的环境是一样的。插件可能会在编辑过程中引入额外费用。通常这不是问题。但将成本乘以 40,000 会显着放大影响。

这是我得到的对宏运行的影响因子:

system clipboard >> plugins >> filetype, syntax

解决方案

系统剪贴板

避免在宏中访问系统剪贴板

与访问内部寄存器相比,访问外部系统剪贴板 +* 会引入额外的成本。它甚至可能永远冻结宏重放(在我的测试中运行 6000 行宏)。

imap 和事件

禁用影响编辑速度的插件

  • 那些做插入映射的,例如imap <CR> <Tab> ...
    • jiangmiao/auto-pairs
    • Raimondi/delimitMate
    • ...
  • :noautocmd :norm @q 在宏运行期间暂时禁用事件。 或者在宏运行之前set eventignore=all,然后将其设置回来。
  • ~~那些与编辑相关的寄存器钩子~~(好像不需要)
    • 相关钩子
      • CursorMoved(I), CursorHold(I)
      • InsertCharPreInsertEnterInsertLeave(Pre)
    • neoclide/coc.nvim
    • brglng/vim-im-select
    • chrisbra/Colorizer
    • ...

注意

  • 并非所有在上述钩子上注册函数的插件都有很大的不同 关于宏运行速度。其中一些只对微不足道的,可以忽略不计的影响 编辑速度。你必须通过重播宏来找到它们 插件并比较时间成本。
  • 无法完全禁用来自 auto-pairs 的插入模式映射, 这是我改用 delimitMate 的原因之一。
  • 在选择时使用 :noautocmd。范围应放在 norm 之前::noa '<,'>norm! @q

这是我在运行宏之前禁用上述插件的切换功能。

在录制宏之前使用 <F3>m 禁用插件。运行宏后, <F3>m 再次重置这些插件的状态。 (我将我所有的开关归到 <F3> 下,m 代表宏。您可以根据需要调整映射。)

function! <SID>ToggleMacro(...)
  " Optimize macro running by disable some plugins.
  if get(g:, '_macro', {}) ==# {}
    let g:_macro = {'state': 1}

    let g:_macro.auto_pairs = get(b:, 'autopairs_enabled')
    if g:_macro.auto_pairs
      let b:autopairs_enabled = 0
    endif

    let g:_macro.delimit_mate = get(b:, 'delimitMate_enabled')
    if g:_macro.delimit_mate
      DelimitMateOff
    endif

    let g:_macro.eventignore = &eventignore
    set eventignore=all

  else
    let g:_macro.state = 0

    let b:autopairs_enabled = g:_macro.auto_pairs

    if g:_macro.delimit_mate
      DelimitMateOn
    endif

    let &eventignore = g:_macro.eventignore

  endif

  if g:_macro.state
    echo 'Macro boost: On'
  else
    echo 'Macro boost: Off'
    unlet g:_macro
  endif
endfunction

nnoremap <F3>m  :call <SID>ToggleMacro()<CR>
command! -nargs=? ToggleMacro call <SID>ToggleMacro(<f-args>)

参考

  • :h autocmd:h noautocmd:h eventignore
  • 感谢Christian Brabandt提及:noautocmdeventignore

答案 4 :(得分:-1)

我遇到了一些问题,即使在少量的行上运行,VIM宏也非常慢(尽管更改很复杂)。 se synmaxcol=1se ft=txtse foldmethod=manual可以有很大帮助。 VIM似乎还不够聪明,无法等到完成宏后再更新语法突出显示和折叠以及其他此类更改。说实话,这是VIM的失败。