Mercurial > vim-gutentags
changeset 156:40153c7a1887
`gtags-cscope` module fixes:
* Vim8 job support.
* Fixes for Windows support.
* Handle multiple databases.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 11 Jan 2017 23:50:00 -0800 |
parents | 4055c696a9b4 |
children | 6b00f4383708 84dbc92c4243 |
files | autoload/gutentags/gtags_cscope.vim |
diffstat | 1 files changed, 120 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/autoload/gutentags/gtags_cscope.vim Wed Jan 11 15:38:43 2017 -0800 +++ b/autoload/gutentags/gtags_cscope.vim Wed Jan 11 23:50:00 2017 -0800 @@ -31,7 +31,23 @@ " Gutentags Module Interface {{{ -let s:db_connected = 0 +let s:added_db_files = {} +let s:job_db_files = [] + +function! s:add_db(db_file) abort + if filereadable(a:db_file) + call gutentags#trace( + \"Adding cscope DB file: " . a:db_file) + set nocscopeverbose + execute 'cs add ' . fnameescape(a:db_file) + set cscopeverbose + let s:added_db_files[a:db_file] = 1 + else + call gutentags#trace( + \"Not adding cscope DB file because it doesn't " . + \"exist yet: " . a:db_file) + endif +endfunction function! gutentags#gtags_cscope#init(project_root) abort let l:db_path = gutentags#get_cachefile( @@ -44,7 +60,7 @@ let b:gutentags_files['gtags_cscope'] = l:db_file - execute 'set cscopeprg=' . g:gutentags_gtags_cscope_executable + execute 'set cscopeprg=' . fnameescape(g:gutentags_gtags_cscope_executable) " The combination of gtags-cscope, vim's cscope and global files is " a bit flaky. Environment variables are safer than vim passing @@ -52,69 +68,127 @@ let $GTAGSDBPATH = l:db_path let $GTAGSROOT = a:project_root - if g:gutentags_auto_add_gtags_cscope && filereadable(l:db_file) - set nocscopeverbose - execute 'cs add ' . fnameescape(l:db_file) - set cscopeverbose - let s:db_connected = 1 + if g:gutentags_auto_add_gtags_cscope && !has_key(s:added_db_files, l:db_file) + let s:added_db_files[l:db_file] = 0 + call s:add_db(l:db_file) endif endfunction -function! gutentags#gtags_cscope#command_terminated(job_id, data, event) abort - if a:data == 0 - if !s:db_connected - set nocscopeverbose - execute 'cs add ' . fnameescape(self.db_file) - set cscopeverbose - let s:db_connected = 1 +function! gutentags#gtags_cscope#on_job_out(job, data) abort + call gutentags#trace(a:data) +endfunction + +function! gutentags#gtags_cscope#on_job_exit(job, exit_val) abort + if a:exit_val != 0 + echom "gutentags: gtags-cscope job failed :(" + return + endif + if g:gutentags_auto_add_gtags_cscope + let l:idx = 0 + let l:db_file = '' + for item in s:job_db_files + if item[0] == a:job + let l:db_file = item[1] + break + endif + let l:idx += 1 + endfor + if l:db_file != '' + call s:add_db(l:db_file) + call remove(s:job_db_files, l:idx) endif endif endfunction +function! s:get_unix_cmd(for_job, proj_options, db_path) abort + " Vim's `job_start` gets confused with quoted arguments on Unix, + " prefers lists. + if a:for_job + let l:cmd = [g:gutentags_gtags_executable] + a:proj_options + let l:cmd += ['--incremental', a:db_path] + return l:cmd + else + let l:cmd = gutentags#get_execute_cmd() + let l:cmd .= '"' . g:gutentags_gtags_executable . '"' + let l:cmd .= ' ' . join(a:proj_options, ' ') + let l:cmd .= ' --incremental ' + let l:cmd .= ' "' . a:db_path . '" ' + let l:cmd .= gutentags#get_execute_cmd_suffix() + return l:cmd + endif +endfunction + +function! s:get_win32_cmd(for_job, proj_options, db_path) abort + " Win32 prefers strings either way. + let l:cmd = '' + if !a:for_job + let l:cmd = gutentags#get_execute_cmd() + endif + let l:cmd .= '"' . g:gutentags_gtags_executable . '"' + let l:cmd .= ' ' . join(a:proj_options, ' ') + let l:cmd .= ' --incremental ' + let l:cmd .= ' "' . a:db_path . '"' + if !a:for_job + let l:cmd .= ' ' + let l:cmd .= gutentags#get_execute_cmd_suffix() + endif + return l:cmd +endfunction + function! gutentags#gtags_cscope#generate(proj_dir, db_file, write_mode) abort - let l:db_path = fnamemodify(a:db_file, ':p:h') - - let l:cmd = gutentags#get_execute_cmd() " gtags doesn't honour GTAGSDBPATH and GTAGSROOT, so PWD and dbpath " have to be set + let l:db_path = fnamemodify(a:db_file, ':p:h') let l:proj_options_file = a:proj_dir . '/' . g:gutentags_gtags_options_file - let l:proj_options = '' + let l:proj_options = [] if filereadable(l:proj_options_file) - let l:lines = readfile(l:proj_options_file) - let l:proj_options .= join(l:lines, ' ') + let l:proj_options = readfile(l:proj_options_file) endif - let l:cmd .= ' PWD=' . a:proj_dir - let l:cmd .= ' ' . g:gutentags_gtags_executable - let l:cmd .= ' ' . l:proj_options - let l:cmd .= ' --incremental ' - let l:cmd .= ' --quiet ' - let l:cmd .= ' ' . l:db_path - let l:cmd .= ' ' - let l:cmd .= gutentags#get_execute_cmd_suffix() + let l:use_jobs = has('job') - call gutentags#trace("Running: " . l:cmd) - call gutentags#trace("In: " . getcwd()) - if !g:gutentags_fake - if !(has('nvim') && exists('*jobwait')) - if !g:gutentags_trace - silent execute l:cmd - else - execute l:cmd - endif + let l:prev_cwd = getcwd() + execute "chdir " . fnameescape(a:proj_dir) + try + if has('win32') + let l:cmd = s:get_win32_cmd(l:use_jobs, l:proj_options, l:db_path) else - let job_dict = { 'db_file': a:db_file } - let job_cmd = l:cmd - let job_id = jobstart(job_cmd, job_dict) + let l:cmd = s:get_unix_cmd(l:use_jobs, l:proj_options, l:db_path) endif - let l:full_gtags_file = fnamemodify(l:db_path, ':p') - call gutentags#add_progress('gtags_cscope', a:db_file) - else - call gutentags#trace("(fake... not actually running)") - endif - call gutentags#trace("") + call gutentags#trace("Running: " . string(l:cmd)) + call gutentags#trace("In: " . getcwd()) + if !g:gutentags_fake + if l:use_jobs + let l:job_opts = { + \'exit_cb': 'gutentags#gtags_cscope#on_job_exit', + \'out_cb': 'gutentags#gtags_cscope#on_job_out', + \'err_cb': 'gutentags#gtags_cscope#on_job_out' + \} + let l:job = job_start(l:cmd, job_opts) + call add(s:job_db_files, [l:job, a:db_file]) + else + if !g:gutentags_trace + silent execute l:cmd + else + execute l:cmd + endif + if g:gutentags_auto_add_gtags_cscope + call s:add_db(a:db_file) + endif + endif + + let l:full_gtags_file = fnamemodify(l:db_path, ':p') + call gutentags#add_progress('gtags_cscope', a:db_file) + else + call gutentags#trace("(fake... not actually running)") + endif + call gutentags#trace("") + finally + " Restore the previous working directory. + execute "chdir " . fnameescape(l:prev_cwd) + endtry endfunction " }}}