Tipps und Tricks zu Vim und Ctags [geschlossen]

485

Ich habe gerade Ctags (um bei der C ++ - Entwicklung zu helfen) mit meinem Vim (oder besser gVim) installiert und möchte Ihre bevorzugten Befehle, Makros, Verknüpfungen und Tipps herausfinden, die damit einhergehen ...

Teilen Sie Ihr bestes Arsenal. Welche anderen Vim-Add-Ons würden Sie für C ++ in der Vim-Entwicklung empfehlen?

BEARBEITEN Welches andere Add-On würden Sie in Verbindung mit Ctags verwenden?

EDIT2 Welche Version von gVim verwenden Sie mit Tags? Macht es einen Unterschied?

EDIT3 Wie verbessern Sie Ihre Programmiererfahrung für große und kleine Projekte?

Kenorb
quelle
15
Stellen Sie sicher, dass Sie üppige ctags (eine moderne Implementierung) verwenden, um die besten Ergebnisse zu erzielen
idbrii
17
Vielleicht ist der Kev nicht konstruktiv?
Floyd
27
obwohl vor closed as not constructivefast zwei Jahren, ist es so konstruktiv für mich
Sazary
15
Ich denke, der wahre Grund für das Schließen dieser Frage hätte sein müssen: "Diese Frage passt, obwohl sie enorm hilfreich ist, nicht in die StackOverflow-Richtlinie für Fragen und Antworten. Lassen Sie diese Frage und die Antworten zu Quora wechseln und diese Website erweitern, während wir hartnäckig weiterhin hilfreich schließen." Fragen und Antworten".
Diego Pino
2
Ich verstehe, warum diese Frage angesichts der Regeln von SO geschlossen wurde. Aber das Markieren einer> 400-Upvote-Frage mit einer> 300-Upvote-Antwort zum Löschen ist etwas mürrisch, nicht wahr ?
DevSolar

Antworten:

394

Ctrl+ ]- gehe zur Definition
Ctrl+ T- Springe von der Definition zurück.
Ctrl+ W Ctrl+ ]- Öffnen Sie die Definition in einer horizontalen Teilung

Fügen Sie diese Zeilen in vimrc hinzu
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

Ctrl+ \- Öffnen Sie die Definition in einer neuen Registerkarte.
Alt+ ]- Öffnen Sie die Definition in einer vertikalen Teilung

Nachdem die Tags generiert wurden. Sie können die folgenden Tasten verwenden, um Funktionen zu markieren und zu markieren:

Ctrl+ Left MouseClick- Zur Definition gehen
Ctrl+ Right MouseClick- Von der Definition zurückspringen

Amjith
quelle
8
C -] => (Steuertaste) und] Taste C - T => (Steuertaste) und T-Taste Nur für Neulinge. Vielen Dank für den neuen Tab-Trick
Kumar
6
In ähnlicher Weise das Fenster mit nach dem Spalten Ctrl-w C-]können Sie tun C-w T(auch bekannt als Umschalt-t) , dass die Spaltung in ein neues Tab zu ändern.
Dash-Tom-Bang
1
@Will Wenn Sie vim vom Terminal aus verwenden, müssen Sie die Terminaleinstellungen ändern, damit sich der Optionsschlüssel wie ein Alt-Schlüssel verhält. Wenn Sie MacVim verwenden, fügen Sie diese Zeile zu vimrc 'set macmeta' hinzu. Es gibt doc für macmeta ,: h macmeta.
Amjith
17
g C-]ist sehr nützlich. Es wird ein kurzer Dialog geöffnet, in dem Sie eine zwischen mehreren Definitionen auswählen können.
Vincenzo Pii
3
g]ist auch nützlich. Sie können den Cursor über dem Tag-Namen positionieren und drücken g], um eine Liste der passenden Tags zu erhalten.
Zeekvfu
176

Eine Zeile, die immer in meiner .vimrc steht:

set tags=./tags;/

Dies sucht im aktuellen Verzeichnis nach "Tags" und arbeitet den Baum in Richtung root auf, bis eines gefunden wird. IOW, Sie können sich an einer beliebigen Stelle in Ihrem Quellbaum befinden, anstatt nur an der Wurzel.

uzi
quelle
37
Es ist übertrieben, zur Wurzel zu gehen. Ich schlage vor, stattdessen nur nach Hause zu gehen: tags + = tags; $ HOME
gotgenes
37
Die Quellbäume, an denen ich arbeite, befinden sich nicht immer in meinem Ausgangsverzeichnis ... und da $ HOME in der Regel zwei Verzeichnisse vom Stamm entfernt ist ... kann ich mir zwei weitere Verzeichnissuchen leisten. :)
Uzi
6
Ich stimme w / uzi zu. Wenn mein cwd / home / me / programming / foo / bar / baz / bang / bam ist, sind das nur 8 Verzeichnissuchen. Ich nehme an, es hängt von Ihrer Geschwindigkeitstoleranz ab, aber die Zeit zum Nachschlagen von 1 Verzeichnis unterscheidet sich nicht merklich von 8 auf meinem Computer.
Nate Murray
1
Es hängt von Ihrem Szenario ab. Ich muss den Vorschlag von gotgenes auf einem meiner Computer verwenden, da sich in / home ungefähr 8.000 Verzeichnisse befinden, und das ist in der Regel etwas träge.
Jkerian
1
Gibt es etwas ähnliches für cscope?
Szx
45

Ein weiteres nützliches Plugin für die C-Entwicklung ist cscope. So wie Sie mit Ctags zu Definitionen springen können, springt Cscope zu den aufrufenden Funktionen.

Wenn Sie cscope in Ihrem ~ / bin / -Verzeichnis haben, fügen Sie Folgendes zu Ihrer .vimrc hinzu und rufen Sie mit g ^] die aufrufende Funktion auf (siehe: Hilfe 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

Fast vergessen ... Genau wie bei ctags müssen Sie die Datenbank generieren (und regelmäßig aktualisieren). Ich benutze das folgende Skript

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

Wobei 'select_files' ein weiteres Skript ist, das die Liste der C- und Header-Dateien aus dem Makefile extrahiert. Auf diese Weise indiziere ich nur die tatsächlich vom Projekt verwendeten Dateien.

Nimrodm
quelle
Was ist der Vorteil von cscope gegenüber ctags? Komplimente sie sich gegenseitig?
Whaledawg
4
Sie ergänzen sich. Ctags findet die Definition eines Symbols oder einer Funktion. Cscope kann alle Orte finden, die eine Funktion aufrufen. Wenn Sie beide verwenden, ist die Navigation in großen Quellbäumen sehr einfach.
Nimrodm
1
AFAIK cscope hat jedoch ein begrenztes Verständnis von C ++.
Luc Hermitte
Es ist begrenzt und nicht sehr gut. Aber für das, was es tut (zu USAGES springen), gibt es keine bessere Alternative. Das Hauptproblem besteht darin, dass Sie, wenn Sie zu Funktionsaufrufen (f) springen möchten, häufig zu einer Stelle springen müssen, an der stattdessen Symbole verwendet werden, und die Ergebnisse mental filtern müssen ...
Greg Rogers
2
@Whaledawg Ja, wenn ich STRG +] drücke, sendet meine Soundkarte "clap.wav" in der Ausgabe :)
Patrizio Rullo
27

Sie können Ihrer ctags-Suche Verzeichnisse hinzufügen. Zum Beispiel habe ich einen ctags-Index für Qt4 erstellt und diesen in meiner .vimrc:

set tags+=/usr/local/share/ctags/qt4
Strager
quelle
16

Ich benutze ALT-left und ALT-right, um vom / zum Tag-Stack zu gelangen.

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

Wenn Sie hjklfür die Bewegung verwenden, können Sie <M-h>und <M-l>stattdessen abbilden .

Strager
quelle
ist nicht dasselbe wie Strg -] und Strg-T - Ich denke, Ihr Vorschlag ist etwas sauberer.
@ Sasha, Verzeihung? Ich weiß nicht was du sagst. = X Zu beachten ist, dass dies auch funktioniert in: help.
Strager
2
Ich denke, das ist intuitiver und sauberer als die Standardeinstellung.
Ayman
1
@ Ayman Verstößt aber auch gegen das Prinzip, die Hände nicht vom Homerow wegbewegen zu müssen, wie die Verwendung von hjkl gegen die Pfeiltasten.
TankorSmash
@TankorSmash, welches Prinzip?
Strager
10

Mehrere gleichnamige Definitionen

<C-w>g<C-]>Öffnen Sie die Definition in einem Split, aber tun Sie :tjumpdies auch, indem Sie entweder zur Definition gehen oder, wenn mehrere Definitionen vorhanden sind, eine Liste mit Definitionen anzeigen, aus denen Sie auswählen können.

Heikki Naski
quelle
2
Ähnlich wie beim ersten Befehl verfügt vim über einen :ptagBefehl, der die Definition in einem Vorschaufenster öffnet.
idbrii
1
Das Vorschaufenster ist schön, weil Sie es mit: pc aus jedem anderen Fenster schließen können, ohne zuerst den Cursor auf das Vorschaufenster bewegen zu müssen.
Heikki Naski
Es gibt auch einen netten Autocmd-Trick mit ptag, bei :h CursorHold-exampledem das Tag für das Element unter dem Cursor im Vorschaufenster nach einer konfigurierbaren Zeitüberschreitung angezeigt wird.
Dash-Tom-Bang
+1 für: tjump Ich habe jetzt gebunden: tjump <Cr> <Cw> <CR> funktioniert besser als <C -]> imho Würde dieses Verhalten gerne kombinieren mit: ptag
Andreas Fliesberg
:helpist manchmal großartig ... sehen :help CTRL-W_g}und:ptjump
Andreas Fliesberg
8

Der Befehl, den ich am häufigsten benutze, ist C-], der zur Definition der Funktion unter dem Cursor springt. Sie können es häufiger verwenden, um mehr Anrufe zu verfolgen. Danach bringt Co dich ein Level zurück, Ci geht wieder tiefer.

raimue
quelle
16
Ct geht im C-] -Stapel eine Ebene zurück, während Co nach einer Bewegung zu einer vorherigen Cursorposition zurückkehrt. Wenn Sie also zu einer Funktion C-] gehen und dann nach unten blättern, kehrt Ct sofort zurück, während Co zum Start der Funktion und dann zurück zum Aufruf zurückkehrt.
Greg Hewgill
6

Ich habe das Taglist- Plug-In als ein Muss empfunden . Es listet alle ihm bekannten Tags (Dateien, die Sie geöffnet haben) in einem separaten Fenster auf und erleichtert das Navigieren in größeren Dateien.

Ich benutze es hauptsächlich für die Python-Entwicklung, aber es kann nur für C / C ++ besser sein.

Walter
quelle
5

Ich habe die Manipulation von Tags in einem experimentellen Plugin zusammengefasst meiner .

In Bezug auf C ++ Entwicklung in vim habe , antworte ich schon da : Ich habe meine eigene Suite verwenden, und ein paar anderen Plugins.

Luc Hermitte
quelle
4

Ich habe Folgendes in meine .gvimrc-Datei eingefügt, die den Baum von jedem Punkt aus nach einer Tags-Datei durchsucht, wenn gvim gestartet wird:

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()

Anschließend regeneriere ich regelmäßig eine Tag-Datei oben in meinem Quellbaum mit einem Skript, das wie folgt aussieht:

#!/bin/bash

find . -regex ".*\.\(c\|h\|hpp\|cc\|cpp\)" -print | ctags --totals --recurse --extra="+qf" --fields="+i" -L -
alanwj
quelle
7
Sie haben gerade die Aufwärtssuche neu erfunden. Siehe: h Dateisuche. Siehe auch stackoverflow.com/questions/563616/vimctags-tips-and-tricks/…
gotgenes
2

Ich benutze vim in macos und die ursprünglichen ctags funktionieren nicht gut, also lade ich die neuesten herunter und konfiguriere make make install it. Ich installiere ctgas in / usr / local / bin / ctags (um das Original zu behalten)

"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>
Zhenyu Li
quelle
1

Ich habe die Suchfunktion SetTags () oben angepasst (die durch die entsprechende ersetzt werden sollte set tags+=./tags;/), um für cscope zu arbeiten. Scheint zu funktionieren!

"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()
dergachev
quelle
3
Wie gotgenes sagte, haben Sie gerade die Aufwärtssuche neu erfunden. Siehe: h Dateisuche. In diesem Plugin finden Sie ein relevantes Beispiel.
idbrii
1

Eine weitere Iteration der obigen Funktion SetCscope (). Dadurch wird der cscope-Vorpfad festgelegt, um Übereinstimmungen zu erhalten, ohne sich in dem Verzeichnis zu befinden, in dem sich "cscope.out" befindet:

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
saoret.one
quelle
3
Wie gotgenes sagte, haben Sie gerade die Aufwärtssuche neu erfunden. Siehe: h Dateisuche. In diesem Plugin finden Sie ein relevantes Beispiel.
idbrii