Vim 新手快速入门文档

Vim是一个类似于Vi的文本编辑器,不过在Vi的基础上增加了很多新的特性,Vim普遍被推崇为类Vi编辑器中最好的一个。如果想熟练使用Linux系统,了解vim的用法是必修课。

vim 的設定檔

~/.vimrc~/.gvimrc    GUI 版本$VIM/vimrc   系統預設值, 最好不去修改$VIM/gvimrc  GUI 版本$VIM\_vimrc  Windows 版本$VIM\_gvimrc

Vim 的基本模式(basic mode)

模式切换是由  键控制的

常態模式(Normal mode)

您一進入 vim 就是處於這常態模式, 只能下按鍵指令, 不能輸入編輯文字. 這些指令可能是游標移動的指令, 也可能是編輯指令或尋找替換指令.
插入模式(Insert mode)

按 i 就會進入插入模式, 此時才可以鍵入文字, 寫您的文章, 按 Esc 又會回到正常模式.

此時在底部狀態列會有字樣

-- INSERT --

视图模式(Visual mode)

這就是把需要處理的文字反白起來, 等待處理的模式.

此時在底部狀態列會有字樣

-- VISUAL --



-- VISUAL LINE --



-- VISUAL BLOCK --

命令模式(Command-line mode)

:

+冒號 就會進入命令列模式, 左下角會有一個冒號:也是按 Esc 回命令列模式.反正正常狀態都是處於常態模式, 這樣才不會把您辛苦打字的文章給隨便搞亂掉.

搜尋時的 / 及 ? 按鍵也是屬於命令列模式.

Ex 模式(Ex mode)

這和命令列模式是一樣的, 但下了命令後不會返回, 會留在行編輯器 ex 的狀態, 有一個冒號在那兒, 等待輸入命令.

由 gQ 按鍵可以進入 Ex 模式, 輸入 visual 可以返回正常模式.

基本教練:step by step

下編輯指令都是在常態模式, 就是您一進入 Vim 時的模式, 只能下指令, 不能鍵入文字.
由命令列來開檔

ecos@ubuntu:~$ vim test.txt

或者

ecos@ubuntu:~$ gvim test.txt

先進入 vim 後再開檔

進入 vim 後, 使用冒號命令

# vim:e test.txt

就可以編輯 test.txt 這個檔, 如果 test.txt 不存在的話, 就會開一個以 test.txt 為名的新檔案.

如果是 gvim, 可由 icon(gtk 版本才有)或功能表來叫出 file browser 來選看看您要編輯哪一個檔, 但如果您是初學的話不建議您這麼做, vi 就是以按鍵快速聞名, 這是她的優點, 您還是學起來吧, 不然沒有 GUI 的時候會很不習慣的.
編寫文件

進入 vim 後, 按 i 進入插入模式, 就可以編寫您的文件了.在 vim 游標的移動可以由方向鍵來移動. Backspace 鍵可消去前一個字元, 中文的話是一個中文字. Del 鍵可刪除游標所在處的字元(中文字).

原始 vi 是不能在插入模式隨意移動游標的, 得進入正常模式才能移動, 因此就常常要按 Esc 來變換模式.
存檔、離開

如果您寫好您的文件, 就可以按 Esc 回到正常模式, 然後 :w 就會存檔(注意, 是冒號命令), 但還不會離開 vim, 要離開可按 :q, 就可以了!也可以合起來用, :wq, 就樣就會存檔後離開. 怎麼樣, 也不會很難吧!只不過操作方式和別的編輯器不一樣罷了, 這樣豈不是很有個性. :-)

盡量記住按鍵的意義, 才不必死背, 如 e 是 edit(編輯), w 是 write(寫入), q 是 quit(離開).

:w 存档:q 退出:wq 保存后退出:w! 强制存档:q! 强制退出

游標的移動

本節所述皆是在 normal-mode, 就是剛進入 vim, 不能輸入文字的狀態)下的移動, 原始的 vi 只能在 c-mode 移動游標, 在 insert-mode 只做文字的輸入, 而不做游標的移動. 當然 Vim 的方向鍵是不論在那一種 mode 皆可移動自如.
基本的游標移動

使用 hjkl 鍵的移動是為了使手不必離開打字區(鍵盤中央的部位), 以加快打字的速度, 所以方向鍵还是不要用了!其實, 一旦習慣了以後, 對於編輯工作的效率會有很大的幫助

h 即 ←j 即 ↓k 即 ↑l 即 →# 翻页Ctrl+f 即 PageDown 翻頁(Forward  向前 下翻頁)Ctrl+b 即 PageUp   翻頁(Backward 向後 上翻頁)# 我常用的还是 u 和 dCtrl+u --u up    向上10行Ctrl+d --d down  向下10行

進階的游標移動

0    是數字 0 而不是英文字母 o. 或是 Home 鍵, 移至行首, (含空白字元).^    移至行首第一個非空白字元, 注意, 要 Shift 鍵.$    移至行尾, 或 End 鍵. 要 Shift 鍵.G    移至檔尾(全文最後一行的第一個非空白字元處)gg    移至檔首(全文第一行之第一個非空白字元處).在規則表示式(regular expression)中, ^ 是匹配行首, $ 是匹配行尾.gg 是 Vim 的擴充功能, 在 elvis 或原始 vi 中可用 1G 來移至檔首(是數字 1 不是英文字 l).G  原意是 goto, 指移至指定數目行之行首, 如不指定數目, 則預設是最後一行.w    移至次一個字(word)字首. 當然是指英文單字.W    同上, 但會忽略一些標點符號.e    移至後一個字字尾.E    同上, 但會忽略一些標點符號.b    移至前一個字字首.B    同上, 但會忽略一些標點符號.H    移至螢幕頂第一個非空白字元.M    移至螢幕中間第一個非空白字元.L    移至螢幕底第一個非空白字元. 這和 PageDown, PageUp 不一樣, 內文內容並未動, 只是游標在動而已.n|    移至第 n 個字元(欄)處. 注意, 要用 Shift 鍵. n 是從頭起算的.:n    移至第 n 行行首. 或 nG.

特殊的移動

)    移至下一個句子(sentence)首.(    移至上一個句子(sentence)首. sentence(句子)是以 . ! ? 為區格.}    移至下一個段落(paragraph)首.{    移至上一個段落(paragraph)首. paragraph(段落)是以空白行為區格.%    這是匹配 {}, [], () 用的, 例如游標在 { 上只要按 %, 就會跑到相匹配的 } 上.

另還有一些 Vim 的特殊按鍵, 但這得留待最後再來說明, 否則各位恐怕會頭昏眼花了.
基本編輯指令

下編輯指令都是在常態模式, 就是您一進入 Vim 時的模式, 只能下指令, 不能鍵入文字.
五種額外模式(additional mode)
操作等待模式(operator-pending mode)

這其實和一般的常態模式一樣, 只不過是指在常態模式下了某些編輯指令, 等待其他動作的狀態.
取代模式(replace mode)

指下 r or R 指令時所處的狀態.

r 即 替换一个字符R 即 替换一行

在狀態列會有

-- REPLACE --

插入常態模式(insert normal mode)

這是一個很特殊的模式, 在插入模式時, 進入輸入狀態, 但按 Ctrl+O 就會進入插入常態模式, 和常態模式一樣, 只不過執行完所下的指令後又會馬上返回原來的插入模式繼續輸入文字.

狀態列會有

-- (insert) --

插入反白模式(insert visual mode)

這和插入常態模式一樣, 只不過在按 Ctrl+O 後所執行的是反白的 Ctrl+V 或 V 或 v 而進入反白模式, 等反白模式結束又會返回原來的插入模式.

狀態列會有

-- (insert) VISUAL --

插入選擇模式(insert select mode)

鼠标控制选中字段, 這和插入视图模式一樣, 只不過進入的是選擇模式, 而非视图模式.

狀態列會有

-- (insert) SELECT --

進入插入模式的指令

i    在游標所在字元前開始輸入文字(insert).I    在行首開始輸入文字. 此之行首指第一個非空白字元處, 要從真正的第一個字元處開始輸人文字, 可使用 0i 或 gI(Vim 才有).a    在游標所在字元後開始輸入文字(append).A    在行尾開始輸入文字. 這個好用, 您不必管游標在此行的什麼地方, 只要按 A 就會在行尾等著您輸入文字.o    在游標所在下一行開一新行來輸入文字(open).O    在游標所在上一行開一新行來輸入文字(open).J    將下一行整行接至本行(Joint).

刪除指令

x    刪除游標所在處之字元, 在中文指一個中文字. 在 Vim 及 elvis 亦可用 Del 鍵.X    刪除游標前之字元. 不可使用 Backspace 鍵, 除非是在插入模式. Vim 可以正確使用以上兩個指令於中文, 會刪去一個中文字. elvis 則不行, 一個中文字要刪兩次, 即使用 xx.dd    刪除一整行(delete line).dw    刪除一個单词(delete word). 中文会删除一段.dG    刪至檔尾.d1G    刪至檔首. 或 dgg(只能用於 Vim).D    刪至行尾, 或 d$(含游標所在處字元).d0    刪至行首, 或 d^(不含游標所在處字元). 請回憶一下 $ 及 ^ 所代表的意義, 您就可以理解 d$ 及 d^ 的動作, 這就是 vi(m) 可愛之處.

取代及還原

r    取代游標所在處之字元.R    進入取代模式(replace mode), 取代字元至按 Esc 為止.s    替換一個字元為您所輸入的字串. 和 R 不同, R 是覆蓋式的取代, s 則是插入式的取代S   取代整行內容. 或 cc 亦可.c0    取代至行首, 或 c^.cw    替換一個英文字(word), 中文不適用. (change)C    取代至行尾, 即游標所在處以後的字都會被替換. 或 c$.~    游標所在處字元之大小寫互換. 當然不能用於中文. 別忘了 Shift!U    在游標沒離開本行之前, 回復所有編輯動作.u    這個太重要了, 就是 undo, 傳統的 vi 僅支援一次 undo, Vim 及 elvis 就不只了, Vim 幾乎是沒有限制的.Crtl+r    這個也是很重要, 就是 redo 鍵.

Vim 很有個性的, 您在常態模式按了 r 她就會停在那裡等主人鍵入所要替代的字元, 希望您這個當主人的, 不要傻呼呼的也楞在那裡, 趕快鍵入您的新字元吧!:-)
加上數字

5dd    刪除游標所在處(含)起算以下五行內容. 妙吧!3r    按了 3r 後, 您鍵入一個英文字, 則三個字元皆會被您所鍵入的英文取代. 只要 locale 設定正確, 中文也通喔!5J    將五行合併成一行.3x    刪除三個字元. 中文也通.5i A        然後按 Ecs, 插入五個 A. 中文也可以!2i sys Esc  插入 syssys. 中文也可以!5G    游標移至第五行, 是從檔首開始起算. 和 :5 作用相同.5h    移至右第五個字元處, 當然 jkl 都可用

簡單重排功能

Shift + >    整行向右移一個 shiftwidth(預設是 8 個字元, 可重設).Shift + <    整行向左移一個 shiftwidth(預設是 8 個字元, 可重設).:ce(nter)    本行文字置中. 注意是冒號命令!:ri(ght)    本行文字靠右.:le(ft)     本行文字靠左.gqap        整段重排, 或 gqip, 在段落中位何地方都可以使用. 和中文的配合見下述.gqq            本行重排.gqQ            全文重排, 是以游標所在處的段落開始重排至檔尾. 以空白行為段落的間隔.

基本上 gq 就是一個獨立的重排指令, 就像 d 或 y 是獨立的刪除、複製的指令一樣.

所以, 當然是可以加上數目字加以控制, 或和其他指一起用的, 例如:

gq3q    =>    重排三行gq2ap    =>    重排兩個段落gq5j    =>    重排游標以下五行(別忘了 j 是向下移動, 5j 就是向下移動五行, 包括游標所在處就是六行)gq}     =>    well, 這是什麼哇?那就试试吧gq)     =>    在中文文稿, 通常就是一個段落.

重排的功能本不是編輯器的主要功能, 而是文書排版軟體的工作, 但簡單的重排也是很方便, 對於中文而言, 處理上得多花些工夫, 對於希望有中文重排功能的朋友, 可下載 Vim script 來使用:

http://info.sayya.org/~edt1023/vim/format.vim

這是修改自日本朋友的貢獻. 把他置於 $VIMRUNTIME/plugin 目錄下, 重新開啟 vim 就會生效, 對於 J 及 gqap 都會考慮中文的細節. 當然, Vim 只是個文字編輯器, 如果要做進一步的排版, 需要由 office 類的文書處理軟體, 或更進一步的專業 TeX/LaTeX/texinfo/troff/groff 排版軟體來處理.
複製(yank)

yank是什麼意思?有疑問的請查一下字典吧!就好像是中醫治療中的「拔罐」的意思啦(是不是叫「拔罐」?知道的朋友指正一下吧)!

反正在 Vim 中, 她就是複製 copy 的意思. 這在 Vim 的思考邏輯裡, 就是「拔」yank 起來, 「放」put 上去.

其實複製的指令就是 y 一個而已, 為什麼要獨立成一個單元來說明呢?因為 Vim 複製、貼上的功能實在太獨特了, 再配合第三單元介紹的數目字, 及 Vim 內部的緩衝區來使用的話, 您會發現, 原來 Vim 肚子裡還暗藏著秘密武器.
指令說明

yy    複製游標所在行整行. 或大寫一個 Y.2yy      複製兩行, y2y 也可以.y^    複製至行首, 或 y0. 不含游標所在處字元.y$    複製至行尾. 含游標所在處字元.yw    複製一個 word.y2w   複製兩個字.yG    複製至檔尾.y1G   複製至檔首.p     小寫 p 代表貼至游標後(下).P     大寫 P 代表貼至游標前(上). 整行的複製, 按 p 或 P 時是插入式的貼在下(上)一行. 非整行的複製則是貼在游標所在處之後(前).

再来看看有意思的

"ayy  將本行文字複製到 a 緩衝區.  a 可為 26 個英文字母中的一個, 如果是小寫的話, 原先的內容會被清掉, 如果是大寫的話是 append 的作用, 會把內容附加到原先內容之後. " 是 Enter 鍵隔壁的那一個同上符號(ditto marks), 當然是要和 shift 鍵同時按的."ap   將 a 緩衝區的內容貼上.  這個緩衝區的術語在 Vim 稱為 registers, Vim 擴充了相當多的功能. 您用 d、c、s、x、y 等指令改變或刪除的內容都是放在 registers 中的. 例如:您用 dd 刪除的一行, 也是可以使用 p 來貼上的. 只要是在緩衝區的內容都可以使用 p 來貼上, 不是一定要 y 起來的內容才能用 p. 因此您認為 p 是 paste 也可以, 認為是 put 可能較正確.5"ayy 複製五行內容至 a 緩衝區.5"Ayy 再複製五行附在 a 內容之後, 現在 a 中有十行內容了!# 不要我一直用 a 您就認為只有 a 可以用喔. 26 個英文字母都可以的, 交叉運用下, 您會發覺 Vim 肚量不小.

問題來了!忘記誰是誰的時候怎麼辦?

:reg(冒號命令)

就會列出所有 registers 的代號及內容. 您現在就試著按看看. 咦!怎麼還有數目字、特殊符號的緩衝區, 原來您剛剛刪除(複製)的內容就預設放在 " 這個緩衝區, 然後依序是 0,1,2,...9. 也就是說您按 p 不加什麼的話, 是取出 " 緩衝區的內容. % 指的是目前編輯的檔案, # 指的是前一次編輯的檔案. 還有其它的呀!這會在下一節做介紹.

Tab 補全的功能, elvis 也有, 但叫出 registers 列表的命令則沒有, 您得自行記憶在您的腦袋瓜子裡. 而且 elvis 的補全能力並沒 Vim 強.
Register 緩衝區

在 Vim 裡頭, 有許多不同種類的緩衝區, 例如:置放一整個檔案的 buffers 緩衝區;檔案內容操作, 如刪除、yank、置換, 給 Put 要用的 registers 緩衝區;另外還有給書籤要用的 marks 緩衝區.雖然這些內容不一定是放在 RAM 記憶體內, 有的是置於硬碟檔案上, 需要時才從檔案存取, 但這裡通通把他當做是緩衝區, 以方便理解.
天大的指令

. 這是什麼?是英文句點啦!沒錯, 就是英文句點. 什麼意思?重複前次的編輯動作.這個指令太高明了, 只要是編輯動作(移動游標不算, 冒號命令也不算)都可以按英文句點來重複, 要重複幾次都可以.

例如:您按了 yy, 然後按 p 就會複製、貼上一整行,如果要重複這個動作的話, 就可以按 "." , 也可以把游標移到其它地方後再按.其它 dd, dw, r, cw 等編輯指令都可以這樣來重複.如果您要重複做某些編輯動作時, 千萬千萬一定要想到有這麼一個英文句點重複指令. ㄚ, 拜託啦!您一定要常用這個指令.
疑難雜症

那 mouse 中鍵的剪貼功能還有嗎

在 linux 不管在 console 或 X terminal 中都照用不誤.windows 下的話就不能用了, 可以用 Shift+Insert 來代替.  Ctrl+v 在 Vim 中另有作用, 在 windows 下就不必去麻煩它了.

軟體間互相 copy 時, 常常都搞得天下大亂耶!要設成

# 這是 Vim 的擴充功能:set paste

朋友!您睡著了嗎?不要被嚇到了, 您只要開個檔案, 親自操作一下就能心領神會.

那用 mouse 不是更方便嗎?不見得, yyp 來複製貼上一整行比較快, 還是用 mouse 來拉比較快?您可以試看看.
搜尋、替換

搜尋、替換的功能幾乎是每個編輯器必備的功能, 那在 Vim 中有沒有特殊的地方呢?當然有, 您忘了, Vim 是個性十足的編輯器.

最特殊的地方是和規則表示式(regular expression, 簡稱 regexp)結合在一起.

簡單的說她是一種 pattern 的表示法, 在執行動作, 如搜尋或替換時, 就會依據這個 pattern 去找, 所有符合 pattern 的地方就會執行您所下的動作.
搜尋

/   在 c-mode 的情形下, 按 / 就會在左下方出現一個 /, 然後鍵入您要尋找的字串, 按個 Enter 就會開始找.?   和 / 相同, 只是 / 是向前(下)找,  ? 則是向後(上)找.n   繼續尋找.N   繼續尋找(反向).

更方便的搜尋操作(Vim 才有)

*    尋找游標所在處之 word(要完全符合).#    同上, 但 * 是向前(下)找, # 則是向後(上)找.g*    同 * , 但部份符合即可.g#    同 # , 但部份符合即可. n, N 之繼續尋找鍵仍適用.

替換(substitute)

:[range]s/pattern/string/[c,e,g,i]

range   指的是範圍, 1,7 指從第一行至第七行, 1,$ 指從第一行至最後一行, 也就是整篇文章, 也可以 % 代表. 還記得嗎? % 是目前編輯的文章, # 是前一次編輯的文章.pattern    就是要被替換掉的字串, 可以用 regexp 來表示.string  將 pattern 由 string 所取代.c       confirm, 每次替換前會詢問.e       不顯示 error.g       globe, 不詢問, 整行替換.i       ignore 不分大小寫.g       大概都是要加的, 否則只會替換每一行的第一個符合字串. 可以合起來用, 如 cgi, 表示不分大小寫, 整行替換, 替換前要詢問是否替換.

[實例]

:%s/Edwin/Edward/g

這樣整篇文章的 Edwin 就會替換成 Edward.

更進階的搜尋、替換的例子在說明 regexp 的時候還會再詳述. 目前只知道最基本的用法就可以了!其實光這樣就非常好用了. :-)
書籤功能

這又是 Vim 的一個秘密武器, 簡單的說, 您可以在文章中的某處做個記號(marks), 然後跑到其它地方去編輯, 在呼叫這個 mark 時又會回到原處. 妙吧!

mx  x 代表 26 個小寫英文字母, 這樣游標所在處就會被 mark.`x  回到書籤原設定位置. ` 是 backward quote, 就是 Tab 鍵上面那一個.'x  回到書籤設定行行首. ' 是 forward quote, 是 Enter 鍵隔壁那一個.

這裡舉個簡單的子, 請隨便開一個現成的檔案, 把游標移到任一個位置, 然後按 ma 做個 mark, 再按大寫 G 移到檔尾, 然後按 'a 看現在在什麼地方?
Vim 對於書籤的擴充功能

    小寫英文字母

    只作用於單一檔案內.

    大寫英文字母

    可作用於各檔案間.

    例如 mA 會在 viminfo 中紀錄下這個檔案及位置, 結束 vim, 然後再啟動 vim, 按 'A 就會回到當初做標記的那個檔案及所在位置(vim 會自動開啟做有 A 標記的檔案). 別懷疑, 請自行馬上做個實驗就知道啦!:-)

    阿拉伯數目字

    可作用於前次編輯的十個檔案.數目字的用法比較特殊, '0 是回到前一次編輯檔案中離開前的最後位置, '1 則是回到前二次編輯檔案的最後位置,依此類推. 您不必使用 m 來標示, vim 會自動記憶. 很玄吧!* 其實這是 viminfo 的功能, 您要認真追究的話, 請 :h viminfo-file-marks. viminfo 關掉, 就沒這個功能了!所謂前次指的是前次啟動的 vim. 不管是哪一種的書籤, 到達 mark 處(或檔案), 想返回原來的位置(或檔案), 可以按 Ctrl+O.

    显示目前所有書籤的列表

    :marks

多檔、存檔、緊急回復
多檔編輯

多檔編輯會有兩種情形, 一種是在進入 vim 前所用的參數就是多個檔(這種情形稱為 argument list).

另一種情形是進入 vim 後另外再開其它的檔(稱為 buffer list). 不過都可以統稱為 buffer.

:n  編輯下一個檔案.:2n 編輯下二個檔案.:N  編輯前一個檔案. 注意, 這種用法只能用於 argument list 的情形.:e  檔名    這是在進入 vim 後, 在不離開 vim 的情形下再開其它檔案. 只要您要編輯的檔案是在目前目錄, Tab 補全鍵還是可以使用.:e# 或 Ctrl+^ 編輯前一個檔案, 用於兩檔互相編輯時相當好用. 這種用法不管是 argument list 或 buffer list 檔案間皆可使用. 還記得嗎?# 代表的是前一次編輯的檔案.:files 或 :buffers 或 :ls 會列出目前 buffer 中的所有檔案. 在 elvis 中可使用 :b 來叫出 buffers. 在 buffers 中, 減號 -表示這個 buffer 並未載入, 不過, 不必擔心, 載入相當快速的. 加號 + 表示這個 buffer 已經修改過了. # 代表前一次編輯的檔案, % 是目前編輯中的檔案, 這兩個代號應該很熟悉了吧!:bn    buffer next. 編輯次一個 buffer 的檔案.:bp    buffer previous. 編輯前一個 buffer 的檔案.:bl    buffer last. 編輯 buffer 中最後一個檔案. 以上兩個指令 elvis 不適用.:b 檔名或編號    移至該檔.

在 :ls 中就會出示各檔案的編號, 這個編號在未離開 vim 前是不會變的.

這個指令在 elvis 也是可以使用. 當然 :e#編號 也是可以的, 這樣的用法則是所有 vi clone 都通用了.

如果您是使用 Vim 的 GUI, 那就在功能表上就會有 Buffers 這個選項, 可以很容易的知道及移動各 buffer 間.

:bd(elete)    buffer 在未離開 vim 前是不會移除的, 可使用這個指令移除. 其實移除她幹什麼呢?vim 是您在叫用時才會載入的, 因此這些 buffers 並不是像 cache 一般要佔記憶體的.:e! 檔名    這樣也是會開檔, 但會放棄目前編輯檔案的改變, 否則如果檔案已有變動, vim 預設是不讓您隨便離開的. :e! 後不接什麼的話, 代表捨棄一切修改, 重新載入編輯中檔案.:f 或 Ctrl+g    顯示目前編輯的檔名、是否經過修改及目前游標所在之位置.:f 檔名    改變編輯中的檔名. (file):r 檔名    在游標所在處插入一個檔案內容. (read):35 r 檔名    將檔案插入至 35 行之後.gf    這是 vim 的特殊叫檔法, 會叫出游標所在處的 word 為名的檔案, 當然, 這個檔案要在目前目錄內, 否則會開新檔案.

哦!好像有點給他複雜, 主要原因是偶文筆不好啦!不過您何不選個順手的來用就可以了, 選定了, 以後就是使用他, 這樣就不會那麼複雜了. :-)
離開

:q  如本文有修改而沒存檔, 會警告, 且無法離開. (quit):q! 捨棄所有修改, 強迫離開.:wq 存檔後離開. 縱使檔案未曾修改也是會再存一次檔.:x  也是存檔後離開, 但如果檔案沒有修改, 則不會做存檔的動作.ZZ 和 :x  完全一樣, 隨您高興用哪一個.:w 檔名   另存他檔. 不加檔名就是寫入原檔. (write):q 及 :q! 是對目前編輯中的檔案作用, 如果多檔編輯的情形並不會離開 vim, 這時可下 :qa 或 :qa! 來整個離開 vim. a 就是 all 的意思. :指令!, 這個 ! 的意思是強迫中止目前正在編輯的動作, 而去執行所下的指令. 各位應該到目前為止碰過好幾次了吧!ZQ 和 :q! 功能相同

Vim 的加密功能

使用 :X 命令为文件设定一个密码

:XEnter encryption key: ******Enter same key again: ******

如果要取消加密, 可以设置密码为空. 可以禁用交换文件, 以免泄密

vim -x -n file.txt

如果你已在经编辑这个文件了, 那么交换文件 swapfile 可以用下面的命令禁止:

:setlocal noswapfile

由于没了交换文件, 文件复原就不可能了. 为了避免失去编辑的成果, 要比平时更勤快地存盘你的文件.现在你可以像平时一样编辑这个文件并把你所有的秘密放进去. 当你编完文件要退出 Vim 时, 这个文件就被加密存盘了.当你下次用 Vim 编辑这个文件时, 它就会询问你密码.如果你试图用另一个程序来阅读这个文件, 你将读到一堆垃圾. 如果你用 Vim 来编辑这个文件, 但输入了错误的密码, 你也只能得到垃圾. Vim 并不具备检验密码正确性的机制 (这一点使得破译密码更为困难)

vim -x [檔名]

這樣進入 vim 後會要求輸入密碼. 以後加密過的檔案由 vim 開啟時會自動要求輸入密碼. 否則無法開啟. 其它的編輯器當然是無法開啟的.

進入 vim 編輯檔案中, 可用

:X

指令

小心!vim 一開檔就會有個 .檔名.swp 這個檔, 是為了緊急回復用的, 一般是在您所開檔案的所在目錄, 這是個隱藏檔, ls 要有 -a 參數才看得到, 您加密的功能並沒有作用在這個 swp 檔, 因此 root 還是知道您在寫些什麼關於他的壞話的. :-)當然啦!山不轉, 路轉, 路不轉, 人轉, 您也是可以把 swap 的功能關掉的 :set noswf 就行了!但如果您編輯的是大檔案, 則不建議您把 swap 關掉, 這樣會很吃記憶體的. elvis 的話, 其暫存檔是統一集中存放在 /var/tmp/*.ses, 權限是檔案所有者始能讀寫. Vim 的早期版本, 其 *.swp 檔是依原檔案的權限來設定的, 最近的版本則從善如流, 已經改成檔案所有人始能讀寫, 就是 -rw---- 啦!
緊急回復

vim -r 檔名

或進入 vim 後, 输入下面的命令恢复

:recover 檔名

各種標示方法及視窗操作
標示指令

v    小寫 v, 這是屬於字元標示(character visual), 按下 v 後您就可以移動游標, 游標走過的地方就會標示起來. 再按一次 v 或按 Esc 鍵就會結束 v-mode.V    大寫 V, 這是行標示(line visual), 按下 V 後會整行標示起來(包括行首前空白的部分), 您移動上下鍵, 會標示多行. 再按一次 V 或 Esc 鍵就會結束 v-mode.Ctrl+v    這是區塊標示(blockwise visual), 可縱向標示矩形區域. 再按一次 Ctrl+v 就會結束 v-mode. 結束 v-mode 的方式亦可使用 Esc 鍵, 或統一使用 Ctrl+c. Windows 系統下 Ctrl+v 是複製鍵, 可以使用 Ctrl+Q 來替代.d    刪除標示區內容.y    複製標示區內容.c    替換標示區內容.~     標示區內容大小寫互換.gq    重排標示區內容. ㄟ…… 是要先標示好才按的. "ay 還能不能用呢?當然可以, 這樣就會把標示區內容存於 a 緩衝區中. 可以用 "ap 來貼上.Shift+>    標示區內容向右移一個 Tab.Shift+<    標示區內容向左移一個 Tab.

您想更深入嗎?:h visual.txt 就有詳細的介紹. 還有, 別忘了有 Tab 補全鍵可以用.
視窗操作

Ctrl+w n    即 :new. 開一空的新視窗.  這在 Vim 會開在原視窗上半方, 也就是視窗一分為二.Ctrl+w s    即 :sp(lit), 會開一新視窗, 且原檔分屬兩個視窗.Ctrl+w f    開一新視窗, 並編輯游標所在處之 word 為檔名的檔案.Ctrl+w q    即 :q 結束分割出來的視窗.Ctrl+w o    即 :only! 使游標所在之視窗, 成為目前唯一顯示的視窗其它視窗會隱藏起來.Ctrl+w j    移至下視窗.Ctrl+w k    移至上視窗. 還記得 hjkl 的按鍵移動方式嗎?:sp 檔名    開另一新視窗來編輯檔案.

shell 命令及求助系統
shell 命令

:!       外部指令    執行外部指令. 當然您的指令要在 $PATH 環境變數內.:!!      執行前一次執行之外部指令. 在這裡的 ! 可不是強迫中止喔!@:       這是 Vim 的一個很特殊的指令, 可以重複前一次的冒號命令.:sh(ell) 執行 shell. 使用 exit 回到 vim.

這在 Vim GUI 會在原視窗內顯示執行結果, 在 elvis GUI 則會另開一 xterm 視窗.console 或 xterm 下的 vim 當然就是跳出 vim 進入 shell 中.至於是用哪一種 shell 是可以另外設定的, 可由 :set shell= 來設定.

:r !commond     這個就妙了!會在游標所在處次一行插入外部指令 commond 執行後的輸出內容. 例如 :r !date 就會插入日期時間.:n,mw !commond    以 n 至 m 行內之資料, 當做外部指令 commond 的 input.K               大寫 K 會顯示游標所在處之 word 的 man page 系統線上使用手冊.

基本的匹配

*       指前所綁住的字元或字元集合, 出現 0 次或 0 次以上.\+ 和 * 作用相同, 但不包括出現 0 次.\=      指前所綁住的字元恰好出現 0 或 1 次.\|      這是多選, 就是 or 的意思, 被 \| 隔開的 pattern, 任一個符合的話就算符合.\+, \=, \| 會加上一個 \, 是因該字元在 Vim 就具有特殊意義, 在一般的 regexp 中是 +, ?, | 就可以了, 只是提醒您一下, 以免搞混了! 記住 \+ 是不可數的!用辭不是很精確, 只是幫助您記憶啦!在 elvis 及 ed 中是使用 \? 來匹配出現 0 或 1 次, 而不是 \=, 這裡要非常小心!

中介字元(metacharacter, or character classes)

主要是簡化 regexp 的書寫.

\s    表空白字元, 即 Space 或 Tab.\S    表非空白字元.\d    表數目字(digits), 即 [0-9].\D    表非數目字, 即 [^0-9].\w    表一般字元(word character), 包括底線. 即 [0-9a-zA-Z_].\W    表非一般字元, 即 [^0-9a-zA-Z_].\a    表英文字母(alphabetic character), 即 [a-zA-Z].\A    表非英文字母, 即 [^a-zA-Z].\l    表小寫字母(lowercase character), 即 [a-z].\L    表非小寫字母, 即 [^a-z].\u    表大寫字母(uppercase), 即 [A-Z].\U    表非大寫字母, 即 [^A-Z].

原始 vi 不支援此種中介字元. 使用中介字元的比對速度將會比使用字元集合 [] 的快.
全域性的指令

:[range]g/pattern/[cmd]

cmd 是 ed 可用的指令, 預設是 p(print), 您可查一下 man ed, 就可以知道有什麼指令可用.這個小節裡主要是說明 d(delete) 的功能. 因為是要說明如何消除空白行.需注意的是, d 是行刪除指令, 凡含 pattern 的整行都會被刪掉, 而且 range 不指定的話, 預設是全篇文章, 因為 g 就是代表 globe.

在 Vim 的 help 檔裡說的是 ex 指令, 但 ex 實際上是和 Vim 連結的, 因此這裡特別指出 ed. 但 ed 的指令少數可能會和 Vim 的 ex 不同, 這是因為 ed 和 Vim 並非同步在發展, 作者也非同一人.

:g/^$/d

這樣就會刪除全文的空白行. 前面已提過 ^$ 代表的是空白行. 但這裡有個問題, 如果空白行裡包含了其它空白字元(即 Space 或 Tab)的話.表面看起來是和一般空白行一模一樣, 但卻暗藏玄機, 用上面的方法就無法刪除這種空白行了!怎麼辦?來!看招!

:g/^[]*$/d

在 Vim 裡您可以如此照打, 也就是 代表空白字元, 代表按 Tab 鍵的結果.在原始 vi 則不行, 得自行按出特殊字元出來, 就是 Ctrl+v Space 及 Ctrl+v Tab. 或採更簡單的打法:

:g/^\s*$/d

還記得中介中元嗎?好用吧!少打了不少字. :-) 意思就是刪除含 0 或 1 個以上空白字元的行.

有些書中寫成 :%s/^$//g 可以刪除空白行, 這是錯誤的, 因為 :s 這 個指令只更動一行裡的內容物, 但不會做刪除一行的動作.
& 替代變數

代表置換時合於 patern 的字元或字串.

[實例]

:%s/\d\d\d\d\d\d\d\d\d\>/ID:&/g

這樣全文中的身份證字號前就會加上 ID: 字樣, 也就是說 T123456789 會被換成 ID:T123456789.還記得嗎? \d 就是 [0-9], \u 代表大寫的英文字母. 加個 \>是防止 T12345678999 也被換掉.當然前面再加個 \<更保險. ID: 字樣您用中文也行!另一個好用的例子是電話號碼前加上 TeL:, 就請您自行練習了!

[實例]

將檔案 3 至 7 行的資料向右移 2 個空白

:3,7s/.*/ &/

但這樣連空白行也是會插入空白字元, 較高明的做法是:

:3,7s/.\+/ &/

這樣空白行就不會去動它了!想通了 .* 及 .\+ 的意思了嗎?往前翻一下 . * \+ 的定義.

[實例]

將檔案 3 至 7 行的資料向左移 2 個空白

:3,7s/^ //

就是刪去行首的二個空白啦!

[實例]

將全文的 Edward 這個單字, 前後加上中括號

:%s/\/[&]/g

[實例]

將全文的 Edward 這個單字, 改成大寫的.

:%s/\/\U&/g

\U 不是代表非大寫字母嗎?喔!您搞錯位置了.\U 在 pattern 的位置的時候是指非大寫字母的樣式, 即 [^A-Z], 但如果是在置換字串位置的時候是指將其後的字串通通改成大寫.與其相對的是 \L, 會將其後的字串改為小寫. 詳細請 :h sub-replace-special.

[實例]

將全文每行最後加上
這個 HTML tag.

:%s/.*/SPMamp;
/g

怎麼樣, 是否已感覺到 regexp 威力無窮了呢?還是您已經快睡著了呢?:-)不過也請您想想, 如果是在沒有 regexp 功能的編輯器裡, 範例中的一些動作您會怎麼做呢?一個一個去改?
greedy 陷阱

regexp 會有貪心的傾向, 什麼意思呢?就是說在同一行內, 如果有多個符合 pattern 的情形, 會找最長的那一個.請注意!greedy 的特性是針對會反覆比對的 regexp 而言, 例如:*, \=, \+, \{} 等.前面所舉的 .* 的例子, 由於 greedy 的關係, 在整篇文章中做替換時, 會被當成是每一行整行, 因為 regexp 會去找每一行最長符合的那一個.

[實例]

This is a test. Test for regexp.

如果您下

:%s/[Tt].*t/program/g

原意是想把所有的 Test 或 test 換成 program 的, 結果由於 regexp 的貪心, 整個 ``This is a test. Test'' 會換成 program.結果原文就變成了 program for regexp. 因此在全文替換時要非常小心, 避免使用彈性太大的 regexp.像此例, 只要下面这样就可以了!

:%s/\<[Tt]est\>/program/g

最後提醒您, 這可不是 regexp 的全部, 礙於篇幅及在下功力的問題, 當然是沒辦法全面詳盡的向各位做介紹, 在下只是將各位領進門, 修行就得看各位了!
折疊(folding)
手動折疊

折疊的行為表現是由 foldmethod[fdm] 這個設定項來控制的, 這個設定項預設是 manual, 就是手動設定, 這是本節所要敘述的最基本折疊方式.其他折疊方式會在下一節介紹, 折疊的方式, 其中會有互相衝突的地方, 使用上請注意一下.
折疊的產生

手動產生折疊的指令是 zf、zF、:fo[ld], 以下以例子來說明較清楚.

zfap        將游標所在處的那個段落折疊成一行.zf7G        自游標所在處至全文第 7 行折疊起來.:3,9fold    將第 3 行至第 7 行折疊起來.5zF         將游標所在處起算 5 行的內容折疊起來.

也可以將所要折疊的部份以 Shift+v 標記起來, 然以按 zf 就會將標記的內容折疊起來.
折疊的操作

zo    將游標所在處的折疊打開. open.zc    將游標所在處已打開的內容再度折疊起來. close.zr    將全文的所有折疊依層次通通打開. reduce.zm    將全文已打開的折疊依層次通通再折疊起來. more.zR    作用和 zr 同, 但會打開含巢狀折疊(折疊中又還有折疊)的所有折疊.zM    作用和 zm 同, 但對於巢狀折疊亦有作用.zi    這是個切換, 是折疊與不折疊指令間的切換.zn    打開全文的所有折疊. fold none.zN    這是 zn 的相對指令, 回復所有的折疊.

那這個 zn 和 zR 不是都一樣嗎?不是的, zR 的作用於 foldlevel 這個設定項, 是控制折疊的層次,而 zn 則是作用於 foldenable 這個設定項, 他是不管層次的, 只有全關或全開.當然, 所得到的結果有許多情形下是一樣的, 但裡子不一樣, 這在寫 Vim script 時得小心分辨.

通常, 游標在折疊處向左或向右移的話, 折疊也會自動打開. 在進入編輯模式, 例如按 i 或 o, 這是也會自動打開折疊.

其他的複製、刪除及替換等動作還是可以和一般正常文稿一樣的操作,

例如 dd 就會刪掉一整個折疊, yy 會複製一整個折疊, p 會貼上一整個折疊. 把整個折疊就當做是一行就行了.

折疊的記憶

手動折疊, 在下一次開檔時就消失了, 但我們可以使用

:mkview

把折疊的情形記憶起來, 下一次載入同一個檔案時就可以下面这样記憶起以前折疊的情況.

:loadview

當然, 使用手動折疊及記憶, 在操作上並不是很方便, 除非是把他寫成 Vim script 來叫用. 因此下一節要談到自動折疊, 這可能會比較實用一點.
自動折疊

這裡比較實用的是依文件內的標誌來折疊, 因此其他的方式就只稍微介紹了.
以縮行為依據

:set foldmethod=indent

就會依縮行來折疊, 本來預設是

:set foldmethod=normal

請注意, 此時手動折疊的設定會被停止無法使用.
以特殊的表示法為依據

:set foldmethod=expr

另外還要設定

:set foldexpr=...,

可參考線上使用手冊 :h fold-expr 的例子.
以語法為依據

這是在定義語法(syntax)檔時同時加入折疊的定義. 然後

set foldmethod=syntax

就會依照這個語法定義檔去折疊, 請 :h syn-fold.
以是否更改過為依據

這在進入 vimdiff(即 vim -d file1 file2) 時會自動進入 foldmethod=diff 的模式,因此要 diff 設定項設在同一個螢幕顯示才行. 以便整體的瀏覽. 當然要自行更改預設值亦可. 預設是:

setlocal diff foldmethod=diff scrollbind nowrap foldlevel=1

這樣一來, 兩個檔案相同的部份會折疊起來, 沒有折疊的部份就是有差異的地方.
以文件上的標誌為依據

這是跟據文章中的標誌(marker)來做折疊. 這些標誌, 起於 {{{, 止於 }}}, 這中間的部份會折疊起來.通常這些標誌是藏在註解欄裡頭, 例如 C 程式碼的 /* 及 */ 之間, shell script 的 # 之後,Vim script 的 " 之後, 得視程式語言的不同而定, 因此一般的文章就不適合使用了.

這些預設的標誌也可以由 foldmarker 來更改, 但為了文件的流通性, 建議使用預設值就可以了.

當然, 一些程式碼載入時再來設定 :set foldmethod=marker 就太麻煩了, 這個設定可以設在文件內, 例如:

#!/bin/sh# 這是一個 sh script# {{{……這裡是 script 內容, 由 vim 打開這個檔時, 這個部份會自動折疊起來.……# }}}# vim:fdm=marker:ts=2

Vim tags 的使用

tag 指的是文件中的一種特殊的標誌, 在使用 Vim 時, 可以由很簡單的按鍵就馬上跳到那個文章及那個 tag 的位置,也可以跳回原處. 這個功能就好像目前的網頁上的 hyperlink 一樣. 但不一樣的是, 這個 tag 並不是寫在文件裡頭的,而是由 ctags 這支程式(或其他類此的工具程式)來產生相關檔的 tags, 然後存檔於一個外部檔案裡頭, 要用到時再由 Vim 叫出來.
各種程式碼專用 tag 工具

ctags       這是最常用到的, 可能會有兩種版本, 舊的 ctags 只能用於 C 程式碼. exuberant ctags 則可用於 C/C++、Java、Fortran……等等. 可由 ctags -version 得知版本.etags       這是 emacs/xemacs 所附的, 功能也是非常強大.JTags       這只能處理 Java 程式碼.ptags.py    處理 Python 程式碼.ptags       處理 Perl 程式碼.

這裡主要講述 exuberant ctags. 可 man ctags 或 ctags -help 得知所支援的程式語言.在 $VIMRUNTIME/tools 目錄下會有一些工具可以使用, 例如專用在 sh script, Tcl/Tk script 的 tag 工具.其他的 tags 工具, 系統上不一會安裝, 有需要的話得自行安裝, 一般使用, 應該 ctags 就夠用了, ctags 也可以模擬 etags.

以往, Vim 會附上 exuberant ctags, 但新近的版本已沒有附上, 得由使用者自行安裝, 或使用系統上就有的 ctags. 如果系統上的並不是 exuberant ctags, 可自行由 http://ctags.sourceforge.net 下載、安裝.
tags 檔案的格式

以下是一般 tag 檔的結構(以一行為例):

tagname TAB tagfile TAB tagaddress term fieldtagname    這是識別字的名稱, 通常就是一些函數名, 或其他任何識別字.TAB        這是老老實實的一個 Tab 鍵.tagfile    這是 tag 檔的檔名.tagaddress    這是 Ex 指令, 通常就是搜尋指令, 但行數也是可以.term    ;" 這個記號(兩個字元)以後的內容視為註解.field    待瞭解.

tag 檔案的製作

不講究的話, 可以在所解開的 source code 目錄下, 下以下指令:

ctags -R *

這樣會有 source code 目錄下產生一個 tags 這個檔(可以使用 -f 選項來指定檔案名),裡頭就包含了整個 source code 的所有檔案的 tags 資訊, 包括其下所有的子目錄下的檔案.ctags 已盡可能的做到聰明掃描檔案的能力, 會忽略和程式碼無關的檔案. 當然 ctags 還有許多精細的參數可以使用, 請 man ctags.

請注意, ctags 預設會將輸出檔排序, 因此不必自行另外去排序. 有排序有一個好處, 那就是 Vim 會去使用 binary search 的方式去搜尋, 這樣會比較快.
一般的 tag 使用

如果就照上一節的方式產生 tag files, 那麼只要在 source code 目錄下由 vim 去開啟檔案的話,會自動載入 tags 這個檔案, 無需另行載入, 否則要由 :set tags=your.tags 來指定 tags 檔.然後就是照一般使用 Vim 線上說明一樣, 游標移到識別字或函數名上, 按 Ctrl+], 要回到原處就按 Ctrl+T.

請注意, Vim 啟動時, 工作目錄(vim 啟動時的所在目錄)名為 tags 的檔案會自動載入, $VIMRUNTIME/doc 及 $HOME/.vim/doc 目錄下的 tags 檔也會自動載入.而且, 凡是載入的 tags 檔裡頭所有標誌文字都可以使用補全鍵來補全, 別忘了這個好用的功能.

有话要说