Puis-je accéder à une déclaration ou à une définition de fonction dans un projet à plusieurs fichiers source C ++?


15

Puis-je accéder à une déclaration ou à une définition de fonction dans un projet à plusieurs fichiers source C ++?

Disons que j'ai un fichier d'en-tête foo.hpp:

int bar();

et un fichier source foo.cpp:

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

et un fichier principal main.cpp:

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

Vim peut-il trouver à la fois la définition et la déclaration de la fonction à bar()partir de la mainfonction?

Réponses:


15

Les ctags exubérants sont le moyen le plus simple d'y parvenir. Sous GNU / Linux (par exemple Ubuntu ou Debian), vous devriez pouvoir simplement faire

sudo apt-get install exuberant-ctags

(Pour OSX, "$ brew install ctags" devrait suffire; pour Windows, vous pouvez visiter http://ctags.sourceforge.net/ et télécharger l'exécutable autonome)

Ensuite, accédez au dossier racine de votre projet et exécutez

ctags -R --exclude=.git .

Cela analysera l'intégralité de votre projet et créera un fichier ./tags que vim utilisera automatiquement pour vous offrir la possibilité de passer aux fonctions en appuyant sur une touche. À savoir:

Ctrl + ]

avec votre curseur placé sur la fonction pour laquelle vous souhaitez voir l'implémentation. Il existe d'autres combinaisons et de nombreuses fonctions en mode commande qui vous permettent également de parcourir votre code par ctags (par exemple Ctrl+ tpour passer à une ancienne entrée de pile de balises). Voir :help 29.1pour un aperçu.

Notez que vous devez réexécuter les ctags pour chaque changement significatif dans le code et le laisser réindexer votre projet. Vous pouvez soit le faire manuellement, soit apprendre à Vim à le faire sur raccourci clavier ou sur écriture.

Astuce: si vous utilisez largement les ctags, le plugin vim-taglist ( http://vim-taglist.sourceforge.net ) vaut peut-être aussi le coup d'œil. Il vous donne un aperçu de style IDE avec une liste de toutes les fonctions pour cette classe / fichier.


Deux choses à savoir: les ctags universels ont, à bien des égards, remplacé les ctags exubérants. Aussi, comment laisser git synchroniser vos tags
D. Ben Knoble

4

Jusqu'à présent, je peux nommer deux solutions au problème de trouver soit la déclaration soit la définition d'une fonction. Je sais qu'il existe une autre solution basée sur des balises bien connues, mais comme je ne l'utilise pas, je vais laisser les autres vous la donner.

Le plus branché en premier: YouCompleteMe a une :GoToDefinitionet une :GoToDeclarationpaire de commandes.

Celui que j'utilise (il est difficile de changer les habitudes de 10 ans). Mon plugin lh-tags a un moyen de générer une base de données ctags et de la mettre à jour progressivement. Il offre également un moyen ( CTRL+W Meta+Down) de présenter toutes les déclarations et définitions qui correspondent à ce qui se trouve sous le curseur (/ ce qui est sélectionné). Comme cette solution repose sur des ctags, elle ne pourra pas non plus savoir à quelle surcharge l'identifiant sous le curseur est vraiment lié. Les autres solutions basées sur ctags devraient être aussi mauvaises (/ que bonnes) sur ce sujet. Cependant, YCM devrait être beaucoup mieux ici.

Discl.: J'ai mis en place des balises lh comme alternative plus ergonomique à :tselect.

(En fait, je me souviens d'une troisième solution: j'avais démarré un fork de clang-indexer et le plugin vim connexe qui l'aurait encapsulé. Mais avec YCM autour, j'oublierais cette solution)

EDIT: À partir de 2019, la solution la plus efficace repose sur des serveurs LSP . J'utilise COC + ccls pour indexer, sauter et faire bien d'autres choses. Je reviens aux solutions basées sur des balises lorsque je suis trop paresseux pour configurer COC pour un projet sur lequel je ne passerai pas beaucoup de temps ou lorsque je ne peux pas installer les versions récentes de clang et ccls.


1
Merci pour la contribution, testera chaque solution. J'ai testé le YouCompleteMe et ne GoToDeclarationfonctionne qu'avec plusieurs fichiers sources. Voici une citation de la documentation sur GoToDefinition: For C-family languages this only works ... when the definition of the symbol is in the current translation unit.. En outre, les commandes sont :YcmCompleter GoTo*.
Allan Hasegawa

J'ai raté cette ligne. Cela signifie que clang_indexer peut toujours être utile. Les autres solutions peuvent être un peu difficiles à installer. N'hésitez pas à m'envoyer un mail si besoin.
Luc Hermitte

3

Il existe peu d'alternatives. Le premier est ctags. Si vous avez besoin d'un indexeur plus avancé, cscopec'est une meilleure alternative. Par exemple, il vous permettra de répertorier tous les appelants d'une fonction donnée. Ces outils indexeront votre code sans vraiment le comprendre correctement (ils ont une définition grammaticale simple pour savoir ce que signifie un symbole donné). Il est également relativement facile d'étendre cette grammaire. Le taglistplugin est indispensable pour ceux-ci et il est possible d'étendre la grammaire de l'indexeur pour afficher les résultats dans la liste de balises.

Si vous avez besoin de quelque chose de plus que l'indexeur, comme la vérification de la syntaxe, YouCompleteMec'est probablement la voie à suivre. Il est construit sur le dessus llvmet a donc un analyseur approprié. Cela permet de vérifier la syntaxe et la sémantique du code .

Ensuite, si vous travaillez avec un code qui a un langage spécifique à un domaine ou un code intégré, vous finissez souvent par parcourir des fichiers. L'alternative est le Ackscript perl qui essaie d'aider à cette tâche.


0

Je pense que ctags c'est ce dont vous avez besoin. Vim est intégré nativement aux ctags et peut facilement accéder aux définitions et déclarations de fonctions.

Jetez un œil à cet article http://andrew.stwrt.ca/posts/vim-ctags


Veuillez ajouter un résumé du message lié. Les réponses de lien uniquement deviennent inutiles lorsque le lien est mort.
muru
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.