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


120

Vim的多层视图(Windows,Buffers和Tabs)使我有些困惑。假设我分割显示(:sp),然后选择一个不同的缓冲区在每个窗口中显示。现在,我想关闭其中一个缓冲区,但我不想关闭窗口(关闭后,它可以在列表上显示下一个缓冲区或为空缓冲区,这没有关系)。我怎样才能做到这一点?

谢谢。


您是否有理由要关闭缓冲区而不是不再看到缓冲区?
抢劫

9
我实际上也一直在想这个。删除缓冲区并随后必须重建过程中销毁的任何部分,这很烦人。
brettkelly

3
到目前为止,获得了29票。我认为这是一个很常见的用例。当我使用大量缓冲区时,我需要这个。有时我正在使用2个窗口,并想关闭缓冲区。我不希望那个窗户消失。我只希望下一个缓冲区显示在那里。
Wilson Freitas 2014年


Answers:



145

我对此有些混乱,最后想到了:

: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如果\您的前导键是)


1
谢谢!美观而简单,与我见过的几乎所有其他解决方案都不一样。
2013年

16
对于初学者来说,这扔在你的.vimrcmap <leader>q :bp<bar>sp<bar>bn<bar>bd<CR>。重新启动VIM,下次您要关闭缓冲区时,只需键入:\q
EasyCo

5
如果您有一个垂直分割的窗口,这将产生意外的结果。实际上,除了标准(由创建sp)以外的任何窗口拆分配置。
hitzg

2
我认为在.vimrc中添加的内容片段不应在最后加上句号。除此之外,太棒了!这应该是公认的答案。
埃内斯托

3
这很优雅。如其他人所说的,如果你主要使用垂直分割,开关spvsp。我的.vimrc条目如下所示:cnoremap bd bp<bar>vsp<bar>bn<bar>bd
Connor

38

我今天搜索了这个,然后想到了

:b#|bd#

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

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

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

:windo b#

我在有关类似问题答案中添加了有关前一个命令的更多详细信息,其中讨论了该命令的映射(以及一些陷阱)。


也可以做到这一点... :#b|#bd只是在上面交换缓冲区命令和缓冲区编号。
Ashish

我已经使用了一点,但是我一直对它重新打开以前关闭的buffter感到恼火。
pean

@pean这就是我在链接的答案中提到的内容-请参阅“重要说明”。是的,如果这切换到另一个打开的缓冲区,那就更好了。
有效期

1
您也可以分别执行:bn|bd#:bp|bd#切换到上一个或下一个打开的缓冲区,而不是最近访问的缓冲区(b#)。
pavon

12
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

1
我尝试过这种方法,但在使用多个拆分窗口时效果不佳。如果有人遇到相同的问题,这是我的解决方案:nmap <leader>d :ene<CR>:bd #<CR>
caio 2012年

7

我想这就是你要找的

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

试试这个:

使用以下命令查看您的缓冲区ID

:buffers

您将看到类似的缓冲区列表

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

如果要从缓冲区中删除b.py

:2bw

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

:1,3bw

1
我不想移动窗户。我想关闭缓冲区而不触摸窗口的位置,大小或存在性。
莫什

5

对于那些使用NERDTree的人。

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

安装完上述插件后,将以下代码放在我的.vimrc上:

let g:nerdtree_tabs_autoclose=0

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

此处更多信息:https : //github.com/jistr/vim-nerdtree-tabs#configuration


2

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

在窗口中找到其他缓冲区后,:bd #将删除该窗口中的先前缓冲区,并且由于当前缓冲区仍然存在,因此不会关闭该窗口。


2

我曾经用过:

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

但是我发现在某些情况下它关闭了我的窗户。

最近,我注意到我在处理项目时总是使用此功能,并且需要快速打开我的内容.tmux.conf .zshrc才能恢复工作。

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

  • 切换回我以前使用的缓冲区 C-6
  • 键入:bd#要删除以前的缓冲区(我制订这样的:nnoremap <leader>d :bd#<CR>

它使我可以控制要返回的缓冲区,感觉更自然。


1

:enew

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


这将打开一个新的空缓冲区。我想关闭当前缓冲区而不关闭窗口。
莫什

1

我最喜欢的解决方案是bufkill.vim插件(GitHub)。它提供了各种版本的替代版本:b -prefix命令的命令的功能 -prefix命令相同,但保持窗口打开。它们显示最后包含的可见缓冲区,如果没有先前的缓冲区,则显示空白/新缓冲区。

从文档中:

当您要卸载/删除/擦除缓冲区时,请使用:
  :bun /:bd /:bw也可以关闭窗口(vim命令),或者
  :BUN /:BD /:BW保持窗口不变(此脚本)。

1

要“关闭”视图,请使用:hid[e]。如果您已成功拆分视口或打开了多个文件,则可以使用。您无法隐藏显示的最后一个缓冲区。

1进一步帮助我的技巧:用于:e ./path/to/file.work在视口中打开文件而不拆分窗口。

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


1

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

  • 行为类似于内置:bd(如果只有一个窗口,只需调用它!),
    • 发出警告,如果修改了缓冲区,则不执行任何操作。
    • 如果没有其他缓冲区,则通过创建一个:enew
    • 如果存在备用缓冲区buffer-list,则切换到该缓冲区,否则,通过继续:bn
  • 多窗口布局的更合理的行为
    • 不关闭任何窗口,
    • 始终停留在原始窗口上。
    • 对于显示当前缓冲区的每个窗口,请执行上述操作,然后删除旧的当前缓冲区。
nnoremap <Leader> b:调用DeleteCurBufferNotCloseWindow()<CR>

功能!DeleteCurBufferNotCloseWindow()中止
    如果并修改
        echohl ErrorMsg
        echom“ E89:自上次更改以来没有写入”
        echohl无
    elseif winnr('$')== 1
        d
    其他“多窗口
        让oldbuf = bufnr('%')
        让oldwin = winnr()
        而1英寸所有显示oldbuf的窗口将保持打开状态
            如果buflisted(bufnr('#'))
                b#
            其他
                n
                让curbuf = bufnr('%')
                如果curbuf == oldbuf
                    enew” oldbuf是唯一的缓冲区,创建一个
                万一
            万一
            让胜利= bufwinnr(oldbuf)
            如果获胜== -1
                打破
            否则,还有其他显示oldbuf的窗口
                exec win'wincmd w'
            万一
        最后
        删除oldbuf并将窗口还原到oldwin
        exec oldbuf'bd'
        exec oldwin'wincmd w'
    万一
endfunc

0

如果您像我一样,并且是来这里尝试相反的操作,请关闭窗口而不关闭缓冲区,则可以通过以下方法进行操作:

:close


0

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

:bp|bd#

它转到上一个缓冲区,然后删除另一个缓冲区(实际上是我们从中跳出的原始缓冲区)。在没有任何复杂脚本的情况下,这可以实现99%的情况。

作为键盘快捷键,我使用以下命令

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.