comparison hgext/keyword.py @ 12926:edbe32efc89f

keyword: turn regexes and escaped keywords into a propertycache
author Christian Ebert <blacktrash@gmx.net>
date Thu, 04 Nov 2010 22:56:38 +0000
parents 1fab4970354e
children 687006f06e00
comparison
equal deleted inserted replaced
12925:6eab8f0df2ca 12926:edbe32efc89f
168 if kwmaps: # override default templates 168 if kwmaps: # override default templates
169 self.templates = dict((k, templater.parsestring(v, False)) 169 self.templates = dict((k, templater.parsestring(v, False))
170 for k, v in kwmaps) 170 for k, v in kwmaps)
171 else: 171 else:
172 self.templates = _defaultkwmaps(self.ui) 172 self.templates = _defaultkwmaps(self.ui)
173 escaped = '|'.join(map(re.escape, self.templates.keys()))
174 self.re_kw = re.compile(r'\$(%s)\$' % escaped)
175 self.re_kwexp = re.compile(r'\$(%s): [^$\n\r]*? \$' % escaped)
176
177 templatefilters.filters.update({'utcdate': utcdate, 173 templatefilters.filters.update({'utcdate': utcdate,
178 'svnisodate': svnisodate, 174 'svnisodate': svnisodate,
179 'svnutcdate': svnutcdate}) 175 'svnutcdate': svnutcdate})
176
177 @util.propertycache
178 def escape(self):
179 '''Returns bar-separated and escaped keywords.'''
180 return '|'.join(map(re.escape, self.templates.keys()))
181
182 @util.propertycache
183 def rekw(self):
184 '''Returns regex for unexpanded keywords.'''
185 return re.compile(r'\$(%s)\$' % self.escape)
186
187 @util.propertycache
188 def rekwexp(self):
189 '''Returns regex for expanded keywords.'''
190 return re.compile(r'\$(%s): [^$\n\r]*? \$' % self.escape)
180 191
181 def substitute(self, data, path, ctx, subfunc): 192 def substitute(self, data, path, ctx, subfunc):
182 '''Replaces keywords in data with expanded template.''' 193 '''Replaces keywords in data with expanded template.'''
183 def kwsub(mobj): 194 def kwsub(mobj):
184 kw = mobj.group(1) 195 kw = mobj.group(1)
197 208
198 def expand(self, path, node, data): 209 def expand(self, path, node, data):
199 '''Returns data with keywords expanded.''' 210 '''Returns data with keywords expanded.'''
200 if not self.restrict and self.match(path) and not util.binary(data): 211 if not self.restrict and self.match(path) and not util.binary(data):
201 ctx = self.linkctx(path, node) 212 ctx = self.linkctx(path, node)
202 return self.substitute(data, path, ctx, self.re_kw.sub) 213 return self.substitute(data, path, ctx, self.rekw.sub)
203 return data 214 return data
204 215
205 def iskwfile(self, cand, ctx): 216 def iskwfile(self, cand, ctx):
206 '''Returns subset of candidates which are configured for keyword 217 '''Returns subset of candidates which are configured for keyword
207 expansion are not symbolic links.''' 218 expansion are not symbolic links.'''
215 return 226 return
216 kwcmd = self.restrict and lookup # kwexpand/kwshrink 227 kwcmd = self.restrict and lookup # kwexpand/kwshrink
217 if self.restrict or expand and lookup: 228 if self.restrict or expand and lookup:
218 mf = ctx.manifest() 229 mf = ctx.manifest()
219 lctx = ctx 230 lctx = ctx
220 subn = (self.restrict or rekw) and self.re_kw.subn or self.re_kwexp.subn 231 re_kw = (self.restrict or rekw) and self.rekw or self.rekwexp
221 msg = (expand and _('overwriting %s expanding keywords\n') 232 msg = (expand and _('overwriting %s expanding keywords\n')
222 or _('overwriting %s shrinking keywords\n')) 233 or _('overwriting %s shrinking keywords\n'))
223 for f in candidates: 234 for f in candidates:
224 if self.restrict: 235 if self.restrict:
225 data = self.repo.file(f).read(mf[f]) 236 data = self.repo.file(f).read(mf[f])
228 if util.binary(data): 239 if util.binary(data):
229 continue 240 continue
230 if expand: 241 if expand:
231 if lookup: 242 if lookup:
232 lctx = self.linkctx(f, mf[f]) 243 lctx = self.linkctx(f, mf[f])
233 data, found = self.substitute(data, f, lctx, subn) 244 data, found = self.substitute(data, f, lctx, re_kw.subn)
234 elif self.restrict: 245 elif self.restrict:
235 found = self.re_kw.search(data) 246 found = re_kw.search(data)
236 else: 247 else:
237 data, found = _shrinktext(data, subn) 248 data, found = _shrinktext(data, re_kw.subn)
238 if found: 249 if found:
239 self.ui.note(msg % f) 250 self.ui.note(msg % f)
240 self.repo.wwrite(f, data, ctx.flags(f)) 251 self.repo.wwrite(f, data, ctx.flags(f))
241 if kwcmd: 252 if kwcmd:
242 self.repo.dirstate.normal(f) 253 self.repo.dirstate.normal(f)
244 self.repo.dirstate.normallookup(f) 255 self.repo.dirstate.normallookup(f)
245 256
246 def shrink(self, fname, text): 257 def shrink(self, fname, text):
247 '''Returns text with all keyword substitutions removed.''' 258 '''Returns text with all keyword substitutions removed.'''
248 if self.match(fname) and not util.binary(text): 259 if self.match(fname) and not util.binary(text):
249 return _shrinktext(text, self.re_kwexp.sub) 260 return _shrinktext(text, self.rekwexp.sub)
250 return text 261 return text
251 262
252 def shrinklines(self, fname, lines): 263 def shrinklines(self, fname, lines):
253 '''Returns lines with keyword substitutions removed.''' 264 '''Returns lines with keyword substitutions removed.'''
254 if self.match(fname): 265 if self.match(fname):
255 text = ''.join(lines) 266 text = ''.join(lines)
256 if not util.binary(text): 267 if not util.binary(text):
257 return _shrinktext(text, self.re_kwexp.sub).splitlines(True) 268 return _shrinktext(text, self.rekwexp.sub).splitlines(True)
258 return lines 269 return lines
259 270
260 def wread(self, fname, data): 271 def wread(self, fname, data):
261 '''If in restricted mode returns data read from wdir with 272 '''If in restricted mode returns data read from wdir with
262 keyword substitutions removed.''' 273 keyword substitutions removed.'''