Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
151 lines (137 sloc) 5.04 KB
" This file supplies automatic tag regeneration when saving files
" There's a problem with ctags when run with -a (append)
" ctags doesn't remove entries for the supplied source file that no longer exist
" so this script (implemented in python) finds a tags file for the file vim has
" just saved, removes all entries for that source file and *then* runs ctags -a
if has("python")
python << EEOOFF
import os
import string
import os.path
import fileinput
import sys
import vim
def echo(str):
str=str.replace('\\', '\\\\')
str=str.replace('"', "'")
vim.command("redraw | echo \"%s\"" % str)
class AutoTag:
def __init__(self, excludesuffix="", ctags_cmd="ctags", verbose=0):
self.tags = {}
self.excludesuffix = [ "." + s for s in excludesuffix.split(".") ]
verbose = long(verbose)
if verbose > 0:
self.verbose = verbose
else:
self.verbose = 0
self.sep_used_by_ctags = '/'
self.cwd = os.getcwd()
self.ctags_cmd = ctags_cmd
self.count = 0
def findTagFile(self, source):
( drive, file ) = os.path.splitdrive(source)
while file:
file = os.path.dirname(file)
tagsFile = os.path.join(drive, file, "tags")
self.diag(2, "does %s exist?", tagsFile)
if os.path.isfile(tagsFile):
self.diag(2, "Found tags file %s", tagsFile)
return tagsFile
elif not file or file == os.sep or file == "//" or file == "\\\\":
self.diag(2, "exhausted search for tag file for %s", source)
return None
self.diag(2, "Nope. :-| %s does NOT exist", tagsFile)
return None
def addSource(self, source):
if not source:
return
if os.path.splitext(source)[1] in self.excludesuffix:
self.diag(1, "Ignoring excluded file " + source)
return
tagsFile = self.findTagFile(source)
if tagsFile:
self.diag(2, "if tagsFile:")
relativeSource = source[len(os.path.dirname(tagsFile)):]
self.diag(2, "relativeSource = source[len(os.path.dirname(tagsFile)):]")
if relativeSource[0] == os.sep:
self.diag(2, "if relativeSource[0] == os.sep:")
relativeSource = relativeSource[1:]
self.diag(2, "relativeSource = relativeSource[1:]")
if os.sep != self.sep_used_by_ctags:
self.diag(2, "if os.sep != self.sep_used_by_ctags:")
relativeSource = string.replace(relativeSource, os.sep, self.sep_used_by_ctags)
self.diag(2, "relativeSource = string.replace(relativeSource, os.sep, self.sep_used_by_ctags)")
if self.tags.has_key(tagsFile):
self.diag(2, "if self.tags.has_key(tagsFile):")
self.tags[tagsFile].append(relativeSource)
self.diag(2, "self.tags[tagsFile].append(relativeSource)")
else:
self.diag(2, "else:")
self.tags[tagsFile] = [ relativeSource ]
self.diag(2, "self.tags[tagsFile] = [ relativeSource ]")
def stripTags(self, tagsFile, sources):
self.diag(1, "Removing tags for %s from tags file %s", (sources, tagsFile))
backup = ".SAFE"
for line in fileinput.input(files=tagsFile, inplace=True, backup=backup):
if line[-1:] == '\n':
line = line[:-1]
if line[-1:] == '\r':
line = line[:-1]
if line[0] == "!":
print line
else:
fields = string.split(line, "\t")
if len(fields) > 3:
found = False
for source in sources:
if fields[1] == source:
found = True
break
if not found:
print line
else:
print line
os.unlink(tagsFile + backup)
def rebuildTagFiles(self):
for tagsFile in self.tags.keys():
tagsDir = os.path.dirname(tagsFile)
sources = self.tags[tagsFile]
os.chdir(tagsDir)
self.stripTags(tagsFile, sources)
cmd = "%s -a " % self.ctags_cmd
for source in sources:
if os.path.isfile(source):
cmd += " '%s'" % source
self.diag(1, "%s: %s", (tagsDir, cmd))
(ch_in, ch_out) = os.popen2(cmd)
for line in ch_out:
pass
os.chdir(self.cwd)
def diag(self, level, msg, args = None):
if msg and args:
msg = msg % args
if level <= self.verbose:
echo(msg)
EEOOFF
function! AutoTag()
python << EEOOFF
at = AutoTag(vim.eval("g:autotagExcludeSuffixes"), vim.eval("g:autotagCtagsCmd"), long(vim.eval("g:autotagVerbosityLevel")))
at.addSource(vim.eval("expand(\"%:p\")"))
at.rebuildTagFiles()
EEOOFF
endfunction
if !exists("g:autotagVerbosityLevel")
let g:autotagVerbosityLevel=0
endif
if !exists("g:autotagExcludeSuffixes")
let g:autotagExcludeSuffixes="tml.xml"
endif
if !exists("g:autotagCtagsCmd")
let g:autotagCtagsCmd="ctags"
endif
if !exists("g:autotag_autocmd_set")
let g:autotag_autocmd_set=1
autocmd BufWritePost,FileWritePost * call AutoTag ()
endif
endif " has("python")
" vim:sw=3:ts=3