基本使用
我們通常只要在 Normal 模式下輸入 :
冒號就可以進入命令模式.
行號跳轉
通常我們使用 Vim 的命令中, 最常用且高效的命令就是跳轉行號, 譬如我現在要跳轉到 30 行去改點東西
:30
複製程式碼
我想多跳幾行
可以在一個行數範圍區間內跳轉, 譬如我要在 20 到 30 這個範圍跳轉, 只要這樣
:20, 30
複製程式碼
那假如我只想指定某一行的多少行呢?
:20; +10
複製程式碼
效果同上, 只是可以通過 +/-
來控制
刪除指定行程式碼
Vim 可以在 Normal 模式下使用 dd
來刪除整行程式碼, 我現在可以通過命令模式輸入 30 行然後按 dd
來刪除該行, 能不能再快點呢?
:30 d
複製程式碼
我想刪多點
需求又變了, 如果有多行程式碼需要刪除, 一般我的習慣是進入 視覺化模式選中要刪除的程式碼, 然後按下 d
, 其實我們還可以通過命令來刪除多行程式碼, 譬如我要刪除 20, 30 之間的程式碼就可以像這樣
:20, 30 d
複製程式碼
這樣就可以做到刪除指令行範圍內的程式碼, 一個字爽.
從我腳下開始刪
我現在游標在某一行, 但是我不說, 我只想從這一行開始刪到底
:., $ d
複製程式碼
我要刪清爽
現在我們要把當前檔案的所有的程式碼刪掉, 經過上面的例子, 你可能會猜, 這還不簡單
:1, $ d
複製程式碼
是的沒錯, 但是我們還可以這樣
:% d
複製程式碼
移動程式碼
突然我想把 20 到 30 行的程式碼移到 15 行的下面, 一般我們會在刪除的基礎上到指定行下面按 p
貼上, 當然通過命令也能滿足需求.
:20, 30 m 15
複製程式碼
不想移動想複製
繼續剛才的例子, 不過這趟我是想把 20 到 30 行的程式碼複製到 15 行, 只要這樣
:20, 30 t 15
複製程式碼
先到這裡吧, 還有一些 +/-
的操作, 但是我平常基本上沒怎麼用過.
搜尋
最簡單的搜尋
先從普通的搜尋開始, 這個用正則去匹配的, 只需要在命令模式下鍵入斜槓 /
來搜尋就可以了.
然後實戰一下, 假設我們平常寫前端樣式的時候, 有個地方想改一下, 但是隻記得關鍵字
.my-area {
.my-area__item {
font-size: 0.24rem;
/* ... */
}
.my-area__icon {
width: 0.5rem;
height: 0.5rem;
/* ... */
}
/* ... */
}
複製程式碼
只要像下面這樣, 我們就可以全域性將每一行的 my-area
替換成 some-area
:%s /my-area/some-area/
複製程式碼
如果我只是想在當前游標處替換, 我只要把 %
去掉就可以.
繼續舉例子, 假設有如下文字
.test {
.test__test__item {
/* ... */
}
}
複製程式碼
現在我們用上面的 命令來將 test
處理成 hi
, 你會發現原本 test__test__item
變成了 hi__test__item
, 如果我們是要將所有的 test
改成 hi
怎麼辦?
:%s /test/hi/g
複製程式碼
只要加一個 g
選項就可以解決問題了.
Vim 的正則支援
Vim 的正則有四種模式, 分別是 \v \m \M \V
, 一般預設的跟常用的 JavaScript(Perl 風格) 的正則稍微有點區別. 下面只講 \m
模式
元字元 | 說明 |
---|---|
. |
匹配任意字元 |
[xyz] |
匹配括號中的任意一個字元, [a-z] 可匹配小寫字母, [0-9] 可匹配數字 |
[^xyz] |
匹配除括號中字元以外的任意字元 |
\d |
匹配數字, 同 [0-9] |
\D |
匹配數字之外的字元, 同 [^0-9] |
\s |
匹配空白字元(含<TAB> ) |
\S |
匹配非空白字元 |
\t |
匹配<TAB> |
* |
匹配 0- 任意個字元 |
\+ |
匹配 1- 任意個字元 |
\? |
匹配 0-1 個字元 |
\{n,m} |
匹配 n-m 個字元 |
\{n} |
匹配 n 個字元 |
\{n,} |
匹配 n- 任意個字元 |
\{,m} |
匹配 0-m 個字元 |
^ |
匹配行首 |
$ |
匹配行尾 |
\< |
匹配單詞首 |
\> |
匹配單詞尾 |
\ |
可以通過 \ 轉義, 如 \\ 表示反斜槓本身 |
\> |
匹配單詞尾 |
\( 和 \) |
分組 |
\m
模式下跟常規正則的不同
Vim | Perl | 說明 |
---|---|---|
\+ |
+ |
匹配 1- 多個字元 |
\? |
? |
匹配 0-1 個字元 |
\{n,m} |
{n,m} |
匹配 1-m 個字元 |
\( 跟 \) |
( 跟 ) |
分組 |
正則變數
大概瞭解了一下 Vim 支援的正則之後, 我們可以玩點花頭, 先來匹配一下 aabbbaa
, 找規律就好了, 第一部分是兩個 a
, 就假設有多個 a\+
, 第二部分不是 a
同時假設有多個, 所以是 [^a]\+
, 第三部分跟第一部分一樣, 其實可以用正則的變數 \1
來表示第一部分匹配的規則, 但是第一部分沒有加 \(\)
, 這樣是沒法用變數的, 所以最後就是這樣
:/\(a\+\)[^a]\+\1
複製程式碼
接著把 aa
換成 bbb
, bbb
換成 aa
:s /\(a\+\)\([^a]\+\)\1/\2\1\2/
複製程式碼
其實還有一種函式用法
:s /\(a\+\)\([^a]\+\)\1/\=submatch(2) . submatch(1) . submatch(2)
複製程式碼
Vim 玩法還是蠻多的, 就很棒
跟命令模式指令結合
其實這個只要舉一反三就行, 不過還是備個忘, 譬如現在有一段程式碼, 我要把空行刪掉
#include <stdio.h>
int main(int argc, char **argv) {
printf("hello world");
return 0;
}
複製程式碼
而空行可能有 <TAB>
或 空格
:/^\s*$/d
複製程式碼
通過 d
指令這樣就可以把 int main
上面那行空行刪掉了.
再來個貪婪模式跟惰性模式, 現在有一串數字 123 1234 12345 123456
, 這樣替換就會換成 a a a a
:s /\d\{2, 6}/a/g
複製程式碼
而下面這樣替換就會變成 a3 aa aa5 aaa
:s /\d\{-2, 6}/a/g
複製程式碼
要想使用貪婪模式, 就不要用 \{-
, 這樣就是匹配優先的行為, 把 -
去掉就是忽略優先的行為, 也就是惰性模式.
其他
Vim 的正則還支援環視等操作, 但是我不會, 就這樣吧.
身為 95 後, 我為什麼要用 Vim. 從上面的例子中可以看出 Vim 編輯文字方面是高效的, 君不見基本上每個編輯器都提供了 Vim 模式或外掛, 我平常工作中用到的 CLion 的 IdeaVim 外掛非常好使, 能模擬大部分常用的功能, 配合 IntelliJ 平臺的程式碼提示, 開發效率特別高.