Repository: SpaceVim/gtags.vim Branch: master Commit: 7d700d2535a8 Files: 9 Total size: 25.9 KB Directory structure: gitextract_1bffh6fd/ ├── .gitignore ├── .travis.yml ├── .vintrc.yaml ├── README.md ├── addon-info.json ├── autoload/ │ ├── gtags/ │ │ └── logger.vim │ └── gtags.vim ├── doc/ │ └── gtags.txt └── plugin/ └── gtags.vim ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ doc/tags *.class .floo .flooignore *.netrwhist *-rplugin~ *rplugin.vim .SpaceVim.log docs/_site/* docs/Gemfile.lock # Ignore tags created by etags, ctags, gtags (GNU global) and cscope TAGS .TAGS !TAGS/ tags .tags !tags/ gtags.files GTAGS GRTAGS GPATH GSYMS cscope.files cscope.out cscope.in.out cscope.po.out ================================================ FILE: .travis.yml ================================================ language: python sudo: false cache: pip: true env: global: - DEPS=$HOME/deps - PATH=$DEPS/bin:$PATH matrix: - LINT=vimlint-errors - LINT=vimlint - LINT=vint-errors - LINT=vint - LINT=vader matrix: allow_failures: - env: LINT=vimlint - env: LINT=vint install: - | if [ "${LINT#vimlint}" != "$LINT" ]; then git clone --depth=1 https://github.com/syngan/vim-vimlint /tmp/vimlint git clone --depth=1 https://github.com/ynkdir/vim-vimlparser /tmp/vimlparser elif [ "${LINT#vint}" != "$LINT" ]; then virtualenv /tmp/vint && source /tmp/vint/bin/activate && pip install vim-vint elif [ "${LINT#vader}" != "$LINT" ]; then git clone https://github.com/junegunn/vader.vim.git /tmp/vader C_OPTS="--prefix=$DEPS --with-features=huge --disable-gui --enable-pythoninterp" git clone --depth 1 https://github.com/vim/vim cd vim ./configure $C_OPTS make make install cd - fi script: - | if [ "$LINT" = "vimlint" ]; then sh /tmp/vimlint/bin/vimlint.sh -l /tmp/vimlint -p /tmp/vimlparser . elif [ "$LINT" = "vimlint-errors" ]; then sh /tmp/vimlint/bin/vimlint.sh -E -l /tmp/vimlint -p /tmp/vimlparser . elif [ "$LINT" = "vint" ]; then vint . elif [ "$LINT" = "vint-errors" ]; then vint --error . elif [ "$LINT" = "vader" ]; then vim -Nu test/test.vim -c 'Vader! test/**' fi ================================================ FILE: .vintrc.yaml ================================================ cmdargs: # Checking more strictly severity: style_problem policies: ProhibitImplicitScopeVariable: enabled: false ProhibitAbbreviationOption: enabled: false ================================================ FILE: README.md ================================================ # gtags.vim [![](https://spacevim.org/img/build-with-SpaceVim.svg)](https://spacevim.org) [![Build Status](https://travis-ci.org/SpaceVim/gtags.vim.svg?branch=master)](https://travis-ci.org/SpaceVim/gtags.vim) The gtags.vim plugin script integrates the GNU GLOBAL source code tag system with Vim. The development of gtags.vim is stopped. check [gtags.nvim](https://github.com/wsdjeg/gtags.nvim) instead. ## Installation This is part of SpaceVim's tags layer, and based on SpaceVim's API. Features: - generate gtags file automatically - quickfix list support - fuzzy find souces - denite - unite - fzf - leaderf - fzy ================================================ FILE: addon-info.json ================================================ { "name": "gtags", "description": "gtags in vim", "author": "spacevim.org" } ================================================ FILE: autoload/gtags/logger.vim ================================================ scriptencoding utf-8 let s:LOG = SpaceVim#api#import('logger') call s:LOG.set_name('Gtags') "" " set the path to gtags log file. let g:gtags_log_file = get(g:, 'gtags_log_file', '') if !empty(g:gtags_log_file) call s:LOG.set_file(g:gtags_log_file) endif function! gtags#logger#log(level, msg) abort if a:level ==# 'info' call s:LOG.info(a:msg) elseif a:level ==# 'warn' call s:LOG.warn(a:msg) elseif a:level ==# 'error' call s:LOG.error(a:msg) endif endfunction function! gtags#logger#view(...) echo s:LOG.view(get(a:000, 0, 'info')) endfunction ================================================ FILE: autoload/gtags.vim ================================================ scriptencoding utf-8 if !executable('gtags') echohl WarningMsg echom 'you need to install gnu global!' echohl NONE finish else let s:version = split(matchstr(split(system('gtags --version'), '\n')[0], '[0-9]\+\.[0-9]\+'), '\.') endif if exists('g:loaded_gtags') finish endif let g:loaded_gtags = 1 " SpaceVim's API let s:JOB = SpaceVim#api#import('job') let s:FILE = SpaceVim#api#import('file') "" " Set the global command name. If it is not set, will use $GTAGSGLOBAL, and if " $GTAGSGLOBAL still is an empty string, then will use 'global'. let g:gtags_global_command = get(g:, 'gtags_global_command', \ empty($GTAGSGLOBAL) ? 'global' : $GTAGSGLOBAL \ ) "" " Enable/Disable default mappings. By default it is disabled. let g:gtags_auto_map = get(g:, 'gtags_auto_map', 0) "" " This setting will open the |quickfix| list when adding entries. A value of 2 will " preserve the cursor position when the |quickfix| window is " opened. Defaults to 2. let g:gtags_open_list = get(g:, 'gtags_open_list', 2) " -- ctags-x format " let Gtags_Result = "ctags-x" " let Gtags_Efm = "%*\\S%*\\s%l%\\s%f%\\s%m" " " -- ctags format " let Gtags_Result = "ctags" " let Gtags_Efm = "%m\t%f\t%l" " " Gtags_Use_Tags_Format is obsoleted. if exists('g:Gtags_Use_Tags_Format') let g:Gtags_Result = 'ctags' let g:Gtags_Efm = "%m\t%f\t%l" endif if !exists('g:Gtags_Result') let g:Gtags_Result = 'ctags-x' endif if !exists('g:Gtags_Efm') let g:Gtags_Efm = "%*\\S%*\\s%l%\\s%f%\\s%m" endif " Character to use to quote patterns and file names before passing to global. " (This code was drived from 'grep.vim'.) if !exists('g:Gtags_Shell_Quote_Char') if has('win32') || has('win16') || has('win95') let g:Gtags_Shell_Quote_Char = '"' else let g:Gtags_Shell_Quote_Char = "'" endif endif if !exists('g:Gtags_Single_Quote_Char') if has('win32') || has('win16') || has('win95') let g:Gtags_Single_Quote_Char = "'" let g:Gtags_Double_Quote_Char = '\"' else let s:sq = "'" let s:dq = '"' let g:Gtags_Single_Quote_Char = s:sq . s:dq . s:sq . s:dq . s:sq let g:Gtags_Double_Quote_Char = '"' endif endif " " Stack Object. " function! s:Stack() abort let l:this = {} let l:this.container = [] function! l:this.push(item) abort call add(self.container, a:item) endfunction function! l:this.pop() abort if len(self.container) <= 0 throw 'Stack Empty' endif let l:item = self.container[-1] unlet self.container[-1] return l:item endfunction return l:this endfunction function! s:Memorize() abort let l:data = { \'file': expand('%'), \'position': getpos('.'), \} call s:crumbs.push(l:data) endfunction function! gtags#remind() abort try let l:data = s:crumbs.pop() catch call s:Error(v:exception) return endtry execute 'e ' . l:data.file call setpos('.', l:data.position) endfunction if ! exists('s:crumbs') let s:crumbs = s:Stack() endif " " Display error message. " function! s:Error(msg) abort echohl WarningMsg | \ echomsg 'Error: ' . a:msg | \ echohl None endfunction " " Extract pattern or option string. " function! s:Extract(line, target) abort let l:option = '' let l:pattern = '' let l:force_pattern = 0 let l:length = strlen(a:line) let l:i = 0 " skip command name. if a:line =~# '^Gtags' let l:i = 5 endif while l:i < l:length && a:line[l:i] ==# ' ' let l:i = l:i + 1 endwhile while l:i < l:length if a:line[l:i] ==# '-' && l:force_pattern == 0 let l:i = l:i + 1 " Ignore long name option like --help. if l:i < l:length && a:line[l:i] ==# '-' while l:i < l:length && a:line[l:i] !=# ' ' let l:i = l:i + 1 endwhile else let l:c = '' while l:i < l:length && a:line[l:i] !=# ' ' let l:c = a:line[l:i] let l:option = l:option . l:c let l:i = l:i + 1 endwhile if l:c ==# 'e' let l:force_pattern = 1 endif endif else let l:pattern = '' " allow pattern includes blanks. while l:i < l:length if a:line[l:i] ==# "'" let l:pattern = l:pattern . g:Gtags_Single_Quote_Char elseif a:line[l:i] ==# '"' let l:pattern = l:pattern . g:Gtags_Double_Quote_Char else let l:pattern = l:pattern . a:line[l:i] endif let l:i = l:i + 1 endwhile if a:target ==# 'pattern' return l:pattern endif endif " Skip blanks. while l:i < l:length && a:line[l:i] ==# ' ' let l:i = l:i + 1 endwhile endwhile if a:target ==# 'option' return l:option endif return '' endfunction " " Trim options to avoid errors. " function! s:TrimOption(option) abort let l:option = '' let l:length = strlen(a:option) let l:i = 0 while l:i < l:length let l:c = a:option[l:i] if l:c !~# '[cenpquv]' let l:option = l:option . l:c endif let l:i = l:i + 1 endwhile return l:option endfunction " " Execute global and load the result into quickfix window. " function! s:ExecLoad(option, long_option, pattern) abort " Execute global(1) command and write the result to a temporary file. let l:isfile = 0 let l:option = '' let l:result = '' if a:option =~# 'f' let l:isfile = 1 if filereadable(a:pattern) == 0 call s:Error('File ' . a:pattern . ' not found.') return endif endif if a:long_option !=# '' let l:option = a:long_option . ' ' endif " if s:version[0] > 6 || (s:version[0] == 6 && s:version[1] >= 5) " let l:option = l:option . '--nearness=' . expand('%:p:h') . ' ' " endif let l:option = l:option . '--result=' . g:Gtags_Result . ' -q' let l:option = l:option . s:TrimOption(a:option) if l:isfile == 1 let l:cmd = g:gtags_global_command . ' ' . l:option . ' ' . g:Gtags_Shell_Quote_Char . a:pattern . g:Gtags_Shell_Quote_Char else let l:cmd = g:gtags_global_command . ' ' . l:option . 'e ' . g:Gtags_Shell_Quote_Char . a:pattern . g:Gtags_Shell_Quote_Char endif let l:restore_gtagsroot = 0 if empty($GTAGSROOT) let $GTAGSROOT = SpaceVim#plugins#projectmanager#current_root() let l:restore_gtagsroot = 1 endif let l:restore_gtagsdbpath = 0 if empty($GTAGSDBPATH) let $GTAGSDBPATH = s:FILE.unify_path(g:gtags_cache_dir) . s:FILE.path_to_fname($GTAGSROOT) let l:restore_gtagsdbpath = 1 endif let l:result = system(l:cmd) " restore $GTAGSROOT and $GTAGSDBPATH to make it possible to switch " between multiple projects or parent/child projects if l:restore_gtagsroot let $GTAGSROOT = '' endif if l:restore_gtagsdbpath let $GTAGSDBPATH = '' endif e if v:shell_error != 0 if v:shell_error == 2 call s:Error('invalid arguments. (gtags.vim requires GLOBAL 5.7 or later)') elseif v:shell_error == 3 call s:Error('GTAGS not found.') else call s:Error('global command failed. command line: ' . l:cmd) endif return endif if l:result ==# '' if a:option =~# 'f' call s:Error('No tags found in ' . a:pattern) elseif a:option =~# 'P' call s:Error('No path matches found for ' . a:pattern) elseif a:option =~# 'g' call s:Error('No line matches found for ' . a:pattern) else call s:Error('No tag matches found for ' . g:Gtags_Shell_Quote_Char . a:pattern . g:Gtags_Shell_Quote_Char) endif return endif call s:Memorize() " Open the quickfix window if g:gtags_open_list == 1 botright copen elseif g:gtags_open_list == 2 call s:save_prev_windows() botright copen call s:restore_prev_windows() endif " Parse the output of 'global -x or -t' and show in the quickfix window. let l:efm_org = &efm let &efm = g:Gtags_Efm cexpr! l:result let &efm = l:efm_org endfunction let s:prev_windows = [] function! s:save_prev_windows() abort let aw = winnr('#') let pw = winnr() if exists('*win_getid') let aw_id = win_getid(aw) let pw_id = win_getid(pw) else let aw_id = 0 let pw_id = 0 endif call add(s:prev_windows, [aw, pw, aw_id, pw_id]) endfunction function! s:restore_prev_windows() abort let [aw, pw, aw_id, pw_id] = remove(s:prev_windows, 0) if winnr() != pw " Go back, maintaining the '#' window (CTRL-W_p). if pw_id let aw = win_id2win(aw_id) let pw = win_id2win(pw_id) endif if pw if aw exec aw . 'wincmd w' endif exec pw . 'wincmd w' endif endif endfunction " " RunGlobal() " function! gtags#global(line) abort call gtags#logger#log('info', a:line) let l:pattern = s:Extract(a:line, 'pattern') if l:pattern ==# '%' let l:pattern = expand('%') elseif l:pattern ==# '#' let l:pattern = expand('#') endif let l:option = s:Extract(a:line, 'option') " If no pattern supplied then get it from user. if l:pattern ==# '' && l:option !=# 'P' let s:option = l:option if l:option =~# 'f' let l:line = input('Gtags for file: ', expand('%'), 'file') else let l:line = input('Gtags for pattern: ', expand(''), 'custom,GtagsCandidateCore') endif let l:pattern = s:Extract(l:line, 'pattern') if l:pattern ==# '' call s:Error('Pattern not specified.') return endif endif call s:ExecLoad(l:option, '', l:pattern) endfunction " " Execute RunGlobal() depending on the current position. " function! gtags#cursor() abort let l:pattern = expand('') let l:option = "--from-here=\"" . line('.') . ':' . expand('%') . "\"" call s:ExecLoad('', l:option, l:pattern) endfunction " " Core Gtags function " function! gtags#func(type, pattern) abort let l:option = '' if a:type ==# 'g' let l:option .= ' -x ' elseif a:type ==# 'r' let l:option .= ' -x -r ' elseif a:type ==# 's' let l:option .= ' -x -s ' elseif a:type ==# 'e' let l:option .= ' -x -g ' elseif a:type ==# 'f' let l:option .= ' -x -P ' endif call s:ExecLoad('', l:option, a:pattern) endfunction " " Show the current position on mozilla. " (You need to execute htags(1) in your source directory.) " function! gtags#gozilla() abort let l:lineno = line('.') let l:filename = expand('%') call system('gozilla +' . l:lineno . ' ' . l:filename) endfunction " " Custom completion. " function! gtags#complete(lead, line, pos) abort let s:option = s:Extract(a:line, 'option') return s:GtagsCandidateCore(a:lead, a:line, a:pos) endfunction function! s:GtagsCandidateCore(lead, ...) abort if s:option ==# 'g' return '' elseif s:option ==# 'f' if isdirectory(a:lead) if a:lead =~# '/$' let l:pattern = a:lead . '*' else let l:pattern = a:lead . '/*' endif else let l:pattern = a:lead . '*' endif return glob(l:pattern) else let l:cands = system(g:gtags_global_command . ' ' . '-c' . s:option . ' ' . a:lead) if v:shell_error == 0 return l:cands endif return '' endif endfunction function! gtags#show_lib_path() abort echo $GTAGSLIBPATH endfunction function! gtags#add_lib(path) abort let $GTAGSLIBPATH .= ':'.a:path echo $GTAGSLIBPATH endfunction let s:progress = 0 function! gtags#update(single_update) abort let dir = s:FILE.unify_path(g:gtags_cache_dir) \ . s:FILE.path_to_fname(SpaceVim#plugins#projectmanager#current_root()) let cmd = ['gtags'] if !empty(g:gtags_gtagslabel) let cmd += ['--gtagslabel=' . g:gtags_gtagslabel] endif if a:single_update && filereadable(dir . '/GTAGS') let cmd += ['--single-update', expand('%:p')] else let cmd += ['--skip-unreadable'] endif if !isdirectory(dir) call mkdir(dir, 'p') endif let cmd += ['-O', dir] let s:progress = s:JOB.start(cmd, {'on_exit' : funcref('s:on_update_exit')}) endfunction function! s:on_update_exit(...) abort let s:progress = 0 if str2nr(a:2) > 0 && !g:gtags_silent echohl WarningMsg echo 'failed to update gtags, exit data: ' . a:2 echohl None endif endfunction ================================================ FILE: doc/gtags.txt ================================================ *gtags.txt* gtags in vim spacevim.org *gtags* ============================================================================== CONTENTS *gtags-contents* 1. Introduction................................................|gtags-intro| 2. Configuration..............................................|gtags-config| 3. Commands.................................................|gtags-commands| ============================================================================== INTRODUCTION *gtags-intro* The gtags.vim plug-in script integrates the GNU GLOBAL source code tag system with Vim. About the details, see http://www.gnu.org/software/global/. ============================================================================== CONFIGURATION *gtags-config* *g:gtags_global_command* Set the global command name. If it is not set, will use $GTAGSGLOBAL, and if $GTAGSGLOBAL still is an empty string, then will use 'global'. *g:gtags_auto_map* Enable/Disable default mappings. By default it is disabled. *g:gtags_open_list* This setting will open the |quickfix| list when adding entries. A value of 2 will preserve the cursor position when the |quickfix| window is opened. Defaults to 2. *g:gtags_log_file* set the path to gtags log file. ============================================================================== COMMANDS *gtags-commands* :Gtags *:Gtags* General form of Gtags command is as follows: > :Gtags [option] pattern < To go to func, you can say > :Gtags func < Input completion is available. If you forgot function name but recall only some characters of the head, please input them and press key. > :Gtags fu :Gtags func " Vim will append 'nc'. < If you omitted argument, vim ask it like this: > Gtags for pattern: < Vim execute `global -x main', parse the output, list located objects in quickfix window and load the first entry. The quickfix windows is like this: > gozilla/gozilla.c|200| main(int argc, char **argv) gtags-cscope/gtags-cscope.c|124| main(int argc, char **argv) gtags-parser/asm_scan.c|2056| int main() gtags-parser/gctags.c|157| main(int argc, char **argv) gtags-parser/php.c|2116| int main() gtags/gtags.c|152| main(int argc, char **argv) [Quickfix List] < You can go to any entry using quickfix command. :cn go to the next entry. :cp go to the previous entry. :cc{N} go to the {N}th entry. :cl list all entries. You can see the help of quickfix like this: > :h quickfix < 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 string other than symbol, try this. > :Gtags -g ^[sg]et_ < This command accomplishes the same function as grep(1) but is more convenient because it retrieves the entire directory structure. 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 key to the 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`. If you want to search a pattern which starts with a hyphen like '-C' then you can use the -e option like `grep(1)`. > :Gtags -ge -C < By default, Gtags command search only in source files. If you want to search in both source files and text files, or only in text files then > :Gtags -go pattern # both source and text :Gtags -gO pattern # only text file < See `global(1)` for other options. :GtagsCursor *:GtagsCursor* The GtagsCursor command brings you to the definition or reference of the current token. > :GtagsCursor < :GtagsRemind *:GtagsRemind* Use GtagsRemind command to jump to the previous position from where you invoked `:Gtags`. > ":GtagsRemind < :GtagsGenerate[!] {bang} *:GtagsGenerate* Update gtags for current file, with a {bang}, will update the project's gtags database. vim:tw=78:ts=8:ft=help:norl: ================================================ FILE: plugin/gtags.vim ================================================ "" " @section Introduction, intro " The gtags.vim plug-in script integrates the GNU GLOBAL source code tag " system with Vim. About the details, see http://www.gnu.org/software/global/. scriptencoding utf-8 if !exists('g:gtags_cache_dir') let g:gtags_cache_dir = '~/.cache/SpaceVim/tags/' endif if !exists('g:gtags_gtagslabel') let g:gtags_gtagslabel = '' endif if !exists('g:gtags_auto_update') let g:gtags_auto_update = 1 endif if !exists('g:gtags_silent') let g:gtags_silent = 1 endif "" " General form of Gtags command is as follows: " > " :Gtags [option] pattern " " To go to func, you can say " > " :Gtags func " " Input completion is available. If you forgot function name but recall " only some characters of the head, please input them and press key. " > " :Gtags fu " :Gtags func " Vim will append 'nc'. " " If you omitted argument, vim ask it like this: " > " Gtags for pattern: " " Vim execute `global -x main', parse the output, list located " objects in quickfix window and load the first entry. The quickfix " windows is like this: " > " gozilla/gozilla.c|200| main(int argc, char **argv) " gtags-cscope/gtags-cscope.c|124| main(int argc, char **argv) " gtags-parser/asm_scan.c|2056| int main() " gtags-parser/gctags.c|157| main(int argc, char **argv) " gtags-parser/php.c|2116| int main() " gtags/gtags.c|152| main(int argc, char **argv) " [Quickfix List] " " You can go to any entry using quickfix command. " " :cn " go to the next entry. " " :cp " go to the previous entry. " " :cc{N} " go to the {N}th entry. " " :cl " list all entries. " " You can see the help of quickfix like this: " > " :h quickfix " " 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 string other than symbol, try this. " > " :Gtags -g ^[sg]et_ " " This command accomplishes the same function as grep(1) but is more convenient " because it retrieves the entire directory structure. " " 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 key to the 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`. " " If you want to search a pattern which starts with a hyphen like '-C' " then you can use the -e option like `grep(1)`. " > " :Gtags -ge -C " " By default, Gtags command search only in source files. If you want to " search in both source files and text files, or only in text files then " > " :Gtags -go pattern # both source and text " :Gtags -gO pattern # only text file " " See `global(1)` for other options. command! -nargs=* -complete=custom,gtags#complete Gtags call gtags#global() "" " The GtagsCursor command brings you to the definition or reference of " the current token. " > " :GtagsCursor " < command! -nargs=0 GtagsCursor call gtags#cursor() "" " Use GtagsRemind command to jump to the previous position from where you " invoked `:Gtags`. " > " ":GtagsRemind " < command! -nargs=0 GtagsRemind call gtags#remind() "" " Update gtags for current file, with a {bang}, will update the project's " gtags database. command! -nargs=0 -bang GtagsGenerate call gtags#update(1) if g:gtags_auto_update == 1 augroup gtags_core autocmd! au BufWritePost * call gtags#update(1) augroup END endif