formatter: populate fctx from ctx and path value
authorYuya Nishihara <yuya@tcha.org>
Sun, 29 Jul 2018 21:25:37 +0900
changeset 39586 b1239aeef4d9
parent 39585 990a0b071ea5
child 39587 918944f53aac
formatter: populate fctx from ctx and path value Tests will be added by the next patch.
mercurial/formatter.py
--- a/mercurial/formatter.py	Thu Jun 07 21:36:13 2018 +0900
+++ b/mercurial/formatter.py	Sun Jul 29 21:25:37 2018 +0900
@@ -543,6 +543,10 @@
         t.cache[''] = tmpl
     return t
 
+# marker to denote a resource to be loaded on demand based on mapping values
+# (e.g. (ctx, path) -> fctx)
+_placeholder = object()
+
 class templateresources(templater.resourcemapper):
     """Resource mapper designed for the default templatekw and function"""
 
@@ -563,7 +567,10 @@
     def lookup(self, mapping, key):
         if key not in self.knownkeys():
             return None
-        return self._getsome(mapping, key)
+        v = self._getsome(mapping, key)
+        if v is _placeholder:
+            v = mapping[key] = self._loadermap[key](self, mapping)
+        return v
 
     def populatemap(self, context, origmapping, newmapping):
         mapping = {}
@@ -572,6 +579,10 @@
         if self._hasnodespec(origmapping) and self._hasnodespec(newmapping):
             orignode = templateutil.runsymbol(context, origmapping, 'node')
             mapping['originalnode'] = orignode
+        # put marker to override 'fctx' in mapping if any, and flag
+        # its existence to be reported by availablekeys()
+        if 'fctx' not in newmapping and self._hasliteral(newmapping, 'path'):
+            mapping['fctx'] = _placeholder
         return mapping
 
     def _getsome(self, mapping, key):
@@ -580,10 +591,35 @@
             return v
         return self._resmap.get(key)
 
+    def _hasliteral(self, mapping, key):
+        """Test if a literal value is set or unset in the given mapping"""
+        return key in mapping and not callable(mapping[key])
+
+    def _getliteral(self, mapping, key):
+        """Return value of the given name if it is a literal"""
+        v = mapping.get(key)
+        if callable(v):
+            return None
+        return v
+
     def _hasnodespec(self, mapping):
         """Test if context revision is set or unset in the given mapping"""
         return 'node' in mapping or 'ctx' in mapping
 
+    def _loadfctx(self, mapping):
+        ctx = self._getsome(mapping, 'ctx')
+        path = self._getliteral(mapping, 'path')
+        if ctx is None or path is None:
+            return None
+        try:
+            return ctx[path]
+        except error.LookupError:
+            return None # maybe removed file?
+
+    _loadermap = {
+        'fctx': _loadfctx,
+    }
+
 def formatter(ui, out, topic, opts):
     template = opts.get("template", "")
     if template == "json":