Back to Home

Vim: bw,: bd,: bun,: quit,: close. What to do with all this?

vim · vim tips

Vim: bw,: bd,: bun,: quit,: close. What to do with all this?

    Vim has many commands for closing anything and in any combination, but what it doesn’t know is to close everything with one command. To a person who started using Vim recently, this may seem rather strange. Let's try to figure out how to fix this situation.


    When I first met Vim, my eyes widened from the abundance of ways to
    close files, windows, and the editor itself. Here is a list of
    buffers and windows deletion (closing) commands ( full names of commands are indicated in square brackets):

    • : bd [elete] - delete the buffer. It actually just makes the buffer invisible, but
      leaves it in memory.
    • : bw [ipeout] - completely erases (wipeout) the buffer from memory
    • : bun [load] - removes the buffer from memory, but leaves it in the buffer list.
      Useless command, except in cases where you have either a
      gigantic file size or extremely little RAM.
    • : close - close the current split. The buffer is not deleted
    • : q [uit] - purely theoretically, the team should close Vim, in practice, everything is a little more complicated


    I highly recommend setting the set confirm option in .vimrc to
    avoid annoying error messages when trying to close (delete) a buffer with
    unsaved changes. Instead of an error, confirmation of
    closing the unsaved file will appear .

    To close the file in the traditional sense (for any other editor)
    , the command : bw is suitable , but unfortunately all buffer commands
    have the disgusting ability to close the window in which
    they are currently displayed (naturally, if this is not the only window on the screen )
    This problem is solved by installing the bufkill.vim plugin and using the command
    : BW (: BD,: BUN) instead of : bw (: bd ,: bun) .

    The command : q should close Vim, but its behavior depends on the situation and is far from
    intuitive. To close the window, use the command : close , but
    you cannot close the last window with it . Also, you cannot close Vim using the
    delete buffer commands (even if the buffer is the last one).
    As a result, an empty buffer cannot be deleted, the last window
    cannot be closed, and working with several files turns into the game "guess which
    command you need to use now:: bw,: BW,: q or: close". After
    combing the forums, I had to reinvent the wheel, because
    as I needed, I never found. What I needed was a familiar (according to other
    editors) and intuitive way to quickly close files, windows and Vim itself.

    The first problem is to decide on the algorithm of the “usual” way to produce all of the
    above. Through trial and error, the algorithm has become like this:



    At first glance, it’s a little complicated, but when you start using it, everything falls into
    place. Of course, this is not a panacea - windows (not buffers) still need to be closed
    with : close .

    This is what the implementation looks like:

    function! CountListedBuffers() 
      let cnt = 0 
      for nr in range(1,bufnr("$")) 
    	if buflisted(nr) 
    	  let cnt += 1 
    	endif 
      endfor 
      return cnt 
    endfunction 
    function! SmartExit()
    	let s:BufferToKill = bufnr('%')
    	let s:EmptyBuffer = 0
    	if bufname('%') == '' && ! &modified && &modifiable
    		if &buftype == 'nofile' && &swapfile == 0
    			" Is scratch buffer, not empty
    		else
    			let s:EmptyBuffer = 1
    		endif
    	endif
    	" Get a list of all windows which have this buffer loaded
    	let s:WindowListWithBufferLoaded = []
    	let i = 1
    	let buf = winbufnr(i)
    	while buf != -1
    		if buf == s:BufferToKill
    			let s:WindowListWithBufferLoaded += [i]
    		endif
    		let i = i + 1
    		let buf = winbufnr(i)
    	endwhile
    	" Check that the buffer is last
    	if(CountListedBuffers() < 2)
    		let s:LastBuffer = 1
    	else
    		let s:LastBuffer = 0
    	endif
    	if s:LastBuffer
    		if len(s:WindowListWithBufferLoaded) > 1
    			execute "close"
    		else
    			if ! s:EmptyBuffer
    				execute "bw | bw"
    			else
    				execute "q"
    			endif
    		endif
    	else
    		let g:BufKillActionWhenBufferDisplayedInAnotherWindow="kill"
    		execute "BW"
    		let g:BufKillActionWhenBufferDisplayedInAnotherWindow="confirm"
    	endif
    endfunction
    


    To work, you need installed bufkill.vim.

    As a result, my mapping for "closing everything and everything" looks like this:

    "Smart" closing
    nmap qq: call SmartExit () "Close the window, but do not delete the
    nmap qw bufferc

    qq is used by me much more often, it does exactly what, in my understanding, it
    should have done: q, but for some reason it doesn’t.

    Closing

    Total


    I have been using Vim recently, but I got the impression
    that I will have to write such crutches and bicycles more than once! But what a
    sin to conceal - this is extremely exciting. I hope this mini-plugin or the
    information from this article is useful to someone.

    PS Not for the sake of holivara, but how is this with Emacs?

    PPS I don’t use tabs (tabs), I have enough splits within one screen,
    and they do not solve problems when working with buffers, they just add.

    Read Next