2009-08-10 10 views
9

Ho appena iniziato ad usare ctags e apprezzo molto lo strumento, ma il modo in cui gestisco il mio file di tag è alquanto scomodo a mio parere e molto inflessibile.Quali sono i metodi più semplici/migliori per la gestione dei file di tag ctags?

Come Attualmente gestisco il mio file di tag:

  1. ho uno monolitico file di tag memorizzato nella mia cartella home a ~/.vim/tags
  2. Quando aggiorno i miei progetti di codice o di cambiamento ho eseguito uno script che elimina il vecchio file di tag e rigenera il file di tag monolitico (devi cambiare la posizione da cui viene eseguito ctags da quando cambi i progetti)

Avere un file di tag monolitico funziona s per me perché mi permette di passare a tutti i simboli rilevanti per il progetto attuale su cui sto lavorando.

Un singolo file di tag monolitico non funzionerà con un codebase grande/enorme? Perché un enorme file di tag non funziona su una base di codice grande/enorme?

Quali sono altri modi per gestire il file di tag (o taggare i file plurali)?

E perché il nuovo metodo di gestione dei file di tag dovrebbe essere migliore? (Presumibilmente una soluzione migliore sarebbe essere a volte più complessa. Quindi, se la soluzione è più complessa vi chiedo qual è il vantaggio per un metodo più complesso per la gestione dei file di tag.)


P.S. Ho trovato una domanda StackOverflow che parla di ctags chiamato "vimctags-tips-and-tricks" ma questa domanda non parla di come gestire i file di tag.

risposta

7

Ho inserito il file tags nella directory del progetto. Ciò mantiene i tag separati per ogni progetto.

Per codebases di grandi dimensioni, ho ridotto la frequenza con cui lo aggiorno. Solitamente lo aggiorno solo se provo a saltare a una parola chiave e non è lì per qualche motivo. Dopotutto, lo scopo è quello di arrivare rapidamente ad un'altra parte del codice, e se arriva lì con qualsiasi mezzo, allora ha funzionato anche se il file di tag non è aggiornato.

+1

+1 sull'approccio. Uso anche cscope - e ho uno script shell a tre righe che ricrea i file per entrambi quando diventano stantii. –

1

Proprio come Greg, tengo il file di tag nella directory del progetto. Quindi utilizzo il plug-in project con il tag in= per impostare il percorso del file di tag e se utilizzare la ricorsione durante la rigenerazione di tags e cscope.out per diversi progetti.

Solitamente aggiorno il file di tag solo quando ci sono state modifiche significative in quanto il tag di solito ti porta sulla linea giusta (o almeno sulla linea giusta) anche se non è aggiornato. Il motivo principale per cui aggiorno è se ho aggiunto un nuovo enum, struct o simile e voglio che lo tag syntax highlighting sia aggiornato.

10

Un approccio a cui mi sono appassionato di recente è l'utilizzo degli hook VCS (Version Control Systems) per generare i file ctags. Io uso git localmente anche per piccoli progetti e simili, e così i ctags vengono aggiornati ogni volta che commetto (questo è ovviamente possibile con tutti gli altri VC là fuori).

Personalmente, mi piace posizionare il file ctags nella directory di ciascun progetto, ma questo approccio dovrebbe funzionare altrettanto bene a livello globale.

EDIT: Gli hook VCS sono script o programmi che vengono eseguiti automaticamente quando vengono eseguite determinate azioni, come checkout, commit, revert e altri.
Per ulteriori approfondimenti suggerisco i seguenti link:

I ganci sono generalmente disponibili in tutti i VCS in cui mi sono imbattuto, e sono sicuro che sarete in grado di trovare la documentazione per quello che avete scelto di usare.

+0

Non so cosa siano "ganci VCS". Forse potresti elaborare un po 'di più sugli hook VCS e su come è in grado di rigenerare i tag al momento del commit? –

+0

Ho aggiornato la risposta e spero che fornisca ulteriori informazioni ora. Sarò felice di chiarire ulteriormente se necessario. – spatz

+0

ganci lato client o lato server? Penso che il lato client sia migliore per quello che vuoi fare, ma Subversion non fa sul lato client. –

0

Fatta eccezione per i plugin vim per i quali ho un solo file di tag, ho anche un database di ctags per progetto.

Questo implica due cose:

  1. un modo per rilevare "progetti" e per impostare l'impostazione di conseguenza un vim. Ci sono plenty plugins in grado di farlo.
  2. un modo per avere impostazioni diverse per diversi progetti contemporaneamente. Ecco dove setlocal tags=... (/ setlocal tags+=) riproduce la sua parte.

La maggior parte delle volte i progetti non condividono tag. Di conseguenza, sono contento di rilevare il progetto corrente da definire automaticamente dove aggiorno i tag e dove li leggo. Questi sono due casi d'uso distinti e vim gestisce solo (in modo nativo) l'ultimo. I plugin che gestiscono il primo caso d'uso devono specificare una variabile (buffer local) per memorizzare le informazioni.

In realtà durante il salvataggio di un file dovrebbe aggiornare solo uno specifico database di tag, potremmo dover recuperare i tag per più basi contemporaneamente. Questo è un caso d'uso che ho quando lavoro su librerie/progetti che dipendono l'uno dall'altro: spesso devo controllare qualcosa nel codice (~ 3rd party) che impongo. Avrei potuto usare le opzioni globali &tags, ma ho scelto (per ora) di avere valori distinti in buffer distinti. Ancora una volta, questo caso d'uso è curato grazie al plugin vimrc locale che sto usando.

Per quanto riguarda l'aggiornamento del database dei tag, è fatto in un (che sto mantenendo, ma ce ne sono altri con capacità simili): rimuovo i tag associati al file corrente dal database dei tag di progetto associato, quindi aggiorno con l'opzione -a, in background. Non c'è davvero bisogno di analizzare il progetto completo ogni volta che salviamo un file.

Nel caso in cui i file di progetto vengano aggiornati al di fuori dello scope di vim, ho ancora la possibilità di eseguire tag sull'intero progetto. Mentre tutto è trasparente con i ganci di commit, sono in grado di aggiornare il dizionario di controllo ortografico di Vim per non contrassegnare gli identificatori di codice come parole errate. Ho il sospetto che sarebbe un po 'più noioso con un puro approccio di commit-hook.