From cc222f5d8c22825af2906453ebe3833dfa670689 Mon Sep 17 00:00:00 2001 From: Jan Larres Date: Tue, 26 Feb 2013 21:56:12 +1300 Subject: [PATCH] Run ctags even if previous run produced erros, closes #125 If a ctags-compatible program returns an error status code on a parsing failure then it would never be run again on the same file, even if later invocations would have returned normally (for example after fixing an error in the current file). Therefore we need to execute the program on updates as usual, but do not repeat error messages if the previous run already did. --- autoload/tagbar.vim | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/autoload/tagbar.vim b/autoload/tagbar.vim index 7be7d6f..2b7587e 100644 --- a/autoload/tagbar.vim +++ b/autoload/tagbar.vim @@ -1225,6 +1225,7 @@ function! s:BaseTag.initFoldState() abort dict let fileinfo = self.fileinfo if s:known_files.has(fileinfo.fpath) && + \ has_key(fileinfo, '_tagfolds_old') && \ has_key(fileinfo._tagfolds_old[self.fields.kind], self.fullpath) " The file has been updated and the tag was there before, so copy its " old fold state @@ -1877,13 +1878,16 @@ function! s:ProcessFile(fname, ftype) abort " If the file has only been updated preserve the fold states, otherwise " create a new entry - if s:known_files.has(a:fname) + if s:known_files.has(a:fname) && !empty(s:known_files.get(a:fname)) let fileinfo = s:known_files.get(a:fname) call fileinfo.reset() else let fileinfo = s:FileInfo.New(a:fname, a:ftype) endif + " Use a temporary files for ctags processing instead of the original one. + " This allows using Tagbar for files accessed with netrw, and also doesn't + " slow down Tagbar for files that sit on slow network drives. let tempfile = tempname() let ext = fnamemodify(fileinfo.fpath, ':e') if ext != '' @@ -1893,7 +1897,7 @@ function! s:ProcessFile(fname, ftype) abort call writefile(getbufline(fileinfo.bufnr, 1, '$'), tempfile) let fileinfo.mtime = getftime(tempfile) - let ctags_output = s:ExecuteCtagsOnFile(tempfile, a:ftype) + let ctags_output = s:ExecuteCtagsOnFile(tempfile, a:fname, a:ftype) call delete(tempfile) @@ -1992,7 +1996,7 @@ function! s:ProcessFile(fname, ftype) abort endfunction " s:ExecuteCtagsOnFile() {{{2 -function! s:ExecuteCtagsOnFile(fname, ftype) abort +function! s:ExecuteCtagsOnFile(fname, realfname, ftype) abort call s:LogDebugMessage('ExecuteCtagsOnFile called [' . a:fname . ']') let typeinfo = s:known_types[a:ftype] @@ -2041,15 +2045,18 @@ function! s:ExecuteCtagsOnFile(fname, ftype) abort let ctags_output = s:ExecuteCtags(ctags_cmd) if v:shell_error || ctags_output =~ 'Warning: cannot open source file' - echoerr 'Tagbar: Could not execute ctags for ' . a:fname . '!' - echomsg 'Executed command: "' . ctags_cmd . '"' - if !empty(ctags_output) - call s:LogDebugMessage('Command output:') - call s:LogDebugMessage(ctags_output) - echomsg 'Command output:' - for line in split(ctags_output, '\n') - echomsg line - endfor + if !s:known_files.has(a:realfname) || + \ !empty(s:known_files.get(a:realfname)) + echoerr 'Tagbar: Could not execute ctags for ' . a:fname . '!' + echomsg 'Executed command: "' . ctags_cmd . '"' + if !empty(ctags_output) + call s:LogDebugMessage('Command output:') + call s:LogDebugMessage(ctags_output) + echomsg 'Command output:' + for line in split(ctags_output, '\n') + echomsg line + endfor + endif endif return -1 endif @@ -3076,18 +3083,16 @@ function! s:AutoUpdate(fname, force) abort let updated = 0 " Process the file if it's unknown or the information is outdated. - " Also test for entries that exist but are empty, which will be the case - " if there was an error during the ctags execution. " Testing the mtime of the file is necessary in case it got changed " outside of Vim, for example by checking out a different version from a " VCS. - if s:known_files.has(a:fname) && !empty(s:known_files.get(a:fname)) + if s:known_files.has(a:fname) let curfile = s:known_files.get(a:fname) " if a:force || getbufvar(curfile.bufnr, '&modified') || - if a:force || + if a:force || empty(curfile) || \ (filereadable(a:fname) && getftime(a:fname) > curfile.mtime) call s:LogDebugMessage('File data outdated, updating' . - \ ' [' . a:fname . ']') + \ ' [' . a:fname . ']') call s:ProcessFile(a:fname, sftype) let updated = 1 else