01.The Vim Way
Tip 1. Meet the Dot Command
The dot command lets us repeat the last change. It is the most powerful and versatile command in Vim.
Vim’s documentation simply states that the dot command “repeats the last change” (see :h . ).
What is a change?
To understand the power of the dot command, we have to realize that the “last change” could be one of many things. A change could act at the level of individual characters, entire lines, or even the whole file.
Line one
Line two
Line three
Line fourxdeletes the character under the cursor (change on individual characters)dddeletes the current line (change on entire lines)>Gincreases the indentation from the current line until the end of the file (change on the whole file)
The x, dd, and > commands are all executed from Normal mode, but we also create a change each time we dip into Insert mode. From the moment we enter Insert mode (by pressing i, for example) until we return to Normal mode (by pressing <Esc>), Vim records every keystroke. After making a change such as this, the dot command will replay our keystrokes.
The Dot Command Is a Micro Macro
Later, in Chapter 11, Macros, we’ll see that Vim can record any arbitrary number of keystrokes to be played back later. This allows us to capture our most repetitive workflows and replay them at a keystroke. We can think of the dot command as being a miniature macro, or a “micro” if you prefer.
We’ll see a few applications of the dot command throughout this chapter. We’ll also learn a couple of best practices for working with the dot command in Tip 9, Compose Repeatable Changes, and Tip 23, Prefer Operators to Visual Commands Where Possible.
Tip 2. Don't Repeat Yourself
For such a common use case as appending a semicolon at the end of a series of lines, Vim provides a dedicated command that combines two steps into one.
Reduce Extraneous Movement
var foo = 1;
var bar = "a";
var foobar = foo + bar;Practice Problems
- How to add semicolons at the end?
- How to delete semicolons at the end?
- How do I delete the last character in each line using Vim?
12345a
123456b
1234567c
12345678d
123456789eAnswer: :53,57s/.$/
All these commands in Normal mode switch to Insert mode:
iswitch to Insert mode before the cursorIinsert text at the beginning of the lineaappends after the current cursor positionAappends at the end of the current lineoopen a new line below the current oneOopen a new line above the current onecwcut to the end of current word and switch to Insert modecccut the entire line and switch to Insert modescut the current character and switch into Insert modeScut the entire line and switch to Insert mode
Exit from Insert to Normal mode
<Esc>or<C-[>exit Insert mode
From the moment we enter Insert Mode (by pressing i) until we return to Normal mode (by pressing <Esc>), Vim records every keystroke.
This is a test line to play around with the following commands.Two for the Price of One
| Compound Command | Equivalent in Longhand |
|---|---|
C | c$ |
s | cl |
S | ^C |
I | ^i |
A | $a |
o | A<CR> |
O | ko |
Question
svsxi: how do they affect registers differently?Svsddi: how do they affect registers differently?
Tip 3. Take One Step Back, Then Three Forward
We can pad a single character with two spaces (one in front, the other behind) by using an idiomatic Vim solution. At first it might look slightly odd, but the solution has the benefit of being repeatable, which allows us to complete the task effortlessly.
var foo = "method(" + argument1 + "," + argument2 + ")";f{char}tells Vim to look ahead for the next occurrence of the specified character and then move the cursor directly to it if a match is found- we could jump to the next occurrence by repeating the
f+command, or ;will repeat the last search that thefcommand performedxdeletes a character in Normal modesdeletes a character and enters Insert mode
Tip 4. Act, Repeat, Reverse
| Intent | Act | Repeat | Reverse |
|---|---|---|---|
| Make a change | {edit} | . | u |
| Scan a line for next character | f{char} or t{char} | ; | , |
| Scan a line for previous character | F{char} or T{char} | ; | , |
| Scan document for next match | /pattern<CR> | n | N |
| Scan document for previous match | ?pattern<CR> | n | N |
| Perform substitution | :s/target/replacement | & | u |
| Execute a sequence of changes | qx{changes}q | @x | u |
Table 1 — Repeatable Actions and How to Reverse Them
:s%/target/replacementchange the 1st matched occurrence:s%/target/replacement/gchange all occurrences without "confirming each substitution":s%/target/replacement/gcchange all occurrences, 1 by 1 "confirming each substitution"
Tip 5. Find and Replace by Hand
Vim has a :substitute command for find-and-replace tasks, but with this alternative technique, we'll change the first occurrence by hand and then find and replace every other match one by one. The dot command will save us from labor, but we'll meet another nifty one-key command that makes jumping between matches a snap.
...We're waiting for content before the site can go live...
...If you are content with this, let's go ahead with it...
...We'll launch as soon as we have the content...Suppose that we want to use the word "copy" instead of "content". We can just use the substitute command:
Method 1 (replacement for the entire file)
:%s/content/copy/g
Method 2 (search without typing)
*command executes a search for the word under the cursor- the cursor will jump to the next match, and
- all occurrences will be highlighted
cwcommand deletes to the end of the word and then drops us into Insert mode- during a search, press the
nkey, our cursor advances to the next occurrence
If you don't see any highlighting, try running :set hlsearch command.
Method 2 is equivalent to :s%/target/replacement/gc
Tip 6. Meet the Dot Formula
Summarizes Tip 2 3 5
The Ideal: One Keystroke to Move, One Keystroke to Execute