顯示具有 vim 標籤的文章。 顯示所有文章
顯示具有 vim 標籤的文章。 顯示所有文章

2013/03/13

用 vim 調整 tab 和空白混合的程式碼

之前的筆記提過混合 tab 和空白造成 coding style 混亂的問題和建議解法:
在你決定好 coding style 之後,還是要面對一個問題:如何將 tab 和空白已經混亂的程式碼調整好?

方法一是用 Artistic Style 之類的程式碼美化軟體重新編排。這種方法的優點和缺點是重新編排的範圍包含縮排和斷行方式,甚至運算子和括號前後是否需要加上空白等等。若只想針對 tab 和空白做調整,這方式是有風險的大手術。

方法二是利用 vim 半人工轉換。此方法適合縮排大致正確,只需處理 tab 和空白的情況。以下,簡單介紹這個方法。
  1. 首先,請 設定 vim 分別顯示 tab 和空白字元,這樣你才能清楚分辨。
  2. 參考本文一開始介紹的兩篇文章,設定好你理想的 tab 字元處理方式。
  3. 瀏覽你的程式碼,確認縮排位置是否正確,有錯就修正。注意!只看位置,不管 tab 和空白是否混淆。
  4. 然後,執行 vim 的 ":retab" 指令就可按照你的設定重新調整 tab 和空白了 (記得存檔)。若你 coding style 的縮排是用空白字元,也就是這次調整你要將 tab 轉成空白,以上方法可達到完美的程度。但,若你決定以 tab 字元縮排,以上方法會保留不含 tab 的連續空白 (安全起見),不一定每個地方都轉換到。若你確定要全改,用 ":retab!" 指令即可。



2013/03/10

讓 vim 顯示 tab 和行末的空白字元

之前的筆記提過混合 tab 和空白造成 coding style 混亂的問題和建議解法:
以上的解法要團隊共同遵守才有效,但我們經常需接手其他作法不同的團隊的程式。因 tab 和空白都以空白顯示,要分辨原來團隊的作法並不容易。

以下是讓 vim 顯示 tab 和行末空白字元的指令:
set listchars=eol:$,tab:>.,trail:~,extends:>,precedes:<
set list
這種設定會以一般的「大於」和「句點」等一般符號來表現 tab 和行末空白。若怕會混淆,可以試試以下的特殊符號 (至少在 Ubuntu 上可用):
set listchars=eol:↵,tab:»·,trail:╳,extends:»,precedes:«
set list
建議將此指令加在 `~/.vimrc`,當成預設組態。這樣,每次用 vim 時 tab 都會有特別的顯示方式,而看起空白的就是真的空白 (行末的空白除外),很容易分辨。用以下指令就可暫時取消這種顯示方式:
set nolist
有些人可能希望空白也能有不同的顯示方法。方法如下:
highlight Whitespace cterm=underline gui=underline ctermbg=NONE guibg=NONE ctermfg=yellow guifg=yellow
autocmd ColorScheme * highlight Whitespace gui=underline ctermbg=NONE guibg=NONE ctermfg=yellow guifg=yellow
match Whitespace /  \+/
參考資料:

2009/01/13

使用 vim 和 cscope 來 trace 程式碼

Vim 是個很實用的程式編寫工具,不過一開始需要花點心力走過學習曲線。有興趣的人可以在網路上找找學習教材;如果你已經有點基礎但記不清按鍵,以下這個網址提供相當有系統的整理,依照功能分成七個自學課程,很值得一看:
除了編寫程式,Vim 用來追溯程式 (trace code) 也相當好用。例如,先將游標移到程式的某個文字串,再按以下按鍵:
  • '*' 往前找出此文字串 (按 n、N 繼續找)
  • '#' 往後找出此文字串 (按 n、N 繼續找)
  • 'gd' 將此文字串視為 local 變數,找到定義此 local 變數的地方 (如果有的話)
其他追溯程式常見的動作:
  • '%' 找到被配的括號
  • '[[' 找到函數的開頭
  • ']]' 找到下一個函數的開頭
當你維護的軟體專案不小時,上述功能絕對不夠用。這時你需要 cscope 的協助。當你安裝好 cscope,而且建立好專案的 cscope 資料庫之後,將游標移到程式當中某個文字串,按 Ctrl+\ 再按以下按鍵:
  • 's': 即 Symbol,以此文字串當識別字,列出專案當中所有參考到此識別字的地方,包含定義和引用
  • 'g': 即 Global,以此文字串當作 global 變數或函數的名稱,跳到專案中定義此 global 變數或函數的地方 (這個功能有另一個與 ctags 相同的快速鍵 Ctrl-])
  • 'c': 即 Calls,以此文字串當函數名稱,找出所有呼叫到的此函數的函數
  • 't': 即 Text,列出專案中所有出現此文字串的地方 (包含註解)
  • 'e': 即 Egrep,以此文字串當 regular expression,用 egrep 方式來搜尋
  • 'f': 即 File,以此文字串當檔案名稱,開啟此檔案
  • 'i': 即 Includes,以此文字串當 header 檔名稱,列出所有 include 此檔案的檔案
  • 'd': 即 calleD,以此文字串當函數名稱,列出此函數所呼叫到的函數
上述指令若是列出相關程式碼,你可以輸入數字加 Enter 來跳到該檔案的相對位置。按 Ctrl-T 就會回到游標原來的檔案和位置。你也可以用以下的方式來輸入指令 (foo 就是搜尋的文字串):
  • :cscope find symbol foo
  • :cs f s foo
安裝 cscope 的方法:
sudo apt-get install cscope
mkdir -p ~/.vim/plugin
cd ~/.vim/plugin
wget http://cscope.sourceforge.net/cscope_maps.vim
建立及更新軟體專案 cscope 資料庫的簡單方法如下 (其他更複雜的用法請參考 http://cscope.sourceforge.net):
cd PROJECT
cscope -bR

2008/12/29

Vim 建議的四種 TAB 字元處理方式

Vim 的 help 建議四種 TAB 字元處理方式:
  1. 將 'tabstop' 固定設為 8;'softtabstop' 和 'shiftwidth' 設為 4 (或其他你所喜好的縮排長度);然後指定 'noexpandtab'。這樣,vim 在處理檔案的時候會視需求自動混用 TAB 和空白字元,但你按 TAB 或 BS 鍵時,都會以 4 格 (或你喜好的縮排長度) 來移動。

  2. 將 'tabstop' 和 'shiftwidth' 設成你所喜好的縮排長度,然後設定 'expandtab'。這樣,你編輯的檔案將不會有任何 TAB 字元。以其他編輯器來看時,縮排不會受到 TAB 設定不同的影響。

  3. 將 'tabstop' 和 'shiftwidth' 設成你所喜好的縮排長度,然後將此設定以 modeline 的方式寫在檔案之中。這樣,只要使用 vim 而且 modeline 有開啟的話,大家看到的樣子都會一致。

  4. 將 'tabstop' 和 'shiftwidth' 設成相同的值,然後設 'noexpandtab'。這樣,即使別人的設定不一樣,看起來也只是縮排程度不同,結構上是沒有問題的。不過,你只能在每一行的開頭使用 TAB 字元,其他地方的 TAB 字元可能會因縮排長度的不同而破壞原來的排版 (例如:原本對齊的 C 常數定義變沒有對齊)。
個人推薦方式 2 再嵌入 modeline 設定,如下:
vim: set et ts=4 sw=4:
嵌入 modeline 設定不單純只給 vim 看,而是當作一種宣告:本文件的縮排為四格而且以空白展開 TAB,希望修改文件的人都能遵循這個慣例。

但是有一個例外:Makefile。Makefile 的 TAB 字元是有意義的,不可用空白取代,所以 modeline 應該設為:
vim: set noet ts=8 sw=8:
另外,我也建議 ~/.vimrc 要有如下的設定:
set smarttab
set autoindent
這樣寫程式會比較方便。

2008/12/28

Vim 的 modeline

有團隊合作寫程式經驗的人,應該能夠了解共同的 coding style 是非常重要的。先不管 if-else、for、while 之類的述句該怎麼編排,至少縮排幾格、tab 如何處理一定要統一。否則一個 source code 經過幾個人 (其實是編輯器) 的修改,可能會變得不成人形。

問題出在不同的編輯器對 tab 可以有不同的處理方式:對齊四或八格?要不要展開成空白?若編輯器的設定不同,甲看起來漂漂亮亮的排版,在乙那邊可能是歪七扭八的。

Vim 的 modeline 提供一個方便的解法:在 source code 當中就可以指定編輯設定,包含此檔案的 tab 應該要如何解讀。

Modeline 是藏在文件開頭或末尾幾行的特殊格式字串,vim 讀取文件時若發現這些字串便會修正自身的設定。在程式當中,通常是寫在註解裡頭。例如:
// vim: ts=4 sw=4 et
這是 modeline 的第一種寫法。vim: 標記特殊字串的開頭,結尾則是本行結束。特殊字串當中以空白或「:」隔開各個設定項目。利用這種方式,後面不可有其他任何字元,所以,若是用 C 的註解符號必須寫成:
/* vim: ts=4 sw=4 et
*/
第二種寫法同樣以 vim: 標記特殊字串的開始,但之後必須跟著一個 set。下一個「:」代表特殊字串的結束,之後可以有其他文字。例如以下用於 Python 的範例,同一行除了包含 vim modeline 之外,也包含 Pyhton 指定 source code encoding 的寫法:
# vim: set ts=4 sw=4 et: -*- coding: utf-8 -*-
個人推薦這種寫法,因為 vim 的 modeline 處理並非強制的,有些 Linux distro 的 vim 預設值將 modeline 關閉;也有些人有安全顧慮,不想開啟 modeline。遇到此情況,我們可以直接剪貼兩個冒號之間的字串即可複製該設定。若要啟用或關閉 modeline 功能可以編輯 ~/.vimrc:
set modeline
set modelines=2
第一行是啟用 modeline;第二行是將搜尋 modeline 的範圍設定為文件開頭和末尾各兩行,若省略則預設為五行。

參考資料:

2008/01/29

vim 的彩色語法顯示

昨天剛安裝好的 Ubuntu virtual appliance 有個缺點:vim 不會以彩色來顯示文件的語法格式。

上網找解法,發現很多人都有相同的問題,也有很多人回答,但排在前幾名的答案都不太管用。我想是每個人的環境都不太相同,問問題的沒有說清楚自己的環境,回答問題的人只就自己的環境來回答的緣故吧?

研究了很久終於把這問題解決了。希望以下的方法對你是管用的 :)

首先,先確定你安裝的 vim 是否有把彩色語法顯示的功能編譯進去。方法是直接問 vim (vim --version)。這個指令除了顯示版本號碼之外,還會顯示有哪些功能。彩色語法顯示這個功能就叫 syntax。如以下範例:
    # vim --version | grep syntax
    -scrollbind -signs -smartindent -sniff -statusline -sun_workshop
    -syntax
syntax 前面是個減號,就表示這個 vim 根本沒有將彩色語法顯示的功能編譯進去,你再怎麼調整設定也沒有用。Ubuntu 預先安裝的是 vim-tiny 就是這種陽春版,必須安裝標準版的 vim 才有此功能。方法安裝如下:
    # apt-get update
    # apt-get install vim
接下來,找個 source code 或 Makefile 來編輯看看。如果已經有彩色語法顯示,恭喜你大功告成了。如果還不行,請在 vim 上下這個指令看看:「 :syntax on 」。如果有彩色出現,就代表彩色語法顯示的預設值是關閉的。這時,請編輯 /etc/vim/vimrc 將 syntax on 之前的註解符號移除,就可以打開這個功能。也請看看你的 vi 是否有 alias 到 vim。

還是不行?那只好請你自己找 Google 先生幫忙了。