學前須知
vim 是什么?
- vim 是人類目前已知的最好 [1] 的 文本編輯器
- vim 是價值60億美元的 文本編輯器
- vim 會成為你最后一個 文本編輯器,因為它是最好的
vim 的宗旨:
更好,
更強,
更快。
學習 vim 的建議步驟:
- 活下來
- 感到舒適
- 感到自己更好、更強、并且更快
- 成為 vim 超人
敬告學習者:
- 學習 vim 的過程是很痛苦的,但用起來棒極了
- 你先要學習最基本的生存技能,然后一點點地去探索奇技淫巧
- 就像學習樂器一樣,你學習的最開始階段會很痛苦
- 別指望在3天之內, ^in 3 days 把 vim 玩的比其它編輯器更好
開始學習
第一,活下來
一個標準的編輯器應該具備這樣的特點:在鍵盤上打點什么,然后屏幕上就出現什么。但是現在的 vim 不行,它還處于普通(Normal)模式。你需要按下字母 i
來進入插入(Insert)模式。
現在你應該感覺好多了,折騰半天,總算用上了 記事本 (還tm是沒有保存、編輯的閹割版)。既然你這么想,請按下 ESC
鍵,讓我們回到普通模式。
然后,你需要知道這幾個東西:
-
i
: 進入插入模式;ESC
返回普通模式 -
x
: 刪除當前(光標閃爍處)字符 -
:wq
:保存并退出(:w
保存,:q
退出) -
dd
: 剪切當前行 -
p
: 粘貼
這就是 vim 的最基本內容,不過你還是應該知道:
-
hjkl
: 移動光標,等同于插入模式下的←↓↑→
[^j down] -
:help <command>
: <command> 的幫助文檔,比如:help i
(:help
收獲完整幫助文檔)
[^j down]: 為了記住這鬼東西,你要告訴自己 j
和 ↓
有點像
現在,你已經知道了最基本的生存技能,大概能順利活著了。
什么時候你掌握好了(把這幾個命令用得很自然,就像吃喝拉撒一般),就可以進入第二階段了。(估計得費上幾天功夫)
對了,得說幾句幫助你理解普通模式:
你一定知道 Ctrl-c
是 復制
,這跟字母 c
本身幾乎毫無關系(你非得說 c for copy
我也沒辦法)。這就好像一用了 Ctrl
,就改變這整個世界的原本意思。 vim 的普通模式,就相當于一直按著 Ctrl
(或其它某些 非打印字符
鍵)進行各種處理。
最后還有點事兒:
-
<xxx>
: 應依情景被替換的內容(內容類別由xxx
指定),比如<command>
就意味著此處應輸入某命令,<text>
則代表文本 - 所有以
:
開頭的命令,結尾都默認要按下Enter
鍵,比如:q
其實意味著你要按下:
、q
和Enter
3個鍵 - 命令都要用 西文 輸入,要
:
不要:
- 非
:
打頭的命令,你是看不見(它們的顯示)的
第二,感到舒適
既然你活下來了,就有必要提高點生活質量,而非像一條狗 [3] 那樣無奈、痛苦。
這里是更多的技巧 ^more skills ,值得記下來并進行嘗試 [4] :
1、進入插入模式的替換方案:
-
a
: 在光標后的位置開始插入 -
o
: 在光標后的一行開始插入 -
O
: 在光標前的一行開始插入 -
cw
: 把光標閃爍處到單詞結尾處的東西刪掉,然后插入
為進一步說明,假設現在處于普通模式,屏幕上有文本 word
,光標在 r
處閃爍,想輸入 <text> 。[^new line]
為得到的效果 | 應選用的插入模式進入命令 |
---|---|
wo<text>rd |
i |
wor<text>d |
a |
word\n<text> |
o |
<text>\nword |
O |
wo<text> |
cw |
[^new line]: 你應該知道 \n
代表換行(new line)
2、基本移動
-
0
: 到達當前行的開頭(相當于Home
鍵) -
^
: 到達當前行開頭第一個非空白類字符 -
$
: 到達當前行的結尾(相當于End
) -
g_
: 到達當前行結尾最后一個非空白類字符 -
/<pattern>
: 查找<pattern>
,比如/word
就是在查找word
這個單詞
3、復制粘貼
-
P
: 在光標閃爍處之前粘貼(p
則是在之后) -
yy
: 復制當前行(相當于ddp
或ddP
—— 剪切并粘貼)
4、撤銷和重做
-
u
: 撤銷 -
Ctrl-r
: 重做
5、打開、保存、退出和文檔切換
-
:e <path/to/file>
: 打開某路徑下的文檔 -
:w
: 保存 -
:saveas <path/to/file>
: 把當前文本保存到某路徑下 -
:x
/ZZ
/:wq
: 保存并退出當前文檔 -
:q!
: 退出并不保存當前文檔(:qa!
退出所有打開的文檔并不保存) -
:bn
/:bp
:切換到下一個/上一個打開的文檔
第三,感到自己更好、更強、并且更快
祝賀你走到了這里!現在要開始一些有趣的東西了。 [5]
首先,更好
來看看 vim 怎么體現機器的自我修養吧。 [6]
-
.
: 重復上一條指令 -
N<command>
: 重復做N次<command>
來看一些例子:
-
2dd
: 剪切當前2行(光標閃爍行及下一行) -
3p
: 粘貼3次剪切板的文本
假設現在屏幕上顯示:
line1
line2
而光標在 line1
那行,那么在普通模式下輸入 2dd3p
(注意你看不見這些非 :
開頭的命令,別慌),文本就會變成:
line1
line2
line1
line2
line1
line2
100iword <ESC>
: 效果如下,千萬別忘了最后按下ESC
鍵,也別忘了那個空格
word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word.
:重復上面的命令,這里的話,就是再寫100個word
3.
: 再寫3個word
(而非300個,多聰明的 vim 命令)
其次,更強
vim 一大優點就是,它能讓你更有效地穿梭于文本之間。別跳過這節。
行間移動:
-
NG
: 到第N行 -
gg
: 到文本開頭(相當于1G
) -
G
: 到文本結尾行
詞間移動:
-
w
: 到下一個單詞開頭 -
e
: 到當前單詞結尾 -
W
: 跳過最近的空白區,到下一個非空白字符 -
E
: 到最近空白區前的那個非空白字符
假設現在處于普通模式,屏幕上有文本:
The quick-brown* fox jumps over the lazy dog.
而光標在 u
上。那么:
輸入的命令 | 光標會到達的位置 |
---|---|
w |
- |
e |
k |
W |
f |
E |
* |
碼農的“凌波微波”
-
%
: 到達開括號處,適用于大中小三種括號
比如普通模式下, 有文本printf("foo");
,光標位于"foo")
的任意位置,按下%
, 都可以立馬到達(
處。 -
*
/#
: 到當前單詞出現的下一個/上一個位置
如果你不覺得 %
、 *
和 #
特別有用,只能說你不是碼農,或者不是資深碼農。
最后,更快
還記得上一階段提到的基本移動嗎?學習它的原因是,你會寫大量的 <start position><command><end position>
樣式的指令。
比如 0y$
的作用是,從當前行的第一個字符,復制到這行的結尾; ye
, 從光標處復制到這個單詞結束; y2/word
復制了光標所在處和 word
第2次出現中間的文本。
能用于復制命令 y
的,自然也能用于剪切命令 d
,虛擬選擇命令 v
,大寫命令 gU
, 小寫命令 gu
,……這需要你去不斷探索。
第四,成為 vim 超人
你現在應該能很爽地用 vim 了。不過接下來,才是 vim 真正的殺手锏。
1、 行內移動
你只需要小手一按,就能:
-
0
: 到第0列去 -
^
: 到第1個字符去 -
$
: 到-1列去 -
g_
: 到第-1個字符去 -
f<char>
: 到光標后尋找某字符 -
,
/;
: 到該字符出現的上一處/下一處去 -
Nf<char>
: 到光標后某字符出現的第N處去 -
t<char>
: 到光標后某字符前面的那個字符去 -
F
,T
:和f
跟t
差不多,不過都是向找光標前找
假設在普通模式下,屏幕上有文本 x = fib(6 + 7); #this is a comment.
,光標在 b
處,那么:
命令 | 光標會到的位置 |
---|---|
0 |
x 前的那個
|
^ |
x |
$ |
. 后 再之后的那個
|
g_ |
. |
fi |
this 的那個 i
|
2fi |
is 的那個 i
|
ti |
h |
Fi |
fib 的那個 i
|
Ti |
b |
結合這節和之前的東西,你會發現 dt<char>
能把從光標處到某字符之前的東西都剪切走。
tbc……