Могу ли я перейти к объявлению или определению функции в проекте с несколькими исходными файлами C ++?

15

Могу ли я перейти к объявлению или определению функции в проекте с несколькими исходными файлами C ++?

Допустим, у меня есть заголовочный файл foo.hpp:

int bar();

и исходный файл foo.cpp:

#include "foo.hpp"
int bar() { return 42; }

и основной файл main.cpp:

#include "foo.hpp"
int main() { bar(); return 0; }

Может ли vim найти определение и объявление функции bar()из mainфункции?

Аллан Хасегава
источник

Ответы:

15

Exuberant ctags - самый простой способ добиться этого. Под GNU / Linux (например, Ubuntu или Debian) вы можете просто

sudo apt-get install exuberant-ctags

(Для OSX должно хватить «$ brew install ctags»; для Windows вы можете посетить http://ctags.sourceforge.net/ и загрузить автономный исполняемый файл)

Затем перейдите в корневую папку вашего проекта и запустите

ctags -R --exclude=.git .

Это отсканирует весь ваш проект и создаст файл ./tags, который vim будет автоматически использовать, чтобы предоставить вам возможность переходить к функциям нажатием клавиши. А именно:

Ctrl + ]

поместив курсор на функцию, для которой вы хотите увидеть реализацию. Существуют и другие комбинации и множество функций командного режима, которые также позволяют перемещаться по коду с помощью ctags (например, Ctrl+ tдля перехода к более старой записи стека тегов). Смотрите :help 29.1для обзора.

Обратите внимание, что вы должны перезапускать ctags для каждого значительного изменения в коде и позволять ему переиндексировать ваш проект. Вы можете сделать это вручную или научить vim делать это по горячей клавише или по записи.

Подсказка: если вы широко используете ctags, возможно, стоит посмотреть плагин vim-taglist ( http://vim-taglist.sourceforge.net ). Он дает вам схему в стиле IDE со списком всех функций для этого класса / файла.

рок
источник
Две вещи, которые стоит знать: универсальные ctags во многом заменили exuberant-ctags. Кроме того, как позволить git синхронизировать ваши теги
Д. Бен Нобл
4

До сих пор я могу назвать два решения проблемы нахождения либо объявления, либо определения функции. Я знаю, что есть еще одно хорошо известное решение на основе тегов, но, поскольку я им не пользуюсь, я позволю другим дать его вам.

Более модно один первый: YouCompleteMe имеет :GoToDefinitionи в :GoToDeclarationпару команд.

Тот, который я использую (трудно изменить привычки 10 лет). Мой плагин lh-tags позволяет генерировать базу данных ctags и постепенно обновлять ее. А также он предлагает способ ( CTRL+W Meta+Down) для представления всех объявлений и определений, которые соответствуют тому, что находится под курсором (/ что выбрано). Поскольку это решение опирается на ctags, оно не сможет узнать, с какой перегрузкой действительно связан идентификатор под курсором. Другие решения на основе ctags должны быть такими же плохими (/ хорошими) по этой теме. Однако YCM должен быть намного лучше здесь.

Discl .: Я реализовал lh-теги как более эргономичную альтернативу :tselect.

(На самом деле я помню третье решение: я запустил форк clang-indexer и связанный плагин vim, который бы инкапсулировал его. Но с YCM я бы забыл об этом решении)

РЕДАКТИРОВАТЬ: С 2019 года наиболее эффективное решение полагаться на серверы LSP . Я использую COC + ccls, чтобы индексировать, прыгать и делать еще много вещей. Я возвращаюсь к решениям на основе тегов, когда мне лень настраивать COC для проекта, на который я не буду тратить много времени или где я не могу установить последние версии clang и ccls.

Люк Эрмитт
источник
1
Спасибо за вклад, протестируем каждое решение. Я протестировал YouCompleteMe и GoToDeclarationработает только с несколькими исходными файлами. Вот цитата из документации о GoToDefinition: For C-family languages this only works ... when the definition of the symbol is in the current translation unit.. Также команды есть :YcmCompleter GoTo*.
Аллан Хасэгава
Я пропустил эту строчку. Это означает, что clang_indexer все еще может быть полезен. Другие решения могут быть немного сложными для установки. Не стесняйтесь, присылайте мне по электронной почте, если это будет необходимо.
Люк Эрмит
3

Есть несколько альтернатив. Первый ctags. Если вам нужен более продвинутый индексатор, тогда cscopeэто лучшая альтернатива. Например, это позволит вам перечислить всех абонентов данной функции. Эти инструменты будут индексировать ваш код, не понимая его правильно (у них есть простое определение грамматики, чтобы знать, что означает данный символ). Это также относительно легко расширить эту грамматику. taglistПлагин должен иметь для них , и это можно расширить индексатор грамматику , чтобы показать результаты в taglist.

Если вам нужно что-то большее, чем индексатор, то, например, проверка синтаксиса, тогда YouCompleteMe, вероятно, стоит пойти дальше. Он построен на основе llvmи, следовательно, имеет правильный синтаксический анализатор. Это позволяет проверить синтаксис и семантику кода .

Затем, если вы работаете с кодом, который имеет специфичный для предметной области язык или встроенный код, то вы часто заканчиваете просто поиском файлов. Альтернативой является AckPerl-скрипт, который пытается помочь с этой задачей.

имя
источник
0

Я думаю, что ctags это то, что вам нужно. Vim изначально интегрирован с ctags и может легко переходить к определениям и объявлениям функций.

Посмотрите на эту статью http://andrew.stwrt.ca/posts/vim-ctags

Дэвид Карлос
источник
Пожалуйста, добавьте резюме по ссылке. Ответы, содержащие только ссылки, становятся бесполезными, когда ссылка перестает работать.
Муру