Wskazówki i triki Vim i Ctags [zamknięte]

485

Właśnie zainstalowałem Ctagi (aby pomóc w rozwoju C ++) z moim Vimem (a raczej gVimem) i chciałbym znaleźć twoje ulubione polecenia, makra, skróty, wskazówki, które się z tym zgadzają ...

Podziel się swoim najlepszym arsenałem. Jakie inne dodatki Vima poleciłbyś dla C ++ w rozwoju Vima?

EDYCJA Jakiego innego dodatku używałbyś w połączeniu z Ctags?

EDIT2 Jakiej wersji gVim używasz z tagami? Czy to robi różnicę?

EDIT3 Jak zwiększyć swoje doświadczenie programistyczne zarówno dla dużych, jak i małych projektów?

kenorb
źródło
15
Upewnij się, że używasz bujnych
tagów
17
Być może Kev nie jest konstruktywny?
Floyd
27
chociaż closed as not constructiveprawie dwa lata temu jest to dla mnie takie konstruktywne
sazary
15
Myślę, że prawdziwym powodem zamknięcia tego pytania powinno być: „To pytanie, mimo że jest niezwykle pomocne, nie pasuje do zasad StackOverflow w pytaniach i odpowiedziach. Pozwól temu pytaniu i odpowiedzi przejść do Quory i rozwijaj tę witrynę, podczas gdy uparcie będziemy pomagać przy zamykaniu pytania i odpowiedzi".
Diego Pino
2
Rozumiem, dlaczego to pytanie zostało zamknięte, biorąc pod uwagę zasady SO. Ale oznaczanie pytania> 400 głosowaniem z odpowiedzią> 300 głosowania do usunięcia jest nieco zrzędliwe, prawda?
DevSolar,

Odpowiedzi:

394

Ctrl+ ]- przejdź do definicji
Ctrl+ T- przeskocz z definicji.
Ctrl+ W Ctrl+ ]- Otwórz definicję w układzie poziomym

Dodaj te linie w vimrc
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

Ctrl+ \- Otwórz definicję w nowej karcie
Alt+ ]- Otwórz definicję w podziale pionowym

Po wygenerowaniu tagów. Możesz użyć następujących klawiszy, aby oznaczyć i wyłączyć funkcje:

Ctrl+ Left MouseClick- Przejdź do definicji
Ctrl+ Right MouseClick- Przejdź z definicji

Amjith
źródło
8
C -] => (klawisz Ctrl) i] klawisz C - T => (klawisz Ctrl) i klawisz T Tylko dla początkujących ctags. Dzięki za nową sztuczkę z
kartami
6
Podobnie, po podzieleniu okna Ctrl-w C-]możesz zrobić C-w T(inaczej Shift-t), aby zmienić podział na nową kartę.
dash-tom-bang
1
@Will Jeśli używasz vima z terminala, musisz zmienić preferencje terminala, aby klawisz opcji zachowywał się jak klawisz Alt. Jeśli używasz MacVima, dodaj ten wiersz do vimrc 'set macmeta'. Istnieje dokument dla macmeta: h macmeta.
Amjith,
17
g C-]jest bardzo przydatne. Otwiera szybkie okno dialogowe do wyboru jednej z wielu definicji.
Vincenzo Pii
3
g]jest również przydatne. Możesz ustawić kursor nad nazwą znacznika i nacisnąć, g]aby uzyskać listę pasujących znaczników.
zeekvfu
176

Jedna linia, która zawsze idzie w moim .vimrc:

set tags=./tags;/

Spowoduje to wyszukanie w bieżącym katalogu „znaczników” i przesunie drzewo w kierunku katalogu głównego aż do znalezienia jednego z nich. IOW, możesz być w dowolnym miejscu w drzewie źródłowym zamiast tylko jego katalogu głównego.

uzi
źródło
37
Przechodzenie do roota jest nadmierne. Sugeruję tylko pójście do domu zamiast: tagi + = tagi; $ HOME
gotgenes
37
Drzewa źródłowe, nad którymi pracuję, nie zawsze znajdują się w moim katalogu domowym ... a ponieważ $ HOME to zwykle dwa katalogi z dala od katalogu głównego ... no cóż, stać mnie na dwa kolejne wyszukiwania katalogów. :)
uzi
6
Zgadzam się w / uzi. Jeśli moim cwd jest / home / me / programowanie / foo / bar / baz / bang / bam, to tylko 8 wyszukiwań katalogów. Przypuszczam, że zależy to od twojej tolerancji dla szybkości, ale czas wyszukiwania 1 katalogu nie różni się zauważalnie od 8 na moim komputerze.
Nate Murray
1
Zależy to od twojego scenariusza, muszę użyć sugestii gotgenes na jednej z moich maszyn, ponieważ w katalogu / home znajduje się około 8 000 katalogów, a to jest dość powolne.
jkerian
1
Czy istnieje coś podobnego cscope?
szx 7.12.12
45

Inną przydatną wtyczką do programowania w języku C jest cscope Podobnie jak Ctags pozwala przeskakiwać do definicji, Cscope przeskakuje do wywołania funkcji .

Jeśli masz cscope w katalogu ~ / bin /, dodaj do .vimrc i użyj g ^], aby przejść do funkcji wywołującej (patrz: 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

Prawie zapomniałem ... Podobnie jak ctags - musisz wygenerować (i okresowo aktualizować) bazę danych. Używam następującego skryptu

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

Gdzie „select_files” to kolejny skrypt, który wyodrębnia listę plików C i plików nagłówkowych z Makefile. W ten sposób indeksuję tylko pliki faktycznie używane przez projekt.

nimrodm
źródło
Jaka jest przewaga cscope nad ctags? Czy się uzupełniają?
Whaledawg,
4
Uzupełniają się. Ctags znajduje definicję symbolu lub funkcji. Cscope może znaleźć wszystkie miejsca wywołujące funkcję. użycie obu z nich sprawia, że ​​nawigacja w dużych drzewach źródłowych jest bardzo łatwa.
nimrodm
1
Jednak cscope AFAIK ma ograniczone rozumienie C ++.
Luc Hermitte
Jest ograniczony i niezbyt dobry. Ale za to, co robi (przeskakując do UŻYTKOWANIA), nie ma lepszej alternatywy. Jego głównym problemem jest to, że jeśli chcesz przejść do wywołań funkcji (f), często musisz skakać do dowolnego miejsca, w którym używany jest symbol (y), i mentalnie filtrować wyniki ...
Greg Rogers
2
@Whaledawg Tak, kiedy naciskam CTRL +] moja karta dźwiękowa wysyła „clap.wav” w wyjściu :)
Patrizio Rullo
27

Możesz dodawać katalogi do wyszukiwania ctags. Na przykład mam indeks ctags zbudowany dla Qt4 i mam go w moim .vimrc:

set tags+=/usr/local/share/ctags/qt4
strager
źródło
16

Używam ALT-left i ALT-right, aby pop / push z / do stosu znaczników.

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

Jeśli używasz hjklruchu, możesz odwzorować <M-h>i <M-l>zamiast tego.

strager
źródło
to nie to samo co ctrl -] i ctrl-t - myślę, że twoja sugestia jest nieco czystsza.
@Sasha, Pardon? Nie wiem co mówisz. = X Uwaga: działa to również w: help.
strager
2
Myślę, że jest to bardziej intuicyjne i czystsze niż domyślne.
Ayman
1
@Ayman Ale narusza również zasadę, że nie trzeba odrywać rąk od domu, jak używanie hjkl kontra klawisze strzałek.
TankorSmash
@TankorSmash, jaka zasada?
strager
10

Kilka definicji o tej samej nazwie

<C-w>g<C-]>otwórz definicję w podziale, ale również zrób to, :tjumpco albo przechodzi do definicji, albo, jeśli istnieje kilka definicji, przedstawia listę definicji do wyboru.

Heikki Naski
źródło
2
Podobnie jak pierwsze polecenie, vim ma :ptagpolecenie, które otwiera definicję w oknie podglądu.
idbrii 24.11.11
1
Okno podglądu jest ładne, ponieważ można je zamknąć za pomocą: komputera z dowolnego innego okna, bez konieczności wcześniejszego przesunięcia kursora do okna podglądu.
Heikki Naski
Istnieje również zgrabna sztuczka autocmd z ptag, w :h CursorHold-examplektórej wyświetla znacznik dla elementu pod kursorem w oknie podglądu po ustawionym czasie.
dash-tom-bang
+1 dla: tjump ja już teraz związany: tjump <CR> <Cw> <CR> <działa lepiej niż C -]> imho chcielibyśmy połączyć to zachowanie z: ptag
Andreas Fliesberg
:helpczasem jest niesamowity ... patrz :help CTRL-W_g}i:ptjump
Andreas Fliesberg,
8

Polecenie, którego najczęściej używam, to C-], które przeskakuje do definicji funkcji pod kursorem. Możesz go używać częściej, aby śledzić więcej połączeń. Po tym, Co przeniesie cię z powrotem o jeden poziom, Ci znów idzie głębiej.

raimue
źródło
16
Ct wraca o jeden poziom w stosie C-], a Co wraca do poprzedniej pozycji kursora po ruchu. Jeśli więc C-] przejdziesz do funkcji, a następnie przewrócisz stronę w dół, Ct natychmiast wróci, a Co wróci do początku funkcji, a następnie do połączenia.
Greg Hewgill
6

Uważam, że wtyczka taglist jest niezbędna. Zawiera listę wszystkich znaczników, o których wie (pliki, które otworzyłeś) w osobnym oknie i bardzo ułatwia nawigację po większych plikach.

Używam go głównie do programowania w języku Python, ale może być lepszy tylko w C / C ++.

Walter
źródło
5

Zamknąłem manipulację tagami w eksperymentalnej wtyczce mojej .

Jeśli chodzi o rozwój C ++ w vimie, już tam odpowiedziałem : używam własnego pakietu i kilku innych wtyczek.

Luc Hermitte
źródło
4

W moim pliku .gvimrc umieszczam następujące polecenie, które wyszukuje drzewo z dowolnego miejsca w poszukiwaniu pliku znaczników po uruchomieniu 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()

Następnie okresowo generuję ponownie plik znaczników u góry drzewa źródłowego za pomocą skryptu, który wygląda następująco:

#!/bin/bash

find . -regex ".*\.\(c\|h\|hpp\|cc\|cpp\)" -print | ctags --totals --recurse --extra="+qf" --fields="+i" -L -
alanwj
źródło
7
Właśnie wymyśliłeś wyszukiwanie w górę. Patrz: h wyszukiwanie plików. Zobacz także stackoverflow.com/questions/563616/vimctags-tips-and-tricks/…
gotgenes
2

Używam vima w macos, a oryginalne ctagi nie działają dobrze, więc pobieram najnowsze i konfiguruję make make install. Instaluję ctgas w / usr / local / bin / ctags (aby zachować oryginalny)

"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
źródło
1

Dostosowałem funkcję wyszukiwania SetTags () powyżej (która powinna zostać zastąpiona odpowiednikiem set tags+=./tags;/), aby działała dla cscope. Wydaje się działać!

"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()
dergaczew
źródło
3
Jak powiedział gotgenes, właśnie odkryłeś na nowo wyszukiwanie w górę. Patrz: h wyszukiwanie plików. Zobacz tę wtyczkę dla odpowiedniego przykładu.
idbrii 24.11.11
1

Kolejna iteracja powyższej funkcji SetCscope (). To ustawia ścieżkę wstępną cscope, aby uzyskać dopasowania bez znajdowania się w katalogu, w którym „cscope.out” to:

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
źródło
3
Jak powiedział gotgenes, właśnie odkryłeś na nowo wyszukiwanie w górę. Patrz: h wyszukiwanie plików. Zobacz tę wtyczkę dla odpowiedniego przykładu.
idbrii