如何在不关闭窗口的情况下关闭缓冲区?

Vim 的多层视图(Windows、 Buffers 和 Tabs)让我有点困惑。假设我分割了 display (: sp) ,然后选择一个不同的缓冲区在每个窗口中显示。现在我想关闭其中一个缓冲区,但是我不希望窗口关闭(关闭后,它可以显示列表上的下一个缓冲区或一个空缓冲区,这并不重要)。我怎么能这么做?

34385 次浏览

使用“ : bd”作为命令。

会的

:enew

做你想做的?它将在当前窗口中编辑一个新的、未命名的缓冲区,使现有文件在任何其他窗口中保持打开状态。

我想这就是你要找的

Http://www.vim.org/htmldoc/windows.html#window-moving

试试这个:

查看缓冲区 ID 使用的

:buffers

您将看到缓冲区列表,如

1  a.cpp
2  b.py
3  c.php

如果要从 buffer 中删除 b.py

:2bw

如果要从缓冲区中删除/关闭所有

:1,3bw

我不认为有一个一次性的方法来做到这一点,但您可以做 :enew:ls列出您的缓冲区,并交换到一个不同的使用 :b [number]

一旦你有一个不同的缓冲区在窗口 :bd #将删除以前的缓冲区在窗口,因为当前的缓冲区仍然存在,窗口将不会被关闭。

Vim wiki上有这样的脚本。我不认为有一个内置的,做你想要的。

最新版本的 vim-bufkill 在 github 上.

nmap <leader>d :bprevious<CR>:bdelete #<CR>

在多个窗口中打开一个缓冲区之前,它一直按照应该的方式工作。很好,除非你想使用更大的脚本。

编辑: 这是我现在使用的:

function! BufferDelete()
if &modified
echohl ErrorMsg
echomsg "No write since last change. Not closing buffer."
echohl NONE
else
let s:total_nr_buffers = len(filter(range(1, bufnr('$')), 'buflisted(v:val)'))


if s:total_nr_buffers == 1
bdelete
echo "Buffer deleted. Created new buffer."
else
bprevious
bdelete #
echo "Buffer deleted."
endif
endif
endfunction

我稍微修改了一下,最后想到了:

:bp | sp | bn | bd

下面是键映射的复制/粘贴版本:

:bp<bar>sp<bar>bn<bar>bd<CR>

我已经对它进行了相当多的测试,它在各种条件下都能稳定地工作。当在最后一个缓冲区上使用时,它将给您留下一个新的空白缓冲区。

把这个放进你的.vimrc:

map <leader>q :bp<bar>sp<bar>bn<bar>bd<CR>

重新启动 Vim,或者只启动 :source ~/.vimrc以使更改生效。下次要关闭缓冲区时,只需键入: \q(如果 \是前导键)

我最喜欢的解决方案是 Bufkill Vim插件(GitHub)。它提供了各种 :b前缀命令的替代版本,这些命令与它们的对应命令工作原理相同,但是窗口保持打开状态。它们显示包含的最后一个可见缓冲区,或者如果没有先前的缓冲区,则显示一个空的/新的缓冲区。

根据文件:

When you want to unload/delete/wipe a buffer, use:
:bun/:bd/:bw to close the window as well (vim command), or
:BUN/:BD/:BW to leave the window(s) intact (this script).

我今天找到了这个

:b#|bd#

它将当前窗口更改为先前打开的缓冲区,并删除/隐藏刚刚切换的缓冲区。

这需要至少两个已知的缓冲区。

如果另一个窗口但当前显示相同的缓冲区,这仍然会破坏拆分。可以将所有窗口更改为以前打开的缓冲区

:windo b#

我添加了关于前一个命令的更多细节,讨论了它在 回答类似的问题中的映射(以及一些缺陷)。

要“关闭”视图,请使用 :hid[e]。如果您已经设法拆分了视图端口或打开了多个文件,则可以正常工作。不能隐藏显示的最后一个缓冲区。

1另一个帮助我的技巧: 使用 :e ./path/to/file.work在 viewport 中打开一个文件而不需要分割窗口。

附言。进入 vim 两天后,我仍然很难找到精确的帮助指令。希望这将帮助其他人继续工作,直到他们真正有时间了解 Vim。

给那些使用 NERDTree 的人。

我用这个插件 https://github.com/jistr/vim-nerdtree-tabs修复了这个问题,现在我可以关闭唯一的 buff/file/tab 而不用关闭窗口。

在安装了上面的插件之后,在 my.vimrc 上添加以下代码:

let g:nerdtree_tabs_autoclose=0

上面对变量的描述是: 如果当前选项卡中只有一个窗口,并且它是 NERDTree (默认值为1) ,则关闭该选项卡

更多信息请点击: https://github.com/jistr/vim-nerdtree-tabs#configuration

我过去常用:

:bp<bar>sp<bar>bn<bar>bd<CR>

但我发现有时候它会关上我的窗户。

最近我注意到我总是使用这个当我在一个项目工作,需要快速打开我的 .tmux.conf .zshrc然后再回去工作。

对于这种用法,我发现更好的做法是:

  • 切换回我之前使用 C-6处理的缓冲区
  • 键入 :bd#删除前面的缓冲区(我已经像这样映射了它: nnoremap <leader>d :bd#<CR>)

它允许我控制我要回到的缓冲区,并且感觉更自然。

这是一个非常易读的 vimscript 函数,它可以很好地处理所有情况 ,

  • 行为类似于内置的 in:bd(如果只有一个窗口,只需调用它!) ,
    • 发出警告,如果缓冲区被修改,则什么也不做。
    • 如果没有其他缓冲区,通过 :enew创建一个。
    • 如果存在备用缓冲区并且在 buffer-list中,切换到它,否则转到下一个,via:bn
  • 更合理的多窗口布局行为
    • 不关窗户,
    • 始终停留在原来的窗口。
    • 对于显示当前缓冲区的每个窗口,执行上面列出的操作,然后删除旧的当前缓冲区。
nnoremap <Leader>b :call DeleteCurBufferNotCloseWindow()<CR>


func! DeleteCurBufferNotCloseWindow() abort
if &modified
echohl ErrorMsg
echom "E89: no write since last change"
echohl None
elseif winnr('$') == 1
bd
else  " multiple window
let oldbuf = bufnr('%')
let oldwin = winnr()
while 1   " all windows that display oldbuf will remain open
if buflisted(bufnr('#'))
b#
else
bn
let curbuf = bufnr('%')
if curbuf == oldbuf
enew    " oldbuf is the only buffer, create one
endif
endif
let win = bufwinnr(oldbuf)
if win == -1
break
else        " there are other window that display oldbuf
exec win 'wincmd w'
endif
endwhile
" delete oldbuf and restore window to oldwin
exec oldbuf 'bd'
exec oldwin 'wincmd w'
endif
endfunc

如果你像我一样,来到这里试图做 相反,关闭窗口而不关闭缓冲区,你可以通过:

:close

我个人使用的一个简单版本是

:bp|bd#

它转到前一个缓冲区并删除另一个缓冲区(实际上就是我们跳出的原始缓冲区)。 在没有任何复杂脚本的情况下,99% 的情况下都可以做到这一点。

作为一个快捷键,我使用以下方法

nnoremap <silent> <Leader>c :bp<BAR>bd#<CR>

简单地执行 :new|bd#或粘贴到您的 vimrc

let mapleader = " "
" CLOSE current Buffer without closing window
nnoremap <silent><leader>d :new<BAR>bd#<CR>
" CLOSE current window
noremap <leader>x <c-w>c

然后点击(空格 + d)或(空格 + x)

编辑: 甚至更好

nnoremap <silent><leader>d :new<BAR>bd#<BAR>bp<CR>

我最喜欢 这个的答案,虽然我更喜欢

<CTRL-^>:bd#

因为它的输入速度更快,而且我不需要键盘映射。

命令 <CTRL-^>(与英文键盘相同)切换到备用文件,:bd#删除另一个缓冲区。