Using buffers, windows, and tabs efficiently in Vim

April 20, 2020

Follow @learnvim for more Vim tips and tricks!

Vim has never been like most editors. I've used different editors (Notepad++, Atom, VSCode, and yes, emacs, briefly). Most editors use tabs and windows system. Vim has buffers, windows, and tabs. Some of these abstractions Vim use are different.

If you are new to Vim, I will explain what buffers, windows, and tabs are. I will also show how to use them efficiently.

Table of Contents:

Before we start, if you haven't, add set hidden in your ~/.vimrc and source it. Without this option, whenever a changed buffer goes to "hidden", Vim will prompt you to save the file. For more information about this setting, check out this article and :h hidden.

Vim buffers

A buffer is the in-memory text of a file.

When you open a file in Vim, it creates a new buffer. Do this from your terminal:

vim file1.js

Buffer Vim File 1

After running this, Vim creates one buffer for file1.js. This buffer is stored in-memory.

Exit Vim. Back to console, run:

vim file1.js file2.js

Vim creates 2 buffers: one for file1.js and one for file2.js. You are probably still seeing file1.js.

Buffer file 1 2

However, right now Vim has 2 buffers. You can see all buffers with :ls (or :buffers, or :files).

Buffer File 1 2 ls

There are several ways to go between file1.js buffer and file2.js buffer:

  1. :bnext to go to next buffer (:bprev to go back)
  2. :buffer, then type the name. Vim can autocomplete with <Tab>
  3. :bufferN where N is buffer number. :buffer2 for example, will jump to buffer #2.
  4. Jump between your last 'position' with <Ctrl-O> and <Ctrl-i>. This is not buffer specific, but it works.
  5. Toggle between previous file with <Ctrl-^>

For method #2, you can combine buffers list with buffer name. For example, with this mapping, pressing <Leader>b will display my buffers and types :buffer<space> command. All that is left for me to do is typing the buffer number or buffer name (that Vim can autocomplete).

:nnoremap <Leader>b :buffers<CR>:buffer<Space>

Vim buffer shortcut Leader b

Once a buffer is opened, it remains in your buffers list. We have two buffers opened: file1.js and file1.js buffers. Still in the same vim session, if we want to open a new file, we can do :e file3.js. If we check with :ls, we'll see that we have 3 buffers.

Buffer Vim file 1 2 3 ls

You can type :bdelete to close a buffer. To be honest, in my years of editing with Vim, I almost never needed to delete buffers.

The way I see it, buffer is like Z axis in X-Y-Z coordinate. Imagine X axis to right, Y axis to top, and Z axis towards screen. Your buffers files are lined up in the Z axis. You can traverse the Z axis one file at a time with :bnext/:bprev. You can jump to any coordinate in Z axis with :buffer <filename>. The number of file buffers you have is how long your Z axis is. Vim makes it almost frictionless to travel anywhere along this Z axis.

Vim buffer z axis analogy

Vim windows

A window is a viewport on a buffer. In Vim, you can have multiple windows opened.

From your console, run this again:

vim file1.js

Buffer Vim File 1

What you are looking at the screen is one window that displays buffer file1.js. Window is what you are seeing buffers through.

Exit Vim. In console, run

vim file1.js file2.js

Buffer file 1 2

We've seen this many times now. This time, we have two buffers and still one window.

Don't quit vim yet. Run:

:split file2.js

Window Vim two windows

You are looking at two windows. It's kind of hard to see the texts on bottom window, but the bottom one says file1.js (and top one file2.js). The top window is a viewport for buffer file2.js, the bottom window is a viewport for buffer file1.js.

Remain in this vim session - don't quit yet. Run:

:vsplit file3.js

Window Vim file3 file2 file1

You are now seeing three windows. Top left window displays file3.js buffer. Top right window displays file2.js buffer. Bottom window displays file1.js.

I hope you are starting to see the difference between vim buffers and windows. Don't worry if you aren't - take your time. It took me a while to understand it when I was learning this.

You can have multiple windows displaying one buffer. Right now I am still on top left window that views file3.js buffer. I will type:

:ls
:buffer 2

Window Vim file2 file2 file1

Now both top left and top right windows are displaying file2.js buffer (bottom window still displays file1.js buffer). If I start typing on top left, you'll see that both top left and top right window are changing as I type.

Window typing multiple buffers

To close current window, you can run <Ctrl-W>+C. Alternatively, you can do :quit. When you close a window, a buffer will still be opened (check :ls).

Some useful shortcuts for window:

<Ctrl-W>+v       # Opens a new vertical split
<Ctrl-W>+s       # Opens a new horizontal split
<Ctrl-W>+c       # Closes a window
<Ctrl-W>+o       # Makes current window the only one on screen and closes other windows
<Ctrl-W>+h/j/k/l # Moves the cursor to left/bottom/top/right

Some useful Ex commands:

:vsplit <filename>     # Split window vertically
:split <filename>      # Split window horiontally
:new [filename]        # Create new window

For more, check out :h window.

Vim tabs

A tab page is a collection of windows. In Vim, a tab has different meaning than most text editors. In most text editors (and modern browsers), a tab usually means an open file/ page. When we close it, that file/page goes away.

In Vim, a tab does not represent an open file. We just learned that vim saves opened files in buffers. When we close a tab in vim, the files in that tab are still stored in buffers. A tab can have one or many windows. Think of tabs like layouts or templates.

Let's try it. In console:

vim file1.js

Let's open file2.js in new tab:

:tabnew file2.js

Vim tabs

More tabs navigation:

:tabnew file.txt # open file.txt in a new tab
:tabclose        # Close current tab
:tabnext         # Go to next tab
:tabprevious     # Go to previous tab
:tablast         # Go to last tab
:tabfirst        # Go to first tab

You can also run gt to go to next tab page in Normal mode.

To start vim with multiple tabs, you can do this from console:

vim -p file1.js file2.js file3.js

Thinking in 3D

Moving between windows in Vim is like traveling along X-Y axis in cartesian coordinate. We are moving two-dimensionally. We can move to top, right, bottom, left with <Ctrl-W>+h/j/k/l.

Earlier I said that Vim buffers are like Z axis. Inside each window, you can move along the Z axis with buffer navigation. When we combine window movement with buffer traversal, we are moving in three-dimensional space.

Vim window-buffer in 3d

Each window can view any of our buffers.

Vim 3 windows as viewport to buffers

This X-Y-Z movement is possible thanks to Vim's window and buffer features.

Using buffers, windows, and tabs efficiently

To learn how to use buffers, windows, and tabs efficiently is to understand what they are designed to do.

Use buffers to open up all required files to get current task done. It may be eight or eighty buffer files. Having many buffers opened doesn't effect spatial distribution. Vim has designed switching file buffers to be frictionless. Use that to fly between buffers.

Use windows when you need to view multiple buffers. Like when diffing files, referencing codes, or following code flows.

Use tabs when working on different projects. Like one tab for server codes and one tab for client codes.

In most code editors there are 2 abstractions in their workflows: windows (ex: split screen) and tabs. In Vim there are 3: buffers, windows, and tabs. When I started using Vim full-time, it required a significant paradigm shift. My personal suggestion is to take your time to use it the way they were designed first. If after you've tried it and you still don't think it's for you, use the process that suits you most.

In addition, you can look at plugins such as ctrlp.vim or fzf.vim to boost your workflows.

Ultimately, do what works for you. Just because a certain feature was designed to for X doesn't mean everyone should do X. Feel free to experiment around and find your best workflow.

This is a good place to stop. Thank you for reading. Happy coding!

Resources