" File: gtags.vim " Author: Tama Communications Corporation " Version: 0.1 " Last Modified: Jan 19, 2004 " " Overview " -------- " The gtags.vim plugin script integrates the GNU GLOBAL source code tag system " with Vim. About the details, see http://www.gnu.org/software/global/. " " Installation " ------------ " Drop the file in your plugin directory or source it from your vimrc. " To use this script, you need the GNU GLOBAL installed in your machine. " " Usage " ----- " First of all, you must execute gtags(1) at the root of source directory " to make tag files. " Almost global(1)'s command character is available as a command. " " To go to func, you can say " " :Gtags func " " Special charactor '%', '#' and input completion are available. " " If you omitted argument, vim ask it like this: " " Gtags for pattern: " " You can use all the regular quickfix commands to traverse from one hit to " another. " " :h quickfix " " Suggested map: " map :cn " map :cp " " You can use 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 " " You can browse project files whose path includs specified pattern. " By the way, you can browse under 'vm/' directory by this: " " :Gtags -P /vm/ " " 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 :GtagsCursor " " 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 :Gozilla " " 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('')) 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("") 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() command! -nargs=0 GtagsCursor call s:GtagsCursor() command! -nargs=0 Gozilla call s:Gozilla() " Suggested map: "map :GtagsCursor "map :Gozilla "map :cn "map :cp