1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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
|