這是 Neovim 從零開始系列的第四篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。
效率的下一個層次
前兩篇我們學了 Vim 的語言系統和移動指令。有了這些基礎,你已經能在程式碼中自由移動和編輯了。
這篇要教的三個功能——Dot Command、Registers 和 Macros——會把你的效率再推上一個層次。它們的核心概念是:重複操作的自動化。
Dot Command:最強的單一按鍵
.(dot)這個按鍵可能是 Vim 中投資報酬率最高的功能。它的作用很簡單:
重複上一次的修改操作
基本用法
// 想把所有的 var 改成 const
var name = "Jack"
var age = 30
var city = "Taipei"
操作步驟:
- 游標在第一行的
var上 - 按
cw然後輸入const,按Esc - 移到下一行的
var上,按.——自動執行「把單字改成 const」 - 再移到下一行,按
.——同樣的操作
一個 . 就重複了整個 cw + 輸入 + Esc 的序列。
Dot Command 的威力
. 重複的是上一次「從 Normal mode 進入 Insert mode 到離開」的完整操作,或者是上一次 Normal mode 下的操作指令。
| 上一次操作 | . 會做什麼 |
|---|---|
ciwfoo<Esc> |
把游標下的單字改成 foo |
dd |
刪除一整行 |
A;<Esc> |
在行尾加上分號 |
I// <Esc> |
在行首加上 // |
>> |
向右縮排一次 |
設計你的操作讓 . 更好用
好的 Vim 使用者會刻意設計操作方式,讓後續能用 . 重複。
// 差的做法:用 / 搜尋 + cw 修改
// 好的做法:
// 想在多個行尾加分號
A;<Esc> // 在行尾加分號
j. // 下一行,重複
j. // 再下一行,重複
// 想刪除多行
dd // 刪除一行
. // 再刪一行
. // 再刪一行
Registers:Vim 的多重剪貼簿
在 VSCode 中,剪貼簿只有一個。但 Vim 有多個 registers——你可以把不同的內容存在不同的 register 中。
查看 Registers
:registers " 或 :reg
Register 種類
| Register | 名稱 | 用途 |
|---|---|---|
"" |
未命名 register | 最近一次 d、c、y 的內容(預設) |
"0 |
Yank register | 最近一次 y 的內容 |
"1 ~ "9 |
數字 register | 最近 9 次刪除的內容(歷史) |
"a ~ "z |
命名 register | 你主動存入的內容 |
"+ |
系統剪貼簿 | 和 OS 共用的剪貼簿 |
"* |
選取剪貼簿 | X11 的 primary selection |
"_ |
黑洞 register | 丟進去的東西消失(不影響其他 register) |
". |
上次插入 | 上一次在 Insert mode 輸入的文字 |
"/ |
搜尋 register | 上一次搜尋的 pattern |
使用方式
在任何 d、c、y、p 操作前加上 "{register}:
"ayy → 複製整行到 register a
"ap → 貼上 register a 的內容
"+yy → 複製整行到系統剪貼簿
"+p → 從系統剪貼簿貼上
最常遇到的問題:刪除覆蓋了複製
這可能是 Vim 新手最大的困擾:
1. yy 複製一行
2. dd 刪除另一行
3. p 貼上 → 結果貼出的是剛刪除的行,不是複製的那行!
原因:dd 的內容覆蓋了未命名 register ""。
解決方法(任選一種):
- 用
"0p:register0永遠保存最後一次 yank 的內容 - 用命名 register:
"ayy存到 a,"ap從 a 取出 - 用黑洞 register 刪除:
"_dd刪除但不存入任何 register
實用搭配
"ayiw → 複製游標下的單字到 register a
"byi{ → 複製大括號內容到 register b
...移動到其他地方...
"ap → 貼上 register a 的單字
"bp → 貼上 register b 的大括號內容
Macros:錄製你的操作
如果 Dot Command 是「重複上一步」,那 Macros 就是「重複一整個操作流程」。
基本操作
| 指令 | 功能 |
|---|---|
q{register} |
開始錄製到指定 register(例如 qa) |
q |
停止錄製 |
@{register} |
播放 register 中的 macro(例如 @a) |
@@ |
重播上一次播放的 macro |
{n}@{register} |
播放 N 次 |
錄製 Macro 的步驟
qa → 開始錄製到 register a(狀態列會顯示 recording @a)
...操作... → 執行你想重複的操作
q → 停止錄製
@a → 播放
10@a → 播放 10 次
實戰範例 1:批次加引號
假設有一串沒有引號的文字:
apple
banana
cherry
grape
想把每行都加上引號變成 "apple",:
- 游標在第一行開頭
qa— 開始錄製I"— 在行首插入引號<Esc>A",— 在行尾加上引號和逗號<Esc>j0— 回到 Normal mode,往下一行,到行首q— 停止錄製3@a— 對剩下的 3 行執行
結果:
"apple",
"banana",
"cherry",
"grape",
實戰範例 2:重構函數呼叫
// 把這些呼叫改成 await
fetchUser(id)
fetchPosts(userId)
fetchComments(postId)
qa— 開始錄製Iawait— 在行首加 await<Esc>j0— 下一行行首q— 停止錄製2@a— 執行 2 次
Macro 錄製的技巧
讓 Macro 可靠的關鍵:使用結構化移動而非相對移動。
// 差:用 3l 移動 3 格(如果下一行長度不同就出錯)
// 好:用 w 移到下一個單字(不管間距多少)
// 好:用 0 移到行首(不管游標在哪)
// 好:用 f( 找到括號(不管位置在哪)
Macro 開始和結束時的游標位置要一致,這樣才能連續播放。通常在結尾加上 j0(下一行行首)。
Visual Mode:視覺化選取
Visual Mode 讓你先選取文字,再決定要做什麼操作。這和一般編輯器的「先選取再操作」很像,但 Vim 的選取方式更強大。
三種 Visual Mode
| 指令 | 模式 | 用途 |
|---|---|---|
v |
Character visual | 字元級選取 |
V |
Line visual | 整行選取 |
Ctrl-v |
Block visual | 矩形區塊選取 |
Character Visual (v)
// 從游標開始選取到某個位置
v$ → 選取到行尾
viw → 選取整個單字
vi" → 選取引號內容
v% → 選取到配對括號
選取後可以:
d— 刪除c— 修改y— 複製>— 縮排u— 轉小寫U— 轉大寫:— 對選取範圍執行命令
Line Visual (V)
V → 選取整行
Vj → 選取兩行
V} → 選取到段落結尾
Vip → 選取整個段落
最常見的用法:Vjjjd(選取多行後刪除)或 Vjjj>(選取多行後縮排)。
Block Visual (Ctrl-v):最酷的功能
Block Visual 是 Vim 的獨門功能——矩形區塊選取。
// 想在多行前面加上 //
const a = 1
const b = 2
const c = 3
const d = 4
操作步驟:
- 游標在第一行開頭
Ctrl-v— 進入 Block Visual3j— 往下選取 4 行I//— 輸入//Esc— 完成,4 行都加上了//
// const a = 1
// const b = 2
// const c = 3
// const d = 4
Block Visual 的其他用法:
Ctrl-v+ 選取 +d→ 刪除矩形區塊Ctrl-v+ 選取 +A+ 文字 +Esc→ 在每行尾部追加文字Ctrl-v+ 選取 +c+ 文字 +Esc→ 替換矩形區塊
Undo / Redo
| 指令 | 功能 |
|---|---|
u |
Undo(復原) |
Ctrl-r |
Redo(重做) |
Vim 的 undo 是基於樹狀結構(undo tree),而不是線性的。這意味著你不會因為 undo 後做了新操作就丟失歷史。Neovim 還有插件可以視覺化這棵 undo tree。
貼上(Paste)的技巧
| 指令 | 功能 |
|---|---|
p |
在游標後面貼上 |
P |
在游標前面貼上 |
gp |
貼上後游標移到貼上內容的末尾 |
gP |
同上但在游標前貼上 |
整行貼上 vs 行內貼上
p 的行為取決於被複製內容的類型:
- 如果是用
yy複製的(line-wise),p會貼在下一行 - 如果是用
yw複製的(character-wise),p會貼在游標後
替換指令
| 指令 | 功能 |
|---|---|
r{char} |
替換游標下的字元為 {char} |
R |
進入 Replace mode(持續覆蓋文字) |
:s/old/new/g |
替換當前行的所有 old 為 new |
:%s/old/new/g |
替換整個檔案的所有 old 為 new |
:%s/old/new/gc |
同上但每次替換前確認 |
替換指令的範圍
:s/foo/bar/g " 只替換當前行
:%s/foo/bar/g " 替換整個檔案
:5,10s/foo/bar/g " 替換第 5 到 10 行
:'<,'>s/foo/bar/g " 替換 Visual 選取的範圍
綜合練習
練習 1:Dot Command
- 打開一個有多行
console.log(...)的檔案 - 在第一行的
console前面加上//(用I// <Esc>) - 用
j.重複對下面每一行做同樣的操作
練習 2:Registers
"ayy複製第一行到 register a"byy複製第二行到 register b- 移到檔案其他位置
"ap和"bp分別貼上
練習 3:Macros
- 建立一個每行有一個單字的清單
- 錄製一個 macro,把每行包裝成
<li>word</li> - 用
@a或10@a對所有行執行
練習 4:Block Visual
- 找一段多行程式碼
- 用
Ctrl-v選取多行的開頭 - 用
I在每行前面加上相同的文字
小結
本篇學到的功能讓你可以處理批次操作和重複性工作:
| 功能 | 用途 | 適合場景 |
|---|---|---|
. |
重複上一步 | 簡單的重複修改 |
| Registers | 多重剪貼簿 | 同時保存多段內容 |
| Macros | 錄製操作序列 | 複雜的批次操作 |
| Block Visual | 矩形選取 | 多行同時編輯 |
到這裡,你已經掌握了 Vim 操作的所有核心基礎。這四篇的內容,即使你一直用 VSCode + Vim extension,也完全適用。
下一篇開始,我們要正式進入 Neovim 的世界——安裝 Neovim、寫你的第一個 init.lua 配置檔。
Neovim 系列文章導航
基礎篇
- 為什麼我想離開 VSCode?
- Vim 的語言——動詞、名詞、組合技
- 移動的藝術
- 編輯效率加倍(本篇)
設定篇 5. 安裝 Neovim 與 init.lua 6. Plugin 管理 lazy.nvim 7. 程式碼智能 LSP + 補全 8. 語法高亮與檔案導航
進階篇 9. Git 整合工作流 10. Terminal 與 Claude Code 整合 11. 打造快捷鍵系統 12. 從 VSCode 完全畢業