国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Vim 實(shí)用技術(shù),第 1 部分: 實(shí)用技巧
本系列文章分三部分詳細(xì)闡述了 Vim 的使用技巧、插件、定制。第一部分主要是深入分析了 Vim 的使用。

0. Vim 簡(jiǎn)介

作為開源世界最重要的編輯器之一(另一個(gè)是 Emacs),Vim 以其強(qiáng)大的功能和可定制能力被眾多開發(fā)者所喜愛。不過,也許就是因?yàn)?Vim 的功能太強(qiáng)大了,要真正用好 Vim 并不容易。本文作者在多年的實(shí)際使用中逐漸掌握了一些實(shí)用技術(shù),在此介紹給大家?!疚牟⒉黄髨D對(duì) Vim 作全面而系統(tǒng)的介紹,但也絕非零星地點(diǎn)到即止;而是希望通過介紹一些重要特性和提供相關(guān)參考信息,引起大家的興趣,去深入挖掘其能力,真正把這一強(qiáng)大的工具用好。

下面首先對(duì) Vim 做一下最基本的介紹,并給出一些參考信息,以方便對(duì) Vim 不熟悉的讀者也能夠理解并自己查閱進(jìn)一步信息。

與大部分其它編輯器不同,進(jìn)入 Vim 后,缺省狀態(tài)下鍵入的字符并不會(huì)插入到所編輯的文件之中。Vim 的模式(mode,可以簡(jiǎn)單地理解為“狀態(tài)”)概念非常重要。需要知道,Vim 有以下幾個(gè)模式:

  • 正常(normal)模式,缺省的編輯模式;下面如果不加特殊說(shuō)明,提到的命令都直接在正常模式下輸入;任何其它模式中都可以通過鍵盤上的 Esc 鍵回到正常模式。
  • 命令(command)模式,用于執(zhí)行較長(zhǎng)、較復(fù)雜的命令;在正常模式下輸入“:”(一般命令)、“/”(正向搜索)或“?”(反向搜索)即可進(jìn)入該模式;命令模式下的命令要輸入回車鍵(Enter)才算完成。
  • 插入(insert)模式,輸入文本時(shí)使用;在正常模式下鍵入“i”(insert)或“a”(append)即可進(jìn)入插入模式(也有另外一些命令,如“c”,也可以進(jìn)入插入模式,但這些命令有其它的作用)。
  • 可視(visual)模式,用于選定文本塊;可以在正常模式下輸入“v”(小寫)來(lái)按字符選定,輸入“V”(大寫)來(lái)按行選定,或輸入“Ctrl-V”來(lái)按方塊選定。
  • 選擇(select)模式,與普通的 Windows 編輯器較為接近的選擇文本塊的方式;在以可視模式和選擇模式之一選定文本塊之后,可以使用“Ctrl-G”切換到另一模式——該模式很少在 Linux 上使用,本文中就不再介紹了。

Vim 帶有完整的幫助文檔。在當(dāng)前的 Vim 6.4 的標(biāo)準(zhǔn)發(fā)布中,有一百多章、近六十萬(wàn)英文詞的幫助文件,進(jìn)入 Vim 后輸入“:help”(命令模式中輸入的命令要敲回車鍵才結(jié)束輸入,下面不再說(shuō)明這一點(diǎn))即可訪問。本文在介紹特性時(shí),對(duì)文檔中已經(jīng)說(shuō)明得很詳細(xì)的內(nèi)容只會(huì)提綱挈領(lǐng)地加以簡(jiǎn)短說(shuō)明和提供應(yīng)用范例,并提供訪問相應(yīng)的 Vim 文檔的命令。

一般的發(fā)布版中還常常帶有一個(gè)簡(jiǎn)單的 30 分鐘的 Vim 教程,新手在操作系統(tǒng)的命令行上輸入“vimtutor”命令即可開始學(xué)習(xí)。除上面的簡(jiǎn)單說(shuō)明外,本文并不介紹最基本的 Vim 命令,Vim 的新手應(yīng)該先通過教程熟悉一下 Vim,再繼續(xù)往下閱讀。

建議所有的 Vim 用戶經(jīng)常訪問 Vim 的主站點(diǎn) [1]。上面除了基本的發(fā)布、安裝、下載等信息外,最有用的內(nèi)容是用戶可以上傳自己寫的 Vim 腳本(script)和撰寫自己認(rèn)為有用的提示(tip),供其他 Vim 用戶使用。在寫這一段的時(shí)候,Vim 站點(diǎn)上已有一千三百多個(gè)腳本,提示數(shù)剛好超過了一千。對(duì)于序號(hào)為 nn 的腳本,直接訪問的 URL 是 http://www.vim.org/scripts/script.php?script_id=nn;對(duì)于序號(hào)為 nn 的提示,直接訪問的 URL 是 http://www.vim.org/tips/tip.php?tip_id=nn。

不另加說(shuō)明的話,本文討論的內(nèi)容適用于 Vim 版本 6(即從 6.0 到 6.4)。建議認(rèn)真的 Vim 用戶升級(jí)到 Vim 6.4,最好是自己編譯升級(jí)所有的補(bǔ)丁包。相關(guān)信息網(wǎng)站上都有,此處不再贅述。





回頁(yè)首


1. 實(shí)用技巧

1.1 安裝

如果從 Linux 發(fā)布版直接安裝 Vim,需要注意的一點(diǎn)是,缺省情況下系統(tǒng)并不一定為你安裝了一個(gè)完整的 Vim。比如,在 Red Hat(以及后來(lái)的 Fedora Core)的發(fā)布版中,Vim 被拆成了四個(gè)包:vim-common(公用部分),vim-minimal(最小安裝),vim-enhanced(除 X Window 支持外的完整安裝),和 vim-X11(X Window 圖形界面支持)。最小安裝不能完整展示 Vim 的優(yōu)點(diǎn),通常只是作為 vi 的替代品出現(xiàn),缺少很多重要的特性如多字節(jié)語(yǔ)言支持、鼠標(biāo)支持和腳本支持。如果裝了 X Window 的話,圖形界面的 gvim 也比文本模式的 vim 具有更多的特性。建議大家盡可能安裝完全的 Vim。

如果愿意稍稍費(fèi)一點(diǎn)功夫,自己編譯 Vim 的話,可以更好地定制 Vim?!綆У牧硪粋€(gè)好處是,你如果發(fā)現(xiàn)什么錯(cuò)誤的話,你就可以自己動(dòng)手來(lái)修復(fù)這個(gè)錯(cuò)誤,或至少找到錯(cuò)誤所在的位置,讓 Bram(Vim 的作者)可以更快地解決問題。圖 1 是在 Vim 中執(zhí)行“:version”的結(jié)果的一部分,可以看到 Vim 有很多不同的特性(feature)可在編譯時(shí)打開或關(guān)閉。如果自己編譯的話,就可以選擇打開需要的功能,關(guān)閉不需要的功能,來(lái)獲得一個(gè)既功能強(qiáng)大、又小巧快速的 Vim 定制版本。


圖 1

1.2 中文支持

Vim 支持世界上的主要語(yǔ)言,當(dāng)然也包括中文。如果你用 Vim 編輯中文,而中文不能正確顯示,那有兩種可能性:一是使用的 Vim 不完整,不含多字節(jié)語(yǔ)言支持(multi_byte 特性);二是某個(gè)配置出了問題。

說(shuō)到多語(yǔ)言支持,最基本的概念有兩個(gè):一是文件的語(yǔ)言編碼,而是環(huán)境的內(nèi)部編碼。在較老的操作系統(tǒng)中,不管 Linux 還是 Windows,這兩個(gè)編碼都是一樣的,也就意味著,一次只能處理一種編碼的文件:要么只能處理西文編碼(Latin1,即 ISO-8859-1 [5]),要么只能處理中文編碼(GB2312 [2])。而在新的操作系統(tǒng)中,這兩者可以是不一樣的。在 Linux 上,常見的情況是環(huán)境的內(nèi)部編碼使用 UTF-8 [6],而 UTF-8 可以同任何一種語(yǔ)言編碼作無(wú)損轉(zhuǎn)換,這就保證了系統(tǒng)的多語(yǔ)言處理能力。Vim 這方面秉承了 Unix/Linux 的傳統(tǒng),在內(nèi)部編碼使 UTF-8 的時(shí)候,可以同時(shí)處理不同意語(yǔ)言編碼的文件。

以下列出了和語(yǔ)言編碼的相關(guān)的設(shè)置:

  • 環(huán)境變量 LANG(使用的語(yǔ)言);
  • 環(huán)境變量 LC_CTYPE(使用的內(nèi)部編碼);
  • Vim 選項(xiàng) encoding(Vim 的內(nèi)部編碼);
  • Vim 選項(xiàng) termencoding(Vim 在與屏幕/鍵盤交互時(shí)使用的編碼);
  • Vim 選項(xiàng) fileencoding(Vim 當(dāng)前編輯的文件在存儲(chǔ)時(shí)的編碼);
  • Vim 選項(xiàng) fileencodings(Vim 打開文件時(shí)的嘗試使用的編碼);
  • Vim 選項(xiàng) ambiwidth(對(duì)“不明寬度”字符的處理方式;Vim 6.1.455 后引入)。

如果你的環(huán)境只需要處理簡(jiǎn)體中文的話,那么,最簡(jiǎn)單的方式就是所有的設(shè)定全部使用簡(jiǎn)體中文。只需要:設(shè)定 LANG=zh_CN.GB2312,不設(shè)定 LC_CTYPE(默認(rèn)跟 LANG 一樣),不設(shè)定與編碼相關(guān)的 Vim 選項(xiàng)(默認(rèn)由 LANG 和 LC_CTYPE 決定),也無(wú)需設(shè)定 Vim 選項(xiàng) ambiwidth。也就是說(shuō),我們把語(yǔ)言設(shè)定為中國(guó)(CN)使用的中文(zh),編碼為 GB2312(注意:Vim 內(nèi)部并不識(shí)別國(guó)標(biāo) GB18030 [3],所以此處只能設(shè) GB2312;參看下面關(guān)于 UTF-8 的討論)。

不過,如果按照目前 Linux 下的慣例,內(nèi)部編碼一律使用 UTF-8 的話,會(huì)有一些額外的好處,其中之一就是在這種情況下 Vim 支持同時(shí)編輯多種不同編碼的文件,如簡(jiǎn)體中文和繁體中文(參見圖 2);另外,此時(shí) Vim 也可以通過編碼轉(zhuǎn)換支持 GBK [4] 和 GB18030了。這樣,眾多關(guān)于語(yǔ)言編碼的 Vim 選項(xiàng)就有了用武之地了。下面進(jìn)一步說(shuō)明一下這些選項(xiàng)和推薦設(shè)定(如果適用的話):


圖 2

  • encoding=utf-8:不管文件的編碼如何,不管如何顯示和輸入,Vim 內(nèi)部使用的編碼是 UTF-8;這是國(guó)際化支持的基礎(chǔ)。
  • termencoding:取決于實(shí)際的終端或 X Window 的設(shè)定。舉例來(lái)說(shuō),如果選擇語(yǔ)言簡(jiǎn)體中文登錄到 X Window,或者正在使用 CXTERM [10] 的話,那么該選項(xiàng)應(yīng)被設(shè)為 GB2312;如果使用缺省的語(yǔ)言(LANG=en_US.UTF-8)登錄到 X Window,或者使用 PuTTY [11] 遠(yuǎn)程訪問 Linux 機(jī)器、并且設(shè)定里的字符編碼(配置中 Window-Translation)設(shè)為 UTF-8 的話,該選項(xiàng)就應(yīng)該設(shè)為 utf-8。從 Windows 下使用 PuTTY 遠(yuǎn)程連接 Linux 的請(qǐng)?zhí)貏e注意,測(cè)試表明,僅在使用 UTF-8 的情況下,PuTTY 才能可靠地支持中文的顯示和輸入(顯示字體必須設(shè)成中文字體)。
  • fileencoding:文件載入時(shí),該選項(xiàng)被置為 Vim 認(rèn)定的文件編碼,因此,存儲(chǔ)時(shí)文件的編碼不會(huì)改變。此處和下面 fileencodings 可使用的編碼為 libiconv 支持的所有幾百種編碼(如果編譯時(shí)包含了 iconv 特性的話),與中文相關(guān)的有 gb2312、gbk、gb18030、hz-gb-2312、iso-2022-cn、big5、cp936、cp950 等。如果創(chuàng)建新文件,你又不希望使用 UTF-8 作為文件編碼時(shí),那么,你可能需要手工設(shè)定該選項(xiàng),如“:set fileencoding=gb2312”。需要注意的一點(diǎn)是,使用“set”來(lái)設(shè)定該選項(xiàng)的話會(huì)改變以后新建文件的缺省編碼,而使用“setlocal”的話則只影響當(dāng)前文件(參考“:help setlocal”)。
  • fileencodings=ucs-bom,utf-8,chinese:Vim 會(huì)首先判斷文件的開頭是否是一個(gè) Unicode [7] 的 BOM(byte order mark)字符 [8],是的話則把文件的其余內(nèi)容解釋成相應(yīng)的 Unicode 序列;否的話再試圖把文件內(nèi)容解釋成 UTF-8 的序列;再失敗的話,則把文件解釋為簡(jiǎn)體中文(chinese 是一個(gè)跨平臺(tái)的簡(jiǎn)體中文字符集的別名,Linux 下相當(dāng)于 gb2312 和 euc-cn;此處也可以根據(jù)需要以 gb2312、gbk 或 gb18030 等編碼替代)。需要注意的是,該順序不能顛倒,并且在后面再添加其它編碼如 big5、latin1 也是沒有意義的,因?yàn)?Vim 不能識(shí)別 8 比特編碼中的錯(cuò)誤,因此這些編碼后列的編碼永遠(yuǎn)不會(huì)被用到。
  • ambiwidth=double:把所有的“不明寬度”字符 [9]——指的是在 Unicode 字符集中某些同時(shí)在東西方語(yǔ)言中使用的字符,如省略號(hào)、破折號(hào)、書名號(hào)和全角引號(hào),在西方文字中通常字符寬度等同于普通 ASCII 字符,而在東方文字中通常字符寬度等同于兩倍的普通 ASCII 字符,因而其寬度“不明”——的寬度置為雙倍字符寬度(中文字符寬度)。此數(shù)值只在 encoding 設(shè)為 utf-8 或某一 Unicode 編碼時(shí)才有效。需要額外注意的是,如果你通過終端使用 Vim 的話,需要令終端也將這些字符顯示為雙寬度。比如,XTERM [12] 的情況下應(yīng)該使用選項(xiàng)“-cjk”,即使用命令“uxterm -cjk”來(lái)啟動(dòng)使用雙寬度顯示這些字符的 Unicode X 終端;使用 PuTTY 遠(yuǎn)程連接的話則應(yīng)在配置的 Window-Translation 中選中“Treat CJK ambiguous characters as wide”(參見圖 3)。

    圖 3

需要設(shè)定的選項(xiàng)通常放在用戶的 Vim 資源配置文件中,即在 ~/.vimrc 文件中加入:


set encoding=utf-8                        set fileencoding=chinese                        set fileencodings=ucs-bom,utf-8,chinese                        set ambiwidth=double                        

如果想進(jìn)一步了解這些選項(xiàng)的話,可以使用“:help ‘選項(xiàng)‘”查看幫助文檔中的相關(guān)(英文)信息。幫助中也可以查到這些選項(xiàng)(以及命令)的縮寫:本文中為方便理解,除一些極少有人使用完整拼寫的命令如“:e(dit)”、“:s(ubstitute)”等之外,一般使用完整拼寫而不說(shuō)明或使用縮寫。關(guān)于配置文件 .vimrc,可以使用“:help .vimrc”查看相關(guān)信息。

在使用內(nèi)部編碼 UTF-8 的情況下,如需編輯 fileencodings 之外(其不能自動(dòng)識(shí)別)的文件,則可以使用以下命令:“:e ++enc=編碼 文件名”。詳情可參考“:help ++enc”。

1.3. 鼠標(biāo)支持

不管是文本界面還是圖形界面的 Vim,都支持鼠標(biāo)。不過,在文本界面中,鼠標(biāo)支持缺省沒有被激活;這就意味著,在終端上使用鼠標(biāo),所有的功能仍和沒有使用 Vim 時(shí)相同,并不受 Vim 影響。要激活文本界面中的鼠標(biāo)支持也很容易,只需要執(zhí)行一句“:set mouse=a”即可。

啟用了鼠標(biāo)支持之后,Vim 主要支持的鼠標(biāo)操作有:

  • 單擊移動(dòng)光標(biāo)到點(diǎn)擊的位置;
  • 在幫助的關(guān)鍵字上雙擊顯示該關(guān)鍵字相關(guān)的幫助信息;
  • 在普通文本上雙擊選中點(diǎn)擊位置的單詞;
  • 拖動(dòng)鼠標(biāo)選中文本;
  • 使用鼠標(biāo)滾輪滾動(dòng)當(dāng)前緩沖區(qū)中的文本;
  • 多窗口編輯時(shí)可以拖動(dòng)窗口分欄的位置。

進(jìn)一步的信息可參看“:help ‘mouse‘”、“:help mouse-using”和“:help scroll-mouse-wheel”。

特別需要值得一提的是,在遠(yuǎn)程訪問 Linux 系統(tǒng)時(shí)也是可以使用鼠標(biāo)的。如果使用 X Window 系統(tǒng),自然不必說(shuō);而使用 SSH 遠(yuǎn)程連接時(shí),大部分 Linux 下的終端客戶程序,如 XTERM、GNOME-Terminal [13]、較新版本的 Konsole [14],以及 Windows 下的 PuTTY,支持鼠標(biāo)的使用:你只需簡(jiǎn)單地啟動(dòng) Vim、執(zhí)行一句“:set mouse=a”就可以了(當(dāng)然,也可以把上面的語(yǔ)句去掉起始的冒號(hào)放到 .vimrc 文件中)。

1.4. 空格、制表符和縮進(jìn)

對(duì)于編寫代碼,縮進(jìn)是最基本的概念之一。至于縮進(jìn)是使用空格還是制表符(Tab),或者縮進(jìn)是否正好使用一個(gè)制表符來(lái)表示,很多程序員,特別是 Windows 開發(fā)出身的程序員,很容易混淆。幸好,Vim 對(duì)于這些概念有非常完整的支持,足以應(yīng)付各種復(fù)雜的情況。以下是相關(guān)的主要 Vim 選項(xiàng):

  • shiftwidth(縮進(jìn)的空格數(shù));
  • tabstop(制表符的寬度);
  • expandtab(是否在縮進(jìn)和遇到 Tab 鍵時(shí)使用空格替代;使用 noexpandtab 取消設(shè)置);
  • softtabstop(軟制表符寬度,設(shè)置為非零數(shù)值后使用 Tab 鍵和 Backspace 時(shí)光標(biāo)移動(dòng)的格數(shù)等于該數(shù)值,但實(shí)際插入的字符仍受 tabstop 和 expandtab 控制);
  • autoindent(自動(dòng)縮進(jìn),即每行的縮進(jìn)值與上一行相等;使用 noautoindent 取消設(shè)置);
  • cindent(使用 C 語(yǔ)言的縮進(jìn)方式,根據(jù)特殊字符如“{”、“}”、“:”和語(yǔ)句是否結(jié)束等信息自動(dòng)調(diào)整縮進(jìn);在編輯 C/C++ 等類型文件時(shí)會(huì)自動(dòng)設(shè)定;使用 nocindent 取消設(shè)置);
  • cinoptions(C 語(yǔ)言縮進(jìn)的具體方式,請(qǐng)參考“:help cinoptions-values”);
  • paste(粘貼模式,會(huì)取消所有上述選項(xiàng)的影響來(lái)保證后面的操作——通常是從剪貼板粘貼代碼——保持原有代碼的風(fēng)格;使用 nopaste 取消設(shè)置)。

下面給出一些常用的組合:

  • shiftwidth=4 tabstop=4:很多 Windows 出身的程序員會(huì)習(xí)慣這樣的設(shè)置,讓縮進(jìn)等于制表符寬度。
  • shiftwidth=4 tabstop=8:很多 Unix 程序員的設(shè)置,仍使用較常用的 4 格縮進(jìn),但制表符寬度為標(biāo)準(zhǔn)的 8。
  • cinoptions=>4,n-2,{2,^-2,:2,=2,g0,h2,p5,t0,+2,(0,u0,w1,m1 shiftwidth=2 tabstop=8:標(biāo)準(zhǔn)的 GNU 編碼風(fēng)格的設(shè)置,對(duì) Vim 缺省的 C 縮進(jìn)風(fēng)格作了很多微調(diào),比如,if 語(yǔ)句下的“{”、“}”要在“if”后縮進(jìn)兩格,但函數(shù)定義部分“{”、“}”仍和函數(shù)名一行對(duì)齊。開源軟件經(jīng)常使用該種縮進(jìn)風(fēng)格。

在編輯代碼時(shí)一個(gè)很有用的命令是調(diào)整代碼縮進(jìn),可以很方便地增加(或減少)若干級(jí)縮進(jìn),并自動(dòng)根據(jù)選項(xiàng)設(shè)定使用正確的空格或制表符。只需要使用“V”選中你要調(diào)整的代碼行,然后鍵入“<”(或“>”)即可增加(或減少)一級(jí)縮進(jìn);在鍵入“<”(或“>”)之前鍵入數(shù)字則可以指定增加(或減少)的縮進(jìn)級(jí)數(shù)。

我們要討論的最后一個(gè)相關(guān)的命令是“:retab”。在設(shè)定了 expandtab 選項(xiàng)時(shí),該選項(xiàng)會(huì)把所有的制表符轉(zhuǎn)換成空格。在沒有設(shè)定 expandtab 選項(xiàng)時(shí),使用“:retab!”可把空白字符轉(zhuǎn)換成制表符(可能誤轉(zhuǎn)換,慎用),使用“:retab n”可以把 tabstop 重置為 n,并轉(zhuǎn)換含制表符的連續(xù)空白字符為適當(dāng)?shù)闹票矸涂崭竦慕M合以保證含制表符的行看起來(lái)沒有任何變化。詳細(xì)信息請(qǐng)參看“:help :retab”。

1.5. 模式行(modeline)

沒人愿意每次都手工輸入一大堆的 Tab 和縮進(jìn)設(shè)定。可是,放在 .vimrc 文件中似乎也不是個(gè)好主意:如果我編輯的代碼不止一種風(fēng)格呢?——考慮一下,如果你參加開源軟件項(xiàng)目,你能保證你參加的所有項(xiàng)目,還有你公司里的軟件項(xiàng)目,代碼風(fēng)格都一樣嗎?——Vim 是我用過的第一個(gè)支持在文件中記錄代碼風(fēng)格設(shè)定的編輯器。這個(gè)特性在 Vim 中叫做模式行,實(shí)際上,它所做的是在打開文件時(shí)根據(jù)文件中的 Vim 指令設(shè)定相關(guān)的 Vim 選項(xiàng)。下面就是一個(gè)嵌在 C 源代碼中的模式行:


/* vim: set tabstop=4 shiftwidth=4 expandtab: */                        

模式行有好幾種形式。本文只介紹上面的這種形式(其它形式類似,請(qǐng)自行參考“:help modeline”):行首的“/*”和尾部的“*/”告訴 C 編譯器這是一行注釋,不是代碼的一部分;而 Vim 可通過后面的“vim:”識(shí)別出模式行的開始(必須出現(xiàn)在行首或前面有一個(gè)空白字符);后面則是“set”和空格間隔開的一串 Vim 選項(xiàng);“:”表示模式行結(jié)束。

這種方式非常簡(jiǎn)單,功能也非常強(qiáng)大。另外請(qǐng)注意,出于安全的考慮,模式行中的選項(xiàng)只影響當(dāng)前文件(“:help modeline-local”),也不能做任何設(shè)置選項(xiàng)以外的工作。

1.6. 寄存器

通常的編輯器有一個(gè)剪貼板,以存儲(chǔ)復(fù)制和剪切的內(nèi)容。Vim 中的類似概念叫做寄存器(register)。除了有一個(gè)無(wú)名寄存器外,Vim 還有一大堆有名的寄存器,可以通過“"”(參見“:help "”)或“Ctrl-R”(參見“:help i_CTRL-R”和“:help c_CTRL-R”)加寄存器名(字母、數(shù)字和某些特殊字符,參見“:help registers”;“無(wú)名”寄存器的名字是“"”)來(lái)訪問。比如,你先使用“"ayy”復(fù)制了一行,然后使用“dd”刪掉了一行,然后移動(dòng)光標(biāo)到要復(fù)制到的位置,就可以使用“"aP”把先前復(fù)制的內(nèi)容粘貼上去了。手工編輯是有名寄存器的作用還不是很大,但當(dāng)你想讓 Vim 通過類似于宏的方式自動(dòng)完成工作時(shí),有名寄存器就變成不可缺少的重要功能了。下面我們還會(huì)用到。

在使用 X Window 系統(tǒng)時(shí),有兩個(gè)特殊的寄存器是需要注意一下的:“"*”訪問的寄存器是 X 的主選擇區(qū)域(primary selection),“"+”訪問的寄存器是 X 的剪貼板(clipboard)。如果你要在 Vim 和其它的 X 應(yīng)用程序之間復(fù)制文本內(nèi)容,你可以試一下這兩個(gè)寄存器。

還有一個(gè)很特殊的“寄存器”:“=”。在插入模式或命令模式中,鍵入“Ctrl-R=”,Vim 會(huì)提示你輸入一個(gè)表達(dá)式,普通的整數(shù)運(yùn)算在此完全有效。如果想要進(jìn)行浮點(diǎn)運(yùn)算,請(qǐng)參見第 3.2 節(jié)中的技巧。

1.7. 搜索、替換和正則表達(dá)式

大家應(yīng)該都已經(jīng)知道 Vim 里使用“/模式”(或“?模式”)進(jìn)行搜索,使用“:s/模式/字符串/標(biāo)志”進(jìn)行替換,其中的“模式”是一個(gè)正則表達(dá)式。關(guān)于正則表達(dá)式,不熟悉的話可以邊用邊學(xué),本節(jié)也不打算對(duì) Vim 的正則表達(dá)式作完整的闡述(那可能可以專門寫一本小冊(cè)子了),而只拋磚引玉式地給出一些有用的例子加以說(shuō)明,以及一些實(shí)用技巧。

先說(shuō)一點(diǎn)點(diǎn)搜索。搜索里最最有用的一個(gè)快捷方式是“*”(向下完整匹配光標(biāo)下的單詞)。把光標(biāo)移動(dòng)到你要搜索的詞(變量名、函數(shù)名等)上,比如“test”,然后按“*”,Vim 將自動(dòng)產(chǎn)生一個(gè)對(duì)“\<test\>”(參見“:help /\<”和“:help /\>”)的搜索,也就是說(shuō),搜索完整的單詞“test”。不要小看這個(gè)技巧,它經(jīng)??梢源蠓鹊靥岣咚阉鞯乃俣?。事實(shí)上,這是 Vim 網(wǎng)站上公布的第 1 號(hào)技巧,也是被評(píng)價(jià)最高的技巧。相似的技巧還有“#”(向上完整匹配光標(biāo)下的單詞)、“g*”(向下部分匹配光標(biāo)下的單詞)等,請(qǐng)自行查看(“:help #”等)。

Vim 在搜索和替換時(shí)會(huì)對(duì)匹配成功的文本進(jìn)行加亮,在已經(jīng)完成搜索和替換任務(wù)后,這種加亮有時(shí)反而會(huì)妨礙顯示。Vim 專門提供一個(gè)命令取消這種加亮(直到用戶再一次使用搜索或替換命令):“:nohlsearch”。建議用戶創(chuàng)建一個(gè)鍵盤映射(key mapping)加入到 .vimrc 中,如:


nmap <F2> :nohlsearch<CR>                        

以上命令表示,在正常模式下按 F2 鍵相當(dāng)于輸入“:nohlsearch”后面跟一個(gè)回車,即取消搜索加亮顯示。

再看幾個(gè)搜索替換的實(shí)用例子。

  • 去掉所有的行尾空格:“:%s/\s\+$//”?!?”表示在整個(gè)文件范圍內(nèi)進(jìn)行替換,“\s”表示空白字符(空格和制表符),“\+”對(duì)前面的字符匹配一次或多次(越多越好),“$”匹配行尾(使用“\$”表示單純的“$”字符);被替換的內(nèi)容為空;由于一行最多只需替換一次,不需要特殊標(biāo)志。這個(gè)還是比較簡(jiǎn)單的。
  • 去掉所有的空白行:“:%s/\(\s*\n\)\+/\r/”。這回多了“\(”、“\)”、“\n”、“\r”和“*”。“*”代表對(duì)前面的字符(此處為“\s”)匹配零次或多次(越多越好;使用“\*”表示單純的“*”字符),“\n”代表?yè)Q行符,“\r”代表回車符,“\(”和“\)”對(duì)表達(dá)式進(jìn)行分組,使其被視作一個(gè)不可分割的整體。因此,這個(gè)表達(dá)式的完整意義是,把連續(xù)的換行符(包含換行符前面可能有的連續(xù)空白字符)替換成為一個(gè)單個(gè)的換行符。唯一很特殊的地方是,在模式中使用的是“\n”,而被替換的內(nèi)容中卻不能使用“\n”,而只能使用“\r”。原因是歷史造成的,詳情如果有興趣的話可以查看“:help NL-used-for-Nul”。
  • 去掉所有的“//”注釋:“:%s!\s*//.*!!”。首先可以注意到,這兒分隔符改用了“!”,原因是在模式或字符串部分使用了“/”字符,不換用其他分隔符的話就得在每次使用“/”字符本身時(shí)寫成“\/”,上面的命令得寫成“:%s/\s*\/\/.*//”,可讀性較低。命令本身倒是相當(dāng)簡(jiǎn)單,用過正則表達(dá)式的人估計(jì)都知道“.”匹配表示除換行符之外的任何字符吧。
  • 去掉所有的“/* */”注釋:“:%s!\s*/\*\_.\{-}\*/\s*! !g”。這個(gè)略有點(diǎn)復(fù)雜了,用到了幾個(gè)不太常用的 Vim 正則表達(dá)式特性。“\_.”匹配包含換行在內(nèi)的所有字符;“\{-}”表示前一個(gè)字符可出現(xiàn)零次或多次,但在整個(gè)正則表達(dá)式可以匹配成功的前提下,匹配的字符數(shù)越少越好;標(biāo)志“g”表示一行里可以匹配和替換多次。替換的結(jié)果是個(gè)空格的目的是保證像“int/* space not necessary around comments */main()”這樣的表達(dá)式在替換之后仍然是合法的。

希望上面的這些簡(jiǎn)單的例子能夠引起你使用 Vim 的正則表達(dá)式高效完成任務(wù)的興趣。進(jìn)一步的信息可參考“:help regexp”。

1.8. 自動(dòng)完成和路徑設(shè)定

Vim 支持單詞的自動(dòng)完成。比如,你前面使用了一個(gè)很長(zhǎng)的變量名,叫 aLongVariable,下面你在輸入時(shí),就不用完整鍵入了。很可能,你只需要鍵入“aL”,然后按下“Ctrl-P”(向前搜索可匹配的單詞并完成)就可以得到完整的變量名(沒有得到想要的結(jié)果的話,多按幾下“Ctrl-P”;或者前面多輸入幾個(gè)字符,如“aLongV”)。類似的命令還有“Ctrl-N”(向后搜索可匹配的單詞并完成)、“Ctrl-X Ctrl-L”(搜索可匹配的行并完成)、“Ctrl-X Ctrl-F”(搜索可匹配的文件名并完成)等,具體可參看“:help ins-completion”。

如果你并不熟悉這些功能,但也并不覺得這有什么稀奇的話,下面這個(gè)例子可能會(huì)讓你覺得吃驚。請(qǐng)嘗試打開一個(gè)空白的 C 文件(vim test.c),并輸入:


#include <stdio.h>                        int main()                        {                        pri                        

最后一行不要回車,直接在“pri”后面輸入“Ctrl-P”,你將看到“printf”出現(xiàn)。是的,雖然文件里沒有“printf”,但 Vim 知道到哪里去尋找它!在作關(guān)鍵字匹配完成時(shí),如果當(dāng)前文件和其它打開的文件中沒有想要的結(jié)果,Vim 會(huì)自動(dòng)到“#include”的文件中進(jìn)行進(jìn)一步的搜索(為什么是“#include”呢?請(qǐng)查閱“:help ‘include‘”),搜尋的目錄則由選項(xiàng) path 決定,其缺省值在 Unix(含 Linux)下為“.,/usr/include,,”,代表搜索的目錄依次是文件所在目錄、/usr/include 和當(dāng)前目錄。根據(jù)實(shí)際情況,你可能需要在 .vimrc 文件中設(shè)置該選項(xiàng),加入項(xiàng)目相關(guān)的包含目錄,注意一般要保留最后的“,,”,除非你不需要在當(dāng)前目錄下搜索。

設(shè)置了合適的 path 后,另外帶來(lái)的一個(gè)便利就是可以使用“gf”命令方便地跳轉(zhuǎn)到光標(biāo)下的文件名所代表的文件中。在上面的例子中,把光標(biāo)移到“stdio.h”的任一字符上,鍵入“gf”,則 Vim 會(huì)自動(dòng)打開 /usr/include/stdio.h 文件。使用“Ctrl-O”(參見“:help CTRL-O”)可返回到原先的文件中。

1.9. 文件跳轉(zhuǎn)和 Tags

大家一般都知道,在 Vim 的幫助窗口中的關(guān)鍵字上雙擊鼠標(biāo)或者鍵入“Ctrl-]”即可跳轉(zhuǎn)至該關(guān)鍵字相關(guān)的幫助主題。不過,“跳轉(zhuǎn)至匹配的關(guān)鍵字”這一功能并不僅僅局限于幫助文件。只要有合適的 tags 文件(參見“:help tags-file-format”),我們同樣可以在源代碼中使用這個(gè)方便的功能,跳轉(zhuǎn)到與關(guān)鍵字匹配的“標(biāo)記”處(通常是源代碼中某一函數(shù)、類型、變量或宏的定義位置)。

要產(chǎn)生 tags 文件,通常我們使用 Exuberant Ctags [15]。一般的 Linux 發(fā)布版中均帶有這一工具。Ctags 帶有的選項(xiàng)數(shù)量極多,此處我們僅簡(jiǎn)單介紹如何在一個(gè)典型的多文件、多層目錄的項(xiàng)目中使用其基本功能:我們只需在項(xiàng)目的根目錄處鍵入“ctags -R .”,Ctags 即可自動(dòng)在文件中查找、識(shí)別支持的文件格式、生成 tags 文件。目前 Exuberant Ctags 支持多達(dá) 33 種編程語(yǔ)言 [16],包括了 Linux 下常用的 C、C++、Java、Perl、PHP 等。有了 tags 文件,以下的 Vim 命令就可以方便使用了(進(jìn)一步的信息可參考“:help tags-and-searches”):

  • :tag 關(guān)鍵字(跳轉(zhuǎn)到與“關(guān)鍵字”匹配的標(biāo)記處)
  • :tselect [關(guān)鍵字](顯示與“關(guān)鍵字”匹配的標(biāo)記列表,輸入數(shù)字跳轉(zhuǎn)到指定的標(biāo)記)
  • :tjump [關(guān)鍵字](類似于“:tselect”,但當(dāng)匹配項(xiàng)只有一個(gè)時(shí)直接跳轉(zhuǎn)至標(biāo)記處而不再顯示列表)
  • :tn(跳轉(zhuǎn)到下一個(gè)匹配的標(biāo)記處)
  • :tp(跳轉(zhuǎn)到上一個(gè)匹配的標(biāo)記處)
  • Ctrl-](跳轉(zhuǎn)到與光標(biāo)下的關(guān)鍵字匹配的標(biāo)記處;除“關(guān)鍵字”直接從光標(biāo)位置自動(dòng)獲得外,功能與“:tags”相同)
  • g](與“Ctrl-]”功能類似,但使用的命令是“:tselect”)
  • g Ctrl-](與“Ctrl-]”功能類似,但使用的命令是“:tjump”)
  • Ctrl-T(跳轉(zhuǎn)回上次使用以上命令跳轉(zhuǎn)前的位置)

當(dāng)我們?cè)陧?xiàng)目的根目錄下工作時(shí),上面這些命令工作得很好。但如果我們進(jìn)到多層目錄的里層再運(yùn)行 Vim 打開文件時(shí),這些命令的執(zhí)行結(jié)果通常就變成了錯(cuò)誤信息“E433: No tags file”。這是因?yàn)槿笔?Vim 只在文件所在目錄和當(dāng)前目錄下尋找 tags 文件,而我們前面只在項(xiàng)目的根目錄下生成了 tags 文件,Vim 無(wú)法找到該文件。解決方法有好幾種,我認(rèn)為一般較簡(jiǎn)單的做法是對(duì)每個(gè)項(xiàng)目都在 .vimrc 文件中增加一個(gè)路徑相關(guān)設(shè)定。假設(shè)我們有兩個(gè)項(xiàng)目,位置分別是 /home/my/proj1 和 /home/my/proj2,那我們可以使用:


au BufEnter /home/my/proj1/* setlocal tags+=/home/my/proj1/tags                        au BufEnter /home/my/proj2/* setlocal tags+=/home/my/proj2/tags                        

Vim 選項(xiàng) tags 用于控制檢查的 tags 文件,缺省值為“./tags,tags”,即前面所說(shuō)的文件所在目錄下和當(dāng)前目錄下的 tags 文件。上面兩行自動(dòng)命令告訴 Vim,在打開項(xiàng)目目錄下的文件時(shí),tags 選項(xiàng)中的內(nèi)容要增加項(xiàng)目的 tags 文件的路徑。進(jìn)一步信息可參看“:help ‘tags‘”。

1.10. Make 和 grep

Make [17] 和grep [18] 應(yīng)當(dāng)算是 Unix 世界里無(wú)人不曉的基本工具了吧。很自然的,Vim 對(duì)它們有著特殊的支持。該支持主要通過訪問一個(gè)特殊的快速修訂窗口(quickfix window)來(lái)實(shí)現(xiàn)。直接在 Vim 的命令模式里輸入相應(yīng)的 make 或 grep 命令(如“:grep foo *.c”)即可將命令的執(zhí)行結(jié)果放入該窗口,同時(shí)根據(jù)返回的結(jié)果跳轉(zhuǎn)到第一個(gè)錯(cuò)誤(make 的情況;在使用 grep 時(shí)是匹配成功之處)。以下是常用的“快速修訂”命令:

  • :cn(顯示下一個(gè)錯(cuò)誤)
  • :cp(顯示上一個(gè)錯(cuò)誤)
  • :cl(列出所有的錯(cuò)誤及其編號(hào))
  • :cc(跳轉(zhuǎn)到指定編號(hào)的錯(cuò)誤)
  • :copen(打開快速修訂窗口,在其中顯示所有錯(cuò)誤,可在錯(cuò)誤上雙擊鼠標(biāo)或按回車鍵跳轉(zhuǎn)至該錯(cuò)誤;示例參見圖 4)

    圖 4

  • :cclose(關(guān)閉快速修訂窗口)

Vim 的這個(gè)特性也可以與 make 和 grep 以外的程序一起工作(事實(shí)上,在 Windows XP 上,“:grep”命令一般調(diào)起的是“findstr /n”)。具體調(diào)用那個(gè)程序由選項(xiàng) makeprg(Linux 下缺省為“make”)和 grepprg(Linux 下缺省為“grep -n $* /dev/null”)控制,而如何解析返回的內(nèi)容則由選項(xiàng) errorformat 和 grepformat 控制。鑒于在 Unix/Linux 下一般不需更改這些選項(xiàng)的內(nèi)容,此處不再詳述。

1.11. 執(zhí)行外部命令

在“:make”這樣的命令中,Vim 會(huì)自動(dòng)調(diào)用外部的程序。用戶當(dāng)然也可以自己執(zhí)行外部的程序:估計(jì)很多的人都已經(jīng)知道了用“:!命令”可以在 Vim 中執(zhí)行一個(gè)外部命令。不過,估計(jì)大部分人都不知道,還有其它一些命令可以執(zhí)行外部命令,并且,即使“:!”命令里面也有一些技巧可以使用。

最正規(guī)的執(zhí)行外部命令的方法,如前所述,就是“:!”。比如,我們想要顯示當(dāng)前目錄下的所有文件,就可以直接執(zhí)行:“:!ls”。Vim 會(huì)在一個(gè)終端窗口中進(jìn)行文件列表,然后提示我們按鍵返回 Vim 中。事實(shí)上,這種方式對(duì)于“cp”、“rm”這樣基本不需要輸出的命令比較實(shí)用,而對(duì)于“l(fā)s”這樣關(guān)注于輸出的命令并不太適用。

如果想把外部命令執(zhí)行的結(jié)果插入到當(dāng)前編輯的緩沖區(qū)中,可以考慮使用“:r!”。比如,我們使用“:r!ls”,就可以把“l(fā)s”命令的執(zhí)行結(jié)果插入到緩沖區(qū)中光標(biāo)所在行下面。在使用宏時(shí),這可能會(huì)特別有用。

Vim 的“:!”命令還有一個(gè)特別強(qiáng)大的技巧可以使用。拿一個(gè)實(shí)際例子,我們需要對(duì)在一個(gè)文件的每一行之前插入一個(gè)編號(hào),該怎么做呢?——用 Vim 的宏或者腳本可以完成這一工作,但這不是最高效、最靈活的工作方式。Linux 下一般帶有的 GNU 的 nl,可以用非常靈活的方式來(lái)完成這一任務(wù)——要對(duì)所有的非空行進(jìn)行編號(hào),只需要“:%!nl”;要對(duì)包含空行的所有行進(jìn)行編號(hào)?OK,“:%!nl -ba”。

稍作一點(diǎn)解釋。當(dāng)使用可視模式選中文本行后然后鍵入“:!”(命令行上將出現(xiàn)“:‘<,‘>!”,表示命令的范圍是選定的文本),或者使用“:%!”(表示命令的范圍是整個(gè)緩沖區(qū)中的文本),Vim 在執(zhí)行后面的命令時(shí),將把命令范圍里的文本行作為后面執(zhí)行的命令標(biāo)準(zhǔn)輸入,并用命令執(zhí)行后的標(biāo)準(zhǔn)輸出替換當(dāng)前緩沖區(qū)中的這些文本行。這就是上面的命令行的工作原理。

1.12. 定寬文本排版

在傳統(tǒng)的 Unix 環(huán)境下,文本文件的定義是具有一定長(zhǎng)度限制的文本行的組合 [19]。雖然 Vim 本身對(duì)行的長(zhǎng)度沒有任何實(shí)際的限制,但有一些工具有這樣的限制。為了最大程度的兼容性,也為了在顯示、打印等處理上比較方便,一般推薦在郵件和源代碼中一般不要超出 72 列(最多不超出 80 列)。Vim 在處理定寬的文本方面具有特殊的支持能力。下面是一個(gè)在 Vim 中把行寬(使用選項(xiàng) textwidth)設(shè)為 40 后輸入 Harry Potter and the Half-Blood Prince 的第一句話的結(jié)果:


It was nearing midnight and the Prime                        Minister was sitting alone in his                        office, reading a long memo that was                        slipping through his brain without                        leaving the slightest trace of meaning                        behind.                        

輸入時(shí)我只使用了英文字母和空格,換行符都是 Vim 自動(dòng)插入的。如果在某一行加入或刪除了一些字符后行不就不齊了嗎,該如何處理?很簡(jiǎn)單,把光標(biāo)移到要重新格式化的文本開頭,使用“gq”命令后面跟一個(gè)光標(biāo)移動(dòng)命令確定重新格式化的范圍。比如“gq}”(格式化一段),“gq5j”(格式化 5 行),“gqG”(格式化至文件末尾)。

除了選項(xiàng) textwidth 外,選項(xiàng) formatoptions 確定了跟文本格式化有關(guān)的基本選項(xiàng),常用的數(shù)值有:

  • t:根據(jù) textwidth 自動(dòng)折行;
  • c:在(程序源代碼中的)注釋中自動(dòng)折行,插入合適的注釋起始字符;
  • r:插入模式下在注釋中鍵入回車時(shí),插入合適的注釋起始字符;
  • q:允許使用“gq”命令對(duì)注釋進(jìn)行格式化;
  • n:識(shí)別編號(hào)列表,編號(hào)行的下一行的縮進(jìn)由數(shù)字后的空白決定(與“2”沖突,需要“autoindent”);
  • 2:使用一段的第二行的縮進(jìn)來(lái)格式化文本;
  • l:在當(dāng)前行長(zhǎng)度超過 textwidth 時(shí),不自動(dòng)重新格式化;
  • m:在多字節(jié)字符處可以折行,對(duì)中文特別有效(否則只在空白字符處折行);
  • M:在拼接兩行時(shí)(重新格式化,或者是手工使用“J”命令),如果前一行的結(jié)尾或后一行的開頭是多字節(jié)字符,則不插入空格,非常適合中文

上面提到的注釋,可以是 C/C++ 中的“//”和“/*”,也可以是郵件中引用原文使用的“>”等字符(具體由 comments 選項(xiàng)控制;參見“:help ‘comments‘”)。Vim 在遇到這些字符時(shí),能夠相當(dāng)智能地進(jìn)行處理,足以完成日常編輯源代碼和郵件的需要。在使用一些處理純文本不夠強(qiáng)大的郵件客戶端時(shí),我通常使用 Vim 編輯郵件(特別是英文郵件),然后把結(jié)果貼回到郵件編輯窗口中進(jìn)行發(fā)送。

Vim 中 formatoptions 的缺省值是“tcq”,一般我會(huì)在 .vimrc 文件中加入一行“set formatoptions+=mM”來(lái)確保 Vim 能在中文字符之間折行而不要求空格的存在,并且在大部分情況下可以正確地處理中文重新格式化。

1.13. 其它小技巧

也許你會(huì)覺得這些很有用:

  • %(跳轉(zhuǎn)到與之匹配的括號(hào)處)
  • .(重復(fù)上次的修改命令)
  • `.(跳轉(zhuǎn)到最近修改過的位置)
  • ZQ(無(wú)條件退出)
  • ZZ(存盤退出)
  • ga(顯示光標(biāo)下的字符在當(dāng)前使用的 encoding 下的內(nèi)碼)
  • guw(光標(biāo)下的單詞變?yōu)樾懀?
  • gUw(光標(biāo)下的單詞變?yōu)榇髮懀?
  • :TOhtml(根據(jù) Vim 的語(yǔ)法加亮的方式生成 HTML 代碼;在圖形界面中也可以使用菜單“Syntax—Convert to HTML”達(dá)到同樣效果)

無(wú)聊的時(shí)候,還可以試試(呵呵?。?/p>

  • :help!
  • :help 42
  • :help holy-grail
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
[vim與gvim技巧]vim&gvim技巧大全(10)
vimrc配置
人人都會(huì)Vim
利器系列之 —— 編輯利器 Vim 之基礎(chǔ)配置 | 時(shí)習(xí)之
VIM配置詳解
*25.1* 斷行
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服