Tip dan trik Vim dan Ctags [ditutup]

485

Saya baru saja menginstal Ctags (untuk membantu pengembangan C ++) dengan Vim saya (atau lebih tepatnya gVim), dan ingin mengetahui perintah, makro, cara pintas favorit Anda, kiat-kiat yang menyertainya ...

Bagikan arsenal terbaik Anda. Pengaya Vim apa lagi yang Anda rekomendasikan untuk C ++ pada pengembangan Vim?

Sunting Apa add-on lain yang akan Anda gunakan bersama dengan Ctags?

EDIT2 Versi gVim apa yang Anda gunakan dengan tag? Apakah itu membuat perbedaan?

EDIT3 Bagaimana Anda meningkatkan pengalaman pemrograman Anda untuk proyek-proyek besar dan kecil?

kenorb
sumber
15
Pastikan Anda menggunakan ctag riang (implementasi modern) untuk hasil terbaik: ctags.sourceforge.net
idbrii
17
Mungkin kev tidak konstruktif?
Floyd
27
meskipun closed as not constructivehampir dua tahun yang lalu, itu sangat konstruktif untuk saya
sazary
15
Saya pikir alasan sebenarnya untuk menutup pertanyaan ini seharusnya: "Pertanyaan ini, meskipun sangat membantu, tidak cocok dengan kebijakan T&J StackOverflow. Biarkan pertanyaan dan jawaban ini pindah ke Quora dan kembangkan situs itu sementara kami dengan keras kepala terus menutup membantu pertanyaan dan jawaban".
Diego Pino
2
Saya mengerti mengapa pertanyaan ini ditutup, mengingat aturan SO. Tetapi menandai> 400 pertanyaan upvote dengan jawaban> 300 upvote untuk dihapus sedikit di sisi pemarah, bukan?
DevSolar

Jawaban:

394

Ctrl+ ]- pergi ke definisi
Ctrl+ T- Melompat kembali dari definisi.
Ctrl+ W Ctrl+ ]- Buka definisi dalam split horizontal

Tambahkan baris ini di vimrc
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

Ctrl+ \- Buka definisi di tab baru
Alt+ ]- Buka definisi dalam pemisahan vertikal

Setelah tag dihasilkan. Anda dapat menggunakan tombol berikut untuk menandai dan keluar dari fungsi:

Ctrl+ Left MouseClick- Pergi ke definisi
Ctrl+ Right MouseClick- Melompat kembali dari definisi

Amjith
sumber
8
C -] => (tombol kontrol) dan] tombol C - T => (tombol kontrol) dan tombol T Hanya untuk pemula yang menggunakan tag. Terima kasih untuk trik tab baru
kumar
6
Demikian pula, setelah membelah jendela dengan Ctrl-w C-]Anda dapat melakukan C-w T(alias Shift-t) untuk mengubah yang dipecah menjadi tab baru.
dash-tom-bang
1
@Apakah Jika Anda menggunakan vim dari terminal maka Anda harus mengubah preferensi terminal untuk membuat kunci opsi berperilaku seperti tombol alt. Jika Anda menggunakan MacVim, tambahkan baris ini ke vimrc 'set macmeta'. Ada doc untuk macmeta,: h macmeta.
Amjith
17
g C-]sangat bermanfaat. Ini membuka dialog cepat untuk memilih satu di antara banyak definisi.
Vincenzo Pii
3
g]juga bermanfaat. Anda dapat memposisikan kursor di atas nama tag dan tekan g]untuk mendapatkan daftar tag yang cocok.
zeekvfu
176

Satu baris yang selalu ada di .vimrc saya:

set tags=./tags;/

Ini akan mencari di direktori saat ini untuk "tag", dan bekerja pohon ke arah root sampai ditemukan. TKI, Anda bisa berada di mana saja di pohon sumber Anda alih-alih hanya root itu.

uzi
sumber
37
Naik ke root terlalu berlebihan. Saya sarankan hanya naik ke rumah saja: tag + = tag; $ HOME
gotgenes
37
Pohon sumber tempat saya bekerja tidak selalu ada di direktori home saya ... dan karena $ HOME cenderung dua direktori dari root ... well, saya bisa membeli dua direktori pencarian lagi. :)
uzi
6
Saya setuju dengan uzi. Jika cwd saya adalah / home / me / programming / foo / bar / baz / bang / bam, itu hanya pencarian direktori 8. Saya kira itu tergantung pada toleransi Anda untuk kecepatan, tetapi waktu untuk mencari direktori 1 tidak terasa berbeda dari 8 pada mesin saya.
Nate Murray
1
Itu tergantung pada skenario Anda, saya perlu menggunakan saran gotgen pada salah satu mesin saya karena ada sekitar 8.000 direktori di / rumah, dan itu cenderung agak lamban.
jkerian
1
Apakah ada yang serupa cscope?
szx
45

Plugin lain yang bermanfaat untuk pengembangan C adalah cscope. Sama seperti Ctags memungkinkan Anda melompat ke definisi, Cscope melompat ke fungsi panggilan .

Jika Anda memiliki cscope di direktori ~ / bin / Anda, tambahkan yang berikut ke .vimrc Anda dan gunakan g ^] untuk masuk ke fungsi panggilan (lihat: 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

Hampir lupa ... Sama seperti ctag - Anda harus membuat (dan memperbarui) database secara berkala. Saya menggunakan skrip berikut

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

Di mana 'select_files' adalah skrip lain yang mengekstrak daftar file C dan header dari Makefile. Dengan cara ini saya hanya mengindeks file yang benar-benar digunakan oleh proyek.

nimrodm
sumber
Apa keuntungan dari cscope dibandingkan ctags? Apakah mereka saling memuji?
Whaledawg
4
Mereka saling melengkapi. Ctags menemukan definisi simbol atau fungsi. Cscope dapat menemukan semua tempat yang memanggil fungsi. menggunakan keduanya membuat navigasi di pohon sumber besar sangat mudah.
nimrodm
1
Namun, AFAIK cscope memiliki pemahaman terbatas tentang C ++.
Luc Hermitte
Itu terbatas, dan tidak terlalu bagus. Tetapi untuk apa yang dilakukannya (melompat ke USAGES), tidak ada alternatif yang lebih baik. Masalah utamanya adalah bahwa ketika Anda ingin melompat ke fungsi panggilan (f), Anda sering perlu untuk melompat ke mana saja simbol yang digunakan (s) bukan dan menyaring hasil mental ...
Greg Rogers
2
@Whaledawg Ya, ketika saya menekan CTRL +] kartu suara saya mengirimkan "clap.wav" sebagai hasilnya :)
Patrizio Rullo
27

Anda dapat menambahkan direktori ke pencarian ctag Anda. Sebagai contoh, saya memiliki indeks ctags dibangun untuk Qt4, dan memilikinya di .vimrc saya:

set tags+=/usr/local/share/ctags/qt4
strager
sumber
16

Saya menggunakan ALT-kiri dan ALT-kanan untuk pop / mendorong dari / ke tumpukan tag.

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

Jika Anda gunakan hjkluntuk pergerakan, Anda bisa memetakan <M-h>dan <M-l>sebaliknya.

strager
sumber
tidak sama dengan ctrl -] dan ctrl-t - Saya kira, saran Anda sedikit lebih bersih.
@Sasha, Pardon? Tidak tahu apa yang Anda katakan. = X Sebagai catatan, ini juga berfungsi pada: bantuan.
strager
2
Saya pikir ini lebih intuitif dan lebih bersih daripada yang standar.
Ayman
1
@Ayman Tetapi juga melanggar prinsip tidak harus memindahkan tangan dari homerow, seperti menggunakan hjkl vs tombol panah.
TankorSmash
@TankorSmash, prinsip apa?
strager
10

Beberapa definisi dengan nama yang sama

<C-w>g<C-]>buka definisi dalam split, tetapi juga lakukan :tjumpyang menuju definisi atau, jika ada beberapa definisi, memberi Anda daftar definisi untuk dipilih.

Heikki Naski
sumber
2
Mirip dengan perintah pertama, vim memiliki :ptagperintah yang membuka definisi di jendela pratinjau.
idbrii
1
Jendela pratinjau bagus karena Anda dapat menutupnya dengan: pc dari jendela lain, tanpa harus terlebih dahulu memindahkan kursor ke jendela pratinjau.
Heikki Naski
Ada juga trik autocmd yang rapi dengan ptag di :h CursorHold-examplemana menampilkan tag untuk item di bawah kursor di jendela pratinjau setelah batas waktu dapat dikonfigurasi.
dash-tom-bang
+1 untuk: tjump Saya sekarang terikat: tjump <Cr><Cw> <CR> bekerja lebih baik daripada <C -]> imho Ingin menggabungkan perilaku ini dengan: ptag
Andreas Fliesberg
:helpterkadang mengagumkan ... lihat :help CTRL-W_g}dan:ptjump
Andreas Fliesberg
8

Perintah yang paling saya gunakan adalah C-] yang melompat ke definisi fungsi di bawah kursor. Anda dapat menggunakannya lebih sering untuk mengikuti lebih banyak panggilan. Setelah itu, Co akan membawa Anda kembali satu tingkat, Ci masuk lebih dalam lagi.

raimue
sumber
16
Ct kembali satu tingkat dalam tumpukan C-], sedangkan Co kembali ke posisi kursor sebelumnya setelah gerakan. Jadi jika Anda C-] ke suatu fungsi kemudian turun halaman, Ct akan segera kembali sementara Co akan kembali ke awal fungsi, lalu kembali ke panggilan.
Greg Hewgill
6

Saya telah menemukan plug-in taglist yang harus dimiliki. Ini mencantumkan semua tag yang diketahuinya (file yang telah Anda buka) di jendela terpisah dan membuatnya sangat mudah untuk menavigasi file yang lebih besar.

Saya menggunakannya sebagian besar untuk pengembangan Python, tetapi hanya bisa lebih baik untuk C / C ++.

Walter
sumber
5

Saya telah mengenkapsulasi manipulasi tag dalam plugin eksperimental milik saya.

Mengenai pengembangan C ++ di vim, saya sudah menjawab di sana : Saya menggunakan suite saya sendiri, dan beberapa plugin lainnya.

Luc Hermitte
sumber
4

Saya meletakkan yang berikut ini di file .gvimrc saya, yang mencari pohon dari titik mana saja untuk file tag ketika gvim mulai:

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

Saya kemudian secara berkala membuat kembali file tag di bagian atas pohon sumber saya dengan skrip yang terlihat seperti:

#!/bin/bash

find . -regex ".*\.\(c\|h\|hpp\|cc\|cpp\)" -print | ctags --totals --recurse --extra="+qf" --fields="+i" -L -
alanwj
sumber
7
Anda baru saja menemukan kembali pencarian ke atas. Lihat: h pencarian file. Lihat juga stackoverflow.com/questions/563616/vimctags-tips-and-tricks/…
gotgenes
2

Saya menggunakan vim di macos, dan ctag asli tidak berfungsi dengan baik, jadi saya unduh terbaru dan konfigurasikan make make install it. Saya menginstal ctgas di / usr / local / bin / ctags (untuk menyimpan yang asli)

"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
sumber
1

Saya mengadaptasi fungsi pencarian SetTags () di atas (yang harus diganti dengan yang setara set tags+=./tags;/) agar berfungsi untuk cscope. Tampaknya bekerja!

"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
sumber
3
Seperti yang dikatakan oleh gotgen, Anda baru saja menemukan kembali pencarian ke atas. Lihat: h pencarian file. Lihat plugin ini untuk contoh yang relevan.
idbrii
1

Iterasi lain pada fungsi SetCscope () di atas. Itu menetapkan pre-path cscope untuk mendapatkan kecocokan tanpa harus berada di direktori "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
saoret.one
sumber
3
Seperti yang dikatakan oleh gotgen, Anda baru saja menemukan kembali pencarian ke atas. Lihat: h pencarian file. Lihat plugin ini untuk contoh yang relevan.
idbrii