[vim] global

  • ソース解析をするため、色々とツールを検索したところ、globalというツールがどうやらもっとも便利そうなことが分かった。今まではctagsを使っていたものの、参照先へのアクセスなどができてとても便利なのでこっちにのりかえることにした。



 以下はインストールまでの道のり

wget http://tamacom.com/global/global-5.5.tar.gz /* 最新のglobalを取得*/

tar zxvf global-5.5.tar.gz /*解凍する*/

cd global-5.5

./configure && make && make install /* 場合によっては ./configure --prefix=パス名 と指定する */

インストールし終わったらglobal-5.5フォルダに入っているgtags.vimvimプラグインの中に入れる。


もしlinuxvimを使う場合において、pluginの設定などしてない場合には、mkdir -p ~/.vim/plugin としてpluginフォルダを作成し、その中にgtags.vimスクリプトを入れればvimの起動時に自動的にスクリプトとして組み込まれる。

これでgtagsを使う最低限の設定は完了する。



ただし、これだけでは使いにくいので.vimrcにGtags用の設定をする必要が出てくる。どういった設定をすればいいかは、gtags.vimスクリプトに書いているので、それを参考に設定すればよいと思う。

参考までに、私の設定を載せておきます

map <F2> :buffer 1<CR>
map <F4> :bprevious<CR>
map <F5> :bnext<CR>
map <C-w> :Gtags -r<CR>
map <C-r> :Gtags -s<CR>
map <C-]> :GtagsCursor<CR>
map <C-g> :Gozilla<CR>
map <C-n> :cn<CR>
map <C-p> :cp<CR>

現在linux標準のvimだとうまく動作するのですが、putty上のvimだとなぜかうまく動作してくれない?という状態になっています。どうしたらいいかなぁ..


gtags.vimは以下のように定義されています

"
"       :Gtags fu<TAB>
"       :Gtags func			<- Vim will append 'nc'.
"
" If you omitted argument, vim ask it like this:
"
"       Gtags for pattern: <current token>
"
" Vim execute `global -t main', parse the output, list located
" objects in quickfix window and load the first entry.  The quickfix
" windows is like this:
"
"      gctags/gctags.c|119| main
"      global/global.c|154| main
"      gozilla/gozilla.c|156| main
"      gtags/gtags.c|199| main
"      libglibc/getopt.c|701| main
"      libglibc/getopt1.c|93| main
"      [Error List]
"
" You can go to any entry using quickfix command.
"
" :cn'
"      go to the next entry.
"
" :cp'
"      go to the previous entry.
"
" :ccN'
"      go to the N'th entry.
"
" :cl'
"      list all entries.
"
" You can see the help of quickfix like this:
"
"          :h quickfix
"
" Suggested map:
"       map <C-n> :cn<CR>
"       map <C-p> :cp<CR>
"
" You can use POSIX regular expression too. It requires more execution time though.
"
"       :Gtags ^[sg]et_
"
" It will match to both of 'set_value' and 'get_value'.
"
" To go to the referenced point of func, add -r option.
"
"       :Gtags -r func
"
" To go to any symbols which are not defined in GTAGS, try this.
"
"       :Gtags -s func
"
" To go to any strings other than symbols, try this.
"
"       :Gtags -g ^[sg]et_
"
" This facility utilize grep(1).
"
" To get list of objects in a file 'main.c', use -f command.
"
"       :Gtags -f main.c
"
" If you are editing `main.c' itself, you can use '%' instead.
"
"       :Gtags -f %
"
" You can browse project files whose path includes specified pattern.
" For example:
"
"       :Gtags -P /vm/			<- all files under 'vm' directory.
"       :Gtags -P \.h$			<- all include files.
"	:Gtags -P init			<- all paths includes 'init'
"
" If you omitted the argument and input only 'ENTER' to prompt, vim
" shows list of all files in your project.
"
" You can use all options of global(1) except for the -c, -p, -u and
" all long name options. They are sent to global(1) as is.
" For example, if you want to ignore case distinctions in pattern.
"
"       :Gtags -gi paTtern
"
" It will match to both of 'PATTERN' and 'pattern'.
" See global(1) for other options.
"
" The GtagsCursor command brings you to the definition or reference of
" the current token in C language.
"
"       :GtagsCursor
"
" The GtagsCursor is not perfect though is considerably wise.
"
" Suggested map:
"       map <C-]> :GtagsCursor<CR>
"
" If you have the hypertext generated by htags(1) then you can display
" the same place on mozilla browser. Let's load mozilla and try this:
"
"       :Gozilla
"
" Suggested map:
"       map <C-g> :Gozilla<CR>
"
" If you want to load vim with all main()s then following command line is useful.
"
"	% vim '+Gtags main'
"
" Also see the chapter of 'vim editor' of the online manual of GLOBAL.
"
"	% info global
"
if exists("loaded_gtags") || &cp
    finish
endif
let loaded_gtags = 1

" Open the Gtags output window.  Set this variable to zero, to not open
" the Gtags output window by default.  You can open it manually by using
" the :cwindow command.
" (This code was drived from 'grep.vim'.)
if !exists("Gtags_OpenQuickfixWindow")
    let Gtags_OpenQuickfixWindow = 1
endif

" Character to use to quote patterns and filenames before passing to global.
" (This code was drived from 'grep.vim'.)
if !exists("Gtags_Shell_Quote_Char")
    if has("win32") || has("win16") || has("win95")
        let Gtags_Shell_Quote_Char = ''
    else
        let Gtags_Shell_Quote_Char = "'"
    endif
endif

"
" Display error message.
"
function s:Error(msg)
    echohl WarningMsg |
           \ echomsg 'Error: ' . a:msg |
           \ echohl None
endfunction
"
" Extract pattern or option string.
"
"
function s:Extract(str, target)
    let out = ''
    let mode = ''
    let length = strlen(a:str)
    let i = 0
    while i < length
        let c = a:str[i]
        " Decide mode.
        if c == ' '
            let mode = ''
        elseif mode == ''
            if c == '-'
                " Ignore long name option like --help.
                if i + 1 < length && a:str[i + 1] == '-'
                    let mode = 'ignore'
                else
                    let mode = 'option'
                endif
            else
                let mode = 'pattern'
                if a:target == 'pattern'
                    let out = ''
                endif
            endif
        endif
        if a:target == mode
            if mode == 'pattern'
                if c != ' '
                    let out = out . c
                endif
            elseif mode == 'option'
                if c !~ '[- cpu]'
                    let out = out . c
                endif
            endif
        endif
        let i = i + 1
    endwhile
    return out
endfunction

"
" RunGlobal()
"
function! s:RunGlobal(...)
    let i = 0
    let sep = ' '
    let line = ''

    while i < a:0
        let i = i + 1
        if line == ''
            let line = a:{i}
        else
            let line = line . ' ' . a:{i}
        endif
    endwhile

    let pattern = s:Extract(line, 'pattern')

    " Replace with path name.
    if pattern == '%'
        let pattern = expand('%')
    elseif pattern == '#'
        let pattern = expand('#')
    endif
    let option = s:Extract(line, 'option')

    " If no pattern supplied then get it from user.
    if pattern == ''
        if option =~ 'P'
            return
        endif
        if option =~ 'f'
            let line = input("Gtags for file: ", expand('%'))
        elseif option =~ 'P'
            let line = input("Gtags for pattern: ", '')
        else
            let line = input("Gtags for pattern: ", expand('<cword>'))
        endif
        let ret = s:Extract(line, 'pattern')
        if ret != ''
            let pattern = ret
        endif
        if option == ''
            let ret = s:Extract(line, 'option')
            if ret != ''
                let option = ret
            endif
        endif
    endif
    if option =~ 's' && option =~ 'r'
        call s:Error('Both of -s and -r are not allowed.')
        return
    endif

    " Execute global(1) command and write the result to a temporary file.
    let tmpfile = tempname()
    let pattern = g:Gtags_Shell_Quote_Char . pattern . g:Gtags_Shell_Quote_Char
    let cmd = 'global' . sep . '-tq' . option . sep . pattern
    let stuff = system(cmd . '>' . tmpfile)

    if getfsize(tmpfile) == 0
        call s:Error('Pattern ' . pattern . ' not found.')
        call delete(tmpfile)
        return
    endif
    if v:shell_error != 0
        call s:Error('Pattern ' . pattern . ' not found.')
        call delete(tmpfile)
        return
    endif

    " Parse the output of 'global -t'.
    let efm_org = &efm
    let &efm="%m%\\t%f%\\t%l"
    execute "silent! cfile " . tmpfile
    let &efm = efm_org

    " Open the quickfix window
    if g:Gtags_OpenQuickfixWindow == 1
"        topleft vertical copen
        botright copen
    endif
    cc
    call delete(tmpfile)
endfunction

"
" Execute RunGlobal() depending on the current position.
"
function! s:GtagsCursor()
    let col = col('.') - 1
    let lnum = line('.')
    let line = getline(lnum)
    let token = expand("<cword>")
    let flag = '-s'

    let pat = '^' . token . '[ \t]*('
    if line =~ pat
        let flag = '-r'
    else
        if matchstr(line, "^[ \t]*[a-zA-Z0-9_][a-zA-Z0-9_]*[ \t]*(", col) != ''
            let pat = '^#[ \t]*define[ \t][ \t]*' . token . '('
            if line =~ pat
                let flag = '-r'
            else
                let flag = '-x'
            endif
        endif
    endif
    call s:RunGlobal(flag, token)
endfunction

"
" Show the current position on mozilla.
" (You need to execute htags(1) in your source direcotry.)
"
function! s:Gozilla()
    let lnum = line('.')
    let fname = expand("%")
    let result = system('gozilla +' . lnum . ' ' . fname)
endfunction
"
" Custom completion.
"
function Candidate(ArgLead, CmdLine, CursorPos)
    let option = s:Extract(a:CmdLine, 'option')
    if option =~ 'P'
        return system('global -P ' . a:ArgLead)
    else
        return system('global -c ' . a:ArgLead)
    endif
endfunction

" Define the set of Gtags commands
command! -nargs=* -complete=custom,Candidate Gtags call s:RunGlobal(<f-args>)
command! -nargs=0 GtagsCursor call s:GtagsCursor()
command! -nargs=0 Gozilla call s:Gozilla()
" Suggested map:
"map <C-]> :GtagsCursor<CR>
"map <C-g> :Gozilla<CR>
"map <C-n> :cn<CR>
"map <C-p> :cp<CR>