程序员的七种武器之Ctags

site: Exuberant Ctags

基于正则表达式的文本tag生成器。

不光可以过滤代码文件,普通的有格式的纯文本都可以用。

Tag文件的作用

一般用于编辑器的代码跳转和查找 比如vim 和emacs

Tag文件格式

ctags生成的tag格式: {tagname}<Tab>{tagfile}<Tab>{tagaddress}

example

AddTeamExp data/script/AddTeamExp.lua /^newClass('AddTeamExp', BaseNode)$;"

vim 支持的tag文件格式

vim支持的必须是下面三三种的一种

  1. {tagname} {TAB} {tagfile} {TAB} {tagaddress}
  2. {tagfile}:{tagname} {TAB} {tagfile} {TAB} {tagaddress}
  3. {tagname} {TAB} {tagfile} {TAB} {tagaddress} {term} {field} ..

版本

ctags,我们目前所指的是它的一个多语言实现 Exuberant Ctags,原生支持多达41中编程语言 ctags还可以通过配置文件,增加语言扩展,定制自己的语言类型过滤器

简单使用

ctags -R . 

对当前的路径的文件生成tags

定制自己的类型过滤器

ctags -R . \
		-f ./tags\
		--tag-relative=yes \
		--langdef=MYLUA \
		--langmap=MYLUA:.lua \
		--regex-MYLUA="/newClass\(\'([^ ]+)\',.*/\1/c/" \
		--regex-MYLUA="/.*subclass\([\'\"]([^ ]+)[\'\"]\)/\1/c/" \
		--regex-MYLUA="/[ ]?([a-zA-Z_]+)Layout[ ]?=.*/\1/c/" \
		--regex-MYLUA="/[ ]?([a-zA-Z_]+Layout)[ ]?=.*/\1/c/" \
		--regex-MYLUA="/^([^:.= ]+)[ =]+\{\}/\1/c/" \
		--regex-MYLUA="/^function[ ]+[^:]+:([^ \(]+)/\1/f/" \
		--regex-MYLUA="/^function[ ]+([^:. ]+)\(/\1/f/" \
		--regex-MYLUA="/^function[ ]+[^:]+\.([a-zA-Z_]+)\(/\1/f/" \
		--regex-MYLUA="/^function[ ]+[^:.]+\.class:([a-zA-Z_]+)\(/\1/f/" \
		--regex-MYLUA="/[ ]?local[ ]+function[ ]+([^:.= ]+)\(/\1/f/" \
		--regex-MYLUA="/[ ]?local[ ]+([a-zA-Z_]+)[ ]?=[ ]?function\(/\1/f/" \
		--regex-MYLUA="/([^ ]+)[ ]+=[a-zA-z_ ]+or[ ]+{}/\1/m/" \
		--regex-MYLUA="/.*:mapEvent\(([^,:]+)[, ]+[^ ,:_]+\).*/\1/e/" \
		--regex-MYLUA="/([ ]?[a-zA-Z_-]+)[ ]?=[ ]?InitStaticInt.*/\1/e/"

  # 简单解释
  # c : newClass; subclass
  # c : 匹配 A={} 类似这种的类定义
  # m : 匹配新的Model --> 类似于这种:PveModel = PveModel or {}
  # e : 匹配event和command-->目前只针对于旧代码,evt和command对应的那些
  # f :
  # function A:b(..);        --regex-MYLUA="/^function[ ]+[^:]+:([^ \(]+)/\1/f/" \
  # function aaa(..);        --regex-MYLUA="/^function[ ]+([^:. ]+)\(/\1/f/" \
  # function A.bb(...);      --regex-MYLUA="/^function[ ]+[^:]+\.([a-zA-Z_]+)\(/\1/f/" \
  # function A.class:b(..);  --regex-MYLUA="/^function[ ]+[^:.]+\.class:([a-zA-Z_]+)\(/\1/f/" \
  # local function aa(...);  --regex-MYLUA="/[ ]?local[ ]+function[ ]+([^:.= ]+)\(/\1/f/"
  # local aa = function(..); --regex-MYLUA="/[ ]?local[ ]+([a-zA-Z_]+)[ ]?=[ ]?function\(/\1/f/"

配合vim

在~/.vimrc中加入 set tags+=./tags 这样vim就可以用当前路径下的tag文件来定位和跳转了 具体跳转方式,在vim中查看文档 :h tags

配合emacs

生成emacs能是别的tag文件,需要用到-E 选项

ctags -R -E .