当在vim中关闭一个缓冲区时,我该如何执行一个命令?

4
在vim/vimscript中是否有类似于close-window-hook的东西,这样我就可以在每次关闭窗口时调用一个函数?
我想用它来实现以下场景: 我使用额外的scratch窗口显示文件信息,当我关闭文件时,我希望scratch窗口自动关闭,以便vim退出。
如果您有任何想法可以在没有hook的情况下实现,那也很好。
编辑: 我知道:qa[ll],但是我很懒,只想输入:q或ZZ。
编辑2.71828183: 我接受了autocommand答案,因为它最接近原始问题,但发现使用预览窗口而不是分割窗口的另一种解决方法。当最后一个“正常”窗口关闭时,预览窗口会自动关闭。
4个回答

4
自动命令很棒!在这种情况下,我相信BufLeave可以胜任,但你可能需要BufWinLeave?查看:help autocmd-events以获取完整的事件列表。
另一个重要的部分是:你可以有缓冲区本地的自动命令!(:help autocmd-buflocal)。你可以使用au BufLeave <buffer> ...为当前缓冲区定义自动命令。我的最佳猜测是,你可以在创建临时窗口的任何命令中运行此命令。当你打开临时窗口时,应该能够将临时窗口的缓冲区编号缓存到全局变量中,然后你的自动命令就可以删除该缓冲区(:help :bdelete)。
au BufLeave <buffer> bdelete g:scratch_buffer
call CreateScratchWindow()

function CreateScratchWindow() {
    ...
    let g:scratch_buffer = bufnr("")
}

还有一个函数winbufnr,可以通过窗口获取缓冲区编号。您可以使用任何一个 - 只需确保在使用时当前为scratch窗口/缓冲区!(“”表示当前窗口/缓冲区)。


自动命令是我在寻找钩子时想要的东西,谢谢你的提示。但是我无法让这个自动命令解决我的原始问题。它关闭了 Scratch 缓冲区,但原始文件没有关闭! - 0x89
我认为你想要使用 BufUnload - rampion
1
@rampion: 我认为当一个窗口被关闭时,它包含的缓冲区会变成隐藏状态,这不应该触发 BufUnload。你真的试过吗?@0x89: 非常奇怪。自动命令不应该影响自身之外的执行。使其工作的一种方法可能是让自动命令也关闭原始文件。(使用|连接命令,或编写一个函数供自动命令调用) - Cascabel
如果缓冲区是隐藏的或未加载的,则取决于“hidden”设置以及“bufhidden”选项。也许这就是解决方案:我在我的.vimrc中设置了“set hidden”,所以当我关闭第一个缓冲区时,它变成了_隐藏_,然后自动命令关闭另一个缓冲区,这使得第一个窗口再次可见 - 很棘手!所以我可以在au中关闭窗口。但我找到了另一种解决方案:我使用预览窗口而不是分割窗口(请参阅:help preview)。当没有其他窗口时,它会自动关闭。 - 0x89
哦!对不起,我本来就想建议这个的,但是被缓冲区本地自动命令完全分心了。 - Cascabel

0

添加一个映射。

:nnoremap :q :qa

那么,如果你只想在某一天使用:q,你可以这样做

:qa<backspace>

通常情况下,你可以直接

:q<enter>

并获取

:qa<enter>

免费提供。


0

好的,其实不是一个新问题,但我在寻找时发现了它,现在我知道了BufWinLeave。然而,作者描述的情况是我在我的vimrc中使用NerdTree时遇到的情况,例如当最后一个缓冲区关闭时,我希望vim关闭NerdTree“缓冲区”,然后退出。

autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif

NERDTree特定的内容替换为如何识别scratch缓冲区的内容。


-1

您可以使用

:quitall

或者

:qall

一次性关闭所有窗口。

如果您想忽略未保存的更改,请添加!

:qall!

抱歉,那不是我想要的。我想让第二个窗口自动关闭,无论第一个窗口如何关闭。包括ZZ、:q等任何方式。尤其是我不想一直输入:qa,因为:q已经成为我的习惯了。 - 0x89

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接