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?


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


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.


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.


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


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.


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.


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.


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 ++.




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 -

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>

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

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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.