Suggerimenti e trucchi per Vim e Ctags [chiuso]


485

Ho appena installato Ctags (per aiutare lo sviluppo in C ++) con il mio Vim (o piuttosto gVim) e vorrei scoprire i tuoi comandi preferiti, macro, scorciatoie, suggerimenti che lo accompagnano ...

Condividi il tuo miglior arsenale. Quali altri componenti aggiuntivi di Vim consiglieresti per C ++ sullo sviluppo di Vim?

EDIT Quale altro componente aggiuntivo utilizzeresti insieme a Ctags?

EDIT2 Quale versione di gVim usi con i tag? Fa la differenza?

EDIT3 Come migliorate la vostra esperienza di programmazione per progetti grandi e piccoli?


15
Assicurati di utilizzare esuberanti tag (un'implementazione moderna) per i migliori risultati: ctags.sourceforge.net
idbrii

17
Forse il kev non è costruttivo?
Floyd,

27
anche se closed as not constructivequasi due anni fa, è così costruttivo per me
sazary

15
Penso che il vero motivo per chiudere questa domanda avrebbe dovuto essere: "Questa domanda, nonostante sia estremamente utile, non rientra nella politica di domande e risposte StackOverflow. Lascia che questa domanda e le risposte si spostino su Quora e facciano crescere quel sito mentre continuiamo ostinatamente a chiuderci utile domande e risposte".
Diego Pino,

2
Capisco perché questa domanda è stata chiusa, date le regole di SO. Ma contrassegnare una domanda di voto superiore a 400 con una risposta di voto superiore a 300 per l' eliminazione è un po 'scontroso, no?
DevSolar,

Risposte:


394

Ctrl+ ]- vai alla definizione
Ctrl+ T- Torna indietro dalla definizione.
Ctrl+ W Ctrl+ ]- Apre la definizione in una divisione orizzontale

Aggiungi queste righe in vimrc
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

Ctrl+ \- Apre la definizione in una nuova scheda
Alt+ ]- Apre la definizione in una divisione verticale

Dopo che i tag sono stati generati. È possibile utilizzare i seguenti tasti per taggare e taggare le funzioni:

Ctrl+ Left MouseClick- Vai alla definizione
Ctrl+ Right MouseClick- Torna indietro dalla definizione


8
C -] => (tasto di controllo) e] tasto C - T => (tasto di controllo) e tasto T Solo per i neofiti di tag. Grazie per il nuovo trucco con le schede
kumar l'

6
Allo stesso modo, dopo aver diviso la finestra con Ctrl-w C-]te puoi fare C-w T(aka Shift-t) per cambiare quella divisione in una nuova scheda.
dash-tom-bang,

1
@Will Se si utilizza vim dal terminale, è necessario modificare le preferenze del terminale per fare in modo che il tasto opzione si comporti come un tasto alt. Se stai usando MacVim, aggiungi questa riga a vimrc 'set macmeta'. C'è doc per macmeta,: h macmeta.
Amjith,

17
g C-]è molto utile Apre una finestra di dialogo rapida per selezionarne una tra più definizioni.
Vincenzo Pii,

3
g]è anche utile. È possibile posizionare il cursore sul nome del tag e premere g]per ottenere un elenco di tag corrispondenti.
zeekvfu,

176

Una riga che va sempre nel mio .vimrc:

set tags=./tags;/

Questo cercherà "tag" nella directory corrente e lavorerà l'albero verso root fino a quando non ne verrà trovato uno. IOW, puoi essere ovunque nell'albero dei sorgenti anziché solo alla radice di esso.


37
Salire alla radice è eccessivo. Suggerisco solo di andare a casa invece: tags + = tags; $ HOME
gotgenes,

37
Gli alberi dei sorgenti su cui lavoro non sono sempre nella mia directory home ... e dato che $ HOME tende ad essere a due directory dalla radice ... beh, posso permettermi altre due ricerche nella directory. :)
uzi,

6
Sono d'accordo w / uzi. Se il mio cd è / home / me / programmation / foo / bar / baz / bang / bam, sono solo 8 ricerche di directory. Suppongo che dipenda dalla tua tolleranza per la velocità, ma il tempo di cercare 1 directory non è notevolmente diverso da 8 sulla mia macchina.
Nate Murray,

1
Dipende dal tuo scenario, ho bisogno di usare il suggerimento di gotgenes su una delle mie macchine perché ci sono circa 8.000 directory in / home, e questo tende ad essere un po 'lento.
jkerian,

1
C'è qualcosa di simile per cscope?
szx,

45

Un altro plugin utile per lo sviluppo C è cscope Proprio come Ctags consente di passare alle definizioni, Cscope salta agli chiamata funzioni.

Se hai cscope nella tua directory ~ / bin /, aggiungi quanto segue al tuo .vimrc e usa g ^] per andare alla funzione chiamante (vedi: help cscope).

if has("cscope")
    set csprg=~/bin/cscope
    set csto=0
    set cst
    set nocsverb
    " add any database in current directory
    if filereadable("cscope.out")
        cs add cscope.out
        " else add database pointed to by environment
    elseif $CSCOPE_DB != ""
        cs add $CSCOPE_DB
    endif
endif

Quasi dimenticato ... Proprio come ctags - devi generare (e aggiornare periodicamente) il database. Uso il seguente script

select_files > cscope.files
ctags -L cscope.files
ctags -e -L cscope.files
cscope -ub -i cscope.files

Dove 'select_files' è un altro script che estrae l'elenco di file C e header dal Makefile. In questo modo indicizzo solo i file effettivamente utilizzati dal progetto.


Qual è il vantaggio di cscope rispetto ai tag? Si complimentano a vicenda?
Whaledawg,

4
Si completano a vicenda. Ctags trova la definizione di un simbolo o una funzione. Cscope può trovare tutti i posti che chiamano una funzione. l'utilizzo di entrambi rende molto semplice la navigazione in alberi di grandi dimensioni.
nimrodm,

1
Tuttavia, AFAIK cscope ha una comprensione limitata del C ++.
Luc Hermitte,

È limitato e non molto buono. Ma per quello che fa (saltando su USAGES), non c'è alternativa migliore. Il suo problema principale è che quando vuoi saltare alle funzioni (f), spesso devi saltare ovunque sia usato quel simbolo e filtrare i risultati mentalmente ...
Greg Rogers

2
@Whaledawg Sì, quando premo CTRL +] la mia scheda audio invia "clap.wav" in uscita :)
Patrizio Rullo,

27

È possibile aggiungere directory alla ricerca dei tag. Ad esempio, ho un indice ctags creato per Qt4 e lo ho nel mio .vimrc:

set tags+=/usr/local/share/ctags/qt4


16

Uso ALT-sinistra e ALT-destra per far apparire / spingere da / verso lo stack di tag.

" Alt-right/left to navigate forward/backward in the tags stack
map <M-Left> <C-T>
map <M-Right> <C-]>

Se usi hjklper il movimento puoi mappare <M-h>e <M-l>invece.


non è lo stesso di ctrl -] e ctrl-t - credo che il tuo suggerimento sia un po 'più pulito.

@Sasha, Pardon? Non so cosa stai dicendo. = X Da notare, questo funziona anche in: help.
Strager

2
Penso che questo sia più intuitivo e più pulito di quello predefinito.
Ayman,

1
@Ayman Ma viola anche il principio di non dover spostare le mani dalla home, come usare hjkl contro i tasti freccia.
TankorSmash,

@TankorSmash, quale principio?
Strager

10

Diverse definizioni con lo stesso nome

<C-w>g<C-]>apri la definizione in una divisione, ma fai anche ciò :tjumpche va alla definizione o, se ci sono diverse definizioni, ti presenta un elenco di definizioni tra cui scegliere.


2
Simile al primo comando, vim ha un :ptagcomando che apre la definizione in una finestra di anteprima.
idbrii,

1
La finestra di anteprima è piacevole perché puoi chiuderla con: pc da qualsiasi altra finestra, senza dover prima spostare il cursore sulla finestra di anteprima.
Heikki Naski il

C'è anche un trucco accurato di autocmd con ptag in :h CursorHold-examplecui viene visualizzato il tag per l'elemento sotto il cursore nella finestra di anteprima dopo un timeout configurabile.
dash-tom-bang,

+1 per: tjump ora ho legato: tjump <Cr><Cw> <CR> funziona meglio di <C -]> imho Mi piacerebbe combinare questo comportamento con: ptag
Andreas Fliesberg,

:helpè fantastico a volte ... vedi :help CTRL-W_g}e:ptjump
Andreas Fliesberg il

8

Il comando che sto usando di più è C-] che passa alla definizione della funzione sotto il cursore. Puoi usarlo più spesso per seguire più chiamate. Dopodiché, Co ti riporterà indietro di un livello, Ci andrà ancora più in profondità.


16
Ct torna indietro di un livello nello stack C-], mentre Co ritorna alla posizione precedente del cursore dopo un movimento. Quindi, se si C-] a una funzione, quindi pagina giù, Ct tornerà immediatamente mentre Co tornerà all'inizio della funzione, quindi tornerà alla chiamata.
Greg Hewgill,

6

Ho trovato il plug-in taglist indispensabile . Elenca tutti i tag che conosce (file che hai aperto) in una finestra separata e semplifica la navigazione di file più grandi.

Lo uso principalmente per lo sviluppo di Python, ma può essere migliore solo per C / C ++.


5

Ho incapsulato la manipolazione dei tag in un mio plug-in sperimentale .

Per quanto riguarda lo sviluppo del C ++ in vim, ho già risposto : uso la mia suite e alcuni altri plugin.



4

Ho inserito quanto segue nel mio file .gvimrc, che cerca l'albero da qualsiasi punto per un file tag all'avvio di gvim:

function SetTags()
    let curdir = getcwd()

    while !filereadable("tags") && getcwd() != "/"
        cd ..
    endwhile

    if filereadable("tags")
        execute "set tags=" . getcwd() . "/tags"
    endif

    execute "cd " . curdir
endfunction

call SetTags()

Quindi, rigenerare periodicamente un file di tag nella parte superiore della mia struttura di origine con uno script simile al seguente:

#!/bin/bash

find . -regex ".*\.\(c\|h\|hpp\|cc\|cpp\)" -print | ctags --totals --recurse --extra="+qf" --fields="+i" -L -

7
Hai appena reinventato la ricerca verso l'alto. Vedi: h ricerca file. Vedi anche stackoverflow.com/questions/563616/vimctags-tips-and-tricks/...
gotgenes

2

Uso vim in macos e i tag originali non funzionano bene, quindi scarico il più recente e configuro make make install. Installo ctgas in / usr / local / bin / ctags (per conservare quello originale)

"taglist
let Tlist_Ctags_Cmd = "/usr/local/bin/ctags"
let Tlist_WinWidth = 50
map <leader>ta :TlistToggle<cr>
map <leader>bta :!/usr/local/bin/ctags -R .<CR>
set tags=tags;/
map <M-j> <C-]>
map <M-k> <C-T>

1

Ho adattato la funzione di ricerca SetTags () sopra (che dovrebbe essere sostituita dall'equivalente set tags+=./tags;/) per funzionare con cscope. Sembra funzionare!

"cscope file-searching alternative
function SetCscope()
    let curdir = getcwd()

    while !filereadable("cscope.out") && getcwd() != "/"
            cd ..
                endwhile

    if filereadable("cscope.out")
            execute "cs add " . getcwd() . "/cscope.out"
                endif

    execute "cd " . curdir
    endfunction

call SetCscope()

3
Come diceva Gotgenes, hai appena reinventato la ricerca verso l'alto. Vedi: h ricerca file. Vedi questo plugin per un esempio pertinente.
idbrii,

1

Un'altra iterazione sulla funzione SetCscope () sopra. Ciò imposta il pre-percorso di cscope per ottenere le corrispondenze senza essere sulla directory dove "cscope.out" è:

function s:FindFile(file)
    let curdir = getcwd()
    let found = curdir
    while !filereadable(a:file) && found != "/"
        cd ..
        let found = getcwd()
    endwhile
    execute "cd " . curdir
    return found
endfunction

if has('cscope')    
    let $CSCOPE_DIR=s:FindFile("cscope.out")
    let $CSCOPE_DB=$CSCOPE_DIR."/cscope.out"
    if filereadable($CSCOPE_DB)
        cscope add $CSCOPE_DB $CSCOPE_DIR
    endif

    command -nargs=0 Cscope !cscope -ub -R &
endif

3
Come diceva Gotgenes, hai appena reinventato la ricerca verso l'alto. Vedi: h ricerca file. Vedi questo plugin per un esempio pertinente.
idbrii,
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.