Vim and Ctags tips and tricks [closed]
Asked Answered
B

15

485

I have just installed Ctags (to help with C++ development) with my Vim (or rather gVim), and would like to find out your favorite commands, macros, shortcuts, tips that go along with it...

Share your best arsenal. What other Vim add-ons you would recommend for C++ on Vim development?

EDIT What other add-on you would use in conjunction with Ctags?

EDIT2 What version of gVim you use with tags? Does it make a difference?

EDIT3 How do you enhance your programming experience for both big and small projects?

Backstay answered 19/2, 2009 at 1:37 Comment(9)
Make sure you're using exuberant ctags (a modern implementation) for best results: ctags.sourceforge.netHepatica
Perhaps the kev is not constructive?Peneus
So, I answer here : Try clang + supertab + snipmate. It's like intellisense in vim ! zwiener.org/vimautocomplete.htmlPhyllys
though closed as not constructive almost two years ago, it is so constructive for meRetention
I think the real reason for closing this question should have been: "This question, despite being enormously helpful, doesn't fit in StackOverflow policy of Q&A. Let this question and answers move to Quora and grow that site while we stubbornly keep closing helpful questions and answers".Flunk
The moment I saw this questions on google search result , I knew it would be closed as not constructive question !Fanfare
noremap <c-]> <c-]>zz, just because I want the jump to be centered in screen ;)Puddling
I understand why this question was closed, given the rules of SO. But flagging a >400 upvote question with a >300-upvote answer for deletion is a bit on the grumpy side, isn't it?Reactionary
I'm so sick of seeing questions closed as "not constructive" when they're obviously beneficial to so many people...Tumefy
T
394

Ctrl+] - go to definition
Ctrl+T - Jump back from the definition.
Ctrl+W Ctrl+] - Open the definition in a horizontal split

Add these lines in vimrc
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

Ctrl+\ - Open the definition in a new tab
Alt+] - Open the definition in a vertical split

After the tags are generated. You can use the following keys to tag into and tag out of functions:

Ctrl+Left MouseClick - Go to definition
Ctrl+Right MouseClick - Jump back from definition

Teyde answered 19/2, 2009 at 4:54 Comment(12)
C - ] => (control key) and ] key C - T => (control key) and T key Just for newbies to ctags. Thanks for new tab trickTubercle
Similarly, after splitting the window with Ctrl-w C-] you can do C-w T (aka Shift-t) to change that split into a new tab.Fluecure
When I use your suggestion with "set tags=tags;/", it works in vim, but not in gvim. It says that it cant find the tags files. Any suggestion?Birchfield
@Somebody still uses you MS-DOS: `tags;C:` ? I feel like you might have been joking..Hag
Hm.. one drawback to this is that when there isn't a tag, a new tab/split is still opened up.Sharpe
Similar to your maps, vim has a :ptag command that opens the definition in a preview window.Hepatica
how do i get the A-] to work on Os X?Pompano
@Pompano If you are using vim from the terminal then you have to change the terminal preferences to make option key behave like an alt key. If you are using MacVim then add this line to vimrc 'set macmeta'. There is doc for macmeta, :h macmeta.Teyde
g C-] is very useful. It opens a quick dialog to select one between multiple definitions.Erminna
g] is also useful. You can position the cursor over the tag name and press g] to get a list of matching tags.Allsun
also set splitright might be useful. commands would be executed in a right window after splitEvangel
vim -t <tag> also quite useful: it opens vim on the tagTippler
P
176

One line that always goes in my .vimrc:

set tags=./tags;/

This will look in the current directory for "tags", and work up the tree towards root until one is found. IOW, you can be anywhere in your source tree instead of just the root of it.

Pact answered 12/4, 2009 at 8:58 Comment(7)
Going up to root is excessive. I suggest only going up to home instead: tags+=tags;$HOMESabec
The source trees I work on aren't always in my home directory... and being that $HOME tends to be two directories away from root... well, I can afford two more directory lookups. :)Pact
I agree w/ uzi. If my cwd is /home/me/programming/foo/bar/baz/bang/bam that's only 8 directory lookups. I suppose it depends on your tolerance for speed, but the time to lookup 1 directory isn't noticeably different from 8 on my machine.Corves
I put my tags into a subdirectory, but use a similar trick (that yields the same fix mentioned by @Amit), set tags=_tags/tags;c:/workFluecure
It does depend on your scenario, I need to use gotgenes suggestion on one of my machines because there are roughly 8,000 directories in /home, and that tends to be a bit sluggish.Phonograph
Is there something similar for cscope?Facet
You don't even need / if you go up to root directory. Just ; is enough.Demogorgon
L
45

Another useful plugin for C development is cscope Just as Ctags lets you jump to definitions, Cscope jumps to the calling functions.

If you have cscope in your ~/bin/ directory, add the following to your .vimrc and use g^] to go to the calling function (see :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

Almost forgot... Just as ctags - you have to generate (and periodically update) the database. I use the following script

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

Where 'select_files' is another script that extracts the list of C and header files from the Makefile. This way I index only the files actually used by the project.

Leonialeonid answered 19/2, 2009 at 15:40 Comment(8)
What is the advantage of cscope over ctags? Do they compliment eachother?Houseroom
They complement each other. Ctags finds the definition of a symbol or a function. Cscope can find all the places calling a function. using both of them makes navigation in large source trees very easy.Leonialeonid
However, AFAIK cscope has a limited comprehension of C++.Britska
It is limited, and not very good. But for what it does (jumping to USAGES), there isn't any better alternative. Its main problem is that when you want to jump to function calls (f), you often need to jump to anywhere that symbol is used (s) instead and filter the results mentally...Jewelfish
...because it hates namespaces. Global is also workable, but IMO slightly worse.Jewelfish
Can you show an example of select_files scripts ?Powwow
@Houseroom Yes, when I press CTRL+] my sound card sends "clap.wav" in output :)Plea
@vehomzzz: nimrodm does something fancier with his makefiles, but you could just use find: find . -type f \( -iname "*.cpp" -o -iname "*.h" \)Hepatica
T
27

You can add directories to your ctags lookup. For example, I have a ctags index built for Qt4, and have this in my .vimrc:

set tags+=/usr/local/share/ctags/qt4
Taxaceous answered 19/2, 2009 at 1:41 Comment(0)
D
23

All of the above and...

code_complete : function parameter complete, code snippets, and much more.

taglist.vim : Source code browser (supports C/C++, java, perl, python, tcl, sql, php, etc)

Dewyeyed answered 5/3, 2009 at 19:45 Comment(1)
I think it would be good to add that taglist.vim is the most downloaded vim plugin.Octahedrite
T
16

I use ALT-left and ALT-right to pop/push from/to the tag stack.

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

If you use hjkl for movement you can map <M-h> and <M-l> instead.

Taxaceous answered 19/2, 2009 at 1:40 Comment(5)
isn't the same as ctrl -] and ctrl-t -- I guess, your suggestion is a bit cleaner.Backstay
@Sasha, Pardon? Don't know what you're saying. =X To note, this also works in :help.Taxaceous
I think this is more intuitive and cleaner than the default.Vidovic
@Vidovic But also violates the principle of not having to move the hands off the homerow, like using hjkl vs the arrow keys.Zabrze
@TankorSmash, what principle?Taxaceous
S
10

Several definitions of the same name

<C-w>g<C-]> open the definition in a split, but also do :tjump which either goes to the definition or, if there are several definitions, presents you with a list of definitions to choose from.

Sinusoidal answered 22/4, 2010 at 19:6 Comment(5)
Similar to the first command, vim has a :ptag command that opens the definition in a preview window.Hepatica
The preview window is nice because you can close it with :pc from any other window, without having to first move the cursor to the preview window.Sinusoidal
There's also a neat autocmd trick with ptag at :h CursorHold-example which displays the tag for the item under the cursor in the preview window after a configurable timeout.Fluecure
+1 for :tjump i've now bound :tjump <C-r><C-w><CR> works better than <C-]> imho Would love to combine this behaviour with :ptagFevre
:help is awesome sometimes... see :help CTRL-W_g} and :ptjumpFevre
F
8

The command I am using most is C-] which jumps to the definition of the function under the cursor. You can use it more often to follow more calls. After that, C-o will bring you back one level, C-i goes deeper again.

Farmhand answered 19/2, 2009 at 1:45 Comment(1)
C-t goes back one level in the C-] stack, while C-o goes back to a previous cursor position after a movement. So if you C-] to a function then page down, C-t will go back immediately while C-o will go back to the start of the function, then back to the call.Bonham
P
6

I've found the taglist plug-in a must-have. It lists all tags that it knows about (files that you have opened) in a seperate window and makes it very easy to navigate larger files.

I use it mostly for Python development, but it can only be better for C/C++.

Picro answered 21/2, 2009 at 9:52 Comment(0)
B
5

I've encapsulated tags manipulation in an experimental plugin of mine.

Regarding C++ development in vim, I've already answered there: I use my own suite, and a few other plugins.

Britska answered 19/2, 2009 at 15:3 Comment(0)
T
5

I've been adapting my vim plugins for two years to support big enough c++ project. You can take a look at them.

They use ctags and cscsope.

http://www.vim.org/scripts/script.php?script_id=1638
http://www.vim.org/scripts/script.php?script_id=2507

Tithing answered 5/3, 2009 at 10:50 Comment(0)
F
4

I put the following in my .gvimrc file, which searches up the tree from any point for a tags file when gvim starts:

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

I then periodically regenerate a tags file at the top of my source tree with a script that looks like:

#!/bin/bash

find . -regex ".*\.\(c\|h\|hpp\|cc\|cpp\)" -print | ctags --totals --recurse --extra="+qf" --fields="+i" -L -
Fratricide answered 17/4, 2009 at 23:22 Comment(1)
You just re-invented upward search. See :h file-searching. See also https://mcmap.net/q/55034/-vim-and-ctags-tips-and-tricks-closed/…Sabec
C
2

I use vim in macos, and the original ctags doesn't work well, so I download newest and configure make make install it. I install ctgas in /usr/local/bin/ctags(to keep original one)

"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>
Calk answered 27/12, 2010 at 6:11 Comment(0)
I
1

I adapted the SetTags() search function above (which should be replaced by the equivalent set tags+=./tags;/) to work for cscope. Seems to work!

"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()
Implore answered 4/5, 2011 at 18:50 Comment(1)
As gotgenes said, You just re-invented upward search. See :h file-searching. See this plugin for a relevant example.Hepatica
C
1

Another iteration on the SetCscope() function above. That sets cscope pre-path to get matches without being on the dir where "cscope.out" is:

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
Counteraccusation answered 13/6, 2011 at 16:53 Comment(1)
As gotgenes said, You just re-invented upward search. See :h file-searching. See this plugin for a relevant example.Hepatica

© 2022 - 2024 — McMap. All rights reserved.