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