vim中使用gtags

来源:互联网 发布:网络创业园 编辑:程序博客网 时间:2024/06/05 20:02


  • 下载global
在官网下载global源码

http://www.gnu.org/software/global/download.html


  • 编译并安装global
./configure
make
sudo make install

  • gtags vim脚本配置
copy global 源码目录下到gtags-cscope.vim,gtags.vim到 .vim目录,
本人使用NeoBundle 管理插件


.vimrc中按照如下进行配置,

可以自动在cscope.out 和GTAGS 中自动选择加载索引数据库文件,

脚本会优先检测GTAGS文件是否存在,

如果不存在,则查找cscope.out,


 " gtags-cscope setting {{{

    " I use GNU global instead cscope because global is faster.
    " need install global
    " 1. install global
    " 2. copy /usr/local/share/gtags/gtags-cscope.vim gtags.vim  to
    " ~/.vim/bundle/gtags.vim/plugin/
    " no needed now with the follow function replace the gtags-cscope.vim plugin
    function! s:GtagsCscope_GtagsRoot()
      let s:global_command = "global"
        let cmd = s:global_command . " -pq"
        let cmd_output = system(cmd)
        return strpart(cmd_output, 0, strlen(cmd_output) - 1)
    endfunction


    function! s:GtagsCscope()
        "
        " Get gtagsroot directory.
        "
        let gtagsroot = s:GtagsCscope_GtagsRoot()
      if (!empty(gtagsroot))
        "

        " Load gtags-cscope.

       set cscopetag

        set csprg=gtags-cscope
    "    let s:command = "cs add " . gtagsroot . "/GTAGS"
        let s:option = ''
    "    if g:GtagsCscope_Ignore_Case == 1
            let s:option = s:option . 'C'
    "    endif
    "    if g:GtagsCscope_Absolute_Path == 1
            let s:option = s:option . 'a'
    "    endif
    "    if g:GtagsCscope_Keep_Alive == 1
            let s:option = s:option . 'i'
    "    endif
        if s:option != ''
    "        let s:command = s:command . ' . -' . s:option
        endif
        set nocscopeverbose
        "let s:command = "cs add " . gtagsroot . "/GTAGS" . ' . -' . 'i' . 'a' . 'C'
        let s:command = "cs add " . gtagsroot . "/GTAGS" . ' . -' . 'i' . 'a'
        exe s:command
        set cscopeverbose
        "
        " Key mapping
        "
      " if g:GtagsCscope_Auto_Map == 1
            " The following key mappings are derived from 'cscope_maps.vim'.
            " (The 'd' command is not implemented in gtags-cscope.)
            "
            " normal command
            :nmap <C-\>s :cs find s <C-R>=expand("<cword>")<CR><CR>
            :nmap <C-\>g :cs find g <C-R>=expand("<cword>")<CR><CR>
            :nmap <C-\>c :cs find c <C-R>=expand("<cword>")<CR><CR>
            :nmap <C-\>t :cs find t <C-R>=expand("<cword>")<CR><CR>
            :nmap <C-\>e :cs find e <C-R>=expand("<cword>")<CR><CR>
            :nmap <C-\>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
            :nmap <C-\>i :cs find i <C-R>=expand("<cfile>")<CR><CR>
            ":nmap <C-\>d :cs find d <C-R>=expand("<cword>")<CR><CR>
            " Using 'CTRL-spacebar', the result is displayed in new horizontal window.
      " endif
      endif
    endfunction


    function! UpdateGtags(f)
      let dir = fnamemodify(a:f, ':p:h')
      exe 'silent !cd ' . dir . ' && global -u &> /dev/null &'
    endfunction


    "==
    " windowdir
    "  Gets the directory for the file in the current window
    "  Or the current working dir if there isn't one for the window.
    "  Use tr to allow that other OS paths, too
    function! s:windowdir()
      if winbufnr(0) == -1
        let unislash = getcwd()
      else
        let unislash = fnamemodify(bufname(winbufnr(0)), ':p:h')
      endif
        return tr(unislash, '\', '/')
    endfunc
    "
    "==
    " Find_in_parent
    " find the file argument and returns the path to it.
    " Starting with the current working dir, it walks up the parent folders
    " until it finds the file, or it hits the stop dir.
    " If it doesn't find it, it returns "Nothing"
    function! s:Find_in_parent(fln,flsrt,flstp)
      let here = a:flsrt
      while ( strlen( here) > 0 )
        if filereadable( here . "/" . a:fln )
          return here
        endif
        let fr = match(here, "/[^/]*$")
        if fr == -1
          break
        endif
        let here = strpart(here, 0, fr)
        if here == a:flstp
          break
        endif
      endwhile
      return "Nothing"
    endfunc


    " 下面的函数替代autoload_cscope.vim
    "==
    " Unload_csdb
    "  drop cscope connections.
    function! s:Unload_csdb()
      if exists("b:csdbpath")
        if cscope_connection(3, "out", b:csdbpath)
          let save_csvb = &csverb
          set nocsverb
          exe "cs kill " . b:csdbpath
          set csverb
          let &csverb = save_csvb
        endif
      endif
    endfunc
    "
    "==
    " Cycle_csdb
    "  cycle the loaded cscope db.
    function! s:Cycle_csdb()
        if exists("b:csdbpath")
          if cscope_connection(3, "out", b:csdbpath)
            return
            "it is already loaded. don't try to reload it.
          endif
        endif
        let newcsdbpath = s:Find_in_parent("cscope.out",s:windowdir(),$HOME)
    "    echo "Found cscope.out at: " . newcsdbpath
    "    echo "Windowdir: " . s:windowdir()
        if newcsdbpath != "Nothing"
          let b:csdbpath = newcsdbpath
          if !cscope_connection(3, "out", b:csdbpath)
            let save_csvb = &csverb
            "set nocsverb
            set csverb
            exe "cs add " . b:csdbpath . "/cscope.out " . b:csdbpath
            let &csverb = save_csvb
          endif
          "
        else " No cscope database, undo things. (someone rm-ed it or somesuch)
          call s:Unload_csdb()
        endif
    endfunc


    "如果GTAGS存在, 则使用gtags-cscope
    "如果GTAGS不存在,则使用cscope
    function! SelectCscopeDb()
      set nocscopeverbose   "suppress 'duplicate connection' error
        let gtagsroot = s:GtagsCscope_GtagsRoot()
      if (!empty(gtagsroot))
        set cscopeprg=gtags-cscope
        set cscopetag
        let s:command = "cs add " . gtagsroot . "/GTAGS" . ' . -' . 'i' . 'a'
        exe s:command


        "保存文件时自动更新gtags
        "au BufWritePost *.[ch] call UpdateGtags(expand('<afile>'))
        "au BufWritePost *.[ch]pp call UpdateGtags(expand('<afile>'))
        "au BufWritePost *.[ch]xx call UpdateGtags(expand('<afile>'))
        "au BufWritePost *.java call UpdateGtags(expand('<afile>'))
        "au BufWritePost *.cc call UpdateGtags(expand('<afile>'))
      else
        set csprg=/usr/bin/cscope
        " Use both cscope and ctag
        set cscopetag
        " Use cscope for definition search first
        set cscopetagorder=0
        let g:autocscope_menus=0
          set cscopetagorder=0
        " auto toggle the menu
        augroup autoload_cscope
        au!
        au BufEnter *.[chly]  call <SID>Cycle_csdb()
        au BufEnter *.cc      call <SID>Cycle_csdb()
        au BufEnter *.cpp     call <SID>Cycle_csdb()
        au BufEnter *.java    call <SID>Cycle_csdb()
        au BufUnload *.[chly] call <SID>Unload_csdb()
        au BufUnload *.cc     call <SID>Unload_csdb()
        au BufUnload *.cpp     call <SID>Unload_csdb()
        au BufUnload *.java    call <SID>Unload_csdb()
        augroup END
        nmap <C-\>d :cs find d <C-R>=expand("<cword>")<CR><CR>
        endif
      "set cscopequickfix=c-,d-,e-,f-,g0,i-,s-,t-
      "" 解决cscope与tag共存时ctrl+]有时不正常的bug
      "nmap <C-]> :tj <C-R>=expand("<cword>")<CR><CR>
      nmap <C-\>s :cs find s <C-R>=expand("<cword>")<CR><CR>
        nmap <C-\>g :cs find g <C-R>=expand("<cword>")<CR><CR>
        nmap <C-\>c :cs find c <C-R>=expand("<cword>")<CR><CR>
        nmap <C-\>t :cs find t <C-R>=expand("<cword>")<CR><CR>
        nmap <C-\>e :cs find e <C-R>=expand("<cword>")<CR><CR>
        nmap <C-\>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
        nmap <C-\>i :cs find i <C-R>=expand("<cfile>")<CR><CR>
      set cscopeverbose
    endfunc


    autocmd FileType c,cpp,java,python call SelectCscopeDb()
    command! -nargs=0 GtagsCscope call s:GtagsCscope()
    command! -nargs=0 Cscope call s:Cycle_csdb()
    "}}}
0 0