Skip to main content

Vim Workflow: Buffers, Windows, and Tabs

·926 words·5 mins
Linux Learning Lab
Author
Linux Learning Lab
Writing about code, tools, and workflows.
vim-essentials - This article is part of a series.
Part 4: This Article

The Mental Model
#

Vim uses three layers for organizing open files:

  • Buffers — an open file in memory (you can have many, even without seeing them)
  • Windows — a viewport into a buffer (splits on screen)
  • Tabs — a collection of windows (like workspace layouts)

The relationship:

Tab
├── Window (shows Buffer A)
├── Window (shows Buffer B)
└── Window (shows Buffer A again — same buffer, two views)

Multiple windows can show the same buffer. Buffers exist whether or not they’re visible.

Buffers
#

A buffer is created every time you open a file. Even if you switch to another file, the first one stays in memory.

Opening files into buffers
#

:e file.txt         " Open a file in the current window
:e src/main.js      " Relative paths work
:e .                " Open file explorer (netrw)

Listing buffers
#

:ls
" or
:buffers

Output looks like:

  1  %a  "index.md"       line 42
  2  #   "config.toml"    line 1
  3      "about.md"       line 1
SymbolMeaning
%Current buffer (shown in active window)
#Alternate buffer (last edited, toggle with Ctrl-^)
aActive (loaded and visible)
hHidden (loaded but not visible)
+Modified (unsaved changes)

Switching buffers
#

CommandAction
:bnNext buffer
:bpPrevious buffer
:b3Go to buffer 3
:b fileGo to buffer matching “file” (partial match works)
Ctrl-^Toggle between current and alternate buffer
:bdClose (delete) current buffer
:bd 3Close buffer 3

The alternate buffer
#

Ctrl-^ switches between your two most recent buffers. This is extremely useful when you’re editing two related files (a module and its test, for example).

Windows (Splits)
#

Windows divide your screen to show multiple buffers simultaneously.

Creating splits
#

CommandAction
:sp or Ctrl-w sHorizontal split (same file)
:vsp or Ctrl-w vVertical split (same file)
:sp file.txtHorizontal split with a different file
:vsp file.txtVertical split with a different file

Navigating between windows#

All window commands start with Ctrl-w:

CommandAction
Ctrl-w hMove to window left
Ctrl-w jMove to window below
Ctrl-w kMove to window above
Ctrl-w lMove to window right
Ctrl-w wCycle to next window

Resizing windows
#

CommandAction
Ctrl-w =Equalize all window sizes
Ctrl-w +Increase height
Ctrl-w -Decrease height
Ctrl-w >Increase width
Ctrl-w <Decrease width
Ctrl-w _Maximize height
`Ctrl-w`
:resize 20Set height to 20 lines
:vertical resize 80Set width to 80 columns

Moving windows
#

CommandAction
Ctrl-w HMove window to far left (vertical)
Ctrl-w JMove window to bottom (horizontal)
Ctrl-w KMove window to top (horizontal)
Ctrl-w LMove window to far right (vertical)
Ctrl-w rRotate windows

Closing windows
#

CommandAction
:q or Ctrl-w qClose current window
:only or Ctrl-w oClose all windows except current

Closing a window doesn’t close the buffer — the file stays in memory.

Tabs
#

Tabs in Vim are not like browser tabs. Each tab is a layout of windows. Use them when you want completely different workspace arrangements.

Managing tabs
#

CommandAction
:tabnewOpen a new empty tab
:tabnew file.txtOpen file in a new tab
:tabn or gtNext tab
:tabp or gTPrevious tab
:tabcloseClose current tab
:tabonlyClose all other tabs
3gtGo to tab 3

When to use tabs
#

Tabs are best for separate contexts, not separate files:

  • Tab 1: application code (splits for module + test)
  • Tab 2: configuration files
  • Tab 3: documentation

If you just want to see multiple files, splits are usually better.

The Argument List
#

The argument list tracks files you opened from the command line:

vim src/*.js
:args           " Show the argument list
:next           " Go to next file in arglist
:prev           " Go to previous file
:first          " Go to first file
:last           " Go to last file

Run a command across all files in the arglist
#

" Replace in all argument files
:argdo %s/old/new/gc | update

" Set indentation in all files
:argdo set tabstop=4 | update

Modify the arglist
#

:args src/*.js       " Set arglist to all JS files in src/
:argadd test/*.js    " Add test files to arglist

Practical Workflows
#

Edit a file and its test side by side
#

:e src/auth.js
:vsp test/auth.test.js

Use Ctrl-w l and Ctrl-w h to move between them. Use Ctrl-^ in either window to toggle to the last file you viewed there.

Compare two files
#

vim -d file1.txt file2.txt

Opens in diff mode with changes highlighted.

Open a file from netrw (file explorer)
#

:e .          " Open explorer in current directory
:vsp .        " Open explorer in a split

Navigate with j/k, press Enter to open a file.

Quick reference lookup while editing
#

" You're editing code, need to check something
:sp /etc/hosts        " Open reference in a split
                      " ...read what you need...
Ctrl-w q              " Close the reference split

Run a substitution across multiple files
#

:args src/**/*.js
:argdo %s/oldFunction/newFunction/g | update

Best Practices
#

  • Think of buffers as open files and windows as views — don’t close buffers just because you can’t see them
  • Use Ctrl-^ constantly to toggle between two related files
  • Use splits for files you need to see at the same time
  • Use tabs for separate workspaces, not as a replacement for buffers
  • Use :b with partial names instead of buffer numbers — :b auth is faster than remembering :b7
  • Learn Ctrl-w = to reset window sizes after resizing your terminal
  • Use :argdo for batch operations across files — it’s Vim’s version of find-and-replace across a project
vim-essentials - This article is part of a series.
Part 4: This Article