Vimscript - 以前的缓冲区&传播错误消息

时间:2015-01-08 17:08:24

标签: vim window buffer

我正在开发一个在当前窗口中打开帮助文档的函数,而不是新的拆分。 这是现在的功能:

function! OpenHelpInCurrentWindow(topic) " {{{2
  " Open a helpfile in the current window, rather than a new split.

  try
  " Open the help document.
    execute 'help '.a:topic

    " Get buffer id of the help document.
    let l:help_buffer = bufnr("%")

    " Close the help buffers' window. This *should* return us to the window we ran
    " this command from.
    wincmd c

    " Switch to the help doc's buffer in the current window.
    :execute "buffer ".help_buffer

  catch
    echo 'Sorry, no help for ' . a:topic . '.'
  endtry

endfunction

我将其映射到:H with:

command! -nargs=? -complete=help H call OpenHelpInCurrentWindow(<q-args>) 

目前有两个问题:

如果为帮助文件输入错误名称,则无法打开帮助文件。使用内置帮助命令(:help)时,会以红色显示错误消息,但不需要您点击以继续。

如果我使用echoerr显示错误消息,它会以红色显示消息,但也会显示行号并需要继续(而不是:help的工作方式)。

如果我使用echo显示错误消息,则会以前景色显示(不是像:help那样的红色,但不显示行号或需要继续)。

任何想法如何让我更接近默认行为?

第二个问题是,当您使用此功能打开帮助文档时,前一个缓冲区未正确设置。试图回到我正在使用的地方:bprevious将我转储到错误的文档中。

为什么会发生这种情况,跟踪“缓冲列表”(我认为这不是tagstack),或者我如何修复它的任何想法?

谢谢!

2 个答案:

答案 0 :(得分:1)

是的,函数中的:echoerr打印出多行信息。完全正确的方法是将该部分移出函数,并将:echoerr直接放入:command定义中,但这很麻烦。 (我的ingo-library plugin有一个有用的ingo#err#Get()功能。)

大多数插件只是使用:echohl:echomsg来模拟错误报告:

echohl ErrorMsg
echomsg 'Sorry, no help for ' . a:topic . '.'
echohl None

唯一的缺点是它不会中止命令链,例如:H foo | quit


关于:bprevious,按缓冲区编号导航。由于帮助缓冲区也是缓冲区,因此订单变得混乱。您需要使用其他导航方式,例如备用文件<C-^>:edit #)或参数和:argnext

答案 1 :(得分:1)

忘记窗户洗牌。我们可以通过set buftype=help

在当前缓冲区中打开帮助

我们遇到以下问题:

  • 在成功案例中恢复上一个缓冲区'buftype'的{​​{1}}值
  • 在错误情况下恢复当前缓冲区的#'buftype'
  • 正确地发送%错误消息

:h命令与许多Vim命令一样,会在出现错误消息时设置:h。这意味着我们可以检测到错误消息。然而,正如@Ingo Karkat所说,这将给出一个&#34;堆栈跟踪&#34;在函数内部使用时。我们可以通过v:errmsg来抑制错误来解决这个问题。现在,我们可以检查:silent!并正确恢复v:errmsg

由于您仍希望保留错误消息,我们将在'buftype'定义中使用:execute并让函数返回失败的帮助命令。

以下是生成的代码:

:command

思想

  • 您可能希望查看cmdallias.vim之类的内容,以便更轻松地输入此命令
  • 也许不是所有这些麻烦只是通过function! s:help(subject) let buftype = &buftype let &buftype = 'help' let v:errmsg = '' let cmd = "help " . a:subject silent! execute cmd if v:errmsg != '' let &buftype = buftype return cmd else call setbufvar('#', '&buftype', buftype) endif endfunction command! -nargs=? -bar -complete=help H execute <SID>help(<q-args>) (我的偏好)将帮助窗口提升到自己的标签
  • 如果<c-w>T已经打开的窗口不同,则需要调整该技术以考虑

更多帮助

buftype=help