Question

I've been using ctags with the vim script below and had no problem doing small projects of my own. But as I got into some big projects, in games written in c++, the recursive command of ctags and cscope seem to be a lot slower than I thought. I actually managed to run it on background for now, but it seems my laptop is pretty busy doing the taggings.

I've heard there is a solution that in each sub-directory, you make a tag, and while you're working in a specific sub-directory, you can consult the tag in the root directory for other sub-directory tags. Is this possible? If anyone can give me specific HOW-TOS with this method, I would be very grateful.

Or if there is a better solution, I am very eager to know of it.

Here's my code for the vim script

function! UpdateTags()
    let curdir = getcwd()
    let gitdir = finddir('.git', '.;/')

    if isdirectory(gitdir)
        let l:rootdir = fnamemodify(gitdir, ':h')
        execute 'silent cd ' . l:rootdir
        execute 'silent !ctags -R --c++-kinds=+p --fields=+iaS --extra=+q &'
        if has("cscope")
            execute 'silent !cscope -Rbkq &'
            execute 'silent cs reset'
        endif " has("cscope") 
        execute 'silent cd ' . curdir
    endif
endfunction
Was it helpful?

Solution

I find using ctags -R being slower than use ctags with a file like ctags -L input so What I've done in my current java projects with around 3000 files in it is to ask git to give me the file paths, collect them on an archive (for example, javafiles.txt) and then execute ctags -L javafiles.txt outside of the editor.

If you don't want to leave vim you can use a shellscript to invoke Ctags with the parameters you want. I.E. Create the file autotags.sh in the root of your git project with the following lines:

#!/bin/bash

set -e
git ls-files | sed "/\.cpp$/!d" >> cscope.files


ctags -L cscope.files

Don't forget to give it execution permission. Once you have the shellscript your vimscript code will look like this:

function! UpdateTags()
    let curdir = getcwd()
    let gitdir = finddir('.git', '.;/')

    if isdirectory(gitdir)
        let l:rootdir = fnamemodify(gitdir, ':h')
        execute 'silent cd ' . l:rootdir
        execute 'silent !./autotags.sh &'
        if has("cscope")
            execute 'silent !cscope -bkq &'
            execute 'silent cs reset'
        endif " has("cscope") 
        execute 'silent cd ' . curdir
    endif
endfunction

The filename is cscope.files because It's the name that cscope uses by default. You should read http://cscope.sourceforge.net/large_projects.html

However generating the list of files is not as fast as you may want and the code requires some tweaks to escape that step when it's not needed but in general this is faster than using recursive scanning with ctags or cscope.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top