转 ctags-lua-修改

最近用vim写lua代码,发现由于ctags对lua支持不友好, 很多lua的符号都不能跳转 表现在

1) ctags默认对lua的支持仅限于识别function, 不支持识别常量定义.

2) 如果通过CLASS:MEMBER_FUN(...)方式以及CLASS.MEMBER_FUN()方式定义的function, 所生成的tags是如下形式:

CLASS:MEMBER_FUN ...省略

CLASS.MEMBER_FUN ...省略

这样的tags文件无法直接通过MEMBER_FUN跳转过去. , 比如:通过:tselect MEMBER_FUN也无法找到对应的tag,

除非通过tselect /^.*MEMBER_FUN来找, 但是通过正则效率又太低. 而且会找到很多无关的匹配项.

所以, 本文研究了通过其他手段来生成lua的tags. 主要需要解决两个问题,

1) 支持能对lua中定义的常量/变量生成tags. 为了放置太多变量被索引, 限制变量的值必须是数字. 因为几乎所有的枚举值/常量的值都是数字.

2) 生成的tags去掉类名前缀, 比如:"CLASS:"以及"CLASS."前缀, 以便通过MEMBER_FUN能够直接跳转过去.

解决方法:

用ctags自定义的生成规则, 自己生成了lua文件的tags, 目前看来基本满足需求.

ctags --langdef=MYLUA --langmap=MYLUA:.lua --regex-MYLUA="/^.*\s*function\s*(\w+):(\w+).*$/\2/f/" --regex-MYLUA="/^\s*(\w+)\s*=\s*[0-9]+.*$/\1/e/" --regex-MYLU

A="/^.*\s*function\s*(\w+)\.(\w+).*$/\2/f/" --regex-MYLUA="/^.*\s*function\s*(\w+)\s*\(.*$/\1/f/" --regex-MYLUA="/^\s*(\w+)\s*=\s*\{.*$/\1/e/" --regex-MYLUA="/^\s*module\s+

\"(\w+)\".*$/\1/m,module/" --regex-MYLUA="/^\s*module\s+\"[a-zA-Z0-9._]+\.(\w+)\".*$/\1/m,module/" --languages=MYLUA --excmd=number -R .

关于ctags自定义语言的tags生成器的规则网上可以找到, 参考如下文章:

http://www.cnblogs.com/jianyungsun/archive/2011/01/20/1940262.html

http://helloxchen.itpub.net/category/42725/66614

这里简单的说明一下

1) 上面的语句定义了一种新的语言MYLUA, 该语言支持的文件后缀为*.lua. 定义了几条从源文件生成tags的正则替换规则,

其中三条用来识别function,

两条用来识别常量.

两条用来识别module

ctags在处理时会扫描lua文件的每一行, 分别施加上面几条规则, 任意一条规则匹配上, 则把匹配结果加入的tags文件.

2) 正则语法默认采用perl 兼容的正则语法. 也就是等价于 grep -E, 或者 egrep

3) --excmd指示生成的tags文件的格式. number表示直接写入tag所在文件的行号, 跳转效率最好, 生成的tags文件也比较小.

但是当源文件给改动后, 行号就会不匹配. 可以改为 --excmd=pattern , 这样生成正则匹配的跳转点. 不受源文件修改的影响.

4)-R . 对当前目录以及递归子目录的所有lua文件生成tags

举例:

1.lua文件:

[plain]view plaincopy

  1. module "modules.submodule.mymodule1"
  2. module "modules.mymodule2"
  3. module "mymodule3"
  4. OBJECT_IDS = {
  5. XX=1,
  6. YY = 2,
  7. msg_login = 8001,
  8. msg_login2 = 8001, -- logon
  9. }
  10. function hello()
  11. return nil
  12. end
  13. function xxx.hello()
  14. return nil
  15. end
  16. function xxx:hello()
  17. return nil
  18. end

[plain]view plaincopy

    !_TAG_FILE_FORMAT  2       /extended format; --format=1 will not append ;" to lines/
    !_TAG_FILE_SORTED       1       /0=unsorted, 1=sorted, 2=foldcase/
    !_TAG_PROGRAM_AUTHOR    Darren Hiebert  /dhiebert@users.sourceforge.net/
    !_TAG_PROGRAM_NAME      Exuberant Ctags //
    !_TAG_PROGRAM_URL       http://ctags.sourceforge.net    /official site/
    !_TAG_PROGRAM_VERSION   5.9~svn20110310 //
    OBJECT_IDS      1.lua   4;"     e
    XX      1.lua   5;"     e
    YY      1.lua   6;"     e
    hello   1.lua   11;"    f
    hello   1.lua   14;"    f
    hello   1.lua   17;"    f
    msg_login       1.lua   7;"     e
    msg_login2      1.lua   8;"     e
    mymodule1       1.lua   1;"     m
    mymodule2       1.lua   2;"     m
    mymodule3       1.lua   3;"     m
    

    注: 在如下环境测试通过

    linux:

    Linux ubuntu 2.6.32-21-generic

    ctags:

    Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert

    Compiled: Mar 6 2010, 15:35:10

    Addresses: <dhiebert@users.sourceforge.net>, http://ctags.sourceforge.net

    Optional compiled features: +wildcards, +regex