背景

在我平时用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

在Emacs中使用GNU Global的更多相关文章

  1. [转载]生活在 Emacs 中

    Brian Bilbrey2002 年 8 月 20 日发布 教程简介 本教程讲什么? Emacs 是一个流行的无模式文本编辑器,有许多强大的功能.本教程将教您使用 Emacs 的基础知识.为了让您很 ...

  2. ubuntu14.04编译gnu global 6.6.3

    打算重新折腾下环境,看中了gtags ,可参考 Vim 8 中 C/C++ 符号索引:GTags 篇 ,先记录下编译过程 源码 下载并解压源码 最新的代码到官方下载页面获取 https://www.g ...

  3. 编译GNU Global

    GNU Global是一套界面更友好的tag系统,但是因为其支持的语言太少,现在一般使用其为前端,后端一般使用最新的Universal Ctags. 编译办法如下: 1.去GNU Project ht ...

  4. 使用Emacs中的org-mode写cnblogs之图片插入

    .title { text-align: center; margin-bottom: .2em } .subtitle { text-align: center; font-size: medium ...

  5. Emacs中的拼写检查

    无论是在Emacs中写英文日记(diary).Org mode笔记,还是撰写程序的注释和文档,拼写检查都是一项提高工作效率.保证成果品质的必不可缺的工具.拼写检查对于常见的文字处理软件(如Word.L ...

  6. Emacs中多个golang项目的配置方法

    概述 最近使用golang开发项目时, 发现有时需要同时进行多个golang项目. 在这种情况下, 如果把所有的项目都放在 GOPATH 之下, 不仅管理麻烦(因为各个项目需要提交到不同的代码库), ...

  7. Emacs 中使用中文插件 eim

    在 Emacs 中输入中文,一般用 ibus 一类的输入法也能应付,但来回切换有点麻烦,这里介绍国人写的一个好插件 eim. - 安装 由于在 list-packages 中没有找到这个插件,所以不能 ...

  8. Emacs 中使用 shell

    直接在 Emacs 中使用 shell 能增加一点效率.Emacs 本身支持的 shell 相关的命令很多,此处化繁为简,只用一条足够了. M-x shell:将打开一个名为 * shell * 的 ...

  9. Emacs中使用shell(调出terminal)

    在Emacs中使用shell(调出terminal) 方法: M-x eshell 注意:不能使用 M-x shell,这样调用的是 cmd命令,一些命令无法使用

随机推荐

  1. spring实现定时任务的两种方式

    本文为博主原创,未经允许不得转载 项目中要经常事项定时功能,在网上学习了下用spring的定时功能,基本有两种方式,在这里进行简单的总结, 以供后续参考,此篇只做简单的应用. 1.在spring-se ...

  2. Javascript库的产生和解读

    javascript库的产生,增强了浏览器或javascript语言的某些机制的功能, 让业务开发人员,更专注业务逻辑,而不是机制逻辑.   比如, 0.兼容性 同样的功能函数,不同的浏览器所暴露的a ...

  3. Centos修改系统语言

    使用man page帮助时,发现居然是中文的,不过想想即便英语再水,也要逼着自己去适应.于是百度找了一下修改系统语言的方法. 首先使用 locale 命令查看当前的系统语言 然后修改时一般有两种方法, ...

  4. 技术分享:SSH实战项目

    1.需求分析 系统概述: 企业人事管理系统. 要求对员工信息进行维护. 后台系统先登录,才能操作员工;添加.修改.删除. 没有登录,只能查看列表,不能操作. 功能分类: 1)[管理员模块] 注册/登录 ...

  5. python调用虹软2.0第三版

    这一版,对虹软的功能进行了一些封装,添加了人脸特征比对,比对结果保存到文件,和从文件提取特征进行比对,大体功能基本都已经实现,可以进行下一步的应用开发了 face_class.py from ctyp ...

  6. HDU2017新生赛 友好整数

    思路: 很简单的一个状态压缩,比赛时没想出来. 最多只有2^10个状态,n^2暴力一下也就1e6. 代码: #include<bits/stdc++.h> using namespace ...

  7. HTTP URL 字符转义 字符编码 、 RFC 3986编码规范

    一.为什么要编码转义 通常如果一样东西需要编码,说明这样东西并不适合传输.原因多种多样,如Size过大,包含隐私数据,对于Url来说,之所以要进行编码,是因为Url中有些字符会引起歧义. 例如Url参 ...

  8. C# 中的集合(Array/ArrayList/List<T>/HashTable/Dictionary)

    int [] numbers = new int[5]; // 长度为5,元素类型为 int. string[,] names = new string[5,4]; // 5*4 的二维数组 byte ...

  9. mysql--------大数据量分页sql语句优化

    分页程序原理很简单,这里就不多说了,本篇文章主要说的是在数据表记录量比较大的情况下,如何将分页SQL做到更优化,让MySQL执行的更快的方法. 一般的情况下,我们的分页SQL语句是这样的: ,; 以上 ...

  10. 删除php数组中的元素

    删除一个元素,且保持原有索引不变 使用 unset 函数,示例如下: <?php $array = array(0 => "a", 1 => "b&qu ...