Mercurial > hg
comparison mercurial/templatekw.py @ 37068:aa97e06a1912
templater: use template context to render old-style list template
Prepares for dropping the 'templ' resource.
This means old-style list templates are processed by the same engine class
as the one for the list node. I think that's fine since templates for the
same list should be tightly coupled, and I believe the extension point for
the engine classes isn't actually used.
Now templatekw._showlist() is a compatibility wrapper for _showcompatlist(),
and will be deprecated soon. The function is still marked as private since
I plan to change the interface to get rid of closures capturing context and
mapping.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Fri, 16 Mar 2018 22:47:15 +0900 |
parents | c97b936d8bb5 |
children | 724f2e21d870 |
comparison
equal
deleted
inserted
replaced
37067:04aafcec00b9 | 37068:aa97e06a1912 |
---|---|
27 util, | 27 util, |
28 ) | 28 ) |
29 | 29 |
30 _hybrid = templateutil.hybrid | 30 _hybrid = templateutil.hybrid |
31 _mappable = templateutil.mappable | 31 _mappable = templateutil.mappable |
32 _showlist = templateutil._showlist | |
33 hybriddict = templateutil.hybriddict | 32 hybriddict = templateutil.hybriddict |
34 hybridlist = templateutil.hybridlist | 33 hybridlist = templateutil.hybridlist |
35 compatdict = templateutil.compatdict | 34 compatdict = templateutil.compatdict |
36 compatlist = templateutil.compatlist | 35 compatlist = templateutil.compatlist |
36 _showcompatlist = templateutil._showcompatlist | |
37 | |
38 # TODO: temporary hack for porting; will be removed soon | |
39 class _fakecontextwrapper(object): | |
40 def __init__(self, templ): | |
41 self._templ = templ | |
42 | |
43 def preload(self, t): | |
44 return t in self._templ | |
45 | |
46 def process(self, t, mapping): | |
47 return self._templ.generatenamed(t, mapping) | |
48 | |
49 def _showlist(name, values, templ, mapping, plural=None, separator=' '): | |
50 context = _fakecontextwrapper(templ) | |
51 return _showcompatlist(context, mapping, name, values, plural, separator) | |
37 | 52 |
38 def showdict(name, data, mapping, plural=None, key='key', value='value', | 53 def showdict(name, data, mapping, plural=None, key='key', value='value', |
39 fmt=None, separator=' '): | 54 fmt=None, separator=' '): |
40 ui = mapping.get('ui') | 55 ui = mapping.get('ui') |
41 if ui: | 56 if ui: |
201 committed. | 216 committed. |
202 """ | 217 """ |
203 ctx = context.resource(mapping, 'ctx') | 218 ctx = context.resource(mapping, 'ctx') |
204 return ctx.branch() | 219 return ctx.branch() |
205 | 220 |
206 @templatekeyword('branches', requires={'ctx', 'templ'}) | 221 @templatekeyword('branches', requires={'ctx'}) |
207 def showbranches(context, mapping): | 222 def showbranches(context, mapping): |
208 """List of strings. The name of the branch on which the | 223 """List of strings. The name of the branch on which the |
209 changeset was committed. Will be empty if the branch name was | 224 changeset was committed. Will be empty if the branch name was |
210 default. (DEPRECATED) | 225 default. (DEPRECATED) |
211 """ | 226 """ |
228 active = repo._activebookmark | 243 active = repo._activebookmark |
229 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active} | 244 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active} |
230 f = _showlist('bookmark', bookmarks, templ, mapping) | 245 f = _showlist('bookmark', bookmarks, templ, mapping) |
231 return _hybrid(f, bookmarks, makemap, pycompat.identity) | 246 return _hybrid(f, bookmarks, makemap, pycompat.identity) |
232 | 247 |
233 @templatekeyword('children', requires={'ctx', 'templ'}) | 248 @templatekeyword('children', requires={'ctx'}) |
234 def showchildren(context, mapping): | 249 def showchildren(context, mapping): |
235 """List of strings. The children of the changeset.""" | 250 """List of strings. The children of the changeset.""" |
236 ctx = context.resource(mapping, 'ctx') | 251 ctx = context.resource(mapping, 'ctx') |
237 childrevs = ['%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()] | 252 childrevs = ['%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()] |
238 return compatlist(context, mapping, 'children', childrevs, element='child') | 253 return compatlist(context, mapping, 'children', childrevs, element='child') |
279 ctx = context.resource(mapping, 'ctx') | 294 ctx = context.resource(mapping, 'ctx') |
280 stats = patch.diffstatdata(util.iterlines(ctx.diff(noprefix=False))) | 295 stats = patch.diffstatdata(util.iterlines(ctx.diff(noprefix=False))) |
281 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats) | 296 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats) |
282 return '%d: +%d/-%d' % (len(stats), adds, removes) | 297 return '%d: +%d/-%d' % (len(stats), adds, removes) |
283 | 298 |
284 @templatekeyword('envvars', requires={'ui', 'templ'}) | 299 @templatekeyword('envvars', requires={'ui'}) |
285 def showenvvars(context, mapping): | 300 def showenvvars(context, mapping): |
286 """A dictionary of environment variables. (EXPERIMENTAL)""" | 301 """A dictionary of environment variables. (EXPERIMENTAL)""" |
287 ui = context.resource(mapping, 'ui') | 302 ui = context.resource(mapping, 'ui') |
288 env = ui.exportableenviron() | 303 env = ui.exportableenviron() |
289 env = util.sortdict((k, env[k]) for k in sorted(env)) | 304 env = util.sortdict((k, env[k]) for k in sorted(env)) |
310 if 'files' not in revcache: | 325 if 'files' not in revcache: |
311 revcache['files'] = repo.status(ctx.p1(), ctx)[:3] | 326 revcache['files'] = repo.status(ctx.p1(), ctx)[:3] |
312 files = revcache['files'][index] | 327 files = revcache['files'][index] |
313 return compatlist(context, mapping, name, files, element='file') | 328 return compatlist(context, mapping, name, files, element='file') |
314 | 329 |
315 @templatekeyword('file_adds', requires={'repo', 'ctx', 'revcache', 'templ'}) | 330 @templatekeyword('file_adds', requires={'repo', 'ctx', 'revcache'}) |
316 def showfileadds(context, mapping): | 331 def showfileadds(context, mapping): |
317 """List of strings. Files added by this changeset.""" | 332 """List of strings. Files added by this changeset.""" |
318 return _showfilesbystat(context, mapping, 'file_add', 1) | 333 return _showfilesbystat(context, mapping, 'file_add', 1) |
319 | 334 |
320 @templatekeyword('file_copies', | 335 @templatekeyword('file_copies', |
321 requires={'repo', 'ctx', 'cache', 'revcache', 'templ'}) | 336 requires={'repo', 'ctx', 'cache', 'revcache'}) |
322 def showfilecopies(context, mapping): | 337 def showfilecopies(context, mapping): |
323 """List of strings. Files copied in this changeset with | 338 """List of strings. Files copied in this changeset with |
324 their sources. | 339 their sources. |
325 """ | 340 """ |
326 repo = context.resource(mapping, 'repo') | 341 repo = context.resource(mapping, 'repo') |
343 plural='file_copies') | 358 plural='file_copies') |
344 | 359 |
345 # showfilecopiesswitch() displays file copies only if copy records are | 360 # showfilecopiesswitch() displays file copies only if copy records are |
346 # provided before calling the templater, usually with a --copies | 361 # provided before calling the templater, usually with a --copies |
347 # command line switch. | 362 # command line switch. |
348 @templatekeyword('file_copies_switch', requires={'revcache', 'templ'}) | 363 @templatekeyword('file_copies_switch', requires={'revcache'}) |
349 def showfilecopiesswitch(context, mapping): | 364 def showfilecopiesswitch(context, mapping): |
350 """List of strings. Like "file_copies" but displayed | 365 """List of strings. Like "file_copies" but displayed |
351 only if the --copied switch is set. | 366 only if the --copied switch is set. |
352 """ | 367 """ |
353 copies = context.resource(mapping, 'revcache').get('copies') or [] | 368 copies = context.resource(mapping, 'revcache').get('copies') or [] |
354 copies = util.sortdict(copies) | 369 copies = util.sortdict(copies) |
355 return compatdict(context, mapping, 'file_copy', copies, | 370 return compatdict(context, mapping, 'file_copy', copies, |
356 key='name', value='source', fmt='%s (%s)', | 371 key='name', value='source', fmt='%s (%s)', |
357 plural='file_copies') | 372 plural='file_copies') |
358 | 373 |
359 @templatekeyword('file_dels', requires={'repo', 'ctx', 'revcache', 'templ'}) | 374 @templatekeyword('file_dels', requires={'repo', 'ctx', 'revcache'}) |
360 def showfiledels(context, mapping): | 375 def showfiledels(context, mapping): |
361 """List of strings. Files removed by this changeset.""" | 376 """List of strings. Files removed by this changeset.""" |
362 return _showfilesbystat(context, mapping, 'file_del', 2) | 377 return _showfilesbystat(context, mapping, 'file_del', 2) |
363 | 378 |
364 @templatekeyword('file_mods', requires={'repo', 'ctx', 'revcache', 'templ'}) | 379 @templatekeyword('file_mods', requires={'repo', 'ctx', 'revcache'}) |
365 def showfilemods(context, mapping): | 380 def showfilemods(context, mapping): |
366 """List of strings. Files modified by this changeset.""" | 381 """List of strings. Files modified by this changeset.""" |
367 return _showfilesbystat(context, mapping, 'file_mod', 0) | 382 return _showfilesbystat(context, mapping, 'file_mod', 0) |
368 | 383 |
369 @templatekeyword('files', requires={'ctx', 'templ'}) | 384 @templatekeyword('files', requires={'ctx'}) |
370 def showfiles(context, mapping): | 385 def showfiles(context, mapping): |
371 """List of strings. All files modified, added, or removed by this | 386 """List of strings. All files modified, added, or removed by this |
372 changeset. | 387 changeset. |
373 """ | 388 """ |
374 ctx = context.resource(mapping, 'ctx') | 389 ctx = context.resource(mapping, 'ctx') |
463 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset | 478 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset |
464 | 479 |
465 # teach templater latesttags.changes is switched to (context, mapping) API | 480 # teach templater latesttags.changes is switched to (context, mapping) API |
466 _showchangessincetag._requires = {'repo', 'ctx'} | 481 _showchangessincetag._requires = {'repo', 'ctx'} |
467 | 482 |
468 @templatekeyword('manifest', requires={'repo', 'ctx', 'templ'}) | 483 @templatekeyword('manifest', requires={'repo', 'ctx'}) |
469 def showmanifest(context, mapping): | 484 def showmanifest(context, mapping): |
470 repo = context.resource(mapping, 'repo') | 485 repo = context.resource(mapping, 'repo') |
471 ctx = context.resource(mapping, 'ctx') | 486 ctx = context.resource(mapping, 'ctx') |
472 templ = context.resource(mapping, 'templ') | |
473 mnode = ctx.manifestnode() | 487 mnode = ctx.manifestnode() |
474 if mnode is None: | 488 if mnode is None: |
475 # just avoid crash, we might want to use the 'ff...' hash in future | 489 # just avoid crash, we might want to use the 'ff...' hash in future |
476 return | 490 return |
477 mrev = repo.manifestlog._revlog.rev(mnode) | 491 mrev = repo.manifestlog._revlog.rev(mnode) |
478 mhex = hex(mnode) | 492 mhex = hex(mnode) |
479 mapping = mapping.copy() | 493 mapping = mapping.copy() |
480 mapping.update({'rev': mrev, 'node': mhex}) | 494 mapping.update({'rev': mrev, 'node': mhex}) |
481 f = templ.generate('manifest', mapping) | 495 f = context.process('manifest', mapping) |
482 # TODO: perhaps 'ctx' should be dropped from mapping because manifest | 496 # TODO: perhaps 'ctx' should be dropped from mapping because manifest |
483 # rev and node are completely different from changeset's. | 497 # rev and node are completely different from changeset's. |
484 return _mappable(f, None, f, lambda x: {'rev': mrev, 'node': mhex}) | 498 return _mappable(f, None, f, lambda x: {'rev': mrev, 'node': mhex}) |
485 | 499 |
486 @templatekeyword('obsfate', requires={'ui', 'repo', 'ctx', 'templ'}) | 500 @templatekeyword('obsfate', requires={'ui', 'repo', 'ctx', 'templ'}) |
736 f = _showlist(name, ['%d' % r for r in revs], templ, mapping) | 750 f = _showlist(name, ['%d' % r for r in revs], templ, mapping) |
737 return _hybrid(f, revs, | 751 return _hybrid(f, revs, |
738 lambda x: {name: x, 'ctx': repo[x], 'revcache': {}}, | 752 lambda x: {name: x, 'ctx': repo[x], 'revcache': {}}, |
739 pycompat.identity, keytype=int) | 753 pycompat.identity, keytype=int) |
740 | 754 |
741 @templatekeyword('subrepos', requires={'ctx', 'templ'}) | 755 @templatekeyword('subrepos', requires={'ctx'}) |
742 def showsubrepos(context, mapping): | 756 def showsubrepos(context, mapping): |
743 """List of strings. Updated subrepositories in the changeset.""" | 757 """List of strings. Updated subrepositories in the changeset.""" |
744 ctx = context.resource(mapping, 'ctx') | 758 ctx = context.resource(mapping, 'ctx') |
745 substate = ctx.substate | 759 substate = ctx.substate |
746 if not substate: | 760 if not substate: |
756 return compatlist(context, mapping, 'subrepo', sorted(subrepos)) | 770 return compatlist(context, mapping, 'subrepo', sorted(subrepos)) |
757 | 771 |
758 # don't remove "showtags" definition, even though namespaces will put | 772 # don't remove "showtags" definition, even though namespaces will put |
759 # a helper function for "tags" keyword into "keywords" map automatically, | 773 # a helper function for "tags" keyword into "keywords" map automatically, |
760 # because online help text is built without namespaces initialization | 774 # because online help text is built without namespaces initialization |
761 @templatekeyword('tags', requires={'repo', 'ctx', 'templ'}) | 775 @templatekeyword('tags', requires={'repo', 'ctx'}) |
762 def showtags(context, mapping): | 776 def showtags(context, mapping): |
763 """List of strings. Any tags associated with the changeset.""" | 777 """List of strings. Any tags associated with the changeset.""" |
764 return shownames(context, mapping, 'tags') | 778 return shownames(context, mapping, 'tags') |
765 | 779 |
766 @templatekeyword('termwidth', requires={'ui'}) | 780 @templatekeyword('termwidth', requires={'ui'}) |
767 def showtermwidth(context, mapping): | 781 def showtermwidth(context, mapping): |
768 """Integer. The width of the current terminal.""" | 782 """Integer. The width of the current terminal.""" |
769 ui = context.resource(mapping, 'ui') | 783 ui = context.resource(mapping, 'ui') |
770 return ui.termwidth() | 784 return ui.termwidth() |
771 | 785 |
772 @templatekeyword('instabilities', requires={'ctx', 'templ'}) | 786 @templatekeyword('instabilities', requires={'ctx'}) |
773 def showinstabilities(context, mapping): | 787 def showinstabilities(context, mapping): |
774 """List of strings. Evolution instabilities affecting the changeset. | 788 """List of strings. Evolution instabilities affecting the changeset. |
775 (EXPERIMENTAL) | 789 (EXPERIMENTAL) |
776 """ | 790 """ |
777 ctx = context.resource(mapping, 'ctx') | 791 ctx = context.resource(mapping, 'ctx') |