formatter: provide hint of context keys required by template
This allows us to create ctx objects only if necessary.
I tried another idea which is to populate ctx from 'repo' and 'node' value
on demand. It worked, but seemed unnecessarily complicated. So I chose a
simpler one.
The datafields argument is a space-separated string for consistency with
fm.write() API.
--- a/mercurial/formatter.py Thu Jun 14 21:18:58 2018 +0900
+++ b/mercurial/formatter.py Fri Jun 08 22:10:22 2018 +0900
@@ -124,6 +124,7 @@
error,
pycompat,
templatefilters,
+ templatefuncs,
templatekw,
templater,
templateutil,
@@ -192,6 +193,9 @@
# name is mandatory argument for now, but it could be optional if
# we have default template keyword, e.g. {item}
return self._converter.formatlist(data, name, fmt, sep)
+ def contexthint(self, datafields):
+ '''set of context object keys to be required given datafields set'''
+ return set()
def context(self, **ctxs):
'''insert context objects to be used to render template keywords'''
ctxs = pycompat.byteskwargs(ctxs)
@@ -418,6 +422,24 @@
def _symbolsused(self):
return self._t.symbolsuseddefault()
+ def contexthint(self, datafields):
+ '''set of context object keys to be required by the template, given
+ datafields overridden by immediate values'''
+ requires = set()
+ ksyms, fsyms = self._symbolsused
+ ksyms = ksyms - set(datafields.split()) # exclude immediate fields
+ symtables = [(ksyms, templatekw.keywords),
+ (fsyms, templatefuncs.funcs)]
+ for syms, table in symtables:
+ for k in syms:
+ f = table.get(k)
+ if not f:
+ continue
+ requires.update(getattr(f, '_requires', ()))
+ if 'repo' in requires:
+ requires.add('ctx') # there's no API to pass repo to formatter
+ return requires & {'ctx', 'fctx'}
+
def datahint(self):
'''set of field names to be referenced from the template'''
return self._symbolsused[0]