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 |
|
|
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