Vim переходит на неправильный тег - PullRequest
0 голосов
/ 07 ноября 2018

В заголовке указана проблема, поэтому вот контекст. У меня есть крошечный файл C ++

void f(
        int x
      ) { }

void f(
      ) { }

На котором я запускаю ctags.

ctags --recurse --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f tags f.C

Изучение файлов тегов показывает две записи для f, как и ожидалось, с правильными подписями.

Когда я пытаюсь использовать это в Vim, Vim находит функцию с помощью ctrl-], но когда я использую: tnext и: tprev, сообщение говорит tag 1 of 2 или tag 2 of 2, но курсор между ними не перемещается.

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

На основании ответа Инго Карката, вот решение, которое может работать для вас. Если вы запустите ctags (по крайней мере, Exuberant Ctags) с --excmd=number, он выведет номера строк вместо команд поиска местоположения тега, что затем разрешит неоднозначность.

ctags --recurse --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f tags --excmd=number f.C

Недостатком этого является то, что как только вы начнете редактировать файл, теги станут недействительными, пока вы снова не запустите ctags. Шаблоны поиска менее восприимчивы к этому, чем номера строк.

Существуют и другие ответы ( Vim auto-generate ctags - один из них), которые охватывают автоматический запуск ctags при изменениях; Для вас может работать некоторая комбинация двух подходов.

0 голосов
/ 07 ноября 2018

Если вы посмотрите на :help tags-file-format, Vim использует третий столбец (с именем {tagaddress}) в качестве команды (поиска) (:help tag-search ). В сгенерированном файле тегов это выглядит так:

f   foo.cpp /^void f($/;"   f   signature:( )
f   foo.cpp /^void f($/;"   f   signature:( int x )

Шаблон поиска для обеих перегрузок (/^void f($/) идентичен ; Вот почему каждый прыжок тега будет определять местонахождение первого экземпляра! Другими словами, хотя приятно, что программа тегов добавила подпись, Vim, к сожалению, не учитывает это.

При этом очевидный способ обойти проблему - переформатировать исходный код, чтобы (части) подписи были включены в одну строку. Тогда будут разные шаблоны:

b   bar.cpp /^void b()$/;"  f   signature:()
b   bar.cpp /^void b(int x)$/;" f   signature:(int x)

Более правильным (но также и более сложным) путем для решения этой проблемы было бы расширение программы ctags для распознавания этих неоднозначностей, а затем добавление в шаблон положительного взгляда , чтобы также рассмотреть материал в следующей строке.

f   foo.cpp /^void f(\%(\n\s*int x\)\@=/;"  f   signature:( )
f   foo.cpp /^void f(\n\s*)/;"  f   signature:( int x )

К сожалению, Vim, похоже, не понимает этот синтаксис (ни с предвидением, ни без него); Я просто получаю E435: Couldn't find tag, just guessing!.

...