2013-03-22 36 views
3

从技术上讲,我在vim中使用Tagbar来查看文件的标签,但这个问题通常适用于繁琐的ctags,v5.8。我可以将范围信息添加到用`--regex-<LANG>`在生成的ctags中生成的标签吗?

想我已经得到了下面的Python文件,把它foo.py

class foo: 
    def bar(baz): 
     print(baz) 

让我们在其上运行ctagsctags foo.py。得到的tags文件是这样的:

!_ some ctags version/formatting stuff not worth pasting 
bar foo.py /^ def bar(baz):$/;" m class:foo 
foo foo.py /^class foo:$/;" c 

我感兴趣的位是第二线,class:foo的最后一个字段。这是bar()函数的范围。如果我在vim中使用tagbar,它会相应地在该类中嵌套函数。

现在假设我在~/.ctags中添加了对新语言的支持。其实,我加入支持这一傀儡文件:

class foo { 
    include bar 
} 

假设我用下面~/.ctags参数。 “导入”正则表达式是丑陋(errr ...丑陋的人,正则表达式),但它得到足够的做了这个例子的工作:

--langdef=puppet 
--langmap=puppet:.pp 
--regex-puppet=/^class[ \t]*([:a-zA-Z0-9_\-]+)[ \t]*/\1/c,class,classes/ 
--regex-puppet=/^\ \ \ \ include[ \t]*([:a-zA-Z0-9_\-]+)/\1/i,include,includes/ 

,在我tags文件中生成以下标签:

bar foo.pp /^ include bar$/;" i 
foo foo.pp /^class foo {$/;" c 

注意这两行都没有包含范围信息。我的问题是:无论如何,我一般会构建--regex-puppet参数或--regex-<LANG>行来收集有关标签范围的信息?或许宣称符合标准A的标签总是要符合标准B的标签的范围 - 父母?

man ctags表明没有明确的方式来添加任意范围的信息,但我可能俯瞰另一种解决方案(为了强调稍微剪断):

--regex-<LANG>=/regexp/replacement/[kind-spec/][flags] 

     Unless modified by flags, regexp is interpreted as a Posix extended regular expression. The replacement should expand for all matching lines to a non-empty string of 
     characters, or a warning message will be reported. An optional kind specifier for tags matching regexp may follow replacement, which will determine what kind of tag is 
     reported in the "kind" extension field (see TAG FILE FORMAT, below). The full form of kind-spec is in the form of a single letter, a comma, a name (without spaces), a 
     comma, a description, followed by a separator, which specify the short and long forms of the kind value and its textual description (displayed using --list-kinds). Either 
     the kind name and/or the description may be omitted. If kind-spec is omitted, it defaults to "r,regex". Finally, flags are one or more single-letter characters having the 
     following effect upon the interpretation of regexp: 

      b The pattern is interpreted as a Posix basic regular expression. 

      e The pattern is interpreted as a Posix extended regular expression (default). 

      i The regular expression is to be applied in a case-insensitive manner. 

回答

2

没有呢,可惜这是不可能与ctags的正则表达式模式支持。获得ctags生成正确范围的唯一方法是在C中编写一个解析器作为附加模块。如果找到时间,我想增加对更好地处理ctags的新语言的支持,但到目前为止还没有解决问题,我也不确定最好的方法。如果你最感兴趣的是Tagbar支持,还有另一种方法:Tagbar支持任意标签生成程序,只要它们的输出与ctags一致即可,所以你可以写一个简单的解析器,比如说, Python并配置Tagbar来使用它。看看:h tagbar-extend(特别是最后一小节“编写你自己的标记生成程序”),如果这将是一个选项。

0

我正在通用ctags项目的这种功能: https://github.com/universal-ctags/ctags/pull/562

(不要期望太多;正则表达式解析器对于复杂语法是不够的 新功能适用于语法简单的语言。)

实施例1 ::

$ cat /tmp/input.foo 
class foo: 
def bar(baz): 
    print(baz) 
class goo: 
def gar(gaz): 
    print(gaz) 

$ cat /tmp/foo.ctags 
--langdef=foo 
    --map-foo=+.foo 
    --regex-foo=/^class[[:blank:]]+([[:alpha:]]+):/\1/c,class/{scope=set} 
    --regex-foo=/^[[:blank:]]+def[[:blank:]]+([[:alpha:]]+).*:/\1/d,definition/{scope=ref} 

$ ~/var/ctags/ctags --options=/tmp/foo.ctags -o - /tmp/input.foo 
bar /tmp/input.foo /^ def bar(baz):$/;" d class:foo 
foo /tmp/input.foo /^class foo:$/;" c 
gar /tmp/input.foo /^ def gar(gaz):$/;" d class:goo 
goo /tmp/input.foo /^class goo:$/;" c 

实施例2 ::

$ cat /tmp/input.pp 
class foo { 
include bar 
} 

$ cat /tmp/pp.ctags 
--langdef=pp 
    --map-pp=+.pp 
    --regex-pp=/^class[[:blank:]]*([[:alnum:]]+)[[[:blank:]]]*\{/\1/c,class,classes/{scope=push} 
    --regex-pp=/^[[:blank:]]*include[[:blank:]]*([[:alnum:]]+).*/\1/i,include,includes/{scope=ref} 
    --regex-pp=/^[[:blank:]]*\}.*//{scope=pop}{exclusive} 

$ ~/var/ctags/ctags --options=/tmp/pp.ctags -o - /tmp/input.pp 
bar /tmp/input.pp /^ include bar$/;" i class:foo 
foo /tmp/input.pp /^class foo {$/;" c