Passa alla definizione della funzione in vim


241

Come posso passare a una definizione di funzione usando vim? Ad esempio con Visual Assist, posso digitare Alt+ gsotto una funzione e si apre un menu di scelta rapida che elenca i file con le definizioni.

Come posso fare qualcosa del genere in vim?


2
gnu global è meglio di ctags.
Jichao,

6
@Jichao, puoi darci qualche idea in più sulla tua esperienza? Con quali lingue gnu global ha funzionato meglio per te? C'è qualcos'altro nel contesto in cui l'hai preferito in quanto io sono importante? O forse l'hai usato in molti scenari diversi e sembri preferire / preferire sempre? Cosa ti piace di più? Grazie.
still_dreaming_1

@Jichao Ho trasformato il tuo commento in una risposta wiki della community. Gradirei le vostre modifiche e input per questa risposta.
still_dreaming_1

Risposte:


213

Usa i tag. Generare un file tag e dire a vim dove sta usando il comando: tags. Quindi puoi semplicemente passare alla definizione della funzione usando Ctrl-]

Ci sono più trucchi e suggerimenti per i tag in questa domanda .


2
php è abbastanza simile a C che "Exuberant ctags" dovrebbe funzionare con esso. Non so se ha una modalità Python.
Paul Tomblin,

5
Nessuna esperienza con Cscope. Che cos'è è?
Paul Tomblin,

10
La somiglianza con C non ha nulla a che fare con il supporto di CTags a PHP. Supporta PHP e Python. Dai un'occhiata a ctags.sourceforge.net/languages.html per vedere il supporto completo.
dati

2
come posso generare tag?
dwaynemac,

4
sarebbe bello avere un riferimento a dove è meglio imparare come far funzionare quei tag.
Fzs2,

138

Se tutto è contenuto in un file, c'è il comando gd(come in 'goto definition'), che ti porterà alla prima occorrenza nel file della parola sotto il cursore, che è spesso la definizione.


1
cosa succede se non ho la parola sotto il cursore (preferirei digitarla)?
Fuad Saud,

@FuadSaud basta cercarlo usando/
LucasB

6
/non è quasi sempre preciso, poiché corrisponderà a tutte le occorrenze. Ho scoperto che puoi effettivamente fare :tag <function_name>per saltare alla definizione tramite tag.
Fuad Saud,

@Faud La funzione Vai alla definizione si basa sul puntare un identificatore con un cursore (in ogni IDE). Digitare / cercare è un'altra caratteristica, le stai confondendo.
maledetto

101

g* fa un lavoro dignitoso senza che vengano impostati tag.

Cioè, tipo g, *(o solo *- vedi sotto) per cercare la parola sotto il cursore (in questo caso, il nome della funzione). Quindi premere nper passare alla ricorrenza successiva (o Shift- nper precedente).

Non passa direttamente alla definizione, dato che questo comando cerca solo la parola sotto il cursore, ma se non vuoi occuparti di impostare i tag al momento, puoi almeno salvarti dal dover re -tipo il nome della funzione per cercarne la definizione.

--Modifica-- Anche se uso g * da molto tempo, recentemente ho scoperto due scorciatoie per queste scorciatoie!

(a) *salterà alla ricorrenza successiva della parola sotto il cursore. (Non è necessario digitare il g, il comando 'goto' in vi).

(b) #passa alla ricorrenza precedente, in modo simile.

N e n funzionano ancora, ma '#' è spesso molto utile per iniziare la ricerca inizialmente nella direzione opposta, ad esempio, quando si cerca la dichiarazione di una variabile sotto il cursore.


10
La differenza tra *e g*è i confini delle parole nella ricerca. *fa una \<keyword\>ricerca (come \bkeyword\bnella normale regex), mentre g*cerca keywordsenza confini di parole.
Nicolai S,

se hai un centinaio di occorrenze di una funzione in un file, *ti porterà in media 50 hit prima di trovare la definizione.
naught101

49

Utilizzare gdo gDmentre si posiziona il cursore su qualsiasi variabile nel programma.

  1. gd ti porterà alla dichiarazione locale.
  2. gD ti porterà alla dichiarazione globale.

maggiori opzioni di navigazione sono disponibili qui .

Utilizzare cscope per fare riferimento a progetti di grandi dimensioni come il kernel Linux.


14

Come menzionato da Paul Tomblin, devi usare i tag . Si potrebbe anche considerare l'utilizzo dei plugin per selezionare quello appropriato o per visualizzare in anteprima la definizione della funzione sotto il cursore. Senza plug-in avrai mal di testa nel tentativo di selezionare uno dei centinaia di metodi "doAction" sovraccaricati in quanto il supporto ctags integrato non tiene conto del contesto - solo un nome.

Inoltre è possibile utilizzare cscope e il suo 'trovare globale simbolo' la funzione. Ma il tuo vim deve essere compilato con il supporto + cscope che non è un'opzione predefinita di build.

Se sai che la funzione è definita nel file corrente, puoi usare i tasti "gD" in una modalità normale per passare alla definizione del simbolo sotto il cursore.

Ecco il plugin più scaricato per la navigazione
http://www.vim.org/scripts/script.php?script_id=273

Eccone uno che ho scritto per selezionare il contesto mentre vai al tag
http://www.vim.org/scripts/script.php?script_id=2507


Ciao @ mykola-golubyev, il link che hai fornito nella Detailed descriptionsezione dello #2507script è interrotto. Puoi fornirne un altro per favore?
FelikZ

12

Un'altra tecnica comune è quella di posizionare il nome della funzione nella prima colonna. Ciò consente di trovare la definizione con una semplice ricerca.

int
main(int argc, char *argv[])
{
    ...
}

La funzione sopra potrebbe quindi essere trovata con /^mainall'interno del file o con :grep -r '^main' *.cin una directory. Finché il codice viene indentato correttamente, l'unica volta che l'identificatore si verificherà all'inizio di una riga è alla definizione della funzione.

Naturalmente, se non stai usando i tag da questo punto in poi, dovresti vergognarti di te stesso! Tuttavia, trovo utile anche questo standard di codifica.


13
Mi sono sempre chiesto perché alcuni programmatori scrivessero le loro firme in quel modo!
Tarrasch,

Inoltre, quando si scrivono le firme delle funzioni, incluso "{" nella prima colonna, è possibile spostarsi rapidamente su ciascuna funzione premendo]] per andare avanti nel file e [[per tornare indietro.
BentChainRing

12

TL; DR:

Il modo moderno è usare il COC per il completamento simile all'intellisense e uno o più server del linguaggio (LS) per saltare alla definizione (e molto altro). Per funzionalità ancora maggiori (ma non è necessario per passare alla definizione) è possibile installare uno o più debugger e ottenere un'esperienza IDE completa. Avvio rapido:

  1. installa vim-plug per gestire i tuoi plug-in VIM
  2. aggiungi COC e (facoltativamente) Vimspector nella parte superiore di ~/.vimrc:
    call plug#begin()
    Plug 'neoclide/coc.nvim', {'branch': 'release'}
    Plug 'puremourning/vimspector'
    call plug#end()
    
  3. chiama :source $MYVIMRC | PlugInstallper scaricare i plug-in VIM
  4. riavviare vime chiamare :CocInstall coc-marketplaceper ottenere un facile accesso alle estensioni COC
  5. chiamare :CocList marketplacee cercare server di lingue, ad es .:
    • digita pythonper trovare coc-jedi,
    • digita phpper trovare coc-phpls, ecc.
  6. (facoltativamente) consultare install_gadget.py --helpi debugger disponibili, ad esempio:
    • ./install_gadget.py --enable-python,
    • ./install_gadget.py --force-enable-php, eccetera.

Risposta completa:

Language server (LS) è un'applicazione autonoma separata (una per ciascun linguaggio di programmazione) che viene eseguita in background e analizza l'intero progetto in tempo reale esponendo funzionalità extra al tuo editor (qualsiasi editor, non solo vim). Ottieni cose come:

  • completamento tag consapevole dello spazio dei nomi
  • vai alla definizione
  • passa all'errore successivo / precedente
  • trova tutti i riferimenti a un oggetto
  • trova tutte le implementazioni dell'interfaccia
  • rinominare in un intero progetto
  • documentazione su hover
  • snippet, azioni di codice, formattazione, linting e altro ...

La comunicazione con i server delle lingue avviene tramite Language Server Protocol (LSP). Entrambi nvime vim8(o superiori) supportano LSP tramite plug-in, il più popolare è Conquer of Completion (COC).

L'elenco dei server delle lingue sviluppati attivamente e le loro capacità è disponibile sul sito Web di Lang Server . Non tutti sono forniti dalle estensioni COC. Se si desidera utilizzare uno di questi, è possibile scrivere manualmente un'estensione COC o installare LS manualmente e utilizzare la combinazione dei seguenti plug-in VIM in alternativa a COC:

La comunicazione con i debugger avviene tramite DAP ( Debug Adapter Protocol ). Il plug-in DAP più popolare per VIM è Vimspector .

Language Server Protocol (LSP) è stato creato da Microsoft per Visual Studio Code e rilasciato come progetto open source con una licenza MIT permissiva (standardizzata dalla collaborazione con Red Hat e Codenvy). Successivamente Microsoft ha rilasciato anche il Debug Adapter Protocol (DAP). Qualsiasi lingua supportata da VSCode è supportata in VIM.

Consiglio vivamente di utilizzare i server di lingua COC + forniti dalle estensioni COC + ALE per ulteriore linting (ma con supporto LSP disabilitato per evitare conflitti con COC) + Vimspector + debugger forniti da Vimspector (chiamati "gadget") + seguenti plug-in VIM:

call plug#begin()
Plug 'neoclide/coc.nvim'
Plug 'dense-analysis/ale'
Plug 'puremourning/vimspector'
Plug 'scrooloose/nerdtree'
Plug 'scrooloose/nerdcommenter'
Plug 'sheerun/vim-polyglot'
Plug 'yggdroot/indentline'
Plug 'tpope/vim-surround'
Plug 'kana/vim-textobj-user'
  \| Plug 'glts/vim-textobj-comment'
Plug 'janko/vim-test'
Plug 'vim-scripts/vcscommand.vim'
Plug 'mhinz/vim-signify'
call plug#end()

Puoi google ciascuno per vedere cosa fanno.


11

1- installa tag esuberanti. Se stai usando osx, questo articolo mostra un piccolo trucco: http://www.runtime-era.com/2012/05/exuberant-ctags-in-osx-107.html

2- Se si desidera includere solo i tag per i file nella propria directory, eseguire questo comando nella propria directory:

ctags -R

Questo creerà un file "tag" per te.

3- Se stai usando Ruby e desideri includere i tag per le tue gemme (questo è stato davvero utile per me con RubyMotion e le gemme locali che ho sviluppato), procedi come segue:

ctags --exclude=.git --exclude='*.log' -R * `bundle show --paths`

credito: https://coderwall.com/p/lv1qww (nota che ho omesso l'opzione -e che genera tag per emacs anziché vim)

4- Aggiungi la seguente riga al tuo ~ / .vimrc

set autochdir 
set tags+=./tags;

(Perché il punto e virgola: http://vim.wikia.com/wiki/Single_tags_file_for_a_source_tree )

5- Vai alla parola che desideri seguire e premi ctrl + ]; se desideri tornare indietro, usa ctrl+o(fonte: https://stackoverflow.com/a/53929/226255 )


Il collegamento all'articolo Mac menzionato è interrotto. Ecco il link aggiornato: runtime-era.blogspot.com/2012/05/… La soluzione migliore è installare i tag con uno strumento come Homebrew
ZaydH,

6

Secondo la risposta di Paul: sì, i tag (specialmente i tag esuberanti ( http://ctags.sourceforge.net/ )) sono fantastici. Ho anche aggiunto questo al mio vimrc, quindi posso usare un file tag per un intero progetto:

set tags=tags;/

2

Installa cscope. Funziona in modo molto simile ctagsma più potente. Per andare alla definizione, invece di Ctrl+ ], fai Ctrl+ \+ g. Naturalmente puoi usare entrambi contemporaneamente. Ma con un grande progetto (diciamo kernel Linux), cscope è molto più avanti.


1

Dopo aver generato i tag, puoi anche usare quanto segue in vim:

:tag <f_name>

Sopra ti porterà alla definizione della funzione.

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.