[PATCH 2 of 5] formatter: make nested items somewhat readable in template output
Yuya Nishihara
yuya at tcha.org
Sat Apr 7 05:05:41 EDT 2018
# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1521120436 -32400
# Thu Mar 15 22:27:16 2018 +0900
# Node ID 8a79a82137c6a5af4d88e32ec6646db6539e6d60
# Parent 1f9fba66207ee223814feb4e9702d09522542f3d
formatter: make nested items somewhat readable in template output
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -386,7 +386,7 @@ def annotate(ui, repo, *pats, **opts):
% ((pats and m.rel(abs)) or abs))
continue
- fm = rootfm.nested('lines')
+ fm = rootfm.nested('lines', tmpl='{rev}: {line}')
lines = fctx.annotate(follow=follow, skiprevs=skiprevs,
diffopts=diffopts)
if not lines:
@@ -2505,7 +2505,7 @@ def grep(ui, repo, pattern, *pats, **opt
if not opts.get('text') and binary():
fm.plain(_(" Binary file matches"))
else:
- displaymatches(fm.nested('texts'), l)
+ displaymatches(fm.nested('texts', tmpl='{text}'), l)
fm.plain(eol)
found = True
if opts.get('files_with_matches'):
@@ -2847,7 +2847,7 @@ def identify(ui, repo, source=None, rev=
numoutput = ["%d" % p.rev() for p in parents]
output.append("%s%s" % ('+'.join(numoutput), dirty))
- fn = fm.nested('parents')
+ fn = fm.nested('parents', tmpl='{rev}:{node|formatnode}', sep=' ')
for p in parents:
fn.startitem()
fn.data(rev=p.rev())
@@ -5608,7 +5608,7 @@ def version_(ui, **opts):
names.append(name)
vers.append(extensions.moduleversion(module) or None)
isinternals.append(extensions.ismoduleinternal(module))
- fn = fm.nested("extensions")
+ fn = fm.nested("extensions", tmpl='{name}\n')
if names:
namefmt = " %%-%ds " % max(len(n) for n in names)
places = [_("external"), _("internal")]
diff --git a/mercurial/formatter.py b/mercurial/formatter.py
--- a/mercurial/formatter.py
+++ b/mercurial/formatter.py
@@ -95,7 +95,7 @@ Nested example:
>>> def subrepos(ui, fm):
... fm.startitem()
... fm.write(b'reponame', b'[%s]\\n', b'baz')
-... files(ui, fm.nested(b'files'))
+... files(ui, fm.nested(b'files', tmpl=b'{reponame}'))
... fm.end()
>>> show(subrepos)
[baz]
@@ -138,6 +138,10 @@ class _nullconverter(object):
storecontext = False
@staticmethod
+ def wrapnested(data, tmpl, sep):
+ '''wrap nested data by appropriate type'''
+ return data
+ @staticmethod
def formatdate(date, fmt):
'''convert date tuple to appropriate format'''
return date
@@ -210,9 +214,10 @@ class baseformatter(object):
def isplain(self):
'''check for plain formatter usage'''
return False
- def nested(self, field):
+ def nested(self, field, tmpl=None, sep=''):
'''sub formatter to store nested data in the specified field'''
- self._item[field] = data = []
+ data = []
+ self._item[field] = self._converter.wrapnested(data, tmpl, sep)
return _nestedformatter(self._ui, self._converter, data)
def end(self):
'''end output for the formatter'''
@@ -243,6 +248,9 @@ class _plainconverter(object):
storecontext = False
@staticmethod
+ def wrapnested(data, tmpl, sep):
+ raise error.ProgrammingError('plainformatter should never be nested')
+ @staticmethod
def formatdate(date, fmt):
'''stringify date tuple in the given format'''
return dateutil.datestr(date, fmt)
@@ -290,7 +298,7 @@ class plainformatter(baseformatter):
self._write(text, **opts)
def isplain(self):
return True
- def nested(self, field):
+ def nested(self, field, tmpl=None, sep=''):
# nested data will be directly written to ui
return self
def end(self):
@@ -350,6 +358,10 @@ class _templateconverter(object):
storecontext = True
@staticmethod
+ def wrapnested(data, tmpl, sep):
+ '''wrap nested data by templatable type'''
+ return templateutil.mappinglist(data, tmpl=tmpl, sep=sep)
+ @staticmethod
def formatdate(date, fmt):
'''return date tuple'''
return date
diff --git a/tests/test-annotate.t b/tests/test-annotate.t
--- a/tests/test-annotate.t
+++ b/tests/test-annotate.t
@@ -90,6 +90,28 @@ log-like templating
> EOF
$ hg ci -mb2 -d '2 0'
+default output of '{lines}' should be readable
+
+ $ hg annotate -T'{lines}' a
+ 0: a
+ 1: a
+ 1: a
+ $ hg annotate -T'{join(lines, "\n")}' a
+ 0: a
+
+ 1: a
+
+ 1: a
+
+several filters can be applied to '{lines}'
+
+ $ hg annotate -T'{lines|stringify}' a
+ 0: a
+ 1: a
+ 1: a
+ $ hg annotate -T'{lines|count}\n' a
+ 3
+
annotate multiple files (JSON)
$ hg annotate -Tjson a b
diff --git a/tests/test-extension.t b/tests/test-extension.t
--- a/tests/test-extension.t
+++ b/tests/test-extension.t
@@ -1407,6 +1407,11 @@ Test version number support in 'hg versi
$ hg version -q --config extensions.throw=throw.py
Mercurial Distributed SCM (version *) (glob)
+Test template output:
+
+ $ hg version --config extensions.strip= -T'{extensions}'
+ strip
+
Test JSON output of version:
$ hg version -Tjson
diff --git a/tests/test-grep.t b/tests/test-grep.t
--- a/tests/test-grep.t
+++ b/tests/test-grep.t
@@ -48,6 +48,11 @@ simple templated
port:4:914fa752cdea:vaPORTight
port:4:914fa752cdea:imPORT/exPORT
+ $ hg grep port -T '{file}:{rev}:{texts}\n'
+ port:4:export
+ port:4:vaportight
+ port:4:import/export
+
simple JSON (no "change" field)
$ hg grep -Tjson port
diff --git a/tests/test-identify.t b/tests/test-identify.t
--- a/tests/test-identify.t
+++ b/tests/test-identify.t
@@ -62,6 +62,8 @@ test template keywords and functions whi
2147483647 ffff
$ hg id -T '{parents % "{rev} {node|shortest} {desc}\n"}'
0 cb9a a
+ $ hg id -T '{parents}\n'
+ 0:cb9a9f314b8b
test nested template: '{tags}'/'{node}' constants shouldn't override the
default keywords, but '{id}' persists because there's no default keyword
More information about the Mercurial-devel
mailing list