Skip to main content

Understanding the Hierarchy

1

Buffer

A buffer is the in-memory text of a file.
  • Contains the file content being edited
  • Exists independently of windows
  • Can be hidden while you edit other files
2

Window

A window is a viewport onto a buffer.
  • Displays buffer content
  • Multiple windows can show the same buffer
  • Can split horizontally or vertically
3

Tab Page

A tab page is a collection of windows.
  • Contains one or more windows
  • Allows organizing different layouts
  • Like browser tabs for your editing sessions
Tab Page 1          Tab Page 2
┌─────────────┐  ┌─────────────┐
│ Window 1    │  │ Window 3    │
│ (Buffer A)  │  │ (Buffer C)  │
├─────────────┤  └─────────────┘
│ Window 2    │
│ (Buffer B)  │
└─────────────┘

Buffer Management

Buffer States

A buffer can be in one of three states:
StateIn Window?Loaded?Indicator
ActiveYesYesa
HiddenNoYesh
InactiveNoNo

Listing Buffers

:buffers
:ls
:files
Example output:
1 %a   "main.lua"            line 42
2 #h   "config.lua"          line 1
3      "utils.lua"           line 15

Switching Buffers

:buffer 3       " Switch to buffer 3
:b 3            " Short form
:b main.lua     " Switch by name (partial match works)
:b mai<Tab>     " Use tab completion
CTRL-^          " Toggle between current and alternate buffer
:b#             " Same as CTRL-^
3 CTRL-^        " Switch to buffer 3
The alternate buffer (#) is the previously edited buffer. Use CTRL-^ to quickly switch between two files!

Managing Buffers

:badd file.txt      " Add file to buffer list
:bdelete 3          " Delete buffer 3
:bd 3               " Short form
:bd main.lua        " Delete by name
:bd!                " Force delete (discard changes)
:1,3bd              " Delete buffers 1-3
:%bd                " Delete all buffers

Hidden Buffers

" Enable hidden buffers
:set hidden

" Now you can switch buffers without saving
:e file1.txt
" Make changes...
:e file2.txt        " file1.txt becomes hidden
Control per-buffer behavior with 'bufhidden':
:setlocal bufhidden=hide      " Hide this buffer
:setlocal bufhidden=unload    " Unload when hidden
:setlocal bufhidden=delete    " Delete when hidden
:setlocal bufhidden=wipe      " Wipe when hidden

Window Management

Creating Windows

1

Horizontal Split

:split              " Split current window horizontally
:sp                 " Short form
:split file.txt     " Split and edit file.txt
:10split            " Split with 10 lines height
CTRL-W s            " Normal mode split
2

Vertical Split

:vsplit             " Split vertically
:vs                 " Short form
:vsplit file.txt    " Split and edit file.txt
:30vsplit           " Split with 30 columns width
CTRL-W v            " Normal mode split
3

New Window

:new                " New window with empty buffer
:vnew               " Vertical new window
CTRL-W n            " Normal mode new window
Use :split for horizontal (one above the other) and :vsplit for vertical (side by side).
CTRL-W h            " Move to window on the left
CTRL-W j            " Move to window below
CTRL-W k            " Move to window above
CTRL-W l            " Move to window on the right

CTRL-W <Left>       " Alternative: arrow keys
CTRL-W <Down>
CTRL-W <Up>
CTRL-W <Right>

Closing Windows

:quit               " Quit current window
:q                  " Short form
CTRL-W q            " Normal mode quit
CTRL-W c            " Close current window
:close              " Close current window
:only               " Close all other windows
CTRL-W o            " Normal mode only
Closing the last window for a buffer doesn’t delete the buffer — it becomes hidden (if 'hidden' is set) or inactive.

Moving Windows

CTRL-W r            " Rotate windows downward/rightward
CTRL-W R            " Rotate windows upward/leftward

Resizing Windows

CTRL-W +            " Increase height
CTRL-W -            " Decrease height
CTRL-W _            " Maximize height
:resize 20          " Set height to 20 lines
:res +5             " Increase by 5 lines
:res -5             " Decrease by 5 lines
CTRL-W >            " Increase width
CTRL-W <            " Decrease width
CTRL-W |            " Maximize width
:vertical resize 80 " Set width to 80 columns
:vertical res +10   " Increase by 10 columns
CTRL-W =            " Make all windows equal size
:wincmd =           " Ex command form
Set 'winheight' and 'winwidth' to automatically resize the current window.

Window Options

" Set minimum window sizes
:set winminheight=0     " Minimum height (0 = just status line)
:set winminwidth=0      " Minimum width

" Automatic window sizing
:set winheight=999      " Always maximize current window height
:set equalalways        " Auto-resize windows equally
:set splitbelow         " Open new splits below
:set splitright         " Open new splits to the right

Tab Pages

Creating Tabs

1

New Tab

:tabnew             " New tab with empty buffer
:tabnew file.txt    " New tab with file.txt
:tabe file.txt      " Short form
:tabedit file.txt   " Full form
2

Split to Tab

CTRL-W T            " Move current window to new tab
:tab split          " Open current buffer in new tab
:tabnext            " Next tab
:tabn               " Short form
gt                  " Normal mode next tab

:tabprevious        " Previous tab
:tabp               " Short form
gT                  " Normal mode previous tab

3gt                 " Go to tab 3

Managing Tabs

:tabclose           " Close current tab
:tabc               " Short form
:tabonly            " Close all other tabs
:tabo               " Short form

:tabmove 0          " Move tab to position 0 (first)
:tabmove            " Move tab to end
:tabmove +1         " Move tab one position right
:tabmove -1         " Move tab one position left

:tabs               " List all tabs
:tabdo %s/foo/bar/g " Execute command in all tabs

Practical Workflows

Split Editing

" Edit related files side by side
:vsplit config.lua
CTRL-W l
:split utils.lua

Quick Reference Window

" Open reference in bottom split
:botright 10split reference.txt
:setlocal nomodifiable

Multiple File Editing

1

Open Files

:args *.lua         " Add all .lua files to arg list
:all                " Open window for each file
2

Navigate

:next               " Next file
:previous           " Previous file
CTRL-W w            " Next window
3

Bulk Operations

:argdo %s/old/new/g | update    " Replace in all files
:windo set number               " Set option in all windows

Window Layout Presets

:edit file1.txt
:vsplit file2.txt
:windo set scrollbind   " Synchronize scrolling
:edit main.lua
:rightbelow vsplit reference.lua
:resize 80
:edit file1.txt
:vsplit file2.txt
:split file3.txt
CTRL-W h
:split file4.txt
CTRL-W =

Advanced Features

Argument List

The argument list is separate from the buffer list:
:args *.lua         " Set argument list
:args               " Display argument list
:argadd file.txt    " Add to argument list
:argdelete *.bak    " Remove from argument list

:argument 2         " Edit argument 2
:next               " Next argument
:previous           " Previous argument

Buffer-Window Relationship

  • One buffer can appear in multiple windows
  • Changes in one window are reflected in all windows showing that buffer
  • Each window has its own cursor position
  • Window-local options can differ between windows
" Open same buffer in two windows
:split
CTRL-W w
:buffer #           " Both windows now show same buffer

Window-Local Options

" Set options per-window
:setlocal number        " Only this window
:setlocal scrolloff=5   " Only this window
:setlocal colorcolumn=80

Configuration Examples

" Window splitting behavior
set splitbelow      " Horizontal splits below
set splitright      " Vertical splits to the right

" Enable hidden buffers
set hidden

" Window sizes
set winwidth=80
set winheight=10
set winminwidth=5
set winminheight=0

" Status line for all windows
set laststatus=2

" Key mappings
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l

Build docs developers (and LLMs) love