在Emacs中使用GNU Global


背景

在我平時用Emacs編寫C代碼時,經常需要進行代碼的跳轉,主要需求為函數定義的跳轉,某個具 體函數的調用查找,某個結構體的定義跳轉以及結構體中具體某一項的跳轉等,GNU Global就能 完全滿足我的這個需求,所以習慣了Emacs的人可以將Source Insight扔開了。

GNU Global簡介

GNU Global全稱為GNU Global source code tagging system,官方定義為GNU Global是一個可以跨越各 種環境的代碼標記系統,例如在Emacs,VI,Less Viewer,Bash Shell甚至在Web瀏覽器中使用。 可以通過GNU Global查找局部變量,函數,宏,結構體,類並且方便的跳轉到你想要的位置,在進行大型項 目開發時,GNUL Global可以包含許多子目錄,#ifdef語句和許多main函數,它有點向平時經常使用的ctags 和etags,但是有和這兩個tag工具比起來GNU Global有以下兩點更為強大:
  • 和編輯器不具有強綁定關系,所以可以很方便的將其用於各種編輯環境,無論是Emacs的忠實使用者還是Vim的粉絲都可以盡情的使用它來進行代碼跳轉
  • 具有比較強大的查找定義和引用的能力,對於代碼閱讀來說這個能力已經足夠了
GNU Global具有強大的跨平台能力,無論是在Linux還是在BSD系統還是Windows都可以使用。 GNU Global具有以下功能:
  • 內置6種語法分析程序(定義和引用)C,C++,Yacc,Java,PHP4和匯編
  • 通過Ctags的語法解析插件可以支持25中語言(定義和引用)Awk, Dos batch, COBOL, C, C++, C#, Erlang,Fortran, Java, JavaScript, Lisp, Lua, Pascal, Perl, PHP, Python, Ruby, Matlab, OCaml, Scheme, Tcl, TeX, Verilog, Vhdl and Vim
  • 在各種不同的編輯環境中能夠以相同的方式工作,例如
    • Shell命令行
    • Bash Shell
    • Vi編輯器(Vim)
    • Less Viewer
    • Emacs編輯器(Emacs,Mule,XEmacs)
    • Web瀏覽器
    • Doxygen文檔系統
  • 通過特殊的符號表快速查找局部變量
  • 不僅能夠查找定義還可以查找引用
  • 允許重復的tags
  • 給出匹配的路徑
  • 默認分層查找
  • 不僅僅實在代碼級別查找,還可以在庫中查找
  • 生成補全列表
  • 支持多種格式輸出
  • 允許指定標記文件
  • 支持POSIX 1003.2正則表達式
  • 支持idutils作為外部搜索引擎
  • 生成的tag文件獨立於各種體系結構
  • 支持隨時更新tag文件
  • 支持新語言的語法解析插件
  • 支持自定義gtags.conf
  • 使用壓縮格式來節省空間
  • 支持C/S環境(TRAMP)
  • 默認忽略可執行文件,隱藏文件和特殊文件
  • 內置cscope程序(gtags-cscope)
  • 內置grep命令(使用-g)
  • 能夠很好的處理循環符號鏈

GNU Global使用

命令行下使用GLOBAL,在開始使用之前可以看一下FAQ
$more /your/gtags/path/FAQ
首先我們需要使用gtags命令來產生代碼樹的tag文件,例如當我想要瀏覽內核2.4
的代碼時,只需要執行以下命令
$cd ~/code/kernel/
$gtags -v
執行完之后會發現,在kernel目錄下產生了3個tag文件分別是GPATH,GRTAGS,GTAGS,
GTAGS是定義的數據庫,GRTAGS是引用的數據庫,GPATH是路徑的數據庫。
 
基本用法,加入下面的是我們的目錄樹
/home/user/
 |
 |-ROOT/      <- the root of source tree (GTAGS,GRTAGS,...)
    |
    |- README       .....   +---------------+
    |                       |The function of|
    |                       +---------------+
    |- DIR1/
    |  |
    |  |- fileA.c   .....   +---------------+
    |  |                    |main(){        |
    |  |                    |       func1();|
    |  |                    |       func2();|
    |  |                    |}              |
    |  |                    +---------------+
    |  |
    |  |- fileB.c   .....   +---------------+
    |                       |func1(){ ... } |
    |                       +---------------+
    |- DIR2/
       |
       |- fileC.c   .....   +---------------+
                            |#ifdef X       |
                            |func2(){ i++; }|
                            |#else          |
                            |func2(){ i--; }|
                            |#endif         |
                            |func3(){       |
                            |       func1();|
                            |}              |
                            +---------------+
此時我們在ROOT目錄下執行gtags命令生成tag文件,可以使用global命令在代碼中搜索
相關函數,需要注意的是只能在生成TAG文件的目錄及其子目錄中搜索:
$ cd /home/user/ROOT
$ global func1
DIR1/fileB.c            # func1() is defined in fileB.c
$ cd DIR1
$ global func1
fileB.c                 # relative path from DIR1
$ cd ../DIR2
$ global func1
../DIR1/fileB.c         # relative path from DIR2
使用global的-r選項獲取相關引用:
$ global -r func2
../DIR1/fileA.c         # func2() is referred from fileA.c
global支持使用正則表達式來進行搜索:
$ cd /home/user/ROOT
$ global 'func[1-3]'
DIR1/fileB.c            # func1, func2 and func3 are matched
DIR2/fileC.c
global使用-x選項來獲取更多細節:
$ global func2
DIR2/fileC.c
$ global -x func2
func2              2 DIR2/fileC.c       func2(){ i++; }
func2              4 DIR2/fileC.c       func2(){ i--; }
global使用-a選項時可以獲取絕對路徑:
$ global -a func1
/home/user/ROOT/DIR1/fileB.c
global使用-s選項可以搜索沒有在GTAGS中定義的符號:
$ global -xs X
X                  1 DIR2/fileC.c #ifdef X
global使用-g選項可以搜索指定的模式:
$ global -xg '#ifdef'
#ifdef             1 DIR2/fileC.c #ifdef X
global的-O選項表明只在文本文件中搜索,-o在源文件和文本文件中搜索,
-l選項只在當前目錄搜索,使用-P選項可以搜索特定模式的路徑;
 
如果想在庫中搜索相關符號,則需要在每一個GTAGSLIBPATH中執行gtags
命令:
$ pwd
/develop/src/mh                 # this is a source project
$ gtags
$ ls G*TAGS
GRTAGS  GTAGS
$ global mhl
uip/mhlsbr.c                    # mhl() is found
$ global strlen                 # strlen() is not found
$ (cd /usr/src/lib; gtags)      # library source
$ (cd /usr/src/sys; gtags)      # kernel source
$ export GTAGSLIBPATH=/usr/src/lib:/usr/src/sys
$ global strlen
../../../usr/src/lib/libc/string/strlen.c  # found in library
$ global access
../../../usr/src/sys/kern/vfs_syscalls.c   # found in kernel
$ ln -s /usr/src/lib .
$ ln -s /usr/src/sys .
$ gtags
$ global strlen
lib/libc/string/strlen.c
$ global access
sys/kern/vfs_syscalls.c
如果忘記了搜索的符號名,可以使用-c選項來補全:
$ global -c kmem # maybe k..k.. kmem..
kmem_alloc
kmem_alloc_pageable
kmem_alloc_wait
kmem_free
kmem_free_wakeup
kmem_init
kmem_malloc
kmem_suballoc # This is what I need!
$ global kmem_suballoc
../vm/vm_kern.c
 
$ funcs()
> {
> local cur
> cur=${COMP_WORDS[COMP_CWORD]}
> COMPREPLY=(`global -c $cur`)
> }
$ complete -F funcs global
$ global kmem_<TAB><TAB>
kmem_alloc kmem_alloc_wait kmem_init
kmem_alloc_nofault kmem_free kmem_malloc
kmem_alloc_pageable kmem_free_wakeup kmem_suballoc
$ global kmem_s<TAB>
$ global kmem_suballoc
../vm/vm_kern.c

GNU Global在Emacs中的使用

  • 安裝配置Emacs
$HOME/.emacs
+------------------------------------------------------
|(setq load-path (cons "/home/owner/global" load-path))
|(autoload 'gtags-mode "gtags" "" t)
(global-set-key (kbd "M-<f1>") 'gtags-find-file)
(global-set-key (kbd "M-<f2>") 'gtags-find-tag)
(global-set-key (kbd "M-<f3>") 'gtags-find-rtag)
(global-set-key (kbd "M-<f4>") 'gtags-find-symbol)
(global-set-key (kbd "M-<f5>") 'gtags-find-with-grep)
  • 安裝好之后在emacs中可以通過M-x使用如下命令
在瀏覽器中顯示當前屏幕
跳轉到輸入的文件處
通過grep命令搜索
在tag文件中搜索引用
在tag文件中搜索符號
在tag文件中搜索定義
從當前表達式獲得tag名並跳轉
以當前位置作為tag跳轉
在另一個窗口中打開tag跳轉
搜索文件並查詢

tag名字補全
開啟gtags mode
顯示當前文件的tag
從棧中移動到上一個點
從tag列表中選擇一個tag
選擇一個tag
通過某個事件選擇tag
在其他window中選擇tag
訪問tag文件根目錄
gtags-display-browser 
gtags-find-file
gtags-find-pattern 
gtags-find-rtag
gtags-find-symbol
gtags-find-tag
gtags-find-tag-by-event 
gtags-find-tag-from-here
gtags-find-tag-other-window 
gtags-find-with-grep
gtags-find-with-idutils 
gtags-make-complete-list
gtags-mode 
gtags-parse-file
gtags-pop-stack 
gtags-select-mode
gtags-select-tag 
gtags-select-tag-by-event
gtags-select-tag-other-window 
gtags-visit-rootdir


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM