# How to split view multiple buffers in vim

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:

:ls
1 %a   ".vimrc"                       line 1
2      "rsync_to_home.bash"           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.

• 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 – Zaid Gharaybeh 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 ...