這兩天看到一個小練習,要求如下:
在GVIM下,將下面這張圖的內容
改成下面這樣
並且指出,要用批次操作的方式,不能一行一行的鍵入
其實第一反應是利用正規表示式來操作,但是讓用正規表示式以外的操作方式,查了不少方法,最終發現了VIM的宏,覺得挺有意思的,特地記錄一下
宏是用來重複執行一組操作的
操作方式為
1、在普通模式下,按
q
開啟宏操作方式2、隨後輸入一個宏名作為暫存器,為了方便,可以輸入一個小寫字母,但不要用大寫字母喲
3、輸入要批次操作的內容,VIM會將此時所有的操作記錄在暫存器中
4、操作完成後,再次在普通模式下按
q
結束宏記錄5、之後可以呼叫宏操作,呼叫方式有兩種,一種是在普通模式下按
@宏名
,另一種方式是在命令模式下輸入normal @宏名
下面一步步演示
先是在普通模式下依次按下
q
和a
,其中a
是我們的宏名
完成這一步可以看到在VIM視窗的左下角出現了記錄中
字樣,表明隨後的操作都將記錄在VIM的宏中
隨後,我們按下i
進入輸入模式,並輸入
number <回車>
按Esc
退出輸入模式,再按q
,退出宏操作
此時便完成了宏記錄操作,記錄完宏操作後是這樣的
接下來分別用兩種方式呼叫宏
普通模式下,直接輸入@a
可以看到多出了一行內容,用命令列方式呼叫
在命令列輸入
:normal @a
可以看到,再次輸入了一行內容
如果想知道宏名中有哪些操作,可以在命令模式下輸入
:register @a
可以看到剛才記錄在宏名a
中操作全部展示出來了
我們新建一個VIM文字,按照同樣的方式操作一下,只是將宏名由a
換成A
我們先來檢視一下宏名A
中的內容
可以看到,宏中並沒有任何操作,大寫字母的作用是在現有宏中新增操作的
對一個現有的宏,如果我們想修改裡面的操作,如果我們按照
q
a
<一系列操作>
q
這個方式操作只會覆蓋掉原有的宏,並不會在原有宏的基礎上增加操作
接下我們試試在最初的宏a
中加上is 0
,用a
進入和A
進入分別會發生什麼
#方式1
q
a
輸入 is 0
q
可以看到,執行宏操作後,只列印出is 0
,再來看看此時宏a
中的內容
可以看到此時的宏中只有is 0
先將宏改回原來的樣子,再來換一種方式試試
#方式2
q
A
輸入 is 0
q
可以看到此時呼叫宏時,不僅有列印出了number
也列印出了is 0
,最後再看看這種方式更改後宏a
中記錄的操作
有時我們會用到變數,而宏中也可以設定變數,操作方式如下
在進入宏記錄後,在命令列輸入
:let i = 1 <回車>
按 i 進入輸入模式
按Ctrl r = 三個按鍵
在輸入變數名 i 即可插入變數
我們按照這個步驟試一下,過程如下
q
b
:let i = 1 <回車>
進入輸入模式,並輸入Ctrl r = i <回車>
退出輸入模式,並結束宏記錄
普通模式下按下 @b
不過有一點要說明,在一個VIM文字中,所有的變數是共同有的,我們對宏a
進行一個更改
在宏a後面加上
value Ctrl r = i <回車>
可以看到在宏b
中設定的變數在宏a
中依舊可以呼叫
如果我們對變數 i
不斷進行累加,可以在宏a
中加入let i = i + 1
此時,我們也可以在其他宏中更改變數i
,比如我們新建一個宏,如下:
q
c
在命令列輸入
:let i = 10 <回車>
q
普通模式下輸入 @a
可以看到此時i
的值是10
,我們再次在普通模式下按@a
可以看到此時是在10
的基礎上進行累加的
如果,我們再新建一個宏,更改變數i
的變化方式呢,就像下面這樣
q
m
命令列輸入 :let i = i + 50 <回車>
q
普通模式下按 @a
可以看到只有第一次呼叫宏時是按照宏m
的設定變化的,但隨後又按照宏a
的設定變化
下面給出最初的小練習的解決方案
/* 在宏中設定變數 */
q
a
:let i = 1 <回車>
:let j = 2 <回車>
q
/* 在宏中鍵入內容 */
q
a
i
number 組合鍵 i + number 1 = number 組合鍵 j <回車>
ESC
:let i = i + 1 <回車>
:let j = j + 1 <回車>
q
/* 列印 */
普通模式下輸入 20@a
其實利用正規表示式的方式也是能夠實現的,正則表達的方式下次貼出來