這是 Neovim 從零開始系列的第二篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。
為什麼 Vim 像一門語言?
上一篇我們提到 Vim 的操作就像一門語言。這不是比喻——它真的是一套設計精良的文法系統。
大多數編輯器的快捷鍵是「一個組合做一件事」:Ctrl+D 選取下一個相同的詞、Ctrl+Shift+K 刪除整行。每個操作都是獨立的,你需要一個一個背。
Vim 不一樣。它的操作遵循一個簡單的文法:
Operator + Motion = Action
(動詞) (名詞) (動作)
學會 5 個動詞和 10 個名詞,你就有了 50 種操作。這就是 Vim 的 乘法效應。
動詞(Operators)
Operator 定義了你想「做什麼」。以下是最常用的動詞:
| Operator | 功能 | 記憶法 |
|---|---|---|
d |
刪除(delete) | delete |
c |
修改(change)——刪除並進入 Insert mode | change |
y |
複製(yank) | yank(Vim 用 yank 而非 copy) |
v |
選取(visual select) | visual |
> |
向右縮排 | 箭頭方向 |
< |
向左縮排 | 箭頭方向 |
= |
自動排版 | 等號=對齊 |
gu |
轉小寫 | go uppercase 的反向 |
gU |
轉大寫 | go Uppercase |
其中 d、c、y 是你每天都會用到的三個核心動詞。
d vs c 的差別
這兩個很容易搞混,但它們的差別很關鍵:
d(delete):刪除文字後留在 Normal modec(change):刪除文字後進入 Insert mode,讓你直接打新的內容
原始文字:const name = "hello"
按 ci" → const name = "|" (游標在引號內,Insert mode)
按 di" → const name = "" (引號內被清空,Normal mode)
簡單記法:d 是「我要移除」,c 是「我要替換成別的」。
名詞:Motions
Motion 定義了「作用範圍到哪裡」。它們描述從游標目前位置到目標位置的移動。
字元級移動
| Motion | 功能 |
|---|---|
h |
左一個字元 |
l |
右一個字元 |
j |
下一行 |
k |
上一行 |
單字級移動
| Motion | 功能 | 說明 |
|---|---|---|
w |
下一個單字開頭 | word |
b |
上一個單字開頭 | back |
e |
目前單字的結尾 | end |
W |
下一個大單字開頭 | 以空白分隔 |
B |
上一個大單字開頭 | 以空白分隔 |
E |
目前大單字的結尾 | 以空白分隔 |
小寫 w/b/e 以標點符號為分界(hello-world 是兩個 word),大寫 W/B/E 只以空白為分界(hello-world 是一個 WORD)。
行級移動
| Motion | 功能 |
|---|---|
0 |
移到行首(第 0 個字元) |
^ |
移到行首第一個非空白字元 |
$ |
移到行尾 |
搜尋移動
| Motion | 功能 |
|---|---|
f{char} |
移到本行下一個 {char} |
t{char} |
移到本行下一個 {char} 的前一格 |
F{char} |
反向搜尋 {char} |
T{char} |
反向移到 {char} 的後一格 |
名詞:Text Objects
Text Objects 是 Vim 最精華的設計之一。它們描述的不是「從這裡移動到那裡」,而是「一個完整的文字單位」。
語法格式
i + 符號 = inner(內部,不含邊界)
a + 符號 = a/around(包含邊界)
常用 Text Objects
| Text Object | 範圍 | 範例文字 | i 選取 |
a 選取 |
|---|---|---|---|---|
w |
單字 | hello world |
hello |
hello |
" |
雙引號 | "hello" |
hello |
"hello" |
' |
單引號 | 'hello' |
hello |
'hello' |
` |
反引號 | `hello` |
hello |
`hello` |
( 或 ) |
小括號 | (a, b) |
a, b |
(a, b) |
[ 或 ] |
中括號 | [1, 2] |
1, 2 |
[1, 2] |
{ 或 } |
大括號 | { x: 1 } |
x: 1 |
{ x: 1 } |
t |
HTML tag | <p>hi</p> |
hi |
<p>hi</p> |
p |
段落 | 一整個段落 | 段落本身 | 段落 + 前後空行 |
s |
句子 | 一個句子 | 句子本身 | 句子 + 後方空白 |
inner vs around 的實際差異
理解 i 和 a 的差別非常重要:
// 游標在 hello 上
const greeting = "hello world"
di" → const greeting = "" // 刪除引號「內」的文字
da" → const greeting = // 連引號一起刪除
ci" → const greeting = "|" // 清空引號內容並開始輸入
經驗法則:
- 想要替換內容時用
i(保留容器) - 想要整個移除時用
a(連容器一起刪)
組合起來
現在我們把動詞和名詞組合在一起,你會發現 Vim 的威力:
經典組合表
| 組合 | 意思 | 場景 |
|---|---|---|
dw |
刪除到下一個單字 | 刪除一個詞 |
d$ 或 D |
刪除到行尾 | 清除行尾多餘內容 |
dd |
刪除整行 | operator 重複=作用整行 |
ciw |
修改整個單字 | 重新命名變數 |
ci" |
修改引號內容 | 修改字串 |
ci( |
修改括號內容 | 修改函數參數 |
ya{ |
複製整個大括號區塊(含括號) | 複製程式碼區塊 |
yiw |
複製整個單字 | 複製變數名稱 |
dit |
刪除 HTML tag 內容 | 清空 tag |
>i{ |
縮排大括號內的程式碼 | 調整縮排 |
vap |
選取整個段落 | 選取後進一步操作 |
數字修飾
你還可以加入數字來重複操作:
[數字] + 動詞 + 名詞
| 組合 | 意思 |
|---|---|
3dw |
刪除 3 個單字 |
2dd |
刪除 2 行 |
5j |
往下移動 5 行 |
3yy |
複製 3 行 |
實戰範例
讓我們用實際的程式碼來練習:
範例 1:修改函數參數
// 游標在 name 上
function greet(name, age) {
- 要把
name改成userName:按ciw,輸入userName - 要刪除所有參數:按
di( - 要複製所有參數:按
yi(
範例 2:處理字串
# 游標在字串內任意位置
message = "Hello, World!"
- 改字串內容:
ci"→ 輸入新內容 - 刪除整個字串(含引號):
da" - 複製字串內容:
yi"
範例 3:操作程式碼區塊
// 游標在大括號內任意位置
if (condition) {
doSomething()
doAnother()
}
- 刪除括號內所有程式碼:
di{ - 縮排括號內程式碼:
>i{ - 選取括號內程式碼:
vi{
特殊的 Operator 技巧
重複 Operator = 作用整行
把 operator 按兩次,就是對整行操作:
| 組合 | 意思 |
|---|---|
dd |
刪除整行 |
cc |
修改整行 |
yy |
複製整行 |
>> |
縮排整行 |
== |
自動排版整行 |
大寫 = 到行尾
部分 operator 的大寫版本等同於「到行尾」:
| 組合 | 等同於 | 意思 |
|---|---|---|
D |
d$ |
刪除到行尾 |
C |
c$ |
修改到行尾 |
Y |
yy |
複製整行(注意:不是 y$) |
練習建議
第一天:核心三動詞
只專注 d、c、y 加上 w、b、$ 的組合:
dw cw yw
db cb yb
d$ c$ y$
dd cc yy
第二天:加入 Text Objects
開始使用 i 和 a 系列:
diw ciw yiw
di" ci" yi"
di( ci( yi(
di{ ci{ yi{
第三天:搜尋組合
加入 f、t 搭配操作:
df, 刪除到逗號(含逗號)
dt) 刪除到右括號前
ct" 修改到引號前
持續練習
每天刻意用一兩個新組合。不需要一次全背,自然就會記住常用的。
小結
Vim 的組合系統是它最核心的設計,也是它和其他編輯器最大的差異。理解了這個「語言」,後面的所有功能都是在這個基礎上延伸。
本篇重點:
Operator + Motion/TextObject = Action- 核心動詞:
d(刪除)、c(修改)、y(複製) i= inner(不含邊界),a= around(含邊界)- 數字可以重複操作
- Operator 重複兩次 = 作用於整行
下一篇,我們會深入學習所有重要的移動指令——讓你在程式碼中飛速穿梭。
Neovim 系列文章導航
基礎篇
- 為什麼我想離開 VSCode?
- Vim 的語言——動詞、名詞、組合技(本篇)
- 移動的藝術
- 編輯效率加倍
設定篇 5. 安裝 Neovim 與 init.lua 6. Plugin 管理 lazy.nvim 7. 程式碼智能 LSP + 補全 8. 語法高亮與檔案導航
進階篇 9. Git 整合工作流 10. Terminal 與 Claude Code 整合 11. 打造快捷鍵系統 12. 從 VSCode 完全畢業