Reputation: 2628
Vim's multilayered views (Windows, Buffers and Tabs) left me a little confused. Let's say I split the display (:sp) and then select a different buffer to display in each window. Now I want to close one of the buffers, yet I don't want the window to close (After the closing it can display the next buffer on the list or an empty buffer, it doesn't matter). How can I do this?
Upvotes: 164
Views: 48091
Reputation: 4331
There are a bunch of NeoVim plugins to delete a buffer while preserving window layout.
They are listed under awesome-neovim.
Some of them are:
For plain vim, you can use:
Upvotes: 1
Reputation: 363
I like this answer most, although I prefer
<CTRL-^>:bd#
because it is faster to type and I don't need a keymapping.
The command <CTRL-^>
(same as on English keyboard) switches to the alternate file and :bd#
deletes the other buffer.
Upvotes: 2
Reputation: 41
Simply do :new|bd#
or Paste this into your 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
Then hit (space + d) or (space + x)
EDIT: even better with
nnoremap <silent><leader>d :new<BAR>bd#<BAR>bp<CR>
Upvotes: 3
Reputation: 1289
A simple version I use personally is
:bp|bd#
It goes to the previous buffer and deletes the other buffer (which is actually the original where we jumped from). This does what you would expect in 99% of cases without any complicated scripts.
As a keyboard shortcut I use the following
nnoremap <silent> <Leader>c :bp<BAR>bd#<CR>
Upvotes: 8
Reputation: 9876
If you're like me and you came here trying to do the opposite, close the window without closing the buffer, you can do that via:
:close
Upvotes: 1
Reputation: 4365
I messed with this a bit and finally came up with:
:bp | sp | bn | bd
Here's the copy/paste version for key mapping:
:bp<bar>sp<bar>bn<bar>bd<CR>
I've tested it a fair bit and it works consistently in various conditions. When used on the last buffer it will leave you with a new blank buffer.
Throw this in your .vimrc:
map <leader>q :bp<bar>sp<bar>bn<bar>bd<CR>
Restart Vim, or just :source ~/.vimrc
for changes to take effect. Next time you want to close a buffer just type: \q
(if \
is your leader key)
Upvotes: 188
Reputation: 1541
Here is a very readable vimscript function, which handles all cases well,
:bd
(if only one window, just invoke it!),
:enew
.buffer-list
, switch to it, else go next, 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
Upvotes: 3
Reputation: 72926
There's a script on the Vim wiki to do this. I don't think there is a builtin that does what you want.
The latest version of vim-bufkill is on github.
Upvotes: 36
Reputation:
I used to use :
:bp<bar>sp<bar>bn<bar>bd<CR>
But I found certain occasions where it closed my window.
Recently I noticed that I always use this when I am working on a project and need to quickly open my .tmux.conf
.zshrc
before going back to work.
For this usage, I find better to :
C-6
:bd#
to delete the previous buffer (I have mapped it like this : nnoremap <leader>d :bd#<CR>
)It allows me to control the buffer I'm going back to and feels more natural.
Upvotes: 2
Reputation: 3822
For those who use NERDTree.
I fix this using this plugin https://github.com/jistr/vim-nerdtree-tabs and now I can close the only buff/file/tab without closing the window.
After having the plugin above installed put the following code on my .vimrc:
let g:nerdtree_tabs_autoclose=0
The description for the variable above is: Close current tab if there is only one window in it and it's NERDTree (default 1)
More info here: https://github.com/jistr/vim-nerdtree-tabs#configuration
Upvotes: 5
Reputation: 31
To 'close' a view, use :hid[e]
. Works if you have managed to split the viewport or opened multiple files. You can't hide the last buffer on display.
1 Further tip that helped me: use :e ./path/to/file.work
to open a file in viewport without splitting the window.
P.S. At two days into vim I still have trouble finding the precise help commands. Hopefully this will help someone else keep working until they really get time to understand vim.
Upvotes: 1
Reputation: 1949
I searched for this today and came up with
:b#|bd#
which changes the current window to the previously open buffer and deletes/hides the buffer you just switched away from.
This requires at least two known buffers.
If another window but the current shows the same buffer this will still destroy splitting. You can change all windows to the previously open buffer with
:windo b#
I added more detail about the former command discussing a mapping for it (and some pitfalls) in an answer to a similar question.
Upvotes: 61
Reputation: 17323
My favorite solution for this is the bufkill.vim plugin (GitHub). It provides alternate versions of the various :b
-prefix commands that work the same as their counterparts, but leave the window open. They display whatever the last visible buffer contained, or an empty/new buffer if there was no prior buffer.
From the documentation:
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).
Upvotes: 1
Reputation: 633
nmap <leader>d :bprevious<CR>:bdelete #<CR>
Works as it should until one buffer is open in several windows. Good enough unless you want to use the bigger scripts out there.
Edit: this is what i use right now:
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
Upvotes: 15
Reputation: 35990
I think this is what you're looking for
http://www.vim.org/htmldoc/windows.html#window-moving
Try this:
Look ar your buffer id using
:buffers
you will see list of buffers there like
1 a.cpp
2 b.py
3 c.php
if you want to remove b.py from buffer
:2bw
if you want to remove/close all from buffers
:1,3bw
Upvotes: 7
Reputation: 1099
I don't think there is a one shot way to do this, but you could do :enew
or :ls
to list your buffers and swap to a different one using :b [number]
.
Once you've got a different buffer in the window :bd #
will delete the previous buffer in the window, and since the current buffer still exists the window won't be closed.
Upvotes: 3
Reputation: 66263
Would
:enew
do what you want? it will edit a new, unnamed buffer in the current window leaving the existing file open in any other windows.
Upvotes: 1