Vim:关闭除当前缓冲区之外的所有缓冲区

288

如何在Vim中关闭除当前编辑的缓冲区以外的所有缓冲区?


1
我找到了这个链接 - klokop
18个回答

284

我能够轻松地像这样做到:

:%bd|e#

5
这是一个不错的回答。它让 BufOnly 感觉有些过度(我的意思是,整个插件?)除非您正在使用 BufOnly 的参数传递功能。我真正想做的就是:%bd|e# - shmup
71
%bd表示删除所有缓冲区。e#表示打开最后一个缓冲区进行编辑。中间的竖线只是依次执行两个命令。 - OldTimeGuitarGuy
55
你可以使用 %bd|e#|bd# 命令来删除被创建的 [No Name] 缓冲区。 - kshenoy
19
太棒了。那么,这里有我曾经使用BufOnly插件的唯一事情,精简为一个命令:command! BufOnly silent! execute "%bd|e#|bd#" - shmup
12
@Finn,你需要转义|符号:map <leader>o :%bd\|e#<cr>。该命令的作用是删除当前缓冲区并重新打开之前关闭的缓冲区。 - Halil Özgür
显示剩余12条评论

219

3
这不会关闭 NERDTree 缓冲区。 - Uri
3
在执行 bd 命令关闭 vim 本身之前,您可能需要先关闭 NERDTree。可以使用以下命令实现:nnoremap <silent> <leader>c :NERDTreeClose<bar>bufdo bd<CR> - lvarayut
17
文档警告称,:bufdo的参数“不能删除缓冲区或将缓冲区添加到缓冲区列表中”。因此,如果这个解决方案有效,那么它就是偶然的... 而且通常对我不起作用(会切换到另一个缓冲区)。 - glts
19
这个命令关闭了我的所有缓冲区,这不是问题所要求的。 (MacVim版本8.0.1207) - Michael Leonard
9
这个命令会关闭所有缓冲区。如何让当前的缓冲区保持打开状态? - h-rai
显示剩余4条评论

64

61
如果您不关心当前的内容,更简单的做法是这样的(无需脚本):
1,100bd

5
它也会关闭nerdtree缓冲区。 - Afshin Mehrabani
当启用NERDTree时,我使用这个命令遇到了一些问题。我建议使用@VoY提到的BufOnly.vim插件。 - moeabdol
1
我创建了以下映射,用于删除NERDTree缓冲区:nnoremap <leader>bd :%bd | NERDTree<cr> - Uri
6
我使用这个命令已经很长时间了,但现在出现了“E16:无效范围”的错误提示,因为范围内的一些缓冲区实际上并不存在。虽然以前没有处理这种情况,但现在却不能忽略它。 - Jon
3
请执行命令 :ls 查看您实际打开的最大缓冲区,并将范围设置为该缓冲区(例如,如果您的最高缓冲区为22,则执行命令:1,22bd)。在我执行这个命令之前,我也遇到了同样的错误。 - Nairou

59

我这样做。

:w | %bd | e#

如果我只想打开当前缓冲区并关闭所有其他缓冲区,那么这是我的最爱。

工作原理:首先写入当前缓冲区的更改,然后关闭所有打开的缓冲区,最后重新打开我当前正在使用的缓冲区。在Vim中,|将命令的执行链接在一起。如果您的缓冲区已经更新,则可以将上述内容缩短为:%bd | e#.


它大部分时间都能正常工作。但有时“%”不能像所有选择器一样工作。你有猜测吗? - Jinyoung Kim
1
在“:%bd”命令中,“%”范围将被替换为当前缓冲区的起始和结束行号。而不是使用“%”作为范围,您应该指定范围的数字。例如,要删除所有缓冲区,可以使用命令“:1,9999bd”。 - iamnotsam
我刚刚查看了文档。那么,'%'范围依赖于当前文件行数的数量? - Jinyoung Kim
是的,@JinyoungKim,那是正确的。我尝试用一个范围来替代%,但是出现了错误(:w | 1,999bd | e#),所以目前我不知道最好的解决方案。如果你找到了一个,请告诉我。 - iamnotsam
2
我发现了内置函数bufnr("$"),它返回最后一个缓冲区的编号。但是当我像这样使用:1,bufnr("$")bd时,我不知道如何插入字符串。也许最好的解决方案是:1,9999bd - Jinyoung Kim
4
:help :bd 显示 :%bdelete " delete all buffers,因此 % 正是你想要的。我使用了你解决方案的一个变体::%bd<CR><C-O>:bd#<CR>。这将删除所有缓冲区,然后使用 <C-O> 返回到当前文件中的位置,最后使用 :bd# 删除未命名的缓冲区。这会关闭所有缓冲区并让你停留在同一位置。 - Alejandro

28

在 juananruiz 的答案上进行改进。

对你想要保留的缓冲区进行小改动,然后执行:

:1,1000bd

bd 命令(删除缓冲区)不会删除任何存在未保存更改的缓冲区。这样你就可以在缓冲区列表中保留当前(已更改)文件。

编辑:请注意,这也会删除你的 NERDTreeBuffer。你可以使用 :NERDTree 命令恢复它。


完美,简短而简单! :) - arkod
63
"%bd" 实际上代表的是“全部”,而不是 1-1000。 - John Tyree
这是否依赖于设置set nohidden - Felipe Alvarez
1
这是最好的答案。即使您想保留多个缓冲区,它也可以正常工作。 - saud
这应该是被接受的答案。没有需要记忆的命令序列,并且保留了您想要保留的缓冲区的编辑历史记录。就像它变得容易一样,我希望我可以给它更多的赞 :) - Francesco Marchetti-Stasi

20

以下是我的做法。我喜欢在删除所有缓冲区后保持光标位置,而大多数上面介绍的解决方法都忽略了这一点。我认为重新映射命令比输入命令要好,所以我使用<leader>bd来删除所有缓冲区并跳回原始光标位置。

noremap <leader>bd :%bd\|e#\|bd#<cr>\|'"

%bd = 删除所有缓冲区。

e# = 打开最后一个用于编辑的缓冲区(即我正在使用的缓冲区)。

bd# 可以删除使用 %bd 创建的 [No Name] 缓冲区。

管道符只是一个接一个地执行命令。不过,你必须使用 \| 转义它。

'" = 保留我的光标位置。


19

我把这个放在我的 .vimrc 文件中

nnoremap <leader>ca :w <bar> %bd <bar> e# <bar> bd# <CR>

然后你的leader+ca(关闭所有)会关闭除当前缓冲区之外的所有缓冲区。

它所做的是:

:w - 保存当前缓冲区

%bd - 关闭所有缓冲区

e# - 打开上次编辑的文件

bd# - 关闭未命名缓冲区


喜欢它,稍微调整并添加到我的配置中:nnoremap <silent> <leader>bo :w <bar> %bd <bar> e# <bar> bd# <CR><CR> - Harrison Cramer
我建议将 :w ... 更改为 :up ...(更新),只有当前文件发生更改时才会写入。 - SergioAraujo

17

注意: 正如评论中所提到的,这将关闭窗口而不是缓冲区

通过使用

:on[ly][!]

and

:和
:h only

18
仍然有用,因为人们可能会搜索错误的术语,并找到这篇文章。因此感谢你们两个。 :) - archgoon
2
@archgoon 是的,但应该在答案中进行说明。 - andho
你也可以使用 C-W o 来实现这个功能。 - niid

10
关闭所有打开的缓冲区:
silent! execute "1,".bufnr("$")."bd"

关闭所有打开的缓冲区,除了当前的缓冲区

function! CloseAllBuffersButCurrent()
  let curr = bufnr("%")
  let last = bufnr("$")

  if curr > 1    | silent! execute "1,".(curr-1)."bd"     | endif
  if curr < last | silent! execute (curr+1).",".last."bd" | endif
endfunction
将此函数添加到.vimrc中,并使用:call CloseAllBuffersButCurrent()调用它。
方便的映射:
nmap <Leader>\c :call CloseAllBuffersButCurrent()<CR>

我注意到当恢复vim会话时,它会还原缓冲区,我不能再使用上述命令来删除缓冲区。相反,我必须使用 :%bd|e#|bd# 命令。 - shmup
1
最佳解决方案。我添加了一个命令来重新打开NERDTree nmap <Leader>\c :call CloseAllBuffersButCurrent()<CR>:NERDTree<CR> - Gjaa

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