เคล็ดลับและลูกเล่น Vim and Ctags [ปิด]


485

ฉันเพิ่งติดตั้งCtags (เพื่อช่วยในการพัฒนา C ++) กับ Vim ของฉัน (หรือมากกว่า gVim) และต้องการหาคำสั่งแมโครแมโครทางลัดและเคล็ดลับที่คุณชื่นชอบ ...

แบ่งปันคลังแสงที่ดีที่สุดของคุณ Add-on Vim อื่น ๆ ที่คุณอยากจะแนะนำสำหรับ C ++ สำหรับการพัฒนา Vim คืออะไร?

แก้ไขส่วนเสริมอื่น ๆ ที่คุณจะใช้ร่วมกับ Ctags คืออะไร

EDIT2 gVim รุ่นใดที่คุณใช้กับแท็ก มันสร้างความแตกต่างหรือไม่?

EDIT3คุณปรับปรุงประสบการณ์การเขียนโปรแกรมของคุณสำหรับทั้งโครงการขนาดใหญ่และขนาดเล็กได้อย่างไร


15
ตรวจสอบให้แน่ใจว่าคุณใช้ ctags ที่อุดมสมบูรณ์ (การใช้งานที่ทันสมัย) เพื่อผลลัพธ์ที่ดีที่สุด: ctags.sourceforge.net
idbrii

17
บางทีเคฟอาจไม่สร้างสรรค์?
ฟลอยด์

27
แม้ว่าclosed as not constructiveเกือบสองปีที่ผ่านมามันเป็นสิ่งที่สร้างสรรค์สำหรับฉัน
sazary

15
ฉันคิดว่าเหตุผลที่แท้จริงสำหรับการปิดคำถามนี้ควรเป็น: "คำถามนี้แม้ว่าจะเป็นประโยชน์อย่างมาก แต่ไม่เหมาะกับนโยบาย StackOverflow ของคำถามและคำตอบให้คำถามและคำตอบนี้ย้ายไปยัง Quora และเติบโตไซต์นั้นในขณะที่เราปิดท้าย คำถามและคำตอบ".
Diego Pino

2
ฉันเข้าใจว่าทำไมคำถามนี้จึงปิดเนื่องจากกฎของ SO แต่การตั้งค่าสถานะคำถามที่มีคำตอบมากกว่า 400 ข้อพร้อมคำตอบมากกว่า 300 คำตอบสำหรับการลบนั้นเป็นเรื่องที่ไม่ดีเลยใช่ไหม
DevSolar

คำตอบ:


394

Ctrl+ ]- ไปที่คำจำกัดความ
Ctrl+ T- กระโดดกลับจากคำจำกัดความ
Ctrl+ W Ctrl+ ]- เปิดความหมายในแนวนอนแยก

เพิ่มบรรทัดเหล่านี้ใน vimrc
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

Ctrl+ \- เปิดคำจำกัดความในแท็บใหม่
Alt+ ]- เปิดคำจำกัดความในแนวแยก

หลังจากสร้างแท็กแล้ว คุณสามารถใช้ปุ่มต่อไปนี้เพื่อแท็กและแท็กออกจากฟังก์ชั่น:

Ctrl+ Left MouseClick- ไปที่คำนิยาม
Ctrl+ Right MouseClick- กระโดดกลับจากคำจำกัดความ


8
C -] => (ปุ่มควบคุม) และ] ปุ่ม C - T => (ปุ่มควบคุม) และปุ่ม T เพียงสำหรับมือใหม่ถึง ctags ขอบคุณสำหรับเคล็ดลับแท็บใหม่
kumar

6
ในทำนองเดียวกันหลังจากที่แยกหน้าต่างด้วยCtrl-w C-]คุณสามารถทำC-w T(aka Shift-t) เพื่อเปลี่ยนการแบ่งออกเป็นแท็บใหม่
dash-tom-bang

1
@ Will หากคุณใช้ vim จากเทอร์มินัลคุณจะต้องเปลี่ยนการตั้งค่าเทอร์มินัลเพื่อให้คีย์ตัวเลือกทำงานเหมือนปุ่ม alt หากคุณใช้ MacVim ให้เพิ่มบรรทัดนี้ใน vimrc 'set macmeta' มี doc สำหรับ macmeta,: h macmeta
Amjith

17
g C-]มีประโยชน์มาก มันเปิดกล่องโต้ตอบอย่างรวดเร็วเพื่อเลือกหนึ่งระหว่างคำจำกัดความหลาย
Vincenzo Pii

3
g]ยังมีประโยชน์ คุณสามารถวางเคอร์เซอร์ไว้เหนือชื่อแท็กและกดg]เพื่อรับรายการของแท็กที่ตรงกัน
zeekvfu

176

บรรทัดหนึ่งที่มักจะอยู่ใน. vimrc ของฉัน:

set tags=./tags;/

สิ่งนี้จะดูในไดเรกทอรีปัจจุบันสำหรับ "แท็ก" และทำงานต้นไม้สู่รากจนกว่าจะพบ IOW คุณสามารถอยู่ที่ไหนก็ได้ในทรีต้นทางของคุณแทนที่จะเป็นเพียงรากของมัน


37
การขึ้นไปรูทนั้นมากเกินไป ฉันขอแนะนำให้ไปที่บ้านแทน: tags + = tags; $ HOME
gotgenes

37
ต้นไม้ต้นกำเนิดที่ฉันทำงานไม่ได้อยู่ในไดเรกทอรีบ้านของฉันเสมอไป ... และการที่ $ HOME มีแนวโน้มที่จะเป็นสองไดเรกทอรีจากราก ... ก็เป็นไปได้ที่ฉันจะสามารถหาการค้นหาไดเรกทอรีได้อีกสองรายการ :)
2552

6
ฉันเห็นด้วยกับ uzi ถ้า cwd ของฉันคือ / home / me / programming / foo / bar / baz / bang / bam นั่นเป็นการค้นหาไดเรกทอรีเพียง 8 รายการ ฉันคิดว่ามันขึ้นอยู่กับความอดทนของคุณสำหรับความเร็ว แต่เวลาในการค้นหา 1 ไดเรกทอรีไม่แตกต่างอย่างเห็นได้ชัดจาก 8 ในเครื่องของฉัน
Nate Murray

1
มันขึ้นอยู่กับสถานการณ์ของคุณฉันต้องใช้คำแนะนำ gotgenes กับหนึ่งในเครื่องของฉันเพราะมีประมาณ 8,000 ไดเรกทอรีใน / home และนั่นก็มีแนวโน้มที่จะเฉื่อยชาเล็กน้อย
jkerian

1
มีอะไรที่คล้ายกันcscopeไหม?
szx

45

อีกปลั๊กอินที่มีประโยชน์สำหรับการพัฒนา C คือcscope เช่นเดียวกับ Ctags ช่วยให้คุณข้ามไปยังคำจำกัดความ Cscope ข้ามไปยังฟังก์ชั่นการโทร

หากคุณมี cscope ในไดเรกทอรี ~ / bin / ให้เพิ่มรายการต่อไปนี้ใน. vimrc ของคุณและใช้ g ^] เพื่อไปที่ฟังก์ชันการโทร (ดู: 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

เกือบลืม ... เช่นเดียวกับ ctags - คุณต้องสร้าง (และอัปเดตฐานข้อมูลเป็นระยะ) ฉันใช้สคริปต์ต่อไปนี้

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

โดยที่ 'select_files' เป็นสคริปต์อื่นที่แยกรายการของ C และไฟล์ส่วนหัวจาก Makefile วิธีนี้ฉันจัดทำดัชนีเฉพาะไฟล์ที่ใช้จริงโดยโครงการ


ข้อดีของ cscope บน ctags คืออะไร? พวกเขาชมเชยกันไหม?
Whaledawg

4
พวกเขาเติมเต็มซึ่งกันและกัน Ctags ค้นหาคำจำกัดความของสัญลักษณ์หรือฟังก์ชัน Cscope สามารถค้นหาสถานที่ทั้งหมดที่เรียกใช้ฟังก์ชันได้ การใช้ทั้งคู่ทำให้การนำทางในต้นไม้ต้นกำเนิดขนาดใหญ่นั้นง่ายมาก
nimrodm

1
อย่างไรก็ตาม AFAIK cscope มีความเข้าใจที่ จำกัด ของ C ++
ลัค Hermitte

มัน จำกัด และไม่ค่อยดี แต่สำหรับสิ่งที่มันทำ (กระโดดไปที่ USAGES) ไม่มีทางเลือกอื่นที่ดีกว่า ปัญหาหลักของมันคือว่าเมื่อคุณต้องการที่จะข้ามไปยังฟังก์ชั่นการโทร (ฉ), คุณมักจะต้องข้ามไปได้ทุกที่ที่มีการใช้สัญลักษณ์ (s) แทนและกรองผลการค้นหาในจิตใจ ...
เกร็กโรเจอร์ส

2
@ Whaledawg ใช่แล้วเมื่อฉันกด CTRL +] การ์ดเสียงของฉันจะส่ง "clap.wav" ออกมา :)
Patrizio Rullo

27

คุณสามารถเพิ่มไดเรกทอรีลงในการค้นหา ctags ของคุณ ตัวอย่างเช่นฉันมีดัชนี ctags ที่สร้างขึ้นสำหรับ Qt4 และมีสิ่งนี้ใน. vimrc ของฉัน:

set tags+=/usr/local/share/ctags/qt4

23

จากทั้งหมดข้างต้นและ ...

code_complete: พารามิเตอร์ฟังก์ชั่นเสร็จสมบูรณ์ตัวอย่างโค้ดและอีกมากมาย

taglist.vim: ซอร์สโค้ดเบราว์เซอร์ (รองรับ C / C ++, java, perl, python, tcl, sql, php, ฯลฯ )


5
ฉันคิดว่ามันเป็นการดีที่จะเพิ่ม taglist.vim นั้นเป็นปลั๊กอินเสียงเรียกเข้าที่ดาวน์โหลดมากที่สุด
amit

16

ฉันใช้ ALT-left และ ALT-right เพื่อป๊อป / พุชจาก / ไปยังสแต็กแท็ก

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

ถ้าคุณใช้hjklสำหรับการเคลื่อนไหวคุณสามารถแมป<M-h>และ<M-l>แทน


ไม่เหมือนกับ ctrl -] และ ctrl-t - ฉันเดาว่าคำแนะนำของคุณสะอาดกว่าเล็กน้อย

@Sasha, อภัยโทษ? ไม่รู้ว่าคุณกำลังพูดอะไร = X หากต้องการทราบสิ่งนี้ยังใช้งานได้ใน: ความช่วยเหลือ
แปลกหน้า

2
ฉันคิดว่านี่ใช้งานง่ายและสะอาดกว่าค่าเริ่มต้น
Ayman

1
@ Ayman แต่ยังละเมิดหลักการที่ไม่ต้องขยับมือออกจาก homerow เช่นใช้ hjkl vs ปุ่มลูกศร
TankorSmash

@TankorSmash หลักการอะไร?
แปลกหน้า

10

หลายคำนิยามของชื่อเดียวกัน

<C-w>g<C-]>เปิดคำจำกัดความในการแยก แต่ยังทำเช่น:tjumpนั้นไปที่คำจำกัดความหรือถ้ามีหลายคำจำกัดความนำเสนอรายการคำจำกัดความให้คุณเลือก


2
คล้ายกับคำสั่งแรก vim มี:ptagคำสั่งที่เปิดนิยามในหน้าต่างแสดงตัวอย่าง
idbrii

1
หน้าต่างแสดงตัวอย่างนั้นดีเพราะคุณสามารถปิดได้ด้วย: pc จากหน้าต่างอื่น ๆ โดยไม่ต้องเลื่อนเคอร์เซอร์ไปที่หน้าต่างแสดงตัวอย่างก่อน
Heikki Naski

นอกจากนี้ยังมีเคล็ดลับ autocmd ที่เรียบร้อยด้วย ptag :h CursorHold-exampleซึ่งจะแสดงแท็กสำหรับรายการใต้เคอร์เซอร์ในหน้าต่างแสดงตัวอย่างหลังจากหมดเวลาที่กำหนด
dash-tom-bang

+1 สำหรับ: tjump ฉันได้ผูกไว้แล้ว: tjump <Cr><Cw> <CR> ทำงานได้ดีกว่า <C -]> imho ชอบที่จะรวมพฤติกรรมนี้กับ: ptag
Andreas Fliesberg

:helpเป็นบางครั้งที่น่ากลัว ... ดู:help CTRL-W_g}และ:ptjump
Andreas Fliesberg

8

คำสั่งที่ฉันใช้บ่อยที่สุดคือ C-] ซึ่งข้ามไปที่นิยามของฟังก์ชันใต้เคอร์เซอร์ คุณสามารถใช้บ่อยขึ้นเพื่อติดตามการโทรมากขึ้น หลังจากนั้น Co จะนำคุณกลับมาหนึ่งระดับ Ci จะลึกอีกครั้ง


16
Ct กลับไปหนึ่งระดับใน C-] stack ในขณะที่ Co กลับไปที่ตำแหน่งเคอร์เซอร์ก่อนหน้าหลังจากการเคลื่อนไหว ดังนั้นหากคุณ C-] ฟังก์ชั่นแล้วเลื่อนหน้าลง Ct จะกลับไปทันทีในขณะที่ Co จะกลับไปที่จุดเริ่มต้นของฟังก์ชั่นจากนั้นกลับไปที่การโทร
เกร็ก Hewgill

6

ฉันพบปลั๊กอินtaglistที่ต้องมี มันแสดงรายการแท็กทั้งหมดที่รู้เกี่ยวกับ (ไฟล์ที่คุณเปิด) ในหน้าต่างแยกและทำให้ง่ายต่อการนำทางไฟล์ขนาดใหญ่

ฉันใช้มันเป็นส่วนใหญ่ในการพัฒนา Python แต่จะดีกว่าสำหรับ C / C ++ เท่านั้น




4

ฉันใส่สิ่งต่อไปนี้ในไฟล์. gvimrc ซึ่งค้นหาต้นไม้จากจุดใด ๆ สำหรับไฟล์แท็กเมื่อ 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()

จากนั้นฉันจะสร้างไฟล์แท็กขึ้นใหม่เป็นระยะที่ด้านบนสุดของทรีซอร์สของฉันด้วยสคริปต์ที่มีลักษณะดังนี้:

#!/bin/bash

find . -regex ".*\.\(c\|h\|hpp\|cc\|cpp\)" -print | ctags --totals --recurse --extra="+qf" --fields="+i" -L -

7
คุณเพิ่งคิดค้นการค้นหาขึ้นใหม่ ดู: h การค้นหาไฟล์ ดูstackoverflow.com/questions/563616/vimctags-tips-and-tricks/?hl=th
gotgenes

2

ฉันใช้เป็นกลุ่มใน macos และ ctags ดั้งเดิมทำงานได้ไม่ดีดังนั้นฉันจึงดาวน์โหลดใหม่ล่าสุดและกำหนดค่าให้ทำการติดตั้ง ฉันติดตั้ง ctgas ใน / usr / local / bin / ctags (เพื่อเก็บต้นฉบับ)

"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

ฉันปรับฟังก์ชั่นการค้นหา SetTags () ด้านบน (ซึ่งควรถูกแทนที่ด้วยสิ่งที่เทียบเท่าset tags+=./tags;/) เพื่อทำงานกับ cscope ดูเหมือนว่าจะทำงาน!

"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
ดังที่ gotgenes กล่าวว่าคุณเพิ่งคิดค้นการค้นหาขึ้นใหม่ ดู: h การค้นหาไฟล์ ดูปลั๊กอินนี้สำหรับตัวอย่างที่เกี่ยวข้อง
idbrii

1

การวนซ้ำอีกครั้งในฟังก์ชัน SetCscope () ด้านบน นั่นทำให้ cscope pre-path ทำการจับคู่โดยไม่ต้องอยู่บน dir โดยที่ "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

3
ดังที่ gotgenes กล่าวว่าคุณเพิ่งคิดค้นการค้นหาขึ้นใหม่ ดู: h การค้นหาไฟล์ ดูปลั๊กอินนี้สำหรับตัวอย่างที่เกี่ยวข้อง
idbrii
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.