@@ -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:
@@ -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
@@ -3654,6 +3654,100 @@ json filter should escape HTML tags so t
$ hg log -T "{'<foo@example.org>'|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 <<EOF >> .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