If I have 2 buffers split horizontally/vertically and want to close one of them, but i don't want to close a window. I want to keep places of split windows are the same as 开发者_运维百科before closing buffer.
If I press :bd , the window in which was closed buffer also became closed.
Like @RusAlex I don't like plug-ins. I also like to know what code I enter actually does.
nmap ,d :b#<bar>bd#<CR>
In short this adds a key mapping to vim's normal mode waiting for key sequence ,d
. When executed this switches to a previously open buffer and attempts to delete the buffer you switched away from.
Deleting an off-screen buffer keeps the screen split as it is.
The command consists of three space-separated parts:
nmap
- add/change key mapping for mode normal,d
- key sequence to react to; first,
(comma), thend
:b#<bar>bd#<CR>
- key sequence to execute
The command to be executed consists of five parts:
:
- switch vim to mode command-lineb#
- switch window to previously open buffer<bar>
- expect a follow-up command; represents|
(pipe character); used for chaining commandsbd#
- delete previously open buffer, i.e. the buffer just switched away from<CR>
- execute command(s); represents carriage return, basically the keysReturn
orEnter
The command is in the format it is used in a configuration file like ~/.vimrc
. If you want to add the mapping from within vim you prepend :
(colon) - the mapping then will be lost when exiting vim:
:nmap ,d :b#<bar>bd#<CR>
When you open vim it is usually in normal mode as opposed to modes insert (indicated on the bottom of the screen by -- INSERT --
after pressing i
), visual and so on. The n
in nmap
specifies the key mapping to be added to normal mode only. Find more on mappings here
Important notes:
b#
will switch to the current buffer if it is the only known buffer.b#
may switch to a hidden/closed buffer, e.g. the one you just closed by pressing,d
.bd#
will close the current buffer if it is the only known buffer unsplitting the screen leaving you with an empty buffer.bd#
will fail if the buffer switched away from is a hidden/closed buffer.bd#
will still unsplit if after switching another window shows the buffer to close.
Additional notes:
:windo b#
will switch all windows to the previously open buffer. Not sure how to combine withbd
.<CR>
can be left out in which case you have to manually pressReturn
orEnter
to execute.:nmap ,
displays all normal mode mappings starting with,
.:ls
lists open buffers.
It's impossible to have an empty window in vim, but you can just create a new empty file in the current window using :enew
.
I'll have to check on my work computer, but I think the script I'm using for this is BufClose.
You want to delete the buffer but keep the split? You need a new buffer then - :new will do that for you, creating a buffer for a new/empty file, but you'll still need to kill the old buffer/window. In vim a window is a viewport on a buffer, so if you want an empty window you need an empty buffer.
Here's a variation on the answer provided @zenbro that keeps all your (split) windows and tabs open even if the buffer you close is the last one.
The function switches all windows pointing to the current buffer (that you are closing) to the next buffer (or a new buffer if the current buffer is the last one).
function! CloseBuffer()
let curBuf = bufnr('%')
let curTab = tabpagenr()
exe 'bnext'
" If in last buffer, create empty buffer
if curBuf == bufnr('%')
exe 'enew'
endif
" Loop through tabs
for i in range(tabpagenr('$'))
" Go to tab (is there a way with inactive tabs?)
exe 'tabnext ' . (i + 1)
" Store active window nr to restore later
let curWin = winnr()
" Loop through windows pointing to buffer
let winnr = bufwinnr(curBuf)
while (winnr >= 0)
" Go to window and switch to next buffer
exe winnr . 'wincmd w | bnext'
" Restore active window
exe curWin . 'wincmd w'
let winnr = bufwinnr(curBuf)
endwhile
endfor
" Close buffer, restore active tab
exe 'bd' . curBuf
exe 'tabnext ' . curTab
endfunction
To map it:
map <silent> <F4> :call CloseBuffer()<cr>
@RusAlex version + activate current buffer in the end need if delete buffer twice.
nmap ,d :b#<bar>bd#<bar>b<CR>
Here is some workaround:
function! CloseSplitOrDeleteBuffer()
let curNr = winnr()
let curBuf = bufnr('%')
wincmd w " try to move on next split
if winnr() == curNr " there is no split"
exe 'bdelete'
elseif curBuf != bufnr('%') " there is split with another buffer
wincmd W " move back"
exe 'bdelete'
else " there is split with same buffer"
wincmd W
wincmd c
endif
endfunction
nnoremap <silent> Q :call CloseSplitOrDeleteBuffer()<CR>
精彩评论