[PATCH 1 of 2 resend] keyword: compile regexes on demand

Christian Ebert blacktrash at gmx.net
Wed Nov 3 10:06:32 CDT 2010


# HG changeset patch
# User Christian Ebert <blacktrash at gmx.net>
# Date 1288791461 -3600
# Node ID 2ce1ff53e29f4b775ed550c13beb42da3942523e
# Parent  0e0a52bd58f941c00b2a1d57f23676fa486e58c3
keyword: compile regexes on demand

diff --git a/hgext/keyword.py b/hgext/keyword.py
--- a/hgext/keyword.py
+++ b/hgext/keyword.py
@@ -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):
@@ -195,7 +209,7 @@
         '''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)
+            return self.substitute(data, path, ctx, self.rekw().sub)
         return data
 
     def iskwfile(self, cand, ctx):
@@ -213,7 +227,7 @@
         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
+        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:
@@ -226,11 +240,11 @@
             if expand:
                 if lookup:
                     fctx = self.repo.filectx(f, fileid=mf[f]).changectx()
-                data, found = self.substitute(data, f, fctx, subn)
+                data, found = self.substitute(data, f, fctx, 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 +256,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 +264,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):


More information about the Mercurial-devel mailing list