Vim 说 'missing :endif',但我确定它在那里

Vim says 'missing :endif', but I'm sure its there

考虑以下 vim 代码。

function! s:foo()
    if s:bar()
        let a = 1
    endif
endfunction

function! s:bar()
python << EOF
vim.command('echoerr "blabla"')
EOF
endfunction

command! Foo call s:foo()
map <F7> :Foo<CR>

打开一个 vim 会话并按 F7。 Vim 然后会抛出一个错误 E171: Missing :endif。 这怎么可能以及如何在 python 部分内正确发送错误消息?

if s:bar() 期望 s:bar() 到 return 一个值,但 s:bar() 没有。因此 "missing :endif".

附带说明一下,您也没有 import vim Python 代码(但不确定是否仍然需要)。

更新: echoerr 也提出了一个 vim.error。试试这个:

function! s:bar()
    python <<EOF
import vim

vim.command('normal \<Esc>')
vim.command('echohl ErrorMsg')
vim.command('echomsg "blabla"')
vim.command('echohl None')
EOF
    return 1
endfunction

在函数内部,:echoerr 的工作方式类似于 :throw 并引发异常。正常的控制流被中断并且 Vim 抱怨它没有看到 :endif:echoerr 在函数内部几乎没有用,还因为显示了完整的多行堆栈跟踪。

我会通过设置 v:errmsg(或任何其他自定义变量或标志)来解决这个问题,然后在函数结束时直接检查并报告错误:

function! s:foo()
    let v:errmsg = ''
    if s:bar()
        let a = 1
    endif
endfunction

function! s:bar()
python << EOF
vim.command('let v:errmsg = "blabla"')
EOF
endfunction

command! Foo call s:foo() | if ! empty(v:errmsg) | echoerr v:errmsg | endif
map <F7> :Foo<CR>