aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Karkat <swdev@ingo-karkat.de>2013-03-28 10:53:02 +0100
committerIngo Karkat <swdev@ingo-karkat.de>2013-03-28 10:53:02 +0100
commitd789e8e59d42d99a7c424961fc447e509d503aff (patch)
treee7adb3ce682d2dd6eb9be8ebd397d55f40601837
parent44b04871f812418ac0fe7b38e59222de118d07cb (diff)
downloadvim-easytags-d789e8e59d42d99a7c424961fc447e509d503aff.tar.gz
ENH: Avoid tag updating when ctags output has identical fingerprint.
We can avoid the lengthy and blocking update of the tags database when the ctags output returns the same information as before; i.e. nothing tag-relevant has been changed since the last update. Since 7.3.816, Vim has a sha256() function that allows us to quickly calculate a fingerprint over the ctags output. When that is not available, only handle the special case of a (covered) file that has no tags at all (as calculating a hash in Vimscript is costly and would probably defeat the intended speedup).
-rw-r--r--autoload/xolox/easytags.vim37
1 files changed, 35 insertions, 2 deletions
diff --git a/autoload/xolox/easytags.vim b/autoload/xolox/easytags.vim
index 2088f48..0d6e857 100644
--- a/autoload/xolox/easytags.vim
+++ b/autoload/xolox/easytags.vim
@@ -99,8 +99,11 @@ function! xolox#easytags#update(silent, filter_tags, filenames) " {{{2
let tagsfile = xolox#easytags#get_tagsfile()
let firstrun = !filereadable(tagsfile)
let cmdline = s:prep_cmdline(cfile, tagsfile, firstrun, a:filenames, context)
- let output = s:run_ctags(starttime, cfile, tagsfile, firstrun, cmdline)
+ let [output, has_updates] = s:run_ctags(starttime, cfile, tagsfile, firstrun, cmdline)
if !firstrun
+ if !has_updates
+ return 1
+ endif
if have_args && !empty(g:easytags_by_filetype)
" TODO Get the headers from somewhere?!
call s:save_by_filetype(a:filter_tags, [], output, context)
@@ -201,12 +204,41 @@ function! s:prep_cmdline(cfile, tagsfile, firstrun, arguments, context) " {{{3
return have_args ? join(cmdline) : ''
endfunction
+if exists('*sha256')
+function! s:get_fingerprint(cfile, output)
+ return sha256(a:output)
+endfunction
+else
+function! s:get_fingerprint(cfile, output)
+ " Don't want to re-implement a costly hashing function in Vimscript. Just
+ " handle files that never had any tags.
+ if empty(a:output)
+ return get(s:fingerprints, a:cfile, 1)
+ else
+ return ''
+ endif
+endfunction
+endif
+
+let s:fingerprints = {}
+function! s:has_updates(cfile, output)
+ let fingerprint = s:get_fingerprint(a:cfile, a:output)
+ if ! empty(fingerprint) && get(s:fingerprints, a:cfile, '') ==# fingerprint
+ return 0
+ endif
+
+ let s:fingerprints[a:cfile] = fingerprint
+ return 1
+endfunction
+
function! s:run_ctags(starttime, cfile, tagsfile, firstrun, cmdline) " {{{3
let lines = []
+ let has_updates = 1
if a:cmdline != ''
call xolox#misc#msg#debug("easytags.vim %s: Executing %s.", g:xolox#easytags#version, a:cmdline)
try
let lines = xolox#shell#execute(a:cmdline, 1)
+ let has_updates = a:firstrun || s:has_updates(a:cfile, join(lines, "\n"))
catch /^Vim\%((\a\+)\)\=:E117/
" Ignore missing shell.vim plug-in.
let output = system(a:cmdline)
@@ -215,6 +247,7 @@ function! s:run_ctags(starttime, cfile, tagsfile, firstrun, cmdline) " {{{3
throw printf(msg, fnamemodify(a:tagsfile, ':~'), strtrans(output))
endif
let lines = split(output, "\n")
+ let has_updates = a:firstrun || s:has_updates(a:cfile, output)
endtry
if a:firstrun
if a:cfile != ''
@@ -225,7 +258,7 @@ function! s:run_ctags(starttime, cfile, tagsfile, firstrun, cmdline) " {{{3
return []
endif
endif
- return xolox#easytags#parse_entries(lines)
+ return [xolox#easytags#parse_entries(lines), has_updates]
endfunction
function! s:filter_merge_tags(filter_tags, tagsfile, output, context) " {{{3