5

技術的には、vim でTagbarを使用してファイルのタグを表示していますが、この質問は一般的に熱狂的な ctags v5.8 に適用されます。

次の python ファイルがあるとしますfoo.py

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

実行してみましょうctags: ctags 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

私が興味を持っているビットは、2 行目の最後のフィールドですclass:foo。それがbar()機能の範囲です。vimでtagbarを使用すると、それに応じて関数がクラスにネストされます。

ここで、 に新しい言語のサポートを追加するとします~/.ctags。実際、この puppet ファイルのサポートを追加しています。

class foo {
    include bar
}

次の~/.ctags引数を使用するとします。'import' 正規表現は醜い (err... regex としては醜い) ですが、この例では十分に機能します:

--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.
4

2 に答える 2

4

いいえ、残念ながら、ctags の正規表現パターンのサポートでは不可能です。ctags で正しいスコープを生成する唯一の方法は、C で追加モジュールとしてパーサーを作成することです。時間があれば、新しい言語をより適切に処理するためのサポートを ctags に追加したいと考えていますが、まだ実現していません。うまくいきましたが、最善のアプローチについてもまだ確信が持てません。

ただし、Tagbar のサポートに主に関心がある場合は、別のアプローチがあります。Tagbar は、出力が ctags のものと互換性がある限り、任意のタグ生成プログラムをサポートするため、たとえば Python で単純なパーサーを記述して、Tagbar を構成できます。それを使用します。:h tagbar-extend(特に最後のサブセクション「独自のタグ生成プログラムの作成」) を参照してください。

于 2013-03-23T11:43:35.340 に答える
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
于 2015-09-17T17:35:43.043 に答える