vim 是 vi 編輯器的升級(jí)版,是 Linux 世界最為著名的一款文本編輯器,國(guó)外有個(gè)叫 vimgolf 的網(wǎng)站,將 vim 操作比作打高爾夫球,里面設(shè)計(jì)了很多挑戰(zhàn),你可以在那里測(cè)試、提高自己的 vim 水平。
那么,如何衡量你的vim水平?
最簡(jiǎn)單粗暴的方式就是計(jì)算擊鍵數(shù),修改同樣一段文本,擊鍵次數(shù)越少,水平越高,一鍵對(duì)應(yīng)一分,即分?jǐn)?shù)越少,水平越高。
下面這個(gè)挑戰(zhàn)叫:逗號(hào)問(wèn)題
初始文本
,0,1,2,3,4,5,6,7,89
,1,2,3,4,5,6,7,8,90
,2,3,4,5,6,7,8,9,01
,3,4,5,6,7,8,9,0,12
,4,5,6,7,8,9,0,1,23
56,7,8,9,0,1,2,3,4,
67,8,9,0,1,2,3,4,5,
78,9,0,1,2,3,4,5,6,
89,0,1,2,3,4,5,6,7,
90,1,2,3,4,5,6,7,8,
目標(biāo)文本
0,1,2,3,4,5,6,7,8,9
1,2,3,4,5,6,7,8,9,0
2,3,4,5,6,7,8,9,0,1
3,4,5,6,7,8,9,0,1,2
4,5,6,7,8,9,0,1,2,3
5,6,7,8,9,0,1,2,3,4
6,7,8,9,0,1,2,3,4,5
7,8,9,0,1,2,3,4,5,6
8,9,0,1,2,3,4,5,6,7
9,0,1,2,3,4,5,6,7,8
觀察初始文本與目標(biāo)文本差異可知,作者的目標(biāo)是,除了第一列前和最后一列后無(wú)逗號(hào),其余每一位數(shù)字均由,隔開(kāi),原始文本需要改的地方是:
- 前五行
- 第一列逗號(hào)刪掉
- 最后一列兩位數(shù)字用
,分隔開(kāi)
- 后五行
- 第一列兩位數(shù)字用
,分隔開(kāi) - 最后一列逗號(hào)刪掉
- 第一列兩位數(shù)字用
知道了不同,現(xiàn)在就讓我們瞄準(zhǔn)目標(biāo),開(kāi)始打vim高爾夫吧!ready go!
第一局:29分
第一局,我的得分是29分,也就是擊了29鍵。既然是批量操作,我首先想到的是命令模式,該模式也被稱(chēng)為冒號(hào)模式,因?yàn)橐悦疤?hào)開(kāi)頭。

:1,5norm x$P<CR>
- 首先輸入
:進(jìn)入命令模式,要操作前五行,需輸入1,5,這里1也可以換成.,因?yàn)檫M(jìn)入文件時(shí),光標(biāo)在第一行,命令模式中.代表光標(biāo)所在行 -
norm是normal的縮寫(xiě)(可以省兩鍵),即普通模式,兩個(gè)模式各有千秋,普通模式擅長(zhǎng)近程攻擊,操作范圍窄;命令模式適合遠(yuǎn)程攻擊,操作范圍廣,二者優(yōu)勢(shì)互補(bǔ),珠聯(lián)璧合。 -
norm后空一格以輸入普通模式命令,刪(x)第一個(gè)字符(,),跳到行位($在普通模式中是指作用到行尾),在最后一個(gè)字符前粘貼(P)之前刪掉的字符(,),按<CR>(Enter)鍵執(zhí)行操作 - 至此,首輪操作完畢,光標(biāo)跳到第5行倒數(shù)最后一個(gè)逗號(hào)上

:6,$norm $x0p<CR>ZZ
- 同樣是在
命令模式中調(diào)用普通模式,操作范圍是第6行到最后一行,$在命令模式中代表最后一行。 -
$x代表挑戰(zhàn)到行尾,然后刪掉最后一個(gè)字符(,),因?yàn)椴僮鞣秶亲詈笪逍?,所以最后一列的逗?hào)都會(huì)被刪掉 -
0代表絕對(duì)行首,也可以叫它硬行首,軟行首是^,光標(biāo)跳轉(zhuǎn)到行首后,執(zhí)行p,就會(huì)粘貼剛才刪掉的逗號(hào),刪掉的字符會(huì)保存在寄存器中,大寫(xiě)的p在光標(biāo)前粘貼寄存器中的字符,小寫(xiě)的p在光標(biāo)后粘貼寄存器中的字符。按<CR>(Enter)鍵執(zhí)行操作 - 至此全部修改完成,但是別忘了,我們還要保存退出的,這里用的是
ZZ,還可以用:wq和:x,不過(guò)命令模式執(zhí)行需要按<CR>(Enter)鍵,這樣一來(lái),:wq需要按四個(gè)鍵,:x需要按三個(gè)鍵,而ZZ只需要按兩個(gè)鍵便可
第二局:26分
使用命令模式雖然簡(jiǎn)單易懂,但是局限也很明顯,那就是無(wú)法再降低擊鍵數(shù)了,這次我們換一個(gè)模式:可視模式,所謂可視模式其實(shí)還是在普通模式中,只不過(guò)可以像鼠標(biāo)一樣選中字符、行、塊。

<C-V>4jx$<C-V>4jI,<Esc>6G<C-V>4jA,<Esc>$<C-V>4jdZZ
-
<C-V>(ctrl+v)進(jìn)入塊選擇模式,我們想操作前五行的第一列,就向下選中4行(執(zhí)行4j),刪除(x)第一列逗號(hào); -
$<C-V>4jI,<Esc>,意思是跳到行尾,進(jìn)入可視化模式,選中前五行最后一列,在選中列開(kāi)頭插入逗號(hào),然后按ESC退出插入模式 -
6G<C-V>4jA,<Esc>,意思是跳到第6行(普通模式中跳轉(zhuǎn)到第n行,命令是nG),進(jìn)入可視化模式,選中后五行第一列,在選中列末尾插入逗號(hào),然后按ESC退出插入模式 -
$<C-V>4jdZZ,意思是跳到行尾,進(jìn)入可視化模式,選中后五行最后一列,然后刪除該列,最后按ZZ保存退出
第三局:19分
第二次嘗試雖然比第一次降低3次按鍵,但是還有很大的優(yōu)化空間,我們先把他放在一邊,這次我們換一種方式,利用 vim 的錄制宏來(lái)操作。

qa<C-V>4jx6G$q@a0p{$PZZ
-
qa輸完就代表開(kāi)始錄制了,接下來(lái)的操作<C-V>4jx6G$,先是刪除前五行第一列第一個(gè)字符, - 然后
6G跳轉(zhuǎn)到第6行,$跳轉(zhuǎn)到該行尾部,q@a代表結(jié)束錄制,然后重復(fù)一次剛才的操作,后五行最后一個(gè)字符便被刪掉了 -
0p回到第六行行首,并在第一列后粘貼剛才刪掉的, -
{跳轉(zhuǎn)到段首,這里便是第一行第一個(gè)字符,$P跳到行尾并在前一個(gè)字符前粘貼寄存器里內(nèi)容,即, -
ZZ保存退出
第四局:14分

<C-V>Mx$P}<C-V>4kx0pZZ
還記得第二局吧,現(xiàn)在我們來(lái)優(yōu)化下
-
<C-V>Mx進(jìn)入可視化模式,選中前五行第一個(gè)字符并刪掉,M代表屏幕中間行 -
P}<C-V>4kx,P這里直接粘貼,,不用像之前那樣還選中再粘貼,}跳到段尾,進(jìn)入可視化模式,4k像上移動(dòng)4行,即選中最后五行的最后一列,然后刪掉(x) -
0pZZ跳到行首,直接p粘貼寄存器里的,,然后保存退出,一共才用14鍵
這是我能想出來(lái)的最少鍵數(shù)了,不過(guò)還有更變態(tài)的
終極操作:12分

qaxpeq98@aZZ
只有你的擊鍵數(shù)足夠少才能看到比你更少的,我玩到第四局才看到世界排名第一的操作,他是用錄制宏的方式解決的
-
qa開(kāi)始錄制宏,xp刪掉第一個(gè)字符(,),并將其粘貼到后面,e跳到詞尾,即跳到剛才粘貼的那個(gè)逗號(hào)上,然后停止錄制,重復(fù)98次上述操作 - 有個(gè)更變態(tài)的,其實(shí)只需要重復(fù)94次就可以了