# HG changeset patch # User Christian Ebert # Date 1288174531 -3600 # Node ID 211c681fd63453fbc8c947761a8cd5e6ac39d4cc # Parent f7b34429edb71e6e6ad2d518c1f0e6457dc95bd8# Parent 3c5de8747a32830441bfea885a44fe2a11eac95c Merge with stable diff -r 3c5de8747a32 -r 211c681fd634 hgkw/keyword.py --- a/hgkw/keyword.py Wed Oct 20 17:38:21 2010 -0500 +++ b/hgkw/keyword.py Wed Oct 27 11:15:31 2010 +0100 @@ -163,6 +163,8 @@ self.match = match.match(repo.root, '', [], inc, exc) self.restrict = kwtools['hgcmd'] in restricted.split() self.record = False + self.re_kw = None + self.re_kwexp = None kwmaps = self.ui.configitems('keywordmaps') if kwmaps: # override default templates @@ -170,14 +172,26 @@ for k, v in kwmaps) else: self.templates = _defaultkwmaps(self.ui) - escaped = '|'.join(map(re.escape, self.templates.keys())) - self.re_kw = re.compile(r'\$(%s)\$' % escaped) - self.re_kwexp = re.compile(r'\$(%s): [^$\n\r]*? \$' % escaped) - templatefilters.filters.update({'utcdate': utcdate, 'svnisodate': svnisodate, 'svnutcdate': svnutcdate}) + def escape(self): + '''Returns bar-separated list of keywords.''' + return '|'.join(map(re.escape, self.templates.keys())) + + def rekw(self): + '''Compiles regex for unexpanded keywords on demand.''' + if self.re_kw is None: + self.re_kw = re.compile(r'\$(%s)\$' % self.escape()) + return self.re_kw + + def rekwexp(self): + '''Compiles regex for expanded keywords on demand.''' + if self.re_kwexp is None: + self.re_kwexp = re.compile(r'\$(%s): [^$\n\r]*? \$' % self.escape()) + return self.re_kwexp + def substitute(self, data, path, ctx, subfunc): '''Replaces keywords in data with expanded template.''' def kwsub(mobj): @@ -191,11 +205,15 @@ return '$%s: %s $' % (kw, ekw) return subfunc(kwsub, data) + def linkctx(self, path, fileid): + '''Similar to filelog.linkrev, but returns a changectx.''' + return self.repo.filectx(path, fileid=fileid).changectx() + def expand(self, path, node, data): '''Returns data with keywords expanded.''' if not self.restrict and self.match(path) and not util.binary(data): - ctx = self.repo.filectx(path, fileid=node).changectx() - return self.substitute(data, path, ctx, self.re_kw.sub) + ctx = self.linkctx(path, node) + return self.substitute(data, path, ctx, self.rekw().sub) return data def iskwfile(self, cand, ctx): @@ -212,8 +230,8 @@ kwcmd = self.restrict and lookup # kwexpand/kwshrink if self.restrict or expand and lookup: mf = ctx.manifest() - fctx = ctx - subn = (self.restrict or rekw) and self.re_kw.subn or self.re_kwexp.subn + lctx = ctx + re_kw = (self.restrict or rekw) and self.rekw() or self.rekwexp() msg = (expand and _('overwriting %s expanding keywords\n') or _('overwriting %s shrinking keywords\n')) for f in candidates: @@ -225,12 +243,12 @@ continue if expand: if lookup: - fctx = self.repo.filectx(f, fileid=mf[f]).changectx() - data, found = self.substitute(data, f, fctx, subn) + lctx = self.linkctx(f, mf[f]) + data, found = self.substitute(data, f, lctx, re_kw.subn) elif self.restrict: - found = self.re_kw.search(data) + found = re_kw.search(data) else: - data, found = _shrinktext(data, subn) + data, found = _shrinktext(data, re_kw.subn) if found: self.ui.note(msg % f) self.repo.wwrite(f, data, ctx.flags(f)) @@ -242,7 +260,7 @@ def shrink(self, fname, text): '''Returns text with all keyword substitutions removed.''' if self.match(fname) and not util.binary(text): - return _shrinktext(text, self.re_kwexp.sub) + return _shrinktext(text, self.rekwexp().sub) return text def shrinklines(self, fname, lines): @@ -250,7 +268,7 @@ if self.match(fname): text = ''.join(lines) if not util.binary(text): - return _shrinktext(text, self.re_kwexp.sub).splitlines(True) + return _shrinktext(text, self.rekwexp().sub).splitlines(True) return lines def wread(self, fname, data):