vim is the text editor that is always there. Every Linux server, every macOS installation, every Unix system has vi or vim installed. It is the editor that opens when git needs a commit message, when crontab needs editing, and when you SSH into a server that has nothing else installed. It is also the editor that people accidentally open and cannot figure out how to close, which is why “how to exit vim” has been searched millions of times.
The reason vim is confusing at first is that it uses a modal editing model. In most editors, pressing a key types that character. In vim, pressing a key might type a character, navigate the cursor, delete a word, or run a command, depending on which mode you are in. This is the single concept you need to understand before anything else makes sense.
This guide covers what you need to know to be productive in vim on a server: the modes, the essential commands, and the operations you will actually use when editing configuration files, scripts, and server settings.
Why vim matters for server administration#
You do not need to become a vim expert to administer servers. nano is a perfectly good editor for quick config file changes, and it has a gentler learning curve. But there are situations where knowing basic vim is necessary:
- vim is the default editor on many systems. When you run
git commit,crontab -e, orvisudo, the system opens your default editor. On many servers, that default is vim. If you do not know how to save and quit, you are stuck. - Some servers only have vi. Minimal server installations, Docker containers, and rescue environments may have vi (the original) but not nano. vi commands are a subset of vim commands, so knowing vim covers both.
- Remote editing over slow connections. vim’s keyboard-driven interface works over high-latency SSH connections where a mouse-dependent editor would be unusable. Every operation is a key press, no menus to navigate.
- Reading files without modification. vim’s view mode (
vim -Rorview) is a powerful file viewer with search, syntax highlighting, and navigation that works on files of any size.
The modal editing concept#
This is the thing that makes vim different from every other editor you have used. vim has three main modes:
Normal mode (the default)
When you open vim, you are in normal mode. Key presses are commands, not text input. Pressing
j
moves the cursor down. Pressing
dd
deletes a line. Pressing
/
starts a search. Nothing you type in normal mode inserts text into the file.
This is the mode that confuses beginners. They open vim, start typing, and the screen does unexpected things because every letter is a command.
Insert mode (typing text)
Press
i
in normal mode to enter insert mode. Now key presses insert text, like a normal editor. The bottom of the screen shows
-- INSERT --
to remind you which mode you are in.
Press
Esc
to leave insert mode and return to normal mode.
Visual mode (selecting text)
Press
v
in normal mode to enter visual mode. Move the cursor to select text. The selection is highlighted. You can then copy, cut, or perform other operations on the selection.
Press
Esc
to leave visual mode and return to normal mode.
The key rule
If something unexpected is happening, press
Esc
. This always returns you to normal mode. If you are not sure which mode you are in, press
Esc
and you are guaranteed to be in normal mode. Pressing
Esc
multiple times does no harm.
How to exit vim#
This deserves its own section because it is the most common vim question on the internet.
Save and quit
:wq
Press
Esc
first (to make sure you are in normal mode), then type
:wq
and press Enter. The
:
enters command-line mode,
w
writes (saves) the file, and
q
quits.
Alternatively:
ZZ
In normal mode, press
Shift+Z
twice. This saves and quits in one step without entering command-line mode.
Quit without saving
:q!
The
!
forces the quit, discarding any unsaved changes. Use this when you opened a file, made changes you do not want, and need to get out.
Save without quitting
:w
Writes the file to disk but keeps vim open. Useful when you want to save your progress and keep editing.
Quit (only works if no unsaved changes)
:q
If you have unsaved changes, vim refuses and shows “E37: No write since last change.” Either save first (
:w
) or force quit (
:q!
).
Opening files#
vim /etc/nginx/nginx.conf
Opens the file in vim. If the file does not exist, vim creates it when you save.
Open at a specific line number:
vim +47 /etc/nginx/nginx.conf
Open in read-only mode:
vim -R /etc/nginx/nginx.conf
or:
view /etc/nginx/nginx.conf
Open with root permissions:
sudo vim /etc/nginx/nginx.conf
Navigation in normal mode#
You can use arrow keys in vim, and on modern systems they work fine. But the traditional vim navigation keys are on the home row:
| Key | Action |
|---|---|
h
| Move left |
j
| Move down |
k
| Move up |
l
| Move right |
These feel strange at first but become natural with practice. The advantage is that your hands never leave the home row.
Moving by words and lines
| Key | Action |
|---|---|
w
| Move forward to the start of the next word |
b
| Move backward to the start of the previous word |
e
| Move forward to the end of the current word |
0
| Move to the beginning of the current line |
$
| Move to the end of the current line |
^
| Move to the first non-whitespace character of the line |
Moving by pages and file position
| Key | Action |
|---|---|
Ctrl+F
| Page down (forward one screen) |
Ctrl+B
| Page up (back one screen) |
Ctrl+D
| Half page down |
Ctrl+U
| Half page up |
gg
| Go to the first line of the file |
G
| Go to the last line of the file |
47G
| Go to line 47 (or
:47
in command mode) |
The
47G
shortcut is what you use when an error log tells you the problem is on a specific line. In normal mode, type the line number and then
G
.
Entering insert mode#
There are several ways to enter insert mode, each positioning the cursor differently:
| Key | Action |
|---|---|
i
| Insert before the cursor |
a
| Insert after the cursor (append) |
I
| Insert at the beginning of the line |
A
| Insert at the end of the line |
o
| Open a new line below and enter insert mode |
O
| Open a new line above and enter insert mode |
The most common ones are
i
(start typing where the cursor is),
A
(add something to the end of a line), and
o
(add a new line below).
Press
Esc
when you are done typing to return to normal mode.
Deleting text#
All delete commands work in normal mode. They also copy the deleted text into the unnamed register (vim’s clipboard), so deletion is also a cut operation.
| Command | Action |
|---|---|
x
| Delete the character under the cursor |
dd
| Delete the entire current line |
dw
| Delete from the cursor to the start of the next word |
d$
or
D
| Delete from the cursor to the end of the line |
d0
| Delete from the cursor to the beginning of the line |
5dd
| Delete 5 lines starting from the current line |
The pattern
d
+ motion is consistent.
d
means delete, and the next character defines what to delete.
dw
= delete word,
d$
= delete to end of line,
dG
= delete to end of file.
Copy and paste#
vim calls copy “yank” (y).
| Command | Action |
|---|---|
yy
| Yank (copy) the current line |
yw
| Yank from the cursor to the start of the next word |
y$
| Yank from the cursor to the end of the line |
5yy
| Yank 5 lines |
p
| Paste after the cursor (or below the current line for line-wise yanks) |
P
| Paste before the cursor (or above the current line) |
To copy and paste a block of text:
- In normal mode, move to the start of the text
- Press
vto enter visual mode - Move the cursor to select the text you want
- Press
yto yank (copy) the selection - Move to where you want to paste
- Press
pto paste
Paste from system clipboard
When connected via SSH, pasting from your local clipboard works through the terminal emulator, not through vim. Use your terminal’s paste shortcut (Cmd+V on macOS, right-click on Windows Terminal, Ctrl+Shift+V on Linux terminals).
Before pasting into vim from the system clipboard, enter paste mode to prevent vim from auto-indenting the pasted text:
:set paste
Enter insert mode (
i
), paste from your terminal, then disable paste mode:
:set nopaste
Without
:set paste
, vim treats pasted text as if you are typing it and applies auto-indentation rules, which mangles the formatting of pasted code.
Search#
Find text
/search term
In normal mode, press
/
, type your search term, and press Enter. vim jumps to the first match. Press
n
to go to the next match,
N
to go to the previous match.
Search backward
?search term
Same as
/
but searches backward from the cursor position.
Find and replace
:%s/old/new/g
This replaces every occurrence of “old” with “new” in the entire file. The components:
-
%means the entire file (without it, only the current line is affected) -
smeans substitute -
/old/new/is the pattern and replacement -
gmeans global (replace all occurrences on each line, not just the first)
To confirm each replacement:
:%s/old/new/gc
The
c
flag prompts you for each occurrence:
y
to replace,
n
to skip,
a
to replace all remaining.
Case-insensitive search
/search term\c
Append
\c
to make a single search case-insensitive. To make all searches case-insensitive by default:
:set ignorecase
Undo and redo#
| Command | Action |
|---|---|
u
| Undo the last change |
Ctrl+R
| Redo (undo the undo) |
vim has unlimited undo levels. Press
u
repeatedly to undo multiple changes.
Working with multiple lines#
Indent a block
- Enter visual mode (
vorVfor line-wise selection) - Select the lines
- Press
>to indent or<to unindent
Or in normal mode:
5>>
indents 5 lines starting from the current line.
Comment out a block (common in config files)
- Move to the first line of the block
- Press
Ctrl+Vto enter visual block mode - Select down to the last line of the block
- Press
I(capital I) to enter insert mode at the beginning of each line - Type
#(or whatever comment character you need) - Press
Esc
The comment character appears on all selected lines. This is one of vim’s most useful features for server administration, where you frequently need to comment or uncomment blocks of configuration.
Line numbers#
Show line numbers:
:set number
Show relative line numbers (useful for counting lines for commands like
5dd
):
:set relativenumber
Hide line numbers:
:set nonumber
Syntax highlighting#
Enable syntax highlighting:
:syntax on
Disable it:
:syntax off
On most modern systems, syntax highlighting is enabled by default for recognized file types. If your configuration files are not highlighted, the file extension may not be recognized. You can force the file type:
:set filetype=nginx
:set filetype=php
:set filetype=yaml
vim configuration#
Create
~/.vimrc
to customize vim’s behavior:
" Show line numbers
set number
" Enable syntax highlighting
syntax on
" Show matching brackets
set showmatch
" Enable search highlighting
set hlsearch
" Case-insensitive search (unless uppercase is used)
set ignorecase
set smartcase
" Convert tabs to spaces
set expandtab
set tabstop=4
set shiftwidth=4
" Show cursor position in status bar
set ruler
" Enable mouse support
set mouse=a
" Show partial commands
set showcmd
Practical server administration examples#
Edit a Nginx configuration file
sudo vim /etc/nginx/conf.d/example.conf
Navigate to the line you need to change (
:47
to go to line 47), press
i
to enter insert mode, make the change, press
Esc
, type
:wq
to save and quit.
Uncomment a line in a config file
Move the cursor to the
#
at the beginning of the line, press
x
to delete it. That is it. One key press.
Add a line to wp-config.php
Open the file, navigate to where you want to add the line, press
o
to open a new line below and enter insert mode, type the line, press
Esc
, type
:wq
.
Search for a specific setting
Open the file, press
/
, type the setting name (like
max_connections
), press Enter. vim jumps to the first match. Press
n
to cycle through matches.
Replace a domain name in a config file
:%s/old-domain.com/new-domain.com/gc
This finds every occurrence and prompts you to confirm each replacement.
vim vs nano#
Both are available on virtually every server. The choice depends on how often you edit files on servers.
Use nano when: You rarely edit files on servers, you want visible keyboard shortcuts, or the edit is simple and quick.
Use vim when: You edit files on servers frequently, you want efficiency and speed, you need powerful search-and-replace or block operations, or you are working over a slow SSH connection where every keystroke counts.
Most server administrators know both and use whichever fits the task. Quick config change? nano. Complex multi-line edit with search-and-replace? vim. There is no wrong answer.
On Hostney, both vim and nano are available in every SSH container. Connect via SSH (Terminal Access in the control panel) and use whichever editor you prefer. For transferring files rather than editing them in place, use SCP or SFTP.
Quick reference#
| Command | Action |
|---|---|
i
| Enter insert mode |
Esc
| Return to normal mode |
:wq
| Save and quit |
:q!
| Quit without saving |
:w
| Save |
dd
| Delete line |
yy
| Copy line |
p
| Paste |
u
| Undo |
Ctrl+R
| Redo |
/pattern
| Search forward |
n
/
N
| Next / previous match |
:%s/old/new/g
| Find and replace all |
gg
| Go to first line |
G
| Go to last line |
:47
| Go to line 47 |
v
| Enter visual mode |
Ctrl+V
| Enter visual block mode |
>
/
<
| Indent / unindent selection |
:set number
| Show line numbers |
:syntax on
| Enable syntax highlighting |