Using buffers, windows, and tabs efficiently in Vim
Tags: vim, windows, tab, productivity
Published: 2020-04-20 15:07:07

---
title: Using buffers, windows, and tabs efficiently in Vim
published: true
description: how to use buffers, windows, tabs efficiently in Vim
tags: vim, windows, tab, productivity
---

*Follow [@learnvim](https://twitter.com/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:
- [Vim buffers](#buffers)
- [Vim windows](#windows)
- [Vim tabs](#tabs)
- [Thinking in 3D](#3d)
- [Using buffers, windows, and tabs efficiently](#efficient)
- [Resources](#resources)

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](https://medium.com/usevim/vim-101-set-hidden-f78800142855) and `:h hidden`.

<a name="buffers"></a>
# 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](https://dev-to-uploads.s3.amazonaws.com/i/08ar398p92553p44n8pc.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/psp1ko5kchqpgyhmm5x4.png)

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

![Buffer File 1 2 ls](https://dev-to-uploads.s3.amazonaws.com/i/2amvfios7lqobrv1652d.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/wq5jbdcz4culb5bxgs9q.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/a0wbk4e23gogtqn4ikin.png)


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](https://dev-to-uploads.s3.amazonaws.com/i/itav49ikei8d41g39eeq.png)


<a name="windows"></a>
# 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](https://dev-to-uploads.s3.amazonaws.com/i/08ar398p92553p44n8pc.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/psp1ko5kchqpgyhmm5x4.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/mzasn68oypgj3dw48x4b.png)


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](https://dev-to-uploads.s3.amazonaws.com/i/vt63ef9xverhbxe1qsrn.png)


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](https://dev-to-uploads.s3.amazonaws.com/i/xjk5j62swxmllid05o7f.png)


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](https://dev-to-uploads.s3.amazonaws.com/i/dcq7wqxtpgvcr94b6z7g.gif)

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`.

<a name="tabs"></a>
# 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](https://dev-to-uploads.s3.amazonaws.com/i/lz9jhmmujtasi9l0y3cf.png)

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
```

<a name="3d"></a>
# 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](https://dev-to-uploads.s3.amazonaws.com/i/m1w2j1y3j8811hwge3nk.gif)

Each window can view any of our buffers.

![Vim 3 windows as viewport to buffers](https://dev-to-uploads.s3.amazonaws.com/i/vdtga0qq2tuty22rsqxa.png)

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

<a name="efficient"></a>
# 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](https://github.com/kien/ctrlp.vim) or [fzf.vim](https://github.com/junegunn/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!


<a name="resources"></a>
# Resources
- `:h window`
- [Vim close window without closing buffer](https://stackoverflow.com/questions/22087724/vim-close-window-without-closing-buffer/43293466)
[Vim 101: Set Hidden](https://medium.com/usevim/vim-101-set-hidden-f78800142855)
- [Seven habits of effective text editing
](https://moolenaar.net/habits.html)
- [Buffers, windows, and tabs](https://sanctum.geek.nz/arabesque/buffers-windows-tabs/)
- [Why do Vim experts prefer buffers over tabs?](https://stackoverflow.com/questions/26708822/why-do-vim-experts-prefer-buffers-over-tabs)
- [Vim: Buffers, Tabs, Windows & Modes](http://springest.io/vim-buffers-tabs-windows-and-modes)
- [Cheatsheet for Buffers, Windows and Tabs of Vim](https://feici02.github.io/2017/05/28/buffers-windows-tabs.html)