Patchwork [1,of,8] templater: add function that expands internal literal templates

login
register
mail settings
Submitter Yuya Nishihara
Date April 5, 2018, 2:37 p.m.
Message ID <befd68a9bd8bb3ee4e45.1522939039@mimosa>
Download mbox | patch
Permalink /patch/30376/
State Accepted
Headers show

Comments

Yuya Nishihara - April 5, 2018, 2:37 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1521295009 -32400
#      Sat Mar 17 22:56:49 2018 +0900
# Node ID befd68a9bd8bb3ee4e450d20e6e7d279464f3f36
# Parent  d3286dd2ca2f9f9e2b332e00c4b25b21729c54f5
templater: add function that expands internal literal templates

This will be used when rendering nested formatter items with the default
template, e.g.

  fm.nested('parents', tmpl='{rev}:{node|formatnode}', sep=' ')
                             ^^^^^^^^^^^^^^^^^^^^^^^
                             the default item template

Patch

diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -603,6 +603,7 @@  class engine(object):
         self._resources = resources
         self._aliasmap = _aliasrules.buildmap(aliases)
         self._cache = {}  # key: (func, data)
+        self._tmplcache = {}  # literal template: (func, data)
 
     def overlaymap(self, origmapping, newmapping):
         """Create combined mapping from the original mapping and partial
@@ -659,6 +660,13 @@  class engine(object):
                 raise
         return self._cache[t]
 
+    def _parse(self, tmpl):
+        """Parse and cache a literal template"""
+        if tmpl not in self._tmplcache:
+            x = parse(tmpl)
+            self._tmplcache[tmpl] = compileexp(x, self, methods)
+        return self._tmplcache[tmpl]
+
     def preload(self, t):
         """Load, parse, and cache the specified template if available"""
         try:
@@ -672,6 +680,18 @@  class engine(object):
         mapping contains added elements for use during expansion. Is a
         generator.'''
         func, data = self._load(t)
+        return self._expand(func, data, mapping)
+
+    def expand(self, tmpl, mapping):
+        """Perform expansion over a literal template
+
+        No user aliases will be expanded since this is supposed to be called
+        with an internal template string.
+        """
+        func, data = self._parse(tmpl)
+        return self._expand(func, data, mapping)
+
+    def _expand(self, func, data, mapping):
         # populate additional items only if they don't exist in the given
         # mapping. this is slightly different from overlaymap() because the
         # initial 'revcache' may contain pre-computed items.