Kann ich in einem Projekt mit mehreren C ++ - Quelldateien zu einer Funktionsdeklaration oder -definition springen?

14

Kann ich in einem Projekt mit mehreren C ++ - Quelldateien zu einer Funktionsdeklaration oder -definition springen?

Nehmen wir an, ich habe eine Header-Datei foo.hpp:

int bar();

und eine Quelldatei foo.cpp:

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

und eine Hauptdatei main.cpp:

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

Kann vim sowohl die Definition als auch die Deklaration der Funktion bar()aus der mainFunktion herausfinden ?

Allan Hasegawa
quelle

Antworten:

13

Überschwängliche Tags sind der einfachste Weg, dies zu erreichen. Unter GNU / Linux (zB Ubuntu oder Debian) sollten Sie das einfach können

sudo apt-get install exuberant-ctags

(Für OSX sollte "$ brew install ctags" ausreichen. Für Windows können Sie http://ctags.sourceforge.net/ besuchen und die eigenständige ausführbare Datei herunterladen.)

Navigieren Sie dann zum Stammordner Ihres Projekts und führen Sie es aus

ctags -R --exclude=.git .

Dadurch wird Ihr gesamtes Projekt gescannt und eine ./tags-Datei erstellt, die vim automatisch verwendet, um Ihnen die Möglichkeit zu geben, per Tastendruck zu Funktionen zu springen. Nämlich:

Ctrl + ]

Stellen Sie den Cursor auf die Funktion, für die Sie die Implementierung anzeigen möchten. Es gibt andere Kombinationen und viele Befehlsmodusfunktionen, mit denen Sie auch mit ctags durch Ihren Code navigieren können (z. B. Ctrl+, tum zum älteren Tag-Stack-Eintrag zu springen). Sehen Sie :help 29.1für eine Übersicht.

Beachten Sie, dass Sie ctags für jede signifikante Änderung im Code erneut ausführen und Ihr Projekt erneut indizieren müssen. Sie können dies entweder manuell tun oder vim beibringen, dies per Hotkey oder beim Schreiben zu tun.

Hinweis: Wenn Sie Ctags ausgiebig nutzen, ist möglicherweise auch das Plugin vim-taglist ( http://vim-taglist.sourceforge.net ) einen Blick wert. Sie erhalten eine IDE-ähnliche Übersicht mit einer Liste aller Funktionen für diese Klasse / Datei.

Felsen
quelle
Zwei Dinge, die es zu wissen gilt: Universal-Ctags haben überschwängliche Ctags in vielerlei Hinsicht abgelöst. Außerdem, wie Sie git Ihre Tags synchronisieren lassen
D. Ben Knoble
4

Bisher kann ich zwei Lösungen für das Problem nennen, entweder die Deklaration oder die Definition einer Funktion zu finden. Ich weiß, dass es eine andere, auf Tags basierende Lösung gibt, aber da ich sie nicht verwende, lasse ich sie von anderen geben.

Das Modischere zuerst: YouCompleteMe verfügt über ein :GoToDefinitionund :GoToDeclarationzwei Befehle.

Die, die ich benutze (es ist schwer, 10 Jahre lange Gewohnheiten zu ändern). Mein lh-tags- Plugin bietet die Möglichkeit, eine ctags-Datenbank zu generieren und diese schrittweise zu aktualisieren. Außerdem bietet es eine Möglichkeit ( CTRL+W Meta+Down), alle Deklarationen und Definitionen darzustellen , die mit dem übereinstimmen, was sich unter dem Cursor befindet (/ was ausgewählt ist). Da diese Lösung auf ctags basiert, kann sie nicht wissen, mit welcher Überlastung der Bezeichner unter dem Cursor tatsächlich zusammenhängt. Andere ctags-basierte Lösungen sollten zu diesem Thema genauso schlecht (/ so gut) sein. Allerdings sollte YCM hier viel besser sein.

Discl .: Ich habe lh-tags als ergonomischere Alternative zu implementiert :tselect.

(Eigentlich erinnere ich mich an eine dritte Lösung: Ich hatte eine Reihe von Clang-Indexer und das dazugehörige Vim-Plugin gestartet , das es gekapselt hätte. Aber mit YCM würde ich diese Lösung vergessen.)

BEARBEITEN: Ab 2019 basiert die effizienteste Lösung auf LSP-Servern . Ich benutze COC + ccls, um zu indizieren, zu springen und viele weitere Dinge zu tun. Ich greife auf tagbasierte Lösungen zurück, wenn ich zu faul bin, COC für ein Projekt zu konfigurieren, für das ich nicht viel Zeit aufbringe oder in dem ich die neuesten Versionen von clang und ccls nicht installieren kann.

Luc Hermitte
quelle
1
Vielen Dank für die Eingabe, werde jede Lösung testen. Ich habe YouCompleteMe getestet und kann nur GoToDeclarationmit mehreren Quelldateien arbeiten. Hier ist ein Zitat aus der Dokumentation über GoToDefinition: For C-family languages this only works ... when the definition of the symbol is in the current translation unit.. Auch die Befehle sind :YcmCompleter GoTo*.
Allan Hasegawa
Ich habe diese Zeile verpasst. Das bedeutet, dass clang_indexer möglicherweise immer noch nützlich ist. Die Installation der anderen Lösungen ist möglicherweise etwas schwierig. Zögern Sie nicht, mir bei Bedarf eine E-Mail zu senden.
Luc Hermitte
3

Es gibt nur wenige Alternativen. Der erste ist ctags. Wenn Sie einen fortgeschritteneren Indexer benötigen, cscopeist dies eine bessere Alternative. Beispielsweise können Sie alle Anrufer einer bestimmten Funktion auflisten . Diese Tools indizieren Ihren Code, ohne ihn wirklich richtig zu verstehen (sie haben eine einfache Grammatikdefinition, um zu wissen, was ein bestimmtes Symbol bedeutet). Es ist auch relativ einfach, diese Grammatik zu erweitern. Das taglistPlugin ist ein Muss für diese und es ist möglich, die Indexer-Grammatik zu erweitern, um die Ergebnisse in der Tagliste anzuzeigen.

Wenn Sie mehr als nur einen Indexer benötigen, wie die Syntaxprüfung, YouCompleteMeist dies wahrscheinlich der richtige Weg. Es baut auf dem auf llvmund hat daher den richtigen Parser. Dies ermöglicht die Überprüfung der Codesyntax und der Semantik .

Wenn Sie dann mit einem Code arbeiten, der eine domänenspezifische Sprache oder eingebetteten Code enthält, greift der Benutzer häufig nur durch Dateien. Eine Alternative ist AckPerl-Skript, das versucht, bei dieser Aufgabe zu helfen.

Name
quelle
0

Ich denke, das ist genau das, was du brauchst. Vim ist nativ in ctags integriert und kann problemlos zu Funktionsdefinitionen und -deklarationen springen.

Werfen Sie einen Blick auf diesen Artikel http://andrew.stwrt.ca/posts/vim-ctags

David Carlos
quelle
Bitte fügen Sie eine Zusammenfassung des verlinkten Beitrags hinzu. Nur-Link-Antworten werden nutzlos, wenn der Link nicht mehr funktioniert.
muru