- Published on
Vim 效率倍增:重複與自動化

Vim 系列文章
- Vim 生存指南:模式與移動
- Vim 編輯基礎:輸入、刪除和複製貼上
- Vim 選取模式:三種 Visual Mode
- Vim 語法系統:動詞 + 量詞 + 名詞
- Vim 搜尋技巧:快速定位與取代
- Vim 效率倍增:重複與自動化 (本篇)
- Vim 客製化:設定與 IDE 整合
前幾篇學會了 Vim 的核心操作。但高手和新手的差距,在於如何避免重複。這篇要學習三個實用技巧:. 指令、寄存器、和巨集
最強大的按鍵:.
. 是 Vim 中最強大的按鍵。它的功能是:重複上一個編輯動作
什麼是「上一個動作」?
任何改變文字的操作都算,例如:
dw(刪除 word)ciw+ 輸入新內容 + Escx(刪除字元)>>(增加縮排)
不算的:純移動(如 w、j)、搜尋(如 /pattern)
基本用法
foo bar foo bar foo
^(游標在第一個 foo 的 f 上)
按 ciw,輸入 baz,按 Esc
baz bar foo bar foo
^ ← foo 變成 baz
按 w w 移動到下一個 foo
baz bar foo bar foo
^(游標在第二個 foo 的 f 上)
按 .
baz bar baz bar foo
^ ← 第二個 foo 也變成 baz
搜尋 + . 的組合技
這招很實用,用三行內容更能展示跨行搜尋的威力
1 foo bar baz
^(游標在第 1 行的 foo)
2 foo bar baz
3 foo bar baz
按 /foo Enter
1 foo bar baz
2 foo bar baz
^ ← 跳到第 2 行的 foo(搜尋會往下找下一個匹配)
3 foo bar baz
按 ciw,輸入 hello,按 Esc
1 foo bar baz
2 hello bar baz
^ ← 第 2 行的 foo 變成 hello
3 foo bar baz
按 n
1 foo bar baz
2 hello bar baz
3 foo bar baz
^ ← 跳到第 3 行的 foo
按 .
1 foo bar baz
2 hello bar baz
3 hello bar baz
^ ← 第 3 行的 foo 也變成 hello
按 n
1 foo bar baz
^ ← wrap around 回到第 1 行的 foo
2 hello bar baz
3 hello bar baz
按 .
1 hello bar baz
^ ← 全部都變成 hello 了
2 hello bar baz
3 hello bar baz
更快的方式:用 * 搜尋當前單字
把游標放在 foo 上
1. *(搜尋 foo,跳到下一個)
2. ciw 改成 baz,Esc
3. n.n.n.(跳 + 改 + 跳 + 改...)
為什麼 . 這麼強大?
因為 Vim 的設計哲學是
效率 = 精準的動作 × 重複的次數
- 做一次正確的編輯(用最精準的指令)
- 移動到下一個位置
- 按
.重複
你只需要「想」一次,剩下的都是機械式的 n.n.n.
寄存器:多個剪貼簿
Vim 有多個「剪貼簿」,稱為寄存器 (registers)
操作語法
使用寄存器的語法是 "寄存器名稱 + 動作
"a + yy → 複製整行到寄存器 a
"a + p → 從寄存器 a 貼上
"+ + y → 複製到系統剪貼簿
" 是告訴 Vim「接下來要指定寄存器」,後面接寄存器名稱,再接你要做的動作
預設寄存器
當你用 d 或 y 時,內容會存到「預設寄存器」("")
問題是:如果你先 yiw 複製一個 word,然後 dw 刪除另一個 word,想貼上一開始複製的內容… 糟糕!預設寄存器已經被覆蓋了
"0 寄存器:解決方案
"0 永遠存放最近 yank 的內容,不會被 delete 覆蓋
important text delete
^(游標在 important 的 i 上)
按 yiw 複製 "important"
important text delete
^ ← "important" 已複製到 "" 和 "0
按 w w 移動到 "delete"
important text delete
^(游標在 delete 的 d 上)
按 dw 刪除 "delete"
important text
^ ← "delete" 存到 "",覆蓋了 "important"
按 p
important text delete
^ ← 貼出 "delete"(錯誤!)
按 u 復原
important text
^
按 "0p
important text important
^ ← 貼出 "important"(正確!"0 沒被覆蓋)
每次都要按 "0p 有點麻煩,可以在 vimrc 中設定快捷鍵來簡化這個操作,請參考設定與 IDE 整合中的推薦設定
"1 到 "9:刪除歷史
Vim 會自動幫你保留最近 9 次的刪除紀錄
"1:最近一次刪除的內容(整行或多字元的刪除)"2:前一次的刪除"3到"9:依序更早的刪除
每次新的刪除會把舊內容往後推("1 → "2 → "3…)
第一行
^(游標在第一行)
第二行
第三行
按 dd 刪除第一行 → "1 = "第一行"
第二行
^
第三行
按 dd 刪除第二行 → "1 = "第二行","2 = "第一行"
第三行
^
按 "2p
第三行
第一行
^ ← 從 "2 找回最早刪除的 "第一行"
不小心刪錯了?用 :reg 1 2 3 看看刪除歷史,從裡面找回來就好
"-:小刪除寄存器
不是所有刪除都會進入 "1 到 "9,規則很簡單
- 少於一行的刪除(如
dw、x、dl)→ 存到"- - 整行的刪除(如
dd、dj)→ 存到"1
所以 "- 就是專門放「小刪除」的地方,用 "-p 可以貼上最近一次的小刪除
具名寄存器:a-z
你可以用 "a 到 "z 存放不同內容
"ayiw → 複製 word 到寄存器 a
"byy → 複製整行到寄存器 b
"ap → 從寄存器 a 貼上
"bp → 從寄存器 b 貼上
查看所有寄存器
:reg → 顯示所有寄存器內容
:reg a → 只顯示寄存器 a
理解 :reg 輸出
Type Name Content
c "" hello
c "0 hello
l "1 first line^J
l "2 second line^J
c "- world
c "a foo
c "b bar
c "+ clipboard text
c "/ search_pattern
c ". last insert
c ": %s/old/new/g
c "% index.mdx
執行 :reg 後會看到三欄
| 欄位 | 說明 |
|---|---|
| Type | l 代表整行模式 (linewise),c 代表字元模式 (characterwise) |
| Name | 寄存器名稱(如 ""、"0、"a) |
| Content | 寄存器中的內容,^J 代表換行符 |
Type 決定了貼上時的行為:l 會貼成獨立的一行,c 會貼在游標位置
系統剪貼簿
| 寄存器 | 說明 |
|---|---|
"+ | 系統剪貼簿 |
"* | 選取剪貼簿(Linux X11 環境) |
"+y → 複製到系統剪貼簿(可以貼到其他程式)
"+p → 從系統剪貼簿貼上
唯讀寄存器
這幾個寄存器由 Vim 自動維護,你只能讀取不能寫入
| 寄存器 | 說明 |
|---|---|
". | 最近插入的文字 |
": | 最近執行的命令列指令 |
"% | 目前檔案名稱 |
"/ | 最近的搜尋 pattern |
例如忘記剛才搜尋了什麼,用 "/p 就能把搜尋的 pattern 貼出來看
巨集:錄製你的動作
當 . 不夠用的時候,巨集就派上用場了。巨集可以錄製一連串的動作,然後重複播放
操作語法
q + 寄存器名稱 → 開始錄製(例如 qa)
q → 停止錄製
@ + 寄存器名稱 → 播放(例如 @a)
@@ → 重複上次播放
數字 + @a → 播放多次(例如 10@a)
q 是錄製的開關,@ 是播放。寄存器名稱可以用 a 到 z
基本操作
| 指令 | 動作 |
|---|---|
qa | 開始錄製到寄存器 a |
q | 停止錄製 |
@a | 播放寄存器 a 的巨集 |
@@ | 重複上次播放的巨集 |
10@a | 播放 10 次 |
這裡用
a當例子,實際上可以用a到z任一個寄存器
實戰範例:將每行轉成 JSON 格式
1 apple
^(游標在第 1 行)
2 banana
3 cherry
按 qa 開始錄製到寄存器 a
1 apple
^ ← 左下角顯示 recording @a
2 banana
3 cherry
按 I" Esc(行首加 ")
1 "apple
^
2 banana
3 cherry
按 A", Esc(行尾加 ",)
1 "apple",
^
2 banana
3 cherry
按 j 和 0(移到下一行的最前面)
1 "apple",
2 banana
^
3 cherry
按 q(停止錄製)
1 "apple",
2 banana
^ ← 錄製完成
3 cherry
按 2@a(對剩下 2 行執行巨集)
1 "apple",
2 "banana",
3 "cherry",
4
^ ← 全部完成
巨集設計原則
- 從行首開始:先按
0或^,確保位置一致 - 移動到下一行:巨集最後加
j,這樣可以連續執行 - 測試一次:錄完後先執行一次
@a,確認正確 - 用數字前綴:
100@a比按 100 次@a快
另一個範例:產生序號
1 item
^(游標在第 1 行)
按 i1. Esc(在第一行前面加 "1. ")
1 1. item
^
按 qa 開始錄製到寄存器 a
1 1. item
^ ← 左下角顯示 recording @a
按 yy(複製整行)
1 1. item
^ ← 已複製 "1. item"
按 p(貼上到下一行)
1 1. item
2 1. item
^ ← 貼上的新行
按 Ctrl+a(數字加 1)
1 1. item
2 2. item
^ ← 1 變成 2
按 q(停止錄製)
1 1. item
3 2. item
^ ← 錄製完成
按 @a(執行一次巨集)
1 1. item
2 2. item
4 3. item
^ ← 數字加 1 後複製貼上
按 5@a(執行 5 次產生更多行)
1 1. item
2 2. item
3 3. item
4 4. item
5 5. item
6 6. item
7 7. item
8 8. item
^ ← 可繼續執行產生更多
...
其他效率技巧
Ctrl+a / Ctrl+x:數字加減
count = 10
^
Ctrl+a → count = 11(+1)
Ctrl+x → count = 10(-1)
5 Ctrl+a → count = 15(+5)
游標不需要在數字上,Vim 會自動找到該行第一個數字
本篇重點整理
. 指令
- 重複上一個編輯動作
- 搭配 n 使用:n.n.n.
寄存器
"" → 預設寄存器
"0 → 最近 yank(不被 delete 覆蓋)
"1-"9 → 刪除歷史
"- → 小刪除(少於一行)
"a-z → 具名寄存器
"+ → 系統剪貼簿
". ": "% "/ → 唯讀寄存器
:reg → 查看所有
巨集
qa → 開始錄製到 a
q → 停止
@a → 播放
@@ → 重複播放
10@a → 播放 10 次
其他
Ctrl+a / Ctrl+x → 數字加減
圖片來源:AI 產生