在本系列的第一篇博客,做一個說明,本系列是《Practical Vim》一書的筆記。這本書每一章講述一個相關的Vim的操作主題,在每一章中都會以若干個Tip的形式講述一下小的竅門或者說是實現某種任務的捷徑,並且在這個過程中講解很多Vim使用到的命令。作為一本成型的書來說,《Practical Vim》里面會有一些關於背景的描述,也會有一整套比較嚴謹的對於Vim輸入命令以及顯示結果的展示規則。我這里僅僅將每一個Tip涉及的問題,以及通過哪些命令來解決重點提取並且翻譯出來,主要是總結備忘,另一方面也是分享。但是考慮到每一個Tip的標題都無法直譯,因此我就不翻譯了。最后,正所謂條條大路通羅馬,每一個Tip中列出的命令都不見得是唯一方案,更不一定是最優方案(本書作者也是這么認為的)。
Tip1 Meet The Dot Command(使用.命令)
.命令可以重復上一次修改。我們先看看示例文本:
Line one Line two Line three Line four
我們可以使用x命令刪除光標所在的字符。x刪除一個字符就是一次更改。緊接着使用.命令就會重復上一次更改,也就是再次刪除當前光標所在的一個字符。我們看一下書中給的演示(為了方便,這種演示我都截圖):
此外,使用dd可以刪除當前光標所在的行。.命令也可以重復這個操作。示例如下:
我們還可以使用>G來給當前行到文件末尾的所有行增加縮進,同樣也可以重復上面的命令(個人感覺這個比較有用):
Tip2 Don’t Repeat Yourself
有這樣一段js代碼如下:
var foo = 1 var bar = 'a' var foobar = foo + bar
現在需要在代碼的每一行的末尾都添加一個分號;。當然,我們可以將光標移到每一行的末尾(使用$),進入插入模式(a),然后輸入;。但是問題是,這樣的話過於麻煩。我們可以在第一行進行上述操作,然后每到下一行,使用.命令重復一下上次修改即可。示例如下:
在這個例子中,使用了組合命令A代替了命令序列$a。順便說一下幾個常用的組合命令:
Tip3 Take One Step Back, Then Three Forward(退一進三)
有這樣一行js代碼:
var foo = "method("+argument1+","+argument2+")";
這段代碼做了幾次字符串拼接操作。但是看起來很不爽,一般來說,會在+前后各加上一個空格。我們現在就需要完成這個任務。我們先直接展示操作過程,再分別講解:
首先通過f+命令找到(從左到右找)當前行的第一個+字符,s空格+空格,將光標所在的這個字符修改為空格+空格。接下來找到下一個+字符,再使用.重復上一次修改,以此類推。我們在進行第二次查找+字符時,沒有繼續使用fx,而是使用了;。這是因為;可以重復上一次f命令所執行的查找操作。也就是說,這里的;實際上是重復了上一次fx操作。另外需要說明的是,f{char}可以在當前行從左往右查找{}內包含的字符,並且光標直接定位到找到的第一個字符。上面這個方案肯定不會是最好的方案,個人認為作者在這里講這種方案純粹是為了配合這一樣Repeat的主題。
Tip4 Act, Repeat, Reverse
上面提到的.命令主要是重復上一次修改,而;卻可以重復上一次查找以及移動。當我們面對重復性的工作時,比較好的一個策略是將移動和修改都變得可重復。這個Tip主要講的就是如何重復各種上一次操作。
我們逐一解釋:
當我們進行了一些編輯操作后,回到一般模式,使用.可以重復上一次修改,使用u可以撤銷(相當於Windows下很多文本編輯器的ctrl+z)
f{char}或者t{char}從左往右找字符。那么;重復上一次查找與光標移動而,則可以執行一次反向查找與移動操作
F{char}或者T{char}從右往左找字符。那么;重復上一次查找與光標移動而,則可以執行一次反向查找與移動操作
/pattern<CR>。這個命令可以使用pattern這個模式來查找文本中匹配的串,並且跳轉過去。使用n可以重復上一次查找(正向,從上往下找),N則可以進行一次對應的反向查找(從下往上)
?pattern<CR>。與上面相反。
:s/target/replacement這個命令在文本中找到target模式所匹配的文本,以replacement對應的字符串替換,可以使用&來重復一次,使用u撤銷上次替換
qx{changes}q這個比較復雜。q實際上本身是一個記錄命令,這里的x相當於是一個變量名,可以換成y,z等等。當輸入qx之后,Vim的最下方會出現“記錄中”,表示開始記錄操作。緊接着你再進行的一系列鍵入操作,都會被記錄在x這個變量所對應的寄存器里面。直到再按下q鍵,這一次記錄操作算是完成。也就是說{changes}所對應的一系列編輯操作都被保存進了x對應的寄存器。接下來,你可以使用@x來重復x對應寄存器中保存的一系列操作。說了這么一堆,不是很好理解,這里我補充一個例子。
Vim原始屏幕如下:
我們先輸入qy,緊接着Vim屏幕變化如下:
接着我輸入a(在光標后面進入插入模式),Vim屏幕變化如下:
這說明我們進入了插入模式,並且這個操作被記錄了,接下來我們輸入真正要被寫進去的字符,比如xxxxxx再看Vim屏幕的變化:
我們看到,我們輸入的xxxxxx已經在字符e后面添加進去了,現在我們輸入<ESC>來退出插入模式。我們再看Vim屏幕:
我們看到已經退出插入模式了,我們再按q鍵停止記錄,再看看Vim屏幕:
已經停止記錄了。到此為止,我們前面說的qy{changes}q命令算是輸入完了。接下來是使用的問題。我們輸入j$先跳轉到下一行末尾,然后輸入@y我們看看效果:
可以看到,我們寄存在y對應寄存器中的一系列編輯操作被重復執行了一次。以上就是補充的這個命令的一個解釋。
Tip5 Find and Replace by Hand(手動查找和替換)
現在有這樣一段話:
...We're waiting for content before the site can go live... ...If you are content with this, let's go ahead with it... ...We'll launch as soon as we have the content...
現在我們需要用copy來替換content。Vim提供了:substitute命令來進行替換操作,這個命令還有選項能提示我們對於找到的每一個單詞是否替換。但是在這里並不介紹這個單詞。我們先看一下作者在這里使用什么樣的方案:
首先通過/content找到第一個content單詞,使用*命令。*命令能夠查找最近的一個光標所在的單詞,也就是content,然后使用cwcopy命令修改這個單詞為copy,然后使用n執行上一次查找操作,使用.重復上一次修改。依次類推。
Tip6 Meet the Dot Formula
這個Tip里沒有介紹新的命令,只是總結了一下使用.命令的通用情況。這里不再贅述。