Working with big projects, I often find myself needing to view/edit several files at once.

If I have multiple buffers open, is there a way to split the window to view multiple files in one command?

E.g. usually I begin my workflow by entering my project's root directory, entering vim in the terminal, and then entering :n **/*.py to recursively load all python files that exist in the project as buffers.

Simple example, I have these buffers:

  1 %a   ".vimrc"                       line 1
  2      "rsync_to_home.bash"           line 0
  3      "README.md"                    line 0
  4      ".zshrc"                       line 0

I want to split the screen to show "rsync_to_home.bash", ".zshrc", along with the current buffer (.vimrc), as horizontally split windows. To accomplish this, I would have to do:

:sb 2 <Enter>
:sb 4 <Enter>

But calling :sb for each file individually is tedious, and :sb 2 4 doesn't work. Also, if I'm working with a lot of files, I would probably have to repeat :ls between the :sb calls to make sure I'm calling the right buffer numbers.

  • 2
    You can also pass :sb a buffer name... For example :sb rsy followed by :sb zsh, with any unique substring of the buffer (file) name. Regarding using a single command, how about joining them with |? :sb rsy|sb zsh should work...
    – filbranden
    May 14 '20 at 0:05
  • Joining the calls works, I'll go with that or I'll create a function and add to .vimrc if that's the only way May 14 '20 at 0:49

You could write a wrapper to do all the commands at once:

command -bar -nargs=+ -complete=buffer Sbuffers execute map([<f-args>], {_, b -> printf("sbuffer %s", b)})->join("|")

Usage: Sbuffers file1 file2 file3

Completion will use buffer names (so the buffers have to have been loaded). You can tweak this to use any file names with -complete=file, though according to :help :sbuffer files loaded from outside the buffer list will not have 'buflisted' set.

The general idea is to build up the string sbuffer b for each buffer b, and then join them with | to be one command:

sbuffer b1|sbuffer b2|sbuffer b3

And then :execute the whole lot.

We can do this by mapping over the list of arguments ([<f-args>]<f-args> turns the arguments into a list suitable for a function call, which happens to the be same form as needed to make a literal list with []). The one subtlety is that lambdas/Funcrefs given to map are given both the index/key and the value, hence the _ wildcard in the lambda arguments.


As filbranden pointed out, it is possible by joining the sb calls like e.g. this:

:sb rsy|sb zsh

This is useful for when first loading a large project. E.g. by going to project root directory, entering vim in terminal, calling :n **/*.py to load all python files recursively under the current directory (project root), then calling :ls to view all loaded files in buffer, and then to view multiple individual files on one window you use :sb file1.py|sb file2.py|sb file3.py ...

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.