summaryrefslogtreecommitdiff
path: root/.vim/plugin/autotag.vim
diff options
context:
space:
mode:
Diffstat (limited to '.vim/plugin/autotag.vim')
-rw-r--r--.vim/plugin/autotag.vim150
1 files changed, 150 insertions, 0 deletions
diff --git a/.vim/plugin/autotag.vim b/.vim/plugin/autotag.vim
new file mode 100644
index 0000000..8bb2d0e
--- /dev/null
+++ b/.vim/plugin/autotag.vim
@@ -0,0 +1,150 @@
+" 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