如果在删除当前缓冲区后,缓冲区列表为空(即,如果在执行或之前,缓冲区列表中只有当前缓冲区),我希望:bd
和真正退出我的 vim 会话。我该如何实现这一点?我认为这应该很容易,但谷歌搜索并没有真正找到任何有用的东西,到目前为止,我还没有设法编写一个来实现这一点。:bw
:bd
:bw
autocmd
答案1
要检查单个缓冲区,您需要遍历所有潜在缓冲区,并检查它们是否仍然上市(例如:ls
)。每当删除缓冲区时都会触发检查:
:autocmd BufDelete * if len(filter(range(1, bufnr('$')), '! empty(bufname(v:val)) && buflisted(v:val)')) == 1 | quit | endif
答案2
建议的解决方案可能对某些插件存在问题。这是为我解决此问题的快捷方式,它似乎更安全,因为它不依赖于自动命令:
nn q :if ((len(filter(range(1, bufnr('$')), 'buflisted(v:val)')) == 1) && expand('%') == '')<Bar>exe 'q'<Bar>else<Bar>exe 'bd'<Bar>endif<cr>
bd
除非存在没有名称的单个缓冲区,否则它会使用quit
。
答案3
从上面修改:
func Smart_qq()
if expand('%') == '' && ( len( filter( range(1, bufnr('$')), 'buflisted(v:val)' ) ) == 1 )
exe 'quit!'
else
exe 'bdel!'
endif
endfunc
nn qq :call Smart_qq()<cr>
vn qq :call Smart_qq()<cr>
答案4
另一种方法是通过映射来实现。
有两个版本,一个要求保存,一个强制退出:
" Close the current buffer, quit vim if it's the last buffer
" Pass argument '!" to do so without asking to save
function! CloseBufferOrVim(force='')
if len(filter(range(1, bufnr('$')), 'buflisted(v:val)')) == 1
exec ("quit" . a:force)
quit
else
exec ("bdelete" . a:force)
endif
endfunction
nnoremap <silent> <Leader>q :call CloseBufferOrVim()<CR>
nnoremap <silent> <Leader>Q :call CloseBufferOrVim('!')<CR>