void-pointer
void-pointer

Reputation: 14827

Vim: Wiping Out Buffers Editing Nonexistent Files

Often when I'm editing in Vim, I end up restoring a Vim session that refers to a some files in a directory that was moved. The problem occurs after I use :n to open all of the files located in the new directory. Now, when I use :b <buffer-name> to switch to the buffer editing a particular file located in the new directory, there is an ambiguity: two buffers are opened on files with the same name, and one of these files does not exist. So I'm forced to use :ls, manually search for the indices of buffers that are editing nonexistent files, and call :bw on each one of them. Is there some simple command that will automatically wipe out the buffers editing nonexistent files for me?

Also, after manually wiping out the offending buffers, there are abrupt breaks in the indices between consecutive buffers, which makes switching between buffers using :<n>b more difficult. Is there a command that will re-index the buffers for me so that the set of indices is some contiguous range?

Thanks for your help!

Upvotes: 4

Views: 906

Answers (3)

ZyX
ZyX

Reputation: 53614

Try the following command:

function s:WipeBuffersWithoutFiles()
    let bufs=filter(range(1, bufnr('$')), 'bufexists(v:val) && '.
                                          \'empty(getbufvar(v:val, "&buftype")) && '.
                                          \'!filereadable(bufname(v:val))')
    if !empty(bufs)
        execute 'bwipeout' join(bufs)
    endif
endfunction
command BWnex call s:WipeBuffersWithoutFiles()

Usage:

:BWnex<CR>

Note some tricks:

  • filter(range(1, bufnr('$')), 'bufexists(v:val)') will present you a list of all buffers (buffer numbers) that vim currently has.
  • empty(getbufvar(v:val, '&buftype')) checks whether buffer actually should have a file. There are some plugins opening buffers that are never supposed to be represented in filesystem: for example, buffer with a list of currently opened buffers emitted by plugins such as minibufexplorer. These buffers always have &buftype set to something like nofile, normal buffers have empty buftype.

Upvotes: 4

RunHolt
RunHolt

Reputation: 1982

Both of my suggestions are workarounds, but I thought worth mentioning. One way is to :ls then grab with the mouse, paste into a scratch buffer and then launch from command line.

When my buffers get cluttered, I usually close the window. Then I have a command from my shell that launches all checked out files from my source control -- which 90% of the time are the files I am interested in.

I'm usually on cygwin bash. And run

gvim `p4list` `svnopened`

The functions p4list and svnopened are below:

function p4list() {
  export tempscript=`mktemp`
  echo "#!bash" > $tempscript
  p4 opened $@ | sed -e 's/#.*//g' | sed -e 's/$/ \\/g' | sed -e '1~300s/^/\
\
p4 where /' >> $tempscript
  chmod +x $tempscript
  $tempscript | sed -e 's/.* //g' | sed -e 's/

//g' | sed -e 's/\///g' rm $tempscript }

function svnopened() {
    svn st $@ | grep "^\M" | sed -e 's/^.\{8\}//'
}

Upvotes: 1

romainl
romainl

Reputation: 196556

Aren't buffers supposed to be unique?

After this sequence of commands:

:e .bashrc
:e .profile
:e .bashrc
:e .profile
:e .bashrc
:e .profile
:e .bashrc
:e .profile
:e .bashrc

I still have only two buffers available as shown by :buffers or :ls: .bashrc and .profile. Even if I use multiple windows and tabs.

Are you confusing "buffers" with "windows"?

Upvotes: 3

Related Questions