# HG changeset patch # User Yuya Nishihara # Date 2018-06-08 13:10:22 # Node ID 8399438bc7ef7cdfcedb4a4e8ac2b834b70de69c # Parent aa98392eb5b006b3f06d927c699adf9494d8c1cb 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. diff --git a/mercurial/formatter.py b/mercurial/formatter.py --- a/mercurial/formatter.py +++ b/mercurial/formatter.py @@ -124,6 +124,7 @@ from . import ( error, pycompat, templatefilters, + templatefuncs, templatekw, templater, templateutil, @@ -192,6 +193,9 @@ class baseformatter(object): # 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 @@ class templateformatter(baseformatter): 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]