Suppose I have several files open each in a different active buffer. Is there a way to save a specific file in a different buffer without first switching to it?

An example of this occurring is if I opened 10 new files and edited them all. I want to only save 3 of them and discard the changes to the remaining 7 before exiting.

up vote 4 down vote accepted

There are several ways possible to do what you want, but all involve some kind of scripting.

  • Using bufdo

You could use the already mentioned bufdo like this (suppose you want to save the buffer number 4):

:4,4bufdo :w

However, this will internally switch to buffer 4 and the cursor will remain in that buffer. So you would need to add some more scripting to restore the buffer afterwards. Also, if you don't know the buffer number (see :ls to find out), but only know the buffer name you need a little bit of scripting, something like this:

let bufnr=bufnr('name')
if bufnr > 0
   let curbuf=bufnr('%')
   try
       exe bufnr.','.bufnr.'bufdo :w'
   catch
   finally
       exe curbuf.'b'
   endtry
endif

This is totally untested, but the idea should be clear. You could wrap it into a function and create a custom command to call this function.

If you would only like to save a couple of buffers, say buffer 4 and 6 and reset all other buffers, you could do it like this:

bufdo if index([4,6], bufnr('%')) > -1 | :w | else :e! |endif

This will save only buffer number 4 or 6 and reload the other buffers from disk (discarding their changes [depending on your undo settings, this is even undoable]). Note, also untested.

  • Using writefile

Another alternative is to use the writefile() function. That would work like this:

call writefile(getbufline('name', 1, '$'), fnamemodify(bufname('name'), ':p'))

This will get the content of the buffer that matches 'name' and write it. Note, if name matches several buffers, it will probably fail. So it would be good here to add some error handling here as well.

  • 1
    I don't see, why this shouldn't work. – Christian Brabandt Aug 28 '17 at 6:22
  • Nvm, my mistake. It works. – domoremath Sep 10 '17 at 8:13

You can run a command in multiple buffers, and specify a buffer number range with :bufdo:

:[range]bufdo[!] {cmd}  Execute {cmd} in each buffer in the buffer list or if
                        [range] is given only for buffers for which their
                        buffer number is in the [range].  It works like doing
                        this: 
                                :bfirst
                                :{cmd}
                                :bnext
                                :{cmd}
                                etc.

If you want to filter files in the current directory based on a pattern, check :h arglist.

:args 
:argdo update

To close all windows except one or more look up :only, and use :qa! to discard all changes.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.