2011年5月17日 星期二

讓 vim 暫時 highlight 指定的關鍵字

在讀程式碼時, 常需要暫時追踪特定變數, 比方說 class Foo 裡有個 self.client 用做連線, 想追踪 self.client 是如何被產生、設定、使用。以前我會在 client 上按 * 搜尋這個字, vim 裡有設 set hlsearch, 自然會被 hilight。這個作法有兩個缺點:
  1. 一次只能特別標記一個字。
  2. 游標會跑掉, 得再按 ? 跑回來。
剛才想到, 其實可以寫個 nmap, 按個鍵就自動 highlight 目前的關鍵字。參考 cscope 的巨集指令, 總算試出來了, 結果如下:

~/.vimrc

nmap <leader>* :syn match TempKeyword /\<<C-R>=expand("<cword>")<CR>\>/<CR>
nmap <leader>c :syn clear TempKeyword<CR>
hi TempKeyword ctermfg=red
注意, 若你載入的 syntax file 或其它 vim script 有執行 :syntax clear 的話, 要將 hi TermKeyword 那行移到 :syntax clear 之後。像我用的 syntax/python.vim 就有執行 :syntax clear。

用法

<leader> 預設是對到反斜線 ("\"), 若沒設 <leader> 的話, 就是在想 highlight 的字上按 \*, 就會用紅色顯示這個字, 可以在多個字上按 \*, 效果會累加。不想看的時候, 按 \c 清掉所有 highlight 的字。

下面是使用前後的對照圖 ( 游標移到 auth_type 後按 \* ):



備註

<C-R>=expand("<cword>")<CR> 是關鍵, 這段程式碼會取出目前游標所在的字, 展開後填在命令列上。之後再來詳細研究它的結構。<C-R>= 、 expand 、 <cword> 和 <CR> 四個拆開看我都懂, 但合在一起為何有這個效果, 就看不懂了。

2011-05-17 更新: 經 BlueCat 提醒, 重看 <C-R> 的說明, 發現它的功能是填入特定 register 的值。而 = 這個 register 的功用比較特別, 執行後才會讓使用者填入 expression, 再回傳 expression 運算的結果。這樣這串指令合起來的意思就不難懂了。

6 則留言:

  1. <C-R>= 插入, expand() 展開特殊變數, 特殊變數<cword>是游標下的字, <CR> 是 Enter, 所以整段就是"插入目前游標下的字並送出"

    回覆刪除
  2. 這個讚也, 不過用底色 highlight 會不會比較明顯? 感覺著色會跟 syntax highlight 搞混

    回覆刪除
  3. 原來我看錯 <C-R>= 的意思, 重看一遍 :h <C-R> 才看懂, 謝啦

    選紅色是有原因的, 因為我的 python 配色剛好沒用到紅色, 另外我的游標有設「光棒」, 用底色的話, 移到該行時, 反而會蓋掉關鍵字的背景色 XD

    回覆刪除
  4. 設 syntax on 之後這招就無效了啊 Orz, 要改用 matchadd & clearmatch.

    nmap <leader>h :call matchadd("TempKeyword", "<C-R>=expand("<cword>")<CR>")<CR>

    nmap <leader>d :call clearmatches()<CR>

    回覆刪除
  5. 我是在 vimrc 裡先 syntax on 後才設的, 這樣就不會失效

    回覆刪除
  6. 可是我不管放前面放後面, 只要 syntax 一開就無效 Orz..

    回覆刪除

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...