hgkw/keyword.py
branchstable
changeset 855 eca16536349a
parent 854 3450d7f7d1a3
child 864 2cadbd48a31b
equal deleted inserted replaced
852:fb1e8925292d 855:eca16536349a
   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)
   189             ct.show(ctx, root=self.repo.root, file=path)
   200             ct.show(ctx, root=self.repo.root, file=path)
   190             ekw = templatefilters.firstline(self.ui.popbuffer())
   201             ekw = templatefilters.firstline(self.ui.popbuffer())
   191             return '$%s: %s $' % (kw, ekw)
   202             return '$%s: %s $' % (kw, ekw)
   192         return subfunc(kwsub, data)
   203         return subfunc(kwsub, data)
   193 
   204 
       
   205     def linkctx(self, path, fileid):
       
   206         '''Similar to filelog.linkrev, but returns a changectx.'''
       
   207         return self.repo.filectx(path, fileid=fileid).changectx()
       
   208 
   194     def expand(self, path, node, data):
   209     def expand(self, path, node, data):
   195         '''Returns data with keywords expanded.'''
   210         '''Returns data with keywords expanded.'''
   196         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):
   197             ctx = self.repo.filectx(path, fileid=node).changectx()
   212             ctx = self.linkctx(path, node)
   198             return self.substitute(data, path, ctx, self.re_kw.sub)
   213             return self.substitute(data, path, ctx, self.rekw.sub)
   199         return data
   214         return data
   200 
   215 
   201     def iskwfile(self, cand, ctx):
   216     def iskwfile(self, cand, ctx):
   202         '''Returns subset of candidates which are configured for keyword
   217         '''Returns subset of candidates which are configured for keyword
   203         expansion are not symbolic links.'''
   218         expansion are not symbolic links.'''
   210         if not candidates:
   225         if not candidates:
   211             return
   226             return
   212         kwcmd = self.restrict and lookup # kwexpand/kwshrink
   227         kwcmd = self.restrict and lookup # kwexpand/kwshrink
   213         if self.restrict or expand and lookup:
   228         if self.restrict or expand and lookup:
   214             mf = ctx.manifest()
   229             mf = ctx.manifest()
   215         fctx = ctx
   230         lctx = ctx
   216         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
   217         msg = (expand and _('overwriting %s expanding keywords\n')
   232         msg = (expand and _('overwriting %s expanding keywords\n')
   218                or _('overwriting %s shrinking keywords\n'))
   233                or _('overwriting %s shrinking keywords\n'))
   219         for f in candidates:
   234         for f in candidates:
   220             if self.restrict:
   235             if self.restrict:
   221                 data = self.repo.file(f).read(mf[f])
   236                 data = self.repo.file(f).read(mf[f])
   223                 data = self.repo.wread(f)
   238                 data = self.repo.wread(f)
   224             if util.binary(data):
   239             if util.binary(data):
   225                 continue
   240                 continue
   226             if expand:
   241             if expand:
   227                 if lookup:
   242                 if lookup:
   228                     fctx = self.repo.filectx(f, fileid=mf[f]).changectx()
   243                     lctx = self.linkctx(f, mf[f])
   229                 data, found = self.substitute(data, f, fctx, subn)
   244                 data, found = self.substitute(data, f, lctx, re_kw.subn)
   230             elif self.restrict:
   245             elif self.restrict:
   231                 found = self.re_kw.search(data)
   246                 found = re_kw.search(data)
   232             else:
   247             else:
   233                 data, found = _shrinktext(data, subn)
   248                 data, found = _shrinktext(data, re_kw.subn)
   234             if found:
   249             if found:
   235                 self.ui.note(msg % f)
   250                 self.ui.note(msg % f)
   236                 self.repo.wwrite(f, data, ctx.flags(f))
   251                 self.repo.wwrite(f, data, ctx.flags(f))
   237                 if kwcmd:
   252                 if kwcmd:
   238                     self.repo.dirstate.normal(f)
   253                     self.repo.dirstate.normal(f)
   240                     self.repo.dirstate.normallookup(f)
   255                     self.repo.dirstate.normallookup(f)
   241 
   256 
   242     def shrink(self, fname, text):
   257     def shrink(self, fname, text):
   243         '''Returns text with all keyword substitutions removed.'''
   258         '''Returns text with all keyword substitutions removed.'''
   244         if self.match(fname) and not util.binary(text):
   259         if self.match(fname) and not util.binary(text):
   245             return _shrinktext(text, self.re_kwexp.sub)
   260             return _shrinktext(text, self.rekwexp.sub)
   246         return text
   261         return text
   247 
   262 
   248     def shrinklines(self, fname, lines):
   263     def shrinklines(self, fname, lines):
   249         '''Returns lines with keyword substitutions removed.'''
   264         '''Returns lines with keyword substitutions removed.'''
   250         if self.match(fname):
   265         if self.match(fname):
   251             text = ''.join(lines)
   266             text = ''.join(lines)
   252             if not util.binary(text):
   267             if not util.binary(text):
   253                 return _shrinktext(text, self.re_kwexp.sub).splitlines(True)
   268                 return _shrinktext(text, self.rekwexp.sub).splitlines(True)
   254         return lines
   269         return lines
   255 
   270 
   256     def wread(self, fname, data):
   271     def wread(self, fname, data):
   257         '''If in restricted mode returns data read from wdir with
   272         '''If in restricted mode returns data read from wdir with
   258         keyword substitutions removed.'''
   273         keyword substitutions removed.'''