1. Taming Vim — 4. Buffers, Windows & Tabs

    This is the fourth part in the series Taming Vim, a series focused on improving the intermediate Vim user’s understanding and operation of the text editor.

    Introduction

    I’ll mostly be paraphrasing and summarising the introduction to buffers, windows and tabs from the Vim help.

    There are some building blocks to understand with regards to buffers, windows and tabs which will likely influence how you perceive and use them, as well as how they differ from the more traditional perceptions:

    • A buffer is the in-memory contents of a file, the original file remains unchanged until you write the buffer.
    • A window is a viewport on a buffer. You can use multiple windows on one buffer, to view different parts of the same file, or multiple windows for multiple buffers, to view other files at the same time.
    • A tab is a collection of windows, only one tab can be visible at a time.

    By default you start with one tab, one window and one buffer when editing a file with vim file1.

    Buffers

    You can open multiple buffers by invoking Vim with multiple arguments:

    vim file1 file2 file3
    

    Currently loaded buffers can be listed using the :ls command:

    :ls
      1 %a   "file1"                        line 1
      2      "file2"                        line 0
      3      "file3"                        line 0
    

    This output shows us a multitude of information:

    • The unique buffer number, which does not change for the lifetime of your Vim session, which can be quickly switched to with the buffer number followed by Ctrl-^ (that is, Ctrl-Shift-6), e.g. 3 Ctrl-^ will switch to the “file3” buffer. :edit #3 (or :e #3) is the equivalent command-line.
    • The buffer in the current window, denoted by the % indicator. Only one buffer can ever be the current window.
    • An active buffer, one that is loaded and visible, denoted by a. It is possible for multiple buffers to be active if you have multiple windows or tabs.

    Examining :ls after splitting our current window horizontally with Ctrl-W s and switching to buffer 2 with :e #2 we can see new information:

    :ls
      1 #a   "file1"                        line 1
      2 %a   "file2"                        line 1
      3      "file3"                        line 0
    

    Firstly, notice that two buffers are active now because of our window split and buffer switch. Secondly, notice the “alternate buffer” indicator #. You can switch back and forth between the active and alternate buffer with Ctrl-^ (without a number preceding it) or :e #.

    Writing some text into the buffer, without saving, we now see the modification indicator +:

    :ls
      1 #a   "file1"                        line 1
      2 %a + "file2"                        line 1
      3      "file3"                        line 0
    

    Attempting to change away from the modified buffer, with :bnext for example, results in an error: “E37: No write since last change (add ! to override)”, sure enough :bnext! changes the buffer as expected. I personally find this “protection” annoying, fortunately there is the hidden option which allows you to switch away from a modified buffer (called abandoning it) forcing it to become hidden automatically.

    A good way of switching between buffers by name is :buffer (or :b) followed by the name, the upside of this is that Vim will tab-complete the name for you. (Although there is a better way.)

    NOTE: It is important to understand that q! becomes more dangerous with this option, since modified hidden buffers will discarded when quitting without writing.

    If you use the command line frequently it might be useful to know can list the argument list, as given at the command line, with :args and move to the next and previous buffer specified by command line arguments with :next and :prev respectively.

    Buffer reference

    Command Action
    N Ctrl-^ Switch to buffer number N
    :e[dit] #N Switch to buffer number N
    Ctrl-^ Switch to the alternate buffer
    :e[dit] # Switch to the alternate buffer
    :bn[ext] Go to the next buffer
    :bp[revious] Go to the previous buffer
    :bf[irst] Go to the first buffer
    :bl[ast] Go to the last buffer
    :bd[elete] Remove the buffer from the buffer list
    :b[uffer] B Switch to the buffer with the name B

    Windows

    Most of the window commands are quite similar to the buffer commands, understanding the buffer commands will help you understand and remember the window commands.

    Use the -o or -O command-line options to open files in multiple horizontal splits or vertical window splits respectively.

    Windows are an important way to make efficient use of your screen real-estate and increase your productivity. Perhaps the most basic and useful window command is split: pressing Ctrl-W s equally splits the current window horizontally, while Ctrl-W v equally splits the current window vertically. Use Ctrl-W T to move the current window to a new tab.

    Moving between windows is quite logical, after pressing Ctrl-W the normal Vim movement keys (or the more conventional arrow keys) h, j, k or l will move you to the window left, down, up or right from the current window. You can also use Ctrl-W w to move to the window below / right from the current one, or Ctrl-W W to move to the window above / left of the current window. If you find yourself moving back and forth between two windows often, you can use Ctrl-W p to switch to the previously accessed window.

    A cousin of Ctrl-^ from the buffer section, Ctrl-W ^ (or Ctrl-W Ctrl-^) splits the window and edits the alternate buffer, similarly N Ctrl-W Ctrl-^ splits and edits buffer number N.

    Window reference

    Command Action
    Ctrl-W s Split a window horizontally
    Ctrl-W v Split a window vertically
    Ctrl-W p Move to the previously accessed window
    Ctrl-W T Move the current window to a new tab
    Ctrl-W h Move to the window to the left
    Ctrl-W j Move to the window to the below
    Ctrl-W k Move to the window to the above
    Ctrl-W l Move to the window to the right
    Ctrl-W w Move to the window to the below / right
    Ctrl-W W Move to the window to the above / left
    Ctrl-W ^ Split the window and edit the alternate buffer
    N Ctrl-W ^ Split the window and edit buffer number N

    Tabs

    Use the -p command-line option to open arguments in separate tab pages.

    It’s lonely at the top and tabs are no exception. Tabs lack the plethora of commands and options that buffers (and even windows) have but this doesn’t make them any more useful.

    To edit a file in a tab you can use :tabedit filename, much like :edit filename, and :tabclose to close a tab and all its windows. gt and gT will switch to the next and previous tab respectively, a number followed by gt will switch to that tab. I find these shortcuts painful compared to the buffer and window commands and use mappings to make things easier:

    (These mappings are for MacVim (the D modifier is the Command key) but serve as a useful guideline you can adapt to your platform of choice.)

    noremap <D-1> 1gt
    noremap <D-2> 2gt
    noremap <D-3> 3gt
    noremap <D-4> 4gt
    noremap <D-5> 5gt
    noremap <D-6> 6gt
    noremap <D-7> 7gt
    noremap <D-8> 8gt
    noremap <D-9> 9gt
    noremap <D-0> :tablast<CR>
    " MacVim has these bindings by default.
    noremap <D-S-]> gt
    noremap <D-S-[> gT
    

    Now cycling through tabs is accomplished with the more conventional Cmd-{ and Cmd-} commands, and switching to tab 1 with Cmd-1, tab 2 with Cmd-2, etc.

    There is no spoon

    Don’t be intimidated by the number of commands and options for buffers, windows and tabs. Start slowly with a few of the most useful commands and regularly think about your most frequent actions, introducing new commands (or even your own mappings) when you’re comfortable with the others or want to improve your workflow.

    Challenge yourself to find new ways to arrange your buffers within windows or windows within tabs. Unlike a lot of other editors or IDEs you are not limited to one file per tab. There’s not even any reason to only use tabs with files, you can put your quickfix window, grep results, help text, file listings, etc. in tabs too!

    Drew Neil has some great screencasts on the topics of buffers, windows and tabs.

    Experiment!

    These long posts can be time-consuming and tedious both to read and write, I’m going to make an effort to write more concisely and on smaller topics.

Notes

  1. preciselythat posted this