##// END OF EJS Templates
formatter: make nested items somewhat readable in template output
Yuya Nishihara -
r37518:8bb3899a default
parent child Browse files
Show More
@@ -386,7 +386,7 b' def annotate(ui, repo, *pats, **opts):'
386 % ((pats and m.rel(abs)) or abs))
386 % ((pats and m.rel(abs)) or abs))
387 continue
387 continue
388
388
389 fm = rootfm.nested('lines')
389 fm = rootfm.nested('lines', tmpl='{rev}: {line}')
390 lines = fctx.annotate(follow=follow, skiprevs=skiprevs,
390 lines = fctx.annotate(follow=follow, skiprevs=skiprevs,
391 diffopts=diffopts)
391 diffopts=diffopts)
392 if not lines:
392 if not lines:
@@ -2506,7 +2506,7 b' def grep(ui, repo, pattern, *pats, **opt'
2506 if not opts.get('text') and binary():
2506 if not opts.get('text') and binary():
2507 fm.plain(_(" Binary file matches"))
2507 fm.plain(_(" Binary file matches"))
2508 else:
2508 else:
2509 displaymatches(fm.nested('texts'), l)
2509 displaymatches(fm.nested('texts', tmpl='{text}'), l)
2510 fm.plain(eol)
2510 fm.plain(eol)
2511 found = True
2511 found = True
2512 if opts.get('files_with_matches'):
2512 if opts.get('files_with_matches'):
@@ -2848,7 +2848,7 b' def identify(ui, repo, source=None, rev='
2848 numoutput = ["%d" % p.rev() for p in parents]
2848 numoutput = ["%d" % p.rev() for p in parents]
2849 output.append("%s%s" % ('+'.join(numoutput), dirty))
2849 output.append("%s%s" % ('+'.join(numoutput), dirty))
2850
2850
2851 fn = fm.nested('parents')
2851 fn = fm.nested('parents', tmpl='{rev}:{node|formatnode}', sep=' ')
2852 for p in parents:
2852 for p in parents:
2853 fn.startitem()
2853 fn.startitem()
2854 fn.data(rev=p.rev())
2854 fn.data(rev=p.rev())
@@ -5615,7 +5615,7 b' def version_(ui, **opts):'
5615 names.append(name)
5615 names.append(name)
5616 vers.append(extensions.moduleversion(module) or None)
5616 vers.append(extensions.moduleversion(module) or None)
5617 isinternals.append(extensions.ismoduleinternal(module))
5617 isinternals.append(extensions.ismoduleinternal(module))
5618 fn = fm.nested("extensions")
5618 fn = fm.nested("extensions", tmpl='{name}\n')
5619 if names:
5619 if names:
5620 namefmt = " %%-%ds " % max(len(n) for n in names)
5620 namefmt = " %%-%ds " % max(len(n) for n in names)
5621 places = [_("external"), _("internal")]
5621 places = [_("external"), _("internal")]
@@ -95,7 +95,7 b' Nested example:'
95 >>> def subrepos(ui, fm):
95 >>> def subrepos(ui, fm):
96 ... fm.startitem()
96 ... fm.startitem()
97 ... fm.write(b'reponame', b'[%s]\\n', b'baz')
97 ... fm.write(b'reponame', b'[%s]\\n', b'baz')
98 ... files(ui, fm.nested(b'files'))
98 ... files(ui, fm.nested(b'files', tmpl=b'{reponame}'))
99 ... fm.end()
99 ... fm.end()
100 >>> show(subrepos)
100 >>> show(subrepos)
101 [baz]
101 [baz]
@@ -138,6 +138,10 b' class _nullconverter(object):'
138 storecontext = False
138 storecontext = False
139
139
140 @staticmethod
140 @staticmethod
141 def wrapnested(data, tmpl, sep):
142 '''wrap nested data by appropriate type'''
143 return data
144 @staticmethod
141 def formatdate(date, fmt):
145 def formatdate(date, fmt):
142 '''convert date tuple to appropriate format'''
146 '''convert date tuple to appropriate format'''
143 return date
147 return date
@@ -210,9 +214,10 b' class baseformatter(object):'
210 def isplain(self):
214 def isplain(self):
211 '''check for plain formatter usage'''
215 '''check for plain formatter usage'''
212 return False
216 return False
213 def nested(self, field):
217 def nested(self, field, tmpl=None, sep=''):
214 '''sub formatter to store nested data in the specified field'''
218 '''sub formatter to store nested data in the specified field'''
215 self._item[field] = data = []
219 data = []
220 self._item[field] = self._converter.wrapnested(data, tmpl, sep)
216 return _nestedformatter(self._ui, self._converter, data)
221 return _nestedformatter(self._ui, self._converter, data)
217 def end(self):
222 def end(self):
218 '''end output for the formatter'''
223 '''end output for the formatter'''
@@ -243,6 +248,9 b' class _plainconverter(object):'
243 storecontext = False
248 storecontext = False
244
249
245 @staticmethod
250 @staticmethod
251 def wrapnested(data, tmpl, sep):
252 raise error.ProgrammingError('plainformatter should never be nested')
253 @staticmethod
246 def formatdate(date, fmt):
254 def formatdate(date, fmt):
247 '''stringify date tuple in the given format'''
255 '''stringify date tuple in the given format'''
248 return dateutil.datestr(date, fmt)
256 return dateutil.datestr(date, fmt)
@@ -290,7 +298,7 b' class plainformatter(baseformatter):'
290 self._write(text, **opts)
298 self._write(text, **opts)
291 def isplain(self):
299 def isplain(self):
292 return True
300 return True
293 def nested(self, field):
301 def nested(self, field, tmpl=None, sep=''):
294 # nested data will be directly written to ui
302 # nested data will be directly written to ui
295 return self
303 return self
296 def end(self):
304 def end(self):
@@ -350,6 +358,10 b' class _templateconverter(object):'
350 storecontext = True
358 storecontext = True
351
359
352 @staticmethod
360 @staticmethod
361 def wrapnested(data, tmpl, sep):
362 '''wrap nested data by templatable type'''
363 return templateutil.mappinglist(data, tmpl=tmpl, sep=sep)
364 @staticmethod
353 def formatdate(date, fmt):
365 def formatdate(date, fmt):
354 '''return date tuple'''
366 '''return date tuple'''
355 return date
367 return date
@@ -90,6 +90,28 b' log-like templating'
90 > EOF
90 > EOF
91 $ hg ci -mb2 -d '2 0'
91 $ hg ci -mb2 -d '2 0'
92
92
93 default output of '{lines}' should be readable
94
95 $ hg annotate -T'{lines}' a
96 0: a
97 1: a
98 1: a
99 $ hg annotate -T'{join(lines, "\n")}' a
100 0: a
101
102 1: a
103
104 1: a
105
106 several filters can be applied to '{lines}'
107
108 $ hg annotate -T'{lines|stringify}' a
109 0: a
110 1: a
111 1: a
112 $ hg annotate -T'{lines|count}\n' a
113 3
114
93 annotate multiple files (JSON)
115 annotate multiple files (JSON)
94
116
95 $ hg annotate -Tjson a b
117 $ hg annotate -Tjson a b
@@ -1407,6 +1407,11 b" Test version number support in 'hg versi"
1407 $ hg version -q --config extensions.throw=throw.py
1407 $ hg version -q --config extensions.throw=throw.py
1408 Mercurial Distributed SCM (version *) (glob)
1408 Mercurial Distributed SCM (version *) (glob)
1409
1409
1410 Test template output:
1411
1412 $ hg version --config extensions.strip= -T'{extensions}'
1413 strip
1414
1410 Test JSON output of version:
1415 Test JSON output of version:
1411
1416
1412 $ hg version -Tjson
1417 $ hg version -Tjson
@@ -48,6 +48,11 b' simple templated'
48 port:4:914fa752cdea:vaPORTight
48 port:4:914fa752cdea:vaPORTight
49 port:4:914fa752cdea:imPORT/exPORT
49 port:4:914fa752cdea:imPORT/exPORT
50
50
51 $ hg grep port -T '{file}:{rev}:{texts}\n'
52 port:4:export
53 port:4:vaportight
54 port:4:import/export
55
51 simple JSON (no "change" field)
56 simple JSON (no "change" field)
52
57
53 $ hg grep -Tjson port
58 $ hg grep -Tjson port
@@ -62,6 +62,8 b' test template keywords and functions whi'
62 2147483647 ffff
62 2147483647 ffff
63 $ hg id -T '{parents % "{rev} {node|shortest} {desc}\n"}'
63 $ hg id -T '{parents % "{rev} {node|shortest} {desc}\n"}'
64 0 cb9a a
64 0 cb9a a
65 $ hg id -T '{parents}\n'
66 0:cb9a9f314b8b
65
67
66 test nested template: '{tags}'/'{node}' constants shouldn't override the
68 test nested template: '{tags}'/'{node}' constants shouldn't override the
67 default keywords, but '{id}' persists because there's no default keyword
69 default keywords, but '{id}' persists because there's no default keyword
General Comments 0
You need to be logged in to leave comments. Login now