Posso passare a una dichiarazione o definizione di funzione in un progetto con più file di origine C ++?


15

Posso passare a una dichiarazione o definizione di funzione in un progetto con più file di origine C ++?

Diciamo che ho un file di intestazione foo.hpp:

int bar();

e un file sorgente foo.cpp:

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

e un file principale main.cpp:

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

Vim può trovare sia la definizione che la dichiarazione della funzione bar()dalla mainfunzione?

Risposte:


15

I tag esuberanti sono il modo più semplice per raggiungere questo obiettivo. Sotto GNU / Linux (es. Ubuntu o Debian) dovresti essere in grado di farlo

sudo apt-get install exuberant-ctags

(Per OSX "$ brew install ctags" dovrebbe essere sufficiente; per Windows potresti visitare http://ctags.sourceforge.net/ e scaricare l'eseguibile standalone)

Quindi vai alla cartella principale del tuo progetto ed esegui

ctags -R --exclude=.git .

Questo eseguirà la scansione dell'intero progetto e creerà un file ./tags che vim utilizzerà automaticamente per offrirti la possibilità di passare alle funzioni con la semplice pressione di un tasto. Vale a dire:

Ctrl + ]

con il cursore posizionato sulla funzione per cui si desidera vedere l'implementazione. Esistono altre combinazioni e molte funzioni della modalità di comando che ti consentono di navigare nel tuo codice anche tramite ctags (ad es. Ctrl+ tPer passare alla voce di stack di tag più vecchia). Vedi :help 29.1per una panoramica.

Nota che devi rieseguire i tag per ogni modifica significativa nel codice e lasciarlo reindicizzare il tuo progetto. Puoi farlo manualmente o insegnare a vim a farlo sul tasto di scelta rapida o in scrittura.

Suggerimento: se fai ampio uso di ctags, forse vale la pena dare un'occhiata anche al plug -in vim-taglist ( http://vim-taglist.sourceforge.net ). Ti dà una struttura in stile IDE con un elenco di tutte le funzioni per quella classe / file.


Due cose che vale la pena sapere: universal-ctags ha in qualche modo sostituito i tag esuberanti. Inoltre, come consentire a git di sincronizzare i tuoi tag
D. Ben Knoble,

4

Finora posso nominare due soluzioni al problema di trovare la dichiarazione o la definizione di una funzione. So che esiste un'altra soluzione ben nota basata su tag, ma poiché non la utilizzo, permetterò ad altri di dartela.

Il più alla moda per primo: YouCompleteMe ha un :GoToDefinitione un :GoToDeclarationpaio di comandi.

Quello che uso (è difficile cambiare le abitudini di 10 anni). Il mio plugin lh-tags ha un modo per generare un database ctags e aggiornarlo in modo incrementale. Inoltre offre un modo ( CTRL+W Meta+Down) per presentare tutte le dichiarazioni e le definizioni che corrispondono a ciò che è sotto il cursore (/ cosa è selezionato). Poiché questa soluzione si basa su tag, non sarà in grado di sapere quale sovraccarico sia identificato anche l'identificatore sotto il cursore. Altre soluzioni basate su tag dovrebbero essere pessime (/ altrettanto buone) su questo argomento. Tuttavia YCM dovrebbe essere molto meglio qui.

Discl .: Ho implementato lh-tags come alternativa più ergonomica a :tselect.

(In realtà ricordo una terza soluzione: avevo avviato un fork di clang-indexer e il relativo plugin vim che l'avrebbe incapsulato. Ma con YCM in giro, avrei dimenticato questa soluzione)

EDIT: a partire dal 2019, la soluzione più efficiente si basa su server LSP . Sto usando COC + ccls per indicizzare, saltare e fare molte altre cose. Sto tornando alle soluzioni basate su tag quando sono troppo pigro per configurare COC per un progetto in cui non passerò molto tempo o dove non posso installare versioni recenti di clang e ccls.


1
Grazie per l'input, testerà ogni soluzione. Ho testato YouCompleteMe e GoToDeclarationfunziona solo con più file di origine. Ecco una citazione dalla documentazione su GoToDefinition: For C-family languages this only works ... when the definition of the symbol is in the current translation unit.. Inoltre, i comandi sono :YcmCompleter GoTo*.
Allan Hasegawa,

Ho perso questa linea. Ciò significa che clang_indexer potrebbe essere ancora utile. Le altre soluzioni potrebbero essere un po 'complicate da installare. Non esitate a inviarmi un'e-mail, se necessario.
Luc Hermitte,

3

Ci sono poche alternative. Il primo è ctags. Se hai bisogno di un indicizzatore più avanzato, allora cscopeè un'alternativa migliore. Ad esempio, ti consentirà di elencare tutti i chiamanti di una determinata funzione. Questi strumenti indicizzeranno il tuo codice senza realmente capirlo correttamente (hanno una semplice definizione grammaticale per sapere cosa significa un determinato simbolo). È anche relativamente facile estendere quella grammatica. Il taglistplug-in è un must per questi ed è possibile estendere la grammatica dell'indicizzatore per mostrare i risultati nella taglist.

Se hai bisogno di qualcosa di più dell'indicizzatore, allora come il controllo della sintassi YouCompleteMeè probabilmente la strada da percorrere. È costruito sopra il llvme quindi ha un parser adeguato. Ciò consente di verificare la sintassi e la semantica del codice .

Quindi se lavori con un codice che ha una lingua specifica del dominio o un codice incorporato, spesso finisci per passare da un file all'altro. L'alternativa è lo Ackscript perl che cerca di aiutare con questa attività.


0

Penso che i tag siano ciò di cui hai bisogno. Vim è integrato in modo nativo con i tag e può saltare facilmente alle definizioni e alle dichiarazioni delle funzioni.

Dai un'occhiata a questo articolo http://andrew.stwrt.ca/posts/vim-ctags


Aggiungi un riepilogo del post collegato. Le risposte di solo collegamento diventano inutili quando il collegamento si interrompe.
Muru,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.