限制计数修饰符以迭代命令

Limit count modifier to iterate commands

Vim提供了the count modifier,用于对命令进行乘法或加法迭代。如果你使用 vim,你可能对它很熟悉:它允许你写 50j 向下移动 50 次。

有时我在使用其他应用程序时不知不觉输入了一个大数字。当我然后继续使用 vim 并且例如键入 o 开始新行时,vim 自然会尝试创建大量新行,这会慢慢填满内存然后被内核 OOM 杀手杀死。

是否有任何方法可以限制计数器或在大于某个阈值时添加确认?

几乎有效:

function! UpdateCount(n) abort
    let limit = get(g:, 'counter_limit', 99)
    if v:count == 0
        return ''.a:n
    elseif v:count == limit
        return ''
    elseif 10 * v:count + a:n > limit
        return repeat("\<Del>", strlen(v:count)).limit
    else
        return ''.a:n
    endif
endfunction

nnoremap <expr> 0 UpdateCount(0)
nnoremap <expr> 1 UpdateCount(1)
nnoremap <expr> 2 UpdateCount(2)
nnoremap <expr> 3 UpdateCount(3)
nnoremap <expr> 4 UpdateCount(4)
nnoremap <expr> 5 UpdateCount(5)
nnoremap <expr> 6 UpdateCount(6)
nnoremap <expr> 7 UpdateCount(7)
nnoremap <expr> 8 UpdateCount(8)
nnoremap <expr> 9 UpdateCount(9)

但是,不幸的是,它不适用于 0 键,因为 Vim disables any mappings for 0 while entering a count,这是有道理的,因为 0 本身就是命令转到该行的第一个字符,如果未禁用这些映射,则 nnoremap 0 ^ 等命令会破坏 0 在计数中的使用...

所以,是的,除了修补 Vim 以添加限制外,我真的没有找到解决此问题的好方法 一般

如果某些命令比其他命令更容易出现问题(即插入命令,例如 oiA 等),那么您可能需要考虑向其中添加映射,检查其中的 v:count 并在计数超过特定限制时阻止它们。

例如:

function! LimitCount(cmd) abort
    let limit = get(g:, 'counter_limit', 99)
    if v:count > limit
        echomsg "Count ".v:count." is too large, aborting execution of '".a:cmd."' command."
        " Use Ctrl-C to erase the pending count and avoid applying it to the next command.
        return "\<C-C>"
    else
        return a:cmd
    endif
endfunction

nnoremap <expr> o LimitCount('o')
nnoremap <expr> i LimitCount('i')
" And so on for other insertion commands...