1 在文本中插入行號
最近有朋友提到某編輯器有一個可以插入行號的插件,問Vim有沒有辦法可以在文章中插入行號。%$^&*#8~#$@#!……讓我們看一下有多少種方式可以在vim中插入行號或數字序列!
建議看一下Vim官網的這篇文章。里面一部分內容與這篇是重疊的。不過這篇是中文的XD。
我們的目的是在當前編輯文中的每一行前面加上行號或數字序列並用空格分隔,如:
這是第一行
這是第二行
這是第四行
在插入行號后將成為:
1 這是第一行
2 這是第二行
3
4 這是第四行
但有時我們需要對部分行編號。下面的例子是對第二行以后的所有非空行依次編號:
這是第一行
1 這是第二行
2 這是第四行
為了區別行號,我這里就稱之為數字序列。
進入正題。
1.1 使用line()函數
相信這是大多數人第一個想到的解法了——使用line()函數產生行號用:s命令插入行號。
" 為所有行加上行號
" 使用合適的范圍或者正則表達式就可以限定作用的范圍。
:g/^/ s//=line('.').' '/
優點是簡單易用。缺點是不夠靈活,只能用以顯示指定行的行號。
1.2 使用ex命令
vim提供了一些可以打印行號的ex命令,如,”=”, “p #” 和”#“。為了捕捉Vim的命令輸出,我們用redir命令。
" 為前30行加上行號
:redir @a | 1,30# | redir END
:1,30d | put! a
邏輯上很容易理解:1,30#顯示前30行及其行號。保存到寄存器a中,刪掉前30行,再貼上寄存器的內容。
沒什么明顯優點的一種方法。缺點同上。如果不是更改當前編輯區的內容而是直接保存到新文件的話,這種方法就比其他的方法方便。
1.3 使用range()函數
range()是個新的函數,用來產生包含數字序列的列表。當然也可以用來生成行號:
" 為前30行加上行號
:for i in range(31)
:call setline(i,i .' '. getline(i))
:endfor
對range(),setline()的用法見幫助文檔。
range()函數相對前面的2個解法而言要靈活許多,除可用以表示行號,也可以用來編數字序列,相應地也要求一些編程基礎。
1.4 加法運算
這是也是簡單靈活的一種解法。好吧,也許大家第一個想到的解法不是使用line()函數。
" 為所有行加上行號
:let i=1
:g/^/ s//=i . ' '/ |let i=i+1
注意:g后面的兩條命令(😒, :let)一定要寫在一起。這是比較通用的一種編號方式,可以應付大部分的編號問題。
1.5 使用
Vim提供了Ctrl-A和Ctrl-X來分別對光標下(或者光標右邊第一個)數字進行增、減操作。按Ctrl-A一次可加一,按Ctrl-X則是減一。如果你用的是Windows,那很有可能Ctrl-A已被映射成全選了。輸入
:nunmap
使之恢復功能,當然你可以用:nnoremap重新映射到其他鍵。趕緊翻出文檔吧:
:h CTRL-A
:h CTRL-X
:h unmap
:h o_v
先看一下,普通模式下的操作步驟:
第一、手工添加第一行序號和空格。
第二、輸入0”ayw將序號放到寄存器a。
第三、移到下一行並輸入:
qq0”aP0^A”ayawjq
上面的命令將指令序列存進寄存器q。^A表示按Ctrl-A組合鍵。
第四、28@q對接下來的28行添加行號。
上面添加空格是很重要的步驟(因為我們使用了yaw復制數字和空格),這里解釋一下第三步:
qq‘ 開始錄制宏,並保存到寄存器q中 0‘
設定光標的位置到行首
"aP‘ 放上前面保存的序號和空格 0^A‘
回到行首並按Ctrl-A加一
"ayaw‘ 復制當前數字和空格到寄存器A jq‘
移到下一行(這樣我們才能確保28@q是對下面的28行進行操作而不是對當前行操作28次),然后結束宏。
通過與:g指令配合可以對指定行編號。下面的例子對所有以字母開頭的行進行編號。為了說明方便我們直接對寄存器賦值,效果與上面普通模式下的操作是一樣的。注意下面兩例操作中的^A的輸入方法與上面直接按組合鍵的方法有所不同,先按Ctrl-V(不行的話試Ctrl-Q),再按Ctrl-A:
" 先重置a寄存器。
" 再對所有以字母開頭的行編號
:let @a='0 '
" 去掉了j指令
:let @q='0"aP0^A"ayaw'
:g/^\a/ norm @q
如果你用的分隔符不是空格,可以對它進行手工標記:
" 這個例子使用冒號作為分隔符
:let @a=0
:let @q='0"aPa:[0Amm"ayv`m'
:g/^\a/ norm @q
宏指令是Vi最有力的工具之一,在Vim中宏則比以往更強大。宏並非完成此工作最有效率的解法,但寫宏的樂趣要比其他的腳本來得多得多。這個解法經過修改一樣可以適用多種情況,缺點是在寫出一個可行的宏之前要經過多次地調試。
