《Vim實用技巧(第2版)》——2.6 雙劍合璧,天下無敵
本節書摘來自異步社區《Vim實用技巧(第2版)》一書中的第2章,第2.6節,作者:【英】Drew Neil(尼爾)著,更多章節內容可以訪問雲棲社區“異步社區”公眾號查看
2.6 雙劍合璧,天下無敵
Vim的強大很大程度上源自操作符與動作命令相結合。在本節,我們將看到它是如何工作的,並考慮其寓義。
操作符 + 動作命令 = 操作
d{motion} 命令可以對一個字符(dl)、一個完整單詞(daw)或一整個段落(dap)進行操作,它作用的範圍由動作命令決定。c{motion}、y{motion} 以及其他一些命令也類似,它們被統稱為操作符(operator)。可以用 :h operator 來查閱完整的列表,表2-1總結了一些比較常見的操作符。
g~、gu 和 gU 命令要用兩次按鍵來調用,我們可以把上述命令中的 g 當作一個前綴字符,用以改變其後麵的按鍵行為,進一步的討論請參見本技巧最後的“結識操作符待決模式”部分。
操作符與動作命令的結合形成了一種語法。這種語法的第一條規則很簡單,即一個操作由一個操作符,後麵跟一個動作命令組成。學習新的動作命令及操作符,就像是在學習Vim的詞匯一樣。如果掌握了這一簡單的語法規則,在詞匯量增長時,就能表達更多的想法。
假如我們已經知道如何用 daw 刪除一個單詞,然後又學到 gU 命令(參見 :h gU )。它也是個操作符,所以可以用 gUaw 把當前單詞轉換成大寫形式。如果我們的詞匯進一步擴充,學會了作用於段落的 ap 動作命令,就會發現我們可以進行兩個新的操作:用 dap 刪除整個段落,或者用 gUap 把整段文字轉換為大寫。
Vim的語法隻有一條額外規則,即當一個操作符命令被連續調用兩次時,它會作用於當前行。所以 dd 刪除當前行,而 >> 縮進當前行。gU 命令是一種特殊情況,我們既可以用 gUgU ,也可以用簡化版的 gUU 來使它作用於當前行。
表2-1 Vim的操作符命令
擴展命令組合的威力
使用Vim缺省的操作符和動作命令,我們能夠執行的操作的數目是巨大的,然而,我們還可以通過自定義動作命令及操作符來進一步擴充其數目。讓我們想想這寓示著什麼。
自定義操作符與已有動作命令協同工作
隨同Vim發布的標準操作符集合相對比較少,但可以定義新的操作符。Tim Pope的commentary.vim插件提供了一個很好的例子[2],此插件為Vim支持的編程語言增添了注釋及取消注釋的命令。
注釋命令以 gc{motion} 觸發,它會切換指定行的注釋狀態。它是一個操作符命令,因此可以把它和所有動作命令結合在一起。gcap 將切換當前段落的注釋狀態, gcG 會把從當前行到文件結尾間的所有內容注釋掉,gcc 則注釋當前行。
如果你對如何創建自定義操作符感到好奇,可以先閱讀一下文檔 : h :map-operator 。
自定義動作命令與已有操作符協同工作
Vim缺省的動作命令集已經相當全麵了,但是我們還是可以定義新的動作命令及文本對象來進一步增強它。
Kana Natsuno的textobj-entire插件是一個很好的例子[3],它為Vim增加了兩種新的文本對象 ie 和 ae,它們作用於整個文件。
如果想用 = 命令自動縮進整個文件,可以執行 gg=G (就是說,先用 gg 跳到文件開頭,然後用 =G 自動縮進從光標位置到文件結尾的所有內容)。但是如果安裝了textobj-entire插件的話,簡單地執行 =ae 就可以了。運行這條命令時光標在哪兒並不重要,因為它總是作用於整個文件。
注意:
如果同時安裝了commentary和textobj-entire插件,就可以把它們放在一起使用。例如,執行 gcae 會切換整個文件的注釋狀態。
如果你對如何創建自定義動作命令感到好奇,可以由閱讀 :h omap-info 開始。
結識操作符待決模式
普通、插入及可視模式很容易辨識,但是Vim還有另外一些很容易被忽視的模式,操作符待決模式(operator-pending mode)就是一個例子。每天我們無數次地使用它,但通常它隻持續不到一秒時間。舉個例子,在執行命令 dw 時,就會激活該模式。這一模式隻在按 d 及 w 鍵之間的短暫時間間隔內存在,一眨眼工夫就不見了。
如果把Vim想象成有限狀態機,那麼操作符待決模式就是一個隻接受動作命令的狀態。這個狀態在調用操作符時被激活,然後什麼也不做,直到我們提供了一個動作命令,完成整個操作。當操作符待決模式被激活時,我們可以像平常一樣按 <Esc>
中止該操作,返回到普通模式。
很多命令都由兩個或更多的按鍵來調用(查閱 :h g 、:h z
、:h ctrl-w
,或者 :h [
,可以看到一些例子),但在多數情況下,頭一個按鍵隻是第二個按鍵的前綴。這些命令不會激活操作符待決模式,相反,可以把它們當成命名空間(namespace),用來擴充可用命令的數目。隻有操作符才會激活操作符待決模式。
你也許想知道,為什麼要有一個完整的模式,專門用於操作符和動作命令之間的短暫瞬間,而命名空間命令則僅僅是普通模式的一個擴充?好問題!這是因為我們能夠創建自定義映射項來激活或終結操作符待決模式。換句話說,它允許我們創建自定義的操作符及動作命令,從而讓我們可以擴充Vim的詞匯。
最後更新:2017-06-06 07:37:49
上一篇:
《Vim實用技巧(第2版)》——導讀
下一篇:
不常見但是很有用的 gcc 命令行選項(一)
spring-boot+aop實現多數據源切換
Bootstrap Table筆記——1
Oracle 連接查詢
《OpenStack實戰》——1.5 OpenStack發展曆史
finally 不會執行的情況
可循環顯示圖像的Android Gallery組件
Further Adventures With CAS Instructions And Micro Benchmarking
從航空母艦上起飛,是怎樣一種體驗----EDAS帶你快速搞定分布式應用
一道有趣的C#考試題目
HTAP數據庫 PostgreSQL 場景與性能測試之 33 - (OLAP) 物聯網 - 線性字段區間實時統計