# HG changeset patch # User Yuya Nishihara # Date 2016-03-27 11:31:56 # Node ID 867d6ba2353dbe6fd6f688c772ca83524b7b33b2 # Parent 35da193481432f621325eb2693a6c331157d5c16 templater: add parsing and expansion rules to process "templatealias" section The debugtemplate command is updated to show expanded tree, but still the template engine doesn't support alias expansion. That's why the test says "parse error" for now. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -3671,8 +3671,12 @@ def debugtemplate(ui, repo, tmpl, **opts raise error.Abort(_('malformed keyword definition: %s') % d) if ui.verbose: + aliases = ui.configitems('templatealias') tree = templater.parse(tmpl) ui.note(templater.prettyformat(tree), '\n') + newtree = templater.expandaliases(tree, aliases) + if newtree != tree: + ui.note("* expanded:\n", templater.prettyformat(newtree), '\n') mapfile = None if revs is None: diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -872,6 +872,25 @@ exprmethods = { methods = exprmethods.copy() methods["integer"] = exprmethods["symbol"] # '{1}' as variable +class _aliasrules(parser.basealiasrules): + """Parsing and expansion rule set of template aliases""" + _section = _('template alias') + _parse = staticmethod(_parseexpr) + + @staticmethod + def _trygetfunc(tree): + """Return (name, args) if tree is func(...) or ...|filter; otherwise + None""" + if tree[0] == 'func' and tree[1][0] == 'symbol': + return tree[1][1], getlist(tree[2]) + if tree[0] == '|' and tree[2][0] == 'symbol': + return tree[2][1], [tree[1]] + +def expandaliases(tree, aliases): + """Return new tree of aliases are expanded""" + aliasmap = _aliasrules.buildmap(aliases) + return _aliasrules.expand(aliasmap, tree) + # template engine stringify = templatefilters.stringify diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -3654,6 +3654,100 @@ json filter should escape HTML tags so t $ hg log -T "{''|json}\n" -R a -l1 "\u003cfoo@example.org\u003e" +Templater supports aliases of symbol and func() styles: + + $ hg clone -q a aliases + $ cd aliases + $ cat <> .hg/hgrc + > [templatealias] + > r = rev + > rn = "{r}:{node|short}" + > status(c, files) = files % "{c} {file}\n" + > utcdate(d) = localdate(d, "UTC") + > EOF + + $ hg debugtemplate -vr0 '{rn} {utcdate(date)|isodate}\n' + (template + ('symbol', 'rn') + ('string', ' ') + (| + (func + ('symbol', 'utcdate') + ('symbol', 'date')) + ('symbol', 'isodate')) + ('string', '\n')) + * expanded: + (template + (template + ('symbol', 'rev') + ('string', ':') + (| + ('symbol', 'node') + ('symbol', 'short'))) + ('string', ' ') + (| + (func + ('symbol', 'localdate') + (list + ('symbol', 'date') + ('string', 'UTC'))) + ('symbol', 'isodate')) + ('string', '\n')) + hg: parse error: unknown function 'utcdate' + [255] + + $ hg debugtemplate -vr0 '{status("A", file_adds)}' + (template + (func + ('symbol', 'status') + (list + ('string', 'A') + ('symbol', 'file_adds')))) + * expanded: + (template + (% + ('symbol', 'file_adds') + (template + ('string', 'A') + ('string', ' ') + ('symbol', 'file') + ('string', '\n')))) + hg: parse error: unknown function 'status' + [255] + +A unary function alias can be called as a filter: + + $ hg debugtemplate -vr0 '{date|utcdate|isodate}\n' + (template + (| + (| + ('symbol', 'date') + ('symbol', 'utcdate')) + ('symbol', 'isodate')) + ('string', '\n')) + * expanded: + (template + (| + (func + ('symbol', 'localdate') + (list + ('symbol', 'date') + ('string', 'UTC'))) + ('symbol', 'isodate')) + ('string', '\n')) + hg: parse error: unknown function 'utcdate' + [255] + +Unparsable alias: + + $ hg debugtemplate --config templatealias.bad='x(' -v '{bad}' + (template + ('symbol', 'bad')) + abort: failed to parse the definition of template alias "bad": at 2: not a prefix: end + [255] + + $ cd .. + Set up repository for non-ascii encoding tests: $ hg init nonascii