Czy mogę przejść do deklaracji lub definicji funkcji w projekcie wielu plików źródłowych C ++?

15

Czy mogę przejść do deklaracji lub definicji funkcji w projekcie wielu plików źródłowych C ++?

Powiedzmy, że mam plik nagłówkowy foo.hpp:

int bar();

i plik źródłowy foo.cpp:

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

i główny plik main.cpp:

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

Czy vim może znaleźć zarówno definicję, jak i deklarację funkcji bar()z mainfunkcji?

Allan Hasegawa
źródło

Odpowiedzi:

15

Bujne ctagi to najprostszy sposób na osiągnięcie tego. W GNU / Linux (np. Ubuntu lub Debian) powinieneś być w stanie to zrobić

sudo apt-get install exuberant-ctags

(W przypadku systemu OSX powinno wystarczyć polecenie „$ brew install ctags”; w przypadku systemu Windows warto je odwiedzić http://ctags.sourceforge.net/ i pobrać samodzielny plik wykonywalny)

Następnie przejdź do folderu głównego projektu i uruchom

ctags -R --exclude=.git .

Spowoduje to przeskanowanie całego projektu i utworzenie pliku ./tags, którego vim automatycznie użyje, aby umożliwić ci przejście do funkcji po naciśnięciu klawisza. Mianowicie:

Ctrl + ]

z kursorem umieszczonym na funkcji, dla której chcesz zobaczyć implementację. Istnieją inne kombinacje i wiele funkcji trybu poleceń, które pozwalają również poruszać się po kodzie za pomocą znaków ctag (np. Ctrl+, tAby przejść do starszego wpisu stosu znaczników). Zobacz :help 29.1przegląd.

Pamiętaj, że musisz ponownie uruchamiać ctagi dla każdej znaczącej zmiany w kodzie i pozwolić na ponowne zaindeksowanie projektu. Możesz to zrobić ręcznie lub nauczyć vima, aby robił to na skrócie lub podczas pisania.

Wskazówka: jeśli często używasz tagów, być może warto też zajrzeć do wtyczki vim-taglist ( http://vim-taglist.sourceforge.net ). Daje ci zarys w stylu IDE z listą wszystkich funkcji dla tej klasy / pliku.

Skała
źródło
Dwie rzeczy, o których warto wiedzieć: universal-ctags pod wieloma względami zastąpił exuberant-ctags. Ponadto, jak pozwolić gitowi zsynchronizować tagi
D. Ben Knoble
4

Do tej pory mogę wymienić dwa rozwiązania problemu znalezienia albo deklaracji, albo definicji funkcji. Wiem, że istnieje inne dobrze znane rozwiązanie oparte na tagach, ale ponieważ go nie używam, dam innym.

Najpierw bardziej modny: YouCompleteMe ma:GoToDefinition i :GoToDeclarationparę poleceń.

Ten, którego używam (ciężko zmienić 10-letnie nawyki). Moja wtyczka lh-tags ma sposób na generowanie bazy danych ctags i aktualizowanie jej stopniowo. A także oferuje sposób (CTRL+W Meta+Down ) do przedstawienia wszystkich deklaracji i definicji, które pasują do tego, co znajduje się pod kursorem (/ co jest wybrane). Ponieważ to rozwiązanie opiera się na tagach, nie będzie w stanie wiedzieć, które przeciążenie identyfikatora pod kursorem jest również powiązane. Inne rozwiązania oparte na tagach powinny być równie złe (/ tak dobre) w tym temacie. Jednak YCM powinno być tutaj znacznie lepsze.

Discl .: Wdrożyłem tagi lh jako bardziej ergonomiczną alternatywę dla :tselect .

(Właściwie pamiętam trzecie rozwiązanie: uruchomiłem rozwidlenie clang-indexer i powiązanej wtyczki vim która by go zamknęła. Ale mając YCM, zapomnę o tym rozwiązaniu)

EDYCJA: Od 2019 r. Najbardziej wydajne rozwiązanie opiera się na serwerach LSP . Używam COC + ccls do indeksowania, skakania i robienia wielu innych rzeczy. Wracam do rozwiązań opartych na tagach, kiedy jestem zbyt leniwy, aby skonfigurować COC dla projektu, w którym nie spędzę dużo czasu lub w którym nie będę mógł zainstalować najnowszych wersji clang i ccls.

Luc Hermitte
źródło
1
Dziękujemy za wkład, przetestuję każde rozwiązanie. Przetestowałem YouCompleteMe i GoToDeclarationdziała tylko z wieloma plikami źródłowymi. Oto cytat z docs o GoToDefinition: For C-family languages this only works ... when the definition of the symbol is in the current translation unit.. Również polecenia są :YcmCompleter GoTo*.
Allan Hasegawa,
Przegapiłem tę linię. Oznacza to, że clang_indexer może nadal być przydatny. Inne rozwiązania mogą być nieco trudne do zainstalowania. W razie potrzeby nie wahaj się wysłać mi e-maila.
Luc Hermitte
3

Istnieje kilka alternatyw. Pierwszy to ctags. Jeśli potrzebujesz bardziej zaawansowanego indeksatora, cscopejest lepszą alternatywą. Na przykład pozwoli ci wyświetlić listę wszystkich rozmówców danej funkcji. Narzędzia te zaindeksują Twój kod, nie rozumiejąc go właściwie (mają prostą definicję gramatyczną, aby wiedzieć, co oznacza dany symbol). Również stosunkowo łatwo jest rozszerzyć tę gramatykę. ThetaglistPlugin to musi mieć dla nich i to jest możliwe rozszerzenie gramatyki indeksatora aby pokazać wyniki w taglist.

Jeśli potrzebujesz czegoś więcej niż indeksatora, na przykład sprawdzania składni, YouCompleteMeprawdopodobnie jest to właściwa droga. Jest zbudowany na szczycie llvmi dlatego ma odpowiedni parser. Pozwala to sprawdzić składnię kodu i semantykę .

Następnie, jeśli pracujesz z kodem, który ma język specyficzny dla domeny lub kod osadzony, często kończy się to tylko przeglądaniem plików. Alternatywą jest Ackskrypt perla, który próbuje pomóc w tym zadaniu.

Nazwa
źródło
0

Myślę, że ctags jest tym, czego potrzebujesz. Vim jest zintegrowany z ctagami natywnie i może łatwo przejść do definicji funkcji i deklaracji.

Przeczytaj ten artykuł http://andrew.stwrt.ca/posts/vim-ctags

David Carlos
źródło
Dodaj podsumowanie połączonego postu. Odpowiedzi zawierające tylko łącza stają się bezużyteczne, gdy łącze znika.
muru