如何在 vim 中抛出错误,导致静默失败而不打印任何消息?

问题描述 投票:0回答:1

我有一个 vim 函数可以移动光标。它还可能会抛出错误。用于说明目的的简化版本是:

" Move cursor to the 1st line. Errors if the cursor was on the 2nd line.
function! FirstLineErrorOut()
    let l:curr_line = line(".")
    call cursor(1, 1)
    if l:curr_line == 2
        throw "error"
    endif
endfunction

然后我在操作员挂起模式下将密钥绑定到它:

onoremap lb :call FirstLineErrorOut()<cr>

我想要实现的是完成错误之前的操作(即定位光标),然后通过抛出错误来中止操作员挂起模式(参见https://vimhelp.org/map.txt.html#映射错误),但没有显示任何错误消息(即“处理函数时检测到错误... E605:未捕获异常:错误”)。

映射当前定位光标,中止操作员挂起模式,但确实显示错误消息,并且需要用户按

<enter>
才能继续,我想避免这种情况。

请注意,这种效果可以通过内置 vim 键(如

b
ge
)来实现(请参阅 https://stackoverflow.com/a/79261518/7881370 中的讨论),其中光标位于第一行,而不执行删除(
d
)。

我尝试过但没有成功的事情:

  • onoremap <silent> lb :call FirstLineErrorOut()<cr>
    :错误消息仍然显示。
  • onoremap <silent> lb :silent call FirstLineErrorOut()<cr>
    :错误消息仍然显示。
  • onoremap lb :silent! call FirstLineErrorOut()<cr>
    :错误消息被抑制,但操作员挂起模式也不会中止。
  • redir @a
    定义中的
    redir END
    之前和之后添加
    throw "error"
    FirstLineErrorOut()
    :错误消息仍然显示,尽管它也被发送到寄存器
    @a
  • throw "error"
    包围
    try ... catch ... endtry
    :操作员挂起模式当然不会被中止。

非常感谢!

vim
1个回答
0
投票

技巧是首先取消操作员挂起模式,然后根据特定条件重新激活它。受到 vimhelp 中示例的启发。代码:

" Move cursor to the 1st line, run the operator
" unless the cursor was on the 2nd line.
function! FirstLineErrorOut(operator)
    let l:curr_line = line(".")
    if l:curr_line == 2
        call cursor(1, 1)
    else
        execute "normal! " . a:operator . ":call cursor(1, 1)\<cr>"
    endif
endfunction

onoremap lb <esc>:call CancelFirstLineErrorOut(v:operator)<cr>
© www.soinside.com 2019 - 2024. All rights reserved.