Vim C/C++函數名,宏定義和變數的高亮

之前寫qt的時候用過一段時間的Qtcreator,後來自己用vim寫程序的時候才發現vim本身對於函數,用戶自定義的結構,變數,還有宏定義是沒有高亮的。網上百度了一下好像也沒有相關的插件 。

(後來才知道有taghighlight這個插件orz)

於是打算自己寫一個能夠實現上述高亮的東西。使用了ctags+python 正則表達匹配+vim的高亮文件 ,成果如下。

可以針對不同的庫來進行不同的高亮:)

ctags 生成的tag文件似乎並不會記錄用戶自己定義的局部變數,但是全局變數會記錄。因此這個方案應該只能夠高亮全局的變數。

實現的思路很簡單,vim沒有支持變數名和函數的高亮根本原因是vim自身沒有對c++語法的檢測,它的高亮靠的是syntax文件夾下面.vim腳本,如果你打開裡面的cpp.vim查看的話,就會發現vim只對cpp的一些關鍵字和不涉及到語法的部分進行一些正則匹配。我們編輯cpp文件的時候vim匹配到上面的某一個規則便對其進行相應的高亮操作。

那麼我們要對自己寫的變數進行高亮,最簡單的方法就是利用vim的腳本語言。比如我想對c語言的printf 和puts進行高亮只需要在普通模式下輸入

:syn keyword CPrintf printf puts

:hl CPrintf ctermfg=1

你就會發現當前文件所有的printf都被高亮成了終端的第一種顏色。如果用的是Gvim 需要把ctermfg 改成gui=Cyan 。這裡Cyan指的是藍色,也可以改成其他的顏色,詳情可以:help color。

第一行命令指定printf和puts為可以進行高亮操作的關鍵字,第二行指定高亮的顏色。

如果我們把ctags文件中記錄的所有函數,定義和變數使用某種方法提取出來然後將其作為關鍵自動生成上述命令的.vim腳本文件然後讓vim執行就可以將tag文件記錄了的函數,定義和變數進行高亮了。當然這種做法的缺點很明顯:首先就算是指定vim自動更新tags和腳本這個效率也不太高,可能也會佔用不少內存。其次無法擺脫ctags的限制,有些地方可能會進行錯誤的高亮操作。然而不試試也不知道效果怎麼樣,因此我還是寫了一個簡單的python代碼。

# -*- coding: UTF-8 -*-# match.pyimport reimport sysif len(sys.argv) <2: print("at least two args") exit(-1)f = open(sys.argv[1],r)define_dict = dict()v_dict = dict()func_dict = dict()for line in f: obj = re.match(r(S*)s+(.*)s+(/^)?(.*);"s+([p|d|f|v])s+(.*)?,line)#匹配tag if obj: print(tagName: +obj.group(1)) print(tagPath: +obj.group(2)) print(tagdefine: +obj.group(4)) print(tagType: +obj.group(5)+

) if obj.group(5) == v: v_dict[obj.group(1)]=obj.group(5) elif obj.group(5) == d : define_dict[obj.group(1)]=obj.group(5) else : func_dict[obj.group(1)]=obj.group(5)f.close()test = open(/home/kevin/.vim/syntax/+sys.argv[2],w+) test.write(syn keyword mDefine ) #keyword 後面的名字可以自由使用for key in define_dict: # 不同文件中相同的名字後面的高亮會覆蓋前面的高亮 test.write(key+ )#因此可以在生成的不同文件中採用不一樣的名字來實現不同的高亮效果test.write(
)test.write(syn keyword mVariable )for key in v_dict: test.write(key+ )test.write(
)test.write(syn keyword mFunction )for key in func_dict: test.write(key+ )test.write(
)test.write(hi mVariable ctermfg=1
)# 1,2,3 指定終端的3種顏色test.write(hi mDefine ctermfg=2
)# gvim需要改成 guifg={顏色}test.write(hi mFunction ctermfg=3
)# 詳情可以:help syntaxtest.close()

本人是python新手,輕拍。

大致就是讀取tags文件,然後利用正則匹配得到tag的名字和類型,生成.vim高亮文件。 代碼接受兩個參數,第一個指定要讀取的ctags文件的路徑,第二個指定要保存到syntax文件夾的文件名。生成ctags需要用

ctags -R –c++-kinds=+p –fields=+iaS –extra=+q

默認的ctags -R 中是不區分函數和宏定義的,因此如果想用不同的顏色高亮函數和宏就需要上面的參數了。

本人使用的是linux系統,因此為了高亮opengl的函數,在/usr/include/GL 文件夾下用ctags命令生成了tags文件。然後使用python代碼

python match.py /usr/include/GL/tags gl.vim

生成了gl.vim這個高亮文件。接下來vim test.cpp 打開一個cpp文件,然後使用

:so ~/.vim/syntax/gl.vim

載入生成的高亮腳本。接下來應該就能看到效果了。

glfw 庫的函數和gl庫的函數使用了不同的顏色。只是根據兩個tags文件生成兩個腳本文件然後按順序載入而已。

如果不想每次都手動生成載入,可以在.vimrc配置文件中自行加入相關的映射和自動化操作。

個人效果感覺還可以,也沒感受到什麼卡頓。可能opgl的庫還是太小的原因吧= =

第一次在知乎寫文章,寫的亂請輕拍。。

推薦閱讀:

vim 啟動速度優化的一些經驗
用 Vim 寫 Python 的最佳實踐是什麼?
各位的編輯器一般用什麼主題?
SpaceVim release v0.6.0
如何使用Vim為每一行自動編號?

TAG:Vim | CtagsVim插件 |