Patchwork [5,of,6] formatter: populate fctx from ctx and path value

login
register
mail settings
Submitter Yuya Nishihara
Date Sept. 2, 2018, 7:43 a.m.
Message ID <699afc590069f20c593f.1535874182@mimosa>
Download mbox | patch
Permalink /patch/34250/
State New
Headers show

Comments

Yuya Nishihara - Sept. 2, 2018, 7:43 a.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1532867137 -32400
#      Sun Jul 29 21:25:37 2018 +0900
# Node ID 699afc590069f20c593f3f45c0fdc7395d567a19
# Parent  a216d798fdd777f6f06306dcdf4e6ee487fdddf6
formatter: populate fctx from ctx and path value

Tests will be added by the next patch.

Patch

diff --git a/mercurial/formatter.py b/mercurial/formatter.py
--- a/mercurial/formatter.py
+++ b/mercurial/formatter.py
@@ -543,6 +543,10 @@  def maketemplater(ui, tmpl, defaults=Non
         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 @@  class templateresources(templater.resour
     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 @@  class templateresources(templater.resour
         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 @@  class templateresources(templater.resour
             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":