Могу ли я добавить информацию о области действия в теги, сгенерированные с помощью `--regex-<LANG>` в обильных ctags?
Технически, я использую Tagbar в vim для просмотра тегов файла, но этот вопрос должен применяться в основном к exuberant 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
Интересующий меня бит - это последнее поле второй строки, class:foo
, Это сфера bar()
функция. Если я использую tagbar в vim, он соответственно вкладывает функцию в класс.
Теперь предположим, что я добавляю поддержку нового языка в моем ~/.ctags
, На самом деле, я добавляю поддержку для этого файла кукол:
class foo {
include bar
}
Предположим, я использую следующее ~/.ctags
аргументы. Регулярное выражение 'import' некрасиво (ошибочно... ужасно для регулярного выражения), но оно выполняет работу, достаточную для этого примера:
--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
(особенно в последнем подразделе "Написание собственной программы генерации тегов"), если это будет вариант для вас.
Я работаю над такой функцией в универсальном проекте 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