Lesson 6: Buffer Navigation#
In this lesson, you’ll learn to efficiently work with multiple files (buffers) open simultaneously in Neovim.
Learning Objectives#
By the end of this lesson, you’ll be able to:
- Understand buffers, windows, and tabs
- Switch between open files quickly
- Split windows horizontally and vertically
- Navigate between splits
- Manage buffer lifecycle
Understanding Buffers, Windows, and Tabs#
Buffers#
A buffer is an in-memory representation of a file. When you open a file, it loads into a buffer.
Windows#
A window is a viewport displaying a buffer. You can have multiple windows showing different buffers (or the same buffer).
Tabs#
A tab is a collection of windows. Think of tabs as different workspace layouts.
Tab 1: [Window1: buffer1] [Window2: buffer2]
Tab 2: [Window1: buffer3]Opening Multiple Files#
Open files one by one:#
:e src/main/java/com/example/User.java
:e src/main/java/com/example/UserService.java
:e src/main/java/com/example/Main.javaEach :e command opens a file in a new buffer.
Or open multiple from command line:#
nvim file1.java file2.java file3.javaOr using fuzzy finder:#
Press <Space>ff, select a file, press Enter. Repeat for more files.
Switching Between Buffers#
Using Buffer Navigation Keys#
| Key | Action |
|---|---|
<Space>bb | Show buffer picker |
]b | Next buffer |
[b | Previous buffer |
:b <name> | Switch to buffer by name |
:b <number> | Switch to buffer by number |
Using Telescope Buffer Picker#
Press <Space>bb to see all open buffers:
- Type to filter
<Enter>to switch<Ctrl-x>to delete buffer
Quick Switch#
Jump directly to a buffer:
:b User " Partial name matches
:b UserServicePress Tab for auto-completion.
Window Splits#
Creating Splits#
| Key | Action |
|---|---|
<Space>sv | Split window vertically |
<Space>sh | Split window horizontally |
:split or :sp | Horizontal split |
:vsplit or :vs | Vertical split |
Example Layout#
:vsplit " Vertical split (left|right)
:split " Horizontal split (top|bottom)Results in:
┌────────┬────────┐
│ │ │
│ Buffer1│ Buffer2│
│ ├────────┤
│ │ Buffer3│
└────────┴────────┘Navigating Between Splits#
| Key | Action |
|---|---|
<Ctrl-h> | Move to left split |
<Ctrl-j> | Move to split below |
<Ctrl-k> | Move to split above |
<Ctrl-l> | Move to right split |
Tip: This uses vim-tmux-navigator, so it works seamlessly with tmux too.
Resizing Splits#
| Key | Action |
|---|---|
<Ctrl-Up> | Increase height |
<Ctrl-Down> | Decrease height |
<Ctrl-Left> | Decrease width |
<Ctrl-Right> | Increase width |
<Ctrl-w>= | Equalize all splits |
Closing Splits#
| Key | Action |
|---|---|
<Space>sx | Close current split |
:q | Close current window |
:only | Close all but current window |
Practical Workflow Example#
Let’s work with a multi-file Java project:
Scenario: Editing User Management Feature#
Open main files:
nvim src/main/java/com/example/Main.javaOpen related files:
<Space>ff→ type “User.java” →Enter<Space>ff→ type “UserService” →Enter<Space>ff→ type “UserController” →Enter
Arrange workspace:
<Space>sv- Split vertically<Ctrl-l>- Move to right split<Space>bb- PickUserService.java<Space>sh- Split horizontally<Ctrl-j>- Move down<Space>bb- PickUser.java
Now you have:
┌─────────────┬─────────────┐ │ Main.java │UserServ.java│ │ ├─────────────┤ │ │ User.java │ └─────────────┴─────────────┘Navigate while editing:
- Edit Main.java, use
gdonUserService→ jumps to definition <Ctrl-o>- Jump back to Main.java<Ctrl-h>- Move to Main.java split<Ctrl-l>- Move to service/model splits
- Edit Main.java, use
Close when done:
<Space>sx- Close splits one by one- Or
:only- Keep only current split
Buffer Management#
Listing Buffers#
:lsShows:
1 h "Main.java"
2 %a "UserService.java"
3 a "User.java"Flags:
%- current buffer#- alternate buffer (previous)a- active (loaded and displayed)h- hidden (loaded but not displayed)
Closing Buffers#
| Command | Action |
|---|---|
:bd | Delete current buffer |
:bd <name> | Delete specific buffer |
:%bd | Delete all buffers |
:bd! | Force delete (discard changes) |
Saving and Closing#
| Command | Action |
|---|---|
:w | Write (save) current buffer |
:wa | Write all buffers |
:wq | Write and quit |
:qa | Quit all |
:wqa | Write all and quit |
:qa! | Quit all without saving |
Advanced Buffer Workflows#
The Alternate Buffer#
Neovim remembers your previous buffer:
<Ctrl-^> " Switch to alternate (previous) bufferToggle between two files quickly with <Ctrl-^>.
Buffer Arguments#
:args *.java " Set buffer list to all .java files
:argdo %s/old/new/ge " Run command on all buffers
:argdo update " Save allHidden Buffers#
By default, Neovim allows hidden buffers (unsaved changes in background):
:set hidden " Allow switching buffers without savingThis is already enabled in Neovim4j config.
Tabs#
Creating and Using Tabs#
| Command | Action |
|---|---|
:tabnew | Create new tab |
:tabnew <file> | Open file in new tab |
gt | Next tab |
gT | Previous tab |
<number>gt | Go to tab number |
:tabclose | Close current tab |
:tabonly | Close all but current tab |
When to Use Tabs#
Tabs are best for:
- Completely different workflows (e.g., code vs. tests vs. docs)
- Different projects
- Context switching
For the same project, prefer splits and buffers.
Practice Exercises#
Exercise 1: Multi-File Editing#
Open these files as buffers:
- Main.java
- User.java
- UserService.java
- UserController.java
Practice switching with:
<Space>bb- Buffer picker:b User- Command switch]band[b- Next/previous
Exercise 2: Split Workflow#
Create this layout:
┌────────────┬──────────────┐ │ │ │ │ Main.java │UserServ.java │ │ │ │ └────────────┴──────────────┘Add a horizontal split on the right:
┌────────────┬──────────────┐ │ │UserServ.java │ │ Main.java ├──────────────┤ │ │ User.java │ └────────────┴──────────────┘Navigate between all three with
<Ctrl-h/j/k/l>
Exercise 3: Code Review Workflow#
Review changes across files:
- Open old version in left split
- Open new version in right split
- Use
<Ctrl-h/l>to compare - Make edits as needed
Tips for Efficient Buffer Navigation#
- Use fuzzy finder -
<Space>ffis faster than:efor known files - Use
gdliberally - Jump to definitions, then<Ctrl-o>back - Keep related files in splits - Model and Service side-by-side
- Close unused buffers - Keep buffer list clean with
:bd - Master
<Ctrl-^>- Quick toggle between two files - Use marks - Set marks with
m<letter>, jump with'<letter>
Common Patterns#
Pattern 1: Class and Test#
:vs " Vertical split
<Space>ff " Find test fileNow you have class on left, test on right.
Pattern 2: Interface and Implementation#
:vs
" On interface name:
gi " Go to implementationPattern 3: Multi-Class Refactoring#
- Open all related files as buffers
- Use one split for editing
- Switch buffers in that split with
<Space>bb - Or create splits for most-used files
What’s Next?#
In Lesson 7: Code Navigation, you’ll learn to navigate large codebases like a pro.