basically my workflow is as follows I have a bunch of windows open using splits in a terminal in regular vim. Sometimes I have a file open sometimes I don't I usually switch between :buf and :tag to get the file. Ideally I would like something that would work like :buf but if the file is not in the buffer currently then it would preform a :e.

Therefore to simplify:

I type :buf and type part of a filename and hit <tab> it gives me the match for the files and matches as much of the file as it can if the file I want is not in the buffer already I would like to still be able to type that file name and have it load the file. Usually now I have to go back and change the command from a :buf [file] to a :e [file].

Is there a way to create a command that would work like a :buf but open the file if it doesn't already exist? The reason I use :buf to begin with is it limits the scope to files in certain directories and will match them when hitting tab. I hope I explained it correctly :).


:buf FooX[tab]

shows 4 files and has

:buf [very long path]/FooX

Now if the Exact file with prefix FooX is not shown I still want to be able to type FooXFileNotShown.cpp and have it load it like a :e would.

Thanks in advance for your help.


:b[uffer] is only used to access opened buffers. Its completion's "scope" is not restricted to "certain directories" but to the buffers in your buffer-list/argument-list. You can't use that command to open a file that wasn't opened already.

:e[dit] is used to edit a file and its completion is "scoped" to the files and directories directly under Vim's working directory. You can limit the completion list with the wildignore option (:help 'wildignore') or using the awesome ** wildcard (:help starstar).

When you use :e to edit a file that is already in the buffer-list/argument-list, Vim doesn't create a new buffer, it dimply switches to the existing buffer, effectively acting like :b.

So… It looks like you are a little confused about the behavior of :b and that you are simply looking for :e file<Tab>.

  • Not confused about the 2 commands... if you have a file <long path>/fileA.cpp you can type :buf fileA<tab> and it will resolve to the whole file with path. This does NOT happen with :e which was the whole point of the question. – bjackfly Mar 17 '14 at 13:42
  • OK, I didn't get that at all from your question because of your overuse of the word "file". What you get with :b fileA<Tab> is the name of a buffer as stored by Vim in a relatively short list but that list doesn't exist for non-opened files, only for opened buffers. For that kind of completion to be possible on actual filenames, your filesystem must be scanned, the result of that scan must be cached and so on. :find works more or less like that but can be very slow on large directory structures. I suggest you take a look at CtrlP and similar plugins. – romainl Mar 17 '14 at 14:03
  • ok thanks makes sense I think for non opened files it will have to use the tag command – bjackfly Mar 17 '14 at 14:52

So you want a command with a completion of existing buffers, that then either opens the buffer (if existing), or else edits the passed file instead of giving you the E94: No matching buffer error.

How about this:

:command! -nargs=1 -complete=buffer Buf try | execute 'buffer' <q-args> | catch /^Vim\%((\a\+)\)\=:E94/ | execute 'edit' <q-args> | endtry

Custom commands must start with an uppercase letter, but you use the cmdalias.vim - Create aliases for Vim commands plugin to overload the existing :buf command.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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