Buffers, Windows, and Tabs
Summary: in this tutorial, you will learn learn to work with multiple files simultaneously using vim's buffers, split windows, and tab pages for efficient multitasking.
Buffers, Windows, and Tabs
So far, you've been working with one file at a time. But real-world projects involve many files. Vim has a powerful system for managing multiple files: buffers, windows, and tabs. These three concepts work together, but they mean different things than you might expect.
What you'll learn in this tutorial:
- What buffers, windows, and tabs are (they're different from what you think!)
- How to open and switch between multiple files
- How to split your screen to see two (or more) files at once
- How to use tabs to organize your workspace
- How to browse files and directories from inside Vim
- Practical workflows for working with multiple files
Understanding the Three Concepts
Before we start, let's clear up what these terms mean in Vim — they're different from most other editors:
| Concept | What It Is | Analogy |
|---|---|---|
| Buffer | A file loaded into memory | A document you've opened (may or may not be visible) |
| Window | A viewport showing a buffer | A pane on your screen displaying one buffer |
| Tab | A collection of windows | A workspace layout (like virtual desktops on your computer) |
Common confusion: In most editors, a "tab" means an open file. In Vim, a "tab" is more like a window layout. You can have many files (buffers) open, but only some are visible in windows. Tabs let you have different window arrangements.
Think of it this way:
- You're reading 5 books (5 buffers)
- Your desk has room to lay 2 books open side by side (2 windows)
- You have 2 desks in different rooms (2 tabs), each with their own arrangement of open books
Buffers (Your Open Files)
Every time you open a file, Vim creates a buffer — a copy of the file's content in memory. Buffers can be:
- Active — currently displayed in a window
- Hidden — open in memory but not visible on screen
Opening Files as Buffers
:e filename.txt " Open a file (e = edit)
:e src/app.js " Open using a relative path
:e ~/projects/notes.md " Open using an absolute pathWhat does :e mean? The :e command stands for "edit" — it tells Vim to open a file for editing. You type :e followed by the file path. If the file doesn't exist, Vim creates a new empty buffer with that name (the file is created when you save with :w).
Listing All Open Buffers
:ls " Show all buffers (also called :buffers)This shows something like:
1 %a "introduction.mdx" line 15
2 h "installation.mdx" line 1
3 h "modes.mdx" line 42
What the symbols mean:
| Symbol | Meaning |
|---|---|
% | The buffer shown in the current window |
# | The alternate buffer (the one you were looking at before) |
a | Active — displayed in a window somewhere |
h | Hidden — in memory but not visible |
+ | Has unsaved changes |
Switching Between Buffers
| Command | What It Does |
|---|---|
:bnext or :bn | Switch to the next buffer |
:bprev or :bp | Switch to the previous buffer |
:b 3 | Switch to buffer number 3 (use the number from :ls) |
:b filename | Switch to a buffer by name (you can type a partial name and press Tab) |
Ctrl-^ | Switch between the current and alternate buffers (quick toggle) |
Ctrl-^ is your best friend for toggling between two files! If you're switching between a source file and its test file, Ctrl-^ flips back and forth instantly. On some keyboards, this key might be Ctrl-6.
Closing Buffers
:bd " Close the current buffer (bd = buffer delete)
:bd 3 " Close buffer number 3
:bd! " Close without saving (discard changes)Allow Hidden Buffers
By default, Vim warns you if you try to switch buffers when the current one has unsaved changes. Add this to your ~/.vimrc to allow switching freely:
set hidden " Allow switching buffers without saving firstWith hidden set, Vim keeps unsaved buffers in memory. You can save them later or discard changes when you quit.
Windows (Split Your Screen)
Windows are viewports that display buffers. You can split your screen to see multiple files side by side.
Creating Split Windows
| Command | What It Does |
|---|---|
:split or :sp | Split horizontally (new window above) |
:vsplit or :vsp | Split vertically (new window to the left) |
:split filename | Split and open a specific file in the new window |
:vsplit filename | Vertical split and open a specific file |
Ctrl-w s | Split horizontally (same as :split) |
Ctrl-w v | Split vertically (same as :vsplit) |
After splitting, you'll see the same file in both windows. You can then use :e filename in one window to open a different file.
:vsp src/app.js " Open app.js in a vertical split to the left
:sp test/app.test.js " Open test file in a horizontal split aboveMoving Between Windows
All window commands start with Ctrl-w (think "window"):
| Command | Where It Moves You |
|---|---|
Ctrl-w h | To the window on the left |
Ctrl-w j | To the window below |
Ctrl-w k | To the window above |
Ctrl-w l | To the window on the right |
Ctrl-w w | To the next window (cycles through all windows) |
Ctrl-w p | To the previous window you were in |
Speed up window navigation by adding these mappings to your ~/.vimrc:
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>lNow you can just press Ctrl-h, Ctrl-j, Ctrl-k, Ctrl-l to move between windows — no need for the extra w key.
Resizing Windows
| Command | What It Does |
|---|---|
Ctrl-w = | Make all windows equal size |
Ctrl-w + | Make current window taller (one line) |
Ctrl-w - | Make current window shorter (one line) |
Ctrl-w > | Make current window wider (one column) |
Ctrl-w < | Make current window narrower (one column) |
Ctrl-w _ | Maximize current window height |
Ctrl-w | | Maximize current window width |
10 Ctrl-w + | Make current window 10 lines taller |
Closing Windows
| Command | What It Does |
|---|---|
:q | Close the current window |
:q! | Close the current window without saving |
Ctrl-w q | Close the current window |
Ctrl-w o | Close all other windows (keep only the current one) |
:only | Same as Ctrl-w o |
Closing a window doesn't close the buffer! The file is still in memory. If you use :ls, you'll still see it listed. Use :bd to actually remove a buffer from memory.
Moving Windows Around
| Command | What It Does |
|---|---|
Ctrl-w H | Move current window to the far left (becomes vertical split) |
Ctrl-w J | Move current window to the bottom (becomes horizontal split) |
Ctrl-w K | Move current window to the top (becomes horizontal split) |
Ctrl-w L | Move current window to the far right (becomes vertical split) |
Ctrl-w r | Rotate windows in the current row/column |
Ctrl-w R | Rotate in the opposite direction |
Tabs (Window Layouts)
Tabs in Vim are like virtual desktops — each tab can have its own arrangement of windows.
Creating and Managing Tabs
| Command | What It Does |
|---|---|
:tabnew | Create a new empty tab |
:tabnew filename | Create a new tab and open a file in it |
:tabedit filename | Same as :tabnew filename |
gt | Go to the next tab |
gT | Go to the previous tab |
2gt | Go to tab number 2 |
:tabclose | Close the current tab |
:tabonly | Close all other tabs |
:tabs | List all tabs and their windows |
:tabnew src/app.js " Open app.js in a new tab
:tabnew src/utils.js " Open utils.js in another new tab
gt " Switch to the next tab
gT " Switch backWhen to use tabs vs. splits vs. buffers?
- Buffers — always. Every file you open is a buffer. Use
:bnand:bpto switch. - Windows (splits) — when you need to see two files at the same time (e.g., source and test, or HTML and CSS).
- Tabs — when you want separate "workspaces" for different tasks (e.g., one tab for the frontend code, another for the backend).
Many experienced Vim users actually use buffers the most and tabs the least. Experiment and find what works for you.
File Explorer (netrw)
Vim comes with a built-in file browser called netrw. It lets you navigate directories and open files:
:Explore " Open file explorer in the current window (or :Ex for short)
:Sexplore " Open explorer in a horizontal split (or :Sex)
:Vexplore " Open explorer in a vertical split (or :Vex)Navigating netrw
When the file explorer opens, you'll see a directory listing:
| Key | What It Does |
|---|---|
| Enter | Open the file or directory under the cursor |
- | Go up to the parent directory |
% | Create a new file (prompts for a name) |
d | Create a new directory |
D | Delete the file or directory under the cursor |
R | Rename the file under the cursor |
i | Cycle through display formats (list, tree, etc.) |
:Ex " Open the file explorer
" Use j/k to move through the file list
" Press Enter to open a file
" Press - to go up a directorynetrw can look cluttered. Add these settings to your ~/.vimrc for a cleaner file explorer:
let g:netrw_banner = 0 " Hide the banner at the top
let g:netrw_liststyle = 3 " Use tree-style listing
let g:netrw_winsize = 25 " Explorer takes up 25% of the windowPractical Workflows
Workflow 1: Working with Source and Test Files
" Open your source file
:e src/calculator.js
" Split vertically and open the test file
:vsp test/calculator.test.js
" Now you can see both side by side!
" Use Ctrl-w h and Ctrl-w l to switch between them
" Use Ctrl-^ in either window to toggle to the last file you viewedWorkflow 2: Reviewing Multiple Files
" Open several files as buffers
:e src/app.js
:e src/utils.js
:e src/config.js
" Check what's open
:ls
" Switch between them
:bn " Next buffer
:bp " Previous buffer
:b utils " Jump to utils.js (partial name match)Workflow 3: Opening Multiple Files from the Command Line
You can open multiple files when starting Vim:
vim file1.js file2.js file3.js # Opens all three as buffers
vim -O file1.js file2.js # Opens side by side (vertical splits)
vim -o file1.js file2.js # Opens stacked (horizontal splits)
vim -p file1.js file2.js # Opens in separate tabsSummary
Here's what you've learned:
- Buffers are files loaded in memory — use
:lsto list,:bn/:bpto switch,:bdto close - Windows are split views —
:sp(horizontal) and:vsp(vertical) to create - Navigate windows with
Ctrl-w+h/j/k/l - Tabs are window layouts —
:tabnew,gt/gTto switch Ctrl-^toggles between the current and last file (very handy!)- netrw (
:Ex,:Vex) is Vim's built-in file explorer - Set
hiddenin your vimrc to switch buffers without saving first - Open multiple files from the terminal:
vim -O file1 file2for side-by-side
Practice: Working with Multiple Files
Try this workflow exercise:
# Create some practice files first
echo "function add(a, b) { return a + b; }" > math.js
echo "const result = add(2, 3);" > main.js
echo "console.log('testing...');" > test.jsNow open Vim and practice:
vim math.js- Open
main.jsalongside in a vertical split::vsp main.js - Switch to the right window with
Ctrl-w l - Switch back with
Ctrl-w h - Make all windows equal size:
Ctrl-w = - Open
test.jsas a buffer::e test.js - List all buffers:
:ls - Switch to
math.jsbuffer::b math - Toggle between the last two files:
Ctrl-^ - Open the file explorer:
:Vex(vertical split) - Navigate to a file and press Enter to open it
- Close all other windows:
Ctrl-w o - Create a new tab:
:tabnew main.js - Switch between tabs with
gtandgT - Close everything:
:qa(quit all)
Show Solution
" Start with math.js already open (from the command line)
" 1. Vertical split with main.js
:vsp main.js
" Screen now shows math.js on left, main.js on right
" 2 & 3. Navigate between windows
Ctrl-w l " Move to the right window (main.js)
Ctrl-w h " Move back to the left window (math.js)
" 4. Equalize window sizes
Ctrl-w = " Both windows become the same width
" 5. Open another file
:e test.js " test.js replaces whatever was in the current window
" 6. List buffers
:ls
" You'll see: math.js, main.js, test.js
" 7. Switch to math.js by name
:b math " Jumps to math.js (partial name matching)
" 8. Toggle between files
Ctrl-^ " Switches to the last file you were viewing (test.js)
Ctrl-^ " Switches back to math.js
" 9. Open file explorer
:Vex " Opens netrw in a vertical split on the left
" Use j/k to navigate, Enter to open a file
" 10. When you see a file you want, press Enter to open it
" 11. Close all other windows
Ctrl-w o " Only the current window remains
" 12 & 13. Tabs
:tabnew main.js " Opens main.js in a new tab
gt " Switch to the next tab
gT " Switch back to the previous tab
" 14. Quit everything
:qa " Quit all windows and tabs
" Use :qa! if you have unsaved changes you want to discardWritten by the ShellRAG Team
The ShellRAG editorial team writes practical, beginner-friendly Vim tutorials with tested code examples and real-world use cases. Every article is technically reviewed for accuracy and updated regularly.
Learn more about us →