我将一个非常简单的vim宏保存到一个键:qa $ pjq然后用40000 @ a执行40000次。这很慢。我一定做错了,因为虽然它确实有效,但需要60-90秒。这和vim一样快吗?是否有一些设置可以加速这个?是否存在使宏执行变慢的插件混合?
我正在使用Mac并使用MacVim。它是一个纯文本文件,它实际上没有比这简单。
答案 0 :(得分:22)
粘贴40,000行并不需要很长时间,但如果你不断更新屏幕,就像你经常在宏中那样放慢速度。
首先,关于你的宏应该做什么的问题。如果它只是粘贴默认寄存器的内容,那么正确的宏定义只是qapjq
。无需将光标定位在前一行的特定位置。 [编辑:抱歉,我假设你正在进行行式粘贴,如果你在行尾贴上字符顺序注册,则需要定位。 。 ..]
其次,您可以通过设置lazyredraw(:set lazyredraw
)来加速当前的宏,因此屏幕不会随着更新而更新。可能不会把事情加速很多,像这样的键盘宏不像是直接处理缓冲区。
第三,这是另一种方法,需要大约一秒钟:
.,+40000g/.*/normal! $p
答案 1 :(得分:8)
这很正常。正如Herbert Sitz所写,更新屏幕的速度很慢。
您可能只想运行替换命令::.,+40000s/.*/&<c-r>"
。
.,+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
<CR>
<Tab>
...
jiangmiao/auto-pairs
Raimondi/delimitMate
:noautocmd :norm @q
在宏运行期间暂时禁用事件。
或者在宏运行之前set eventignore=all
,然后将其设置回来。CursorMoved(I)
, CursorHold(I)
InsertCharPre
、InsertEnter
、InsertLeave(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
:noautocmd
,eventignore
答案 4 :(得分:-1)
我遇到了一些问题,即使在少量的行上运行,VIM宏也非常慢(尽管更改很复杂)。 se synmaxcol=1
和se ft=txt
和se foldmethod=manual
可以有很大帮助。 VIM似乎还不够聪明,无法等到完成宏后再更新语法突出显示和折叠以及其他此类更改。说实话,这是VIM的失败。