Mercurial > hg
comparison mercurial/templatekw.py @ 28539:119702a8b415
templatekw: use templatekeyword to mark a function as template keyword
Using decorator can localize changes for adding (or removing) a
template keyword function in source code.
This patch also removes leading ":KEYWORD:" part in help document of
each keywords, because using templatekeyword makes it useless.
For similarity to decorator introduced by subsequent patches, this
patch uses 'templatekeyword' instead of 'keyword' as a decorator name,
even though the former is a little redundant in 'templatekw.py'.
file name reason
=================== ================= ==================================
templatekw.py templatekeyword for similarity to others
templatefilters.py templatefilter 'filter' hides Python built-in one
templaters.py templatefunc 'func' is too generic
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Sun, 13 Mar 2016 05:17:06 +0900 |
parents | 009f58f1ea75 |
children | 33bf8bd8c5b9 |
comparison
equal
deleted
inserted
replaced
28538:009f58f1ea75 | 28539:119702a8b415 |
---|---|
11 from . import ( | 11 from . import ( |
12 encoding, | 12 encoding, |
13 error, | 13 error, |
14 hbisect, | 14 hbisect, |
15 patch, | 15 patch, |
16 registrar, | |
16 scmutil, | 17 scmutil, |
17 util, | 18 util, |
18 ) | 19 ) |
19 | 20 |
20 # This helper class allows us to handle both: | 21 # This helper class allows us to handle both: |
194 except error.LookupError: | 195 except error.LookupError: |
195 return None | 196 return None |
196 | 197 |
197 return getrenamed | 198 return getrenamed |
198 | 199 |
199 | 200 # keywords are callables like: |
201 # fn(repo, ctx, templ, cache, revcache, **args) | |
202 # with: | |
203 # repo - current repository instance | |
204 # ctx - the changectx being displayed | |
205 # templ - the templater instance | |
206 # cache - a cache dictionary for the whole templater run | |
207 # revcache - a cache dictionary for the current revision | |
208 keywords = {} | |
209 | |
210 templatekeyword = registrar.templatekeyword(keywords) | |
211 | |
212 @templatekeyword('author') | |
200 def showauthor(repo, ctx, templ, **args): | 213 def showauthor(repo, ctx, templ, **args): |
201 """:author: String. The unmodified author of the changeset.""" | 214 """String. The unmodified author of the changeset.""" |
202 return ctx.user() | 215 return ctx.user() |
203 | 216 |
217 @templatekeyword('bisect') | |
204 def showbisect(repo, ctx, templ, **args): | 218 def showbisect(repo, ctx, templ, **args): |
205 """:bisect: String. The changeset bisection status.""" | 219 """String. The changeset bisection status.""" |
206 return hbisect.label(repo, ctx.node()) | 220 return hbisect.label(repo, ctx.node()) |
207 | 221 |
222 @templatekeyword('branch') | |
208 def showbranch(**args): | 223 def showbranch(**args): |
209 """:branch: String. The name of the branch on which the changeset was | 224 """String. The name of the branch on which the changeset was |
210 committed. | 225 committed. |
211 """ | 226 """ |
212 return args['ctx'].branch() | 227 return args['ctx'].branch() |
213 | 228 |
229 @templatekeyword('branches') | |
214 def showbranches(**args): | 230 def showbranches(**args): |
215 """:branches: List of strings. The name of the branch on which the | 231 """List of strings. The name of the branch on which the |
216 changeset was committed. Will be empty if the branch name was | 232 changeset was committed. Will be empty if the branch name was |
217 default. (DEPRECATED) | 233 default. (DEPRECATED) |
218 """ | 234 """ |
219 branch = args['ctx'].branch() | 235 branch = args['ctx'].branch() |
220 if branch != 'default': | 236 if branch != 'default': |
221 return showlist('branch', [branch], plural='branches', **args) | 237 return showlist('branch', [branch], plural='branches', **args) |
222 return showlist('branch', [], plural='branches', **args) | 238 return showlist('branch', [], plural='branches', **args) |
223 | 239 |
240 @templatekeyword('bookmarks') | |
224 def showbookmarks(**args): | 241 def showbookmarks(**args): |
225 """:bookmarks: List of strings. Any bookmarks associated with the | 242 """List of strings. Any bookmarks associated with the |
226 changeset. Also sets 'active', the name of the active bookmark. | 243 changeset. Also sets 'active', the name of the active bookmark. |
227 """ | 244 """ |
228 repo = args['ctx']._repo | 245 repo = args['ctx']._repo |
229 bookmarks = args['ctx'].bookmarks() | 246 bookmarks = args['ctx'].bookmarks() |
230 active = repo._activebookmark | 247 active = repo._activebookmark |
231 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active} | 248 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active} |
232 f = _showlist('bookmark', bookmarks, **args) | 249 f = _showlist('bookmark', bookmarks, **args) |
233 return _hybrid(f, bookmarks, makemap, lambda x: x['bookmark']) | 250 return _hybrid(f, bookmarks, makemap, lambda x: x['bookmark']) |
234 | 251 |
252 @templatekeyword('children') | |
235 def showchildren(**args): | 253 def showchildren(**args): |
236 """:children: List of strings. The children of the changeset.""" | 254 """List of strings. The children of the changeset.""" |
237 ctx = args['ctx'] | 255 ctx = args['ctx'] |
238 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()] | 256 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()] |
239 return showlist('children', childrevs, element='child', **args) | 257 return showlist('children', childrevs, element='child', **args) |
240 | 258 |
241 # Deprecated, but kept alive for help generation a purpose. | 259 # Deprecated, but kept alive for help generation a purpose. |
260 @templatekeyword('currentbookmark') | |
242 def showcurrentbookmark(**args): | 261 def showcurrentbookmark(**args): |
243 """:currentbookmark: String. The active bookmark, if it is | 262 """String. The active bookmark, if it is |
244 associated with the changeset (DEPRECATED)""" | 263 associated with the changeset (DEPRECATED)""" |
245 return showactivebookmark(**args) | 264 return showactivebookmark(**args) |
246 | 265 |
266 @templatekeyword('activebookmark') | |
247 def showactivebookmark(**args): | 267 def showactivebookmark(**args): |
248 """:activebookmark: String. The active bookmark, if it is | 268 """String. The active bookmark, if it is |
249 associated with the changeset""" | 269 associated with the changeset""" |
250 active = args['repo']._activebookmark | 270 active = args['repo']._activebookmark |
251 if active and active in args['ctx'].bookmarks(): | 271 if active and active in args['ctx'].bookmarks(): |
252 return active | 272 return active |
253 return '' | 273 return '' |
254 | 274 |
275 @templatekeyword('date') | |
255 def showdate(repo, ctx, templ, **args): | 276 def showdate(repo, ctx, templ, **args): |
256 """:date: Date information. The date when the changeset was committed.""" | 277 """Date information. The date when the changeset was committed.""" |
257 return ctx.date() | 278 return ctx.date() |
258 | 279 |
280 @templatekeyword('desc') | |
259 def showdescription(repo, ctx, templ, **args): | 281 def showdescription(repo, ctx, templ, **args): |
260 """:desc: String. The text of the changeset description.""" | 282 """String. The text of the changeset description.""" |
261 s = ctx.description() | 283 s = ctx.description() |
262 if isinstance(s, encoding.localstr): | 284 if isinstance(s, encoding.localstr): |
263 # try hard to preserve utf-8 bytes | 285 # try hard to preserve utf-8 bytes |
264 return encoding.tolocal(encoding.fromlocal(s).strip()) | 286 return encoding.tolocal(encoding.fromlocal(s).strip()) |
265 else: | 287 else: |
266 return s.strip() | 288 return s.strip() |
267 | 289 |
290 @templatekeyword('diffstat') | |
268 def showdiffstat(repo, ctx, templ, **args): | 291 def showdiffstat(repo, ctx, templ, **args): |
269 """:diffstat: String. Statistics of changes with the following format: | 292 """String. Statistics of changes with the following format: |
270 "modified files: +added/-removed lines" | 293 "modified files: +added/-removed lines" |
271 """ | 294 """ |
272 stats = patch.diffstatdata(util.iterlines(ctx.diff())) | 295 stats = patch.diffstatdata(util.iterlines(ctx.diff())) |
273 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats) | 296 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats) |
274 return '%s: +%s/-%s' % (len(stats), adds, removes) | 297 return '%s: +%s/-%s' % (len(stats), adds, removes) |
275 | 298 |
299 @templatekeyword('extras') | |
276 def showextras(**args): | 300 def showextras(**args): |
277 """:extras: List of dicts with key, value entries of the 'extras' | 301 """List of dicts with key, value entries of the 'extras' |
278 field of this changeset.""" | 302 field of this changeset.""" |
279 extras = args['ctx'].extra() | 303 extras = args['ctx'].extra() |
280 extras = util.sortdict((k, extras[k]) for k in sorted(extras)) | 304 extras = util.sortdict((k, extras[k]) for k in sorted(extras)) |
281 makemap = lambda k: {'key': k, 'value': extras[k]} | 305 makemap = lambda k: {'key': k, 'value': extras[k]} |
282 c = [makemap(k) for k in extras] | 306 c = [makemap(k) for k in extras] |
283 f = _showlist('extra', c, plural='extras', **args) | 307 f = _showlist('extra', c, plural='extras', **args) |
284 return _hybrid(f, extras, makemap, | 308 return _hybrid(f, extras, makemap, |
285 lambda x: '%s=%s' % (x['key'], x['value'])) | 309 lambda x: '%s=%s' % (x['key'], x['value'])) |
286 | 310 |
311 @templatekeyword('file_adds') | |
287 def showfileadds(**args): | 312 def showfileadds(**args): |
288 """:file_adds: List of strings. Files added by this changeset.""" | 313 """List of strings. Files added by this changeset.""" |
289 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache'] | 314 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache'] |
290 return showlist('file_add', getfiles(repo, ctx, revcache)[1], | 315 return showlist('file_add', getfiles(repo, ctx, revcache)[1], |
291 element='file', **args) | 316 element='file', **args) |
292 | 317 |
318 @templatekeyword('file_copies') | |
293 def showfilecopies(**args): | 319 def showfilecopies(**args): |
294 """:file_copies: List of strings. Files copied in this changeset with | 320 """List of strings. Files copied in this changeset with |
295 their sources. | 321 their sources. |
296 """ | 322 """ |
297 cache, ctx = args['cache'], args['ctx'] | 323 cache, ctx = args['cache'], args['ctx'] |
298 copies = args['revcache'].get('copies') | 324 copies = args['revcache'].get('copies') |
299 if copies is None: | 325 if copies is None: |
314 lambda x: '%s (%s)' % (x['name'], x['source'])) | 340 lambda x: '%s (%s)' % (x['name'], x['source'])) |
315 | 341 |
316 # showfilecopiesswitch() displays file copies only if copy records are | 342 # showfilecopiesswitch() displays file copies only if copy records are |
317 # provided before calling the templater, usually with a --copies | 343 # provided before calling the templater, usually with a --copies |
318 # command line switch. | 344 # command line switch. |
345 @templatekeyword('file_copies_switch') | |
319 def showfilecopiesswitch(**args): | 346 def showfilecopiesswitch(**args): |
320 """:file_copies_switch: List of strings. Like "file_copies" but displayed | 347 """List of strings. Like "file_copies" but displayed |
321 only if the --copied switch is set. | 348 only if the --copied switch is set. |
322 """ | 349 """ |
323 copies = args['revcache'].get('copies') or [] | 350 copies = args['revcache'].get('copies') or [] |
324 copies = util.sortdict(copies) | 351 copies = util.sortdict(copies) |
325 makemap = lambda k: {'name': k, 'source': copies[k]} | 352 makemap = lambda k: {'name': k, 'source': copies[k]} |
326 c = [makemap(k) for k in copies] | 353 c = [makemap(k) for k in copies] |
327 f = _showlist('file_copy', c, plural='file_copies', **args) | 354 f = _showlist('file_copy', c, plural='file_copies', **args) |
328 return _hybrid(f, copies, makemap, | 355 return _hybrid(f, copies, makemap, |
329 lambda x: '%s (%s)' % (x['name'], x['source'])) | 356 lambda x: '%s (%s)' % (x['name'], x['source'])) |
330 | 357 |
358 @templatekeyword('file_dels') | |
331 def showfiledels(**args): | 359 def showfiledels(**args): |
332 """:file_dels: List of strings. Files removed by this changeset.""" | 360 """List of strings. Files removed by this changeset.""" |
333 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache'] | 361 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache'] |
334 return showlist('file_del', getfiles(repo, ctx, revcache)[2], | 362 return showlist('file_del', getfiles(repo, ctx, revcache)[2], |
335 element='file', **args) | 363 element='file', **args) |
336 | 364 |
365 @templatekeyword('file_mods') | |
337 def showfilemods(**args): | 366 def showfilemods(**args): |
338 """:file_mods: List of strings. Files modified by this changeset.""" | 367 """List of strings. Files modified by this changeset.""" |
339 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache'] | 368 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache'] |
340 return showlist('file_mod', getfiles(repo, ctx, revcache)[0], | 369 return showlist('file_mod', getfiles(repo, ctx, revcache)[0], |
341 element='file', **args) | 370 element='file', **args) |
342 | 371 |
372 @templatekeyword('files') | |
343 def showfiles(**args): | 373 def showfiles(**args): |
344 """:files: List of strings. All files modified, added, or removed by this | 374 """List of strings. All files modified, added, or removed by this |
345 changeset. | 375 changeset. |
346 """ | 376 """ |
347 return showlist('file', args['ctx'].files(), **args) | 377 return showlist('file', args['ctx'].files(), **args) |
348 | 378 |
379 @templatekeyword('graphnode') | |
349 def showgraphnode(repo, ctx, **args): | 380 def showgraphnode(repo, ctx, **args): |
350 """:graphnode: String. The character representing the changeset node in | 381 """String. The character representing the changeset node in |
351 an ASCII revision graph""" | 382 an ASCII revision graph""" |
352 wpnodes = repo.dirstate.parents() | 383 wpnodes = repo.dirstate.parents() |
353 if wpnodes[1] == nullid: | 384 if wpnodes[1] == nullid: |
354 wpnodes = wpnodes[:1] | 385 wpnodes = wpnodes[:1] |
355 if ctx.node() in wpnodes: | 386 if ctx.node() in wpnodes: |
359 elif ctx.closesbranch(): | 390 elif ctx.closesbranch(): |
360 return '_' | 391 return '_' |
361 else: | 392 else: |
362 return 'o' | 393 return 'o' |
363 | 394 |
395 @templatekeyword('latesttag') | |
364 def showlatesttag(**args): | 396 def showlatesttag(**args): |
365 """:latesttag: List of strings. The global tags on the most recent globally | 397 """List of strings. The global tags on the most recent globally |
366 tagged ancestor of this changeset. | 398 tagged ancestor of this changeset. |
367 """ | 399 """ |
368 return showlatesttags(None, **args) | 400 return showlatesttags(None, **args) |
369 | 401 |
370 def showlatesttags(pattern, **args): | 402 def showlatesttags(pattern, **args): |
385 | 417 |
386 tags = latesttags[2] | 418 tags = latesttags[2] |
387 f = _showlist('latesttag', tags, separator=':', **args) | 419 f = _showlist('latesttag', tags, separator=':', **args) |
388 return _hybrid(f, tags, makemap, lambda x: x['latesttag']) | 420 return _hybrid(f, tags, makemap, lambda x: x['latesttag']) |
389 | 421 |
422 @templatekeyword('latesttagdistance') | |
390 def showlatesttagdistance(repo, ctx, templ, cache, **args): | 423 def showlatesttagdistance(repo, ctx, templ, cache, **args): |
391 """:latesttagdistance: Integer. Longest path to the latest tag.""" | 424 """Integer. Longest path to the latest tag.""" |
392 return getlatesttags(repo, ctx, cache)[1] | 425 return getlatesttags(repo, ctx, cache)[1] |
393 | 426 |
427 @templatekeyword('changessincelatesttag') | |
394 def showchangessincelatesttag(repo, ctx, templ, cache, **args): | 428 def showchangessincelatesttag(repo, ctx, templ, cache, **args): |
395 """:changessincelatesttag: Integer. All ancestors not in the latest tag.""" | 429 """Integer. All ancestors not in the latest tag.""" |
396 latesttag = getlatesttags(repo, ctx, cache)[2][0] | 430 latesttag = getlatesttags(repo, ctx, cache)[2][0] |
397 | 431 |
398 return _showchangessincetag(repo, ctx, tag=latesttag, **args) | 432 return _showchangessincetag(repo, ctx, tag=latesttag, **args) |
399 | 433 |
400 def _showchangessincetag(repo, ctx, **args): | 434 def _showchangessincetag(repo, ctx, **args): |
407 offset = 1 | 441 offset = 1 |
408 revs = [p.rev() for p in ctx.parents()] | 442 revs = [p.rev() for p in ctx.parents()] |
409 | 443 |
410 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset | 444 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset |
411 | 445 |
446 @templatekeyword('manifest') | |
412 def showmanifest(**args): | 447 def showmanifest(**args): |
413 repo, ctx, templ = args['repo'], args['ctx'], args['templ'] | 448 repo, ctx, templ = args['repo'], args['ctx'], args['templ'] |
414 mnode = ctx.manifestnode() | 449 mnode = ctx.manifestnode() |
415 if mnode is None: | 450 if mnode is None: |
416 # just avoid crash, we might want to use the 'ff...' hash in future | 451 # just avoid crash, we might want to use the 'ff...' hash in future |
425 repo = ctx.repo() | 460 repo = ctx.repo() |
426 ns = repo.names[namespace] | 461 ns = repo.names[namespace] |
427 names = ns.names(repo, ctx.node()) | 462 names = ns.names(repo, ctx.node()) |
428 return showlist(ns.templatename, names, plural=namespace, **args) | 463 return showlist(ns.templatename, names, plural=namespace, **args) |
429 | 464 |
465 @templatekeyword('namespaces') | |
430 def shownamespaces(**args): | 466 def shownamespaces(**args): |
431 """:namespaces: Dict of lists. Names attached to this changeset per | 467 """Dict of lists. Names attached to this changeset per |
432 namespace.""" | 468 namespace.""" |
433 ctx = args['ctx'] | 469 ctx = args['ctx'] |
434 repo = ctx.repo() | 470 repo = ctx.repo() |
435 namespaces = util.sortdict((k, showlist('name', ns.names(repo, ctx.node()), | 471 namespaces = util.sortdict((k, showlist('name', ns.names(repo, ctx.node()), |
436 **args)) | 472 **args)) |
438 f = _showlist('namespace', list(namespaces), **args) | 474 f = _showlist('namespace', list(namespaces), **args) |
439 return _hybrid(f, namespaces, | 475 return _hybrid(f, namespaces, |
440 lambda k: {'namespace': k, 'names': namespaces[k]}, | 476 lambda k: {'namespace': k, 'names': namespaces[k]}, |
441 lambda x: x['namespace']) | 477 lambda x: x['namespace']) |
442 | 478 |
479 @templatekeyword('node') | |
443 def shownode(repo, ctx, templ, **args): | 480 def shownode(repo, ctx, templ, **args): |
444 """:node: String. The changeset identification hash, as a 40 hexadecimal | 481 """String. The changeset identification hash, as a 40 hexadecimal |
445 digit string. | 482 digit string. |
446 """ | 483 """ |
447 return ctx.hex() | 484 return ctx.hex() |
448 | 485 |
486 @templatekeyword('p1rev') | |
449 def showp1rev(repo, ctx, templ, **args): | 487 def showp1rev(repo, ctx, templ, **args): |
450 """:p1rev: Integer. The repository-local revision number of the changeset's | 488 """Integer. The repository-local revision number of the changeset's |
451 first parent, or -1 if the changeset has no parents.""" | 489 first parent, or -1 if the changeset has no parents.""" |
452 return ctx.p1().rev() | 490 return ctx.p1().rev() |
453 | 491 |
492 @templatekeyword('p2rev') | |
454 def showp2rev(repo, ctx, templ, **args): | 493 def showp2rev(repo, ctx, templ, **args): |
455 """:p2rev: Integer. The repository-local revision number of the changeset's | 494 """Integer. The repository-local revision number of the changeset's |
456 second parent, or -1 if the changeset has no second parent.""" | 495 second parent, or -1 if the changeset has no second parent.""" |
457 return ctx.p2().rev() | 496 return ctx.p2().rev() |
458 | 497 |
498 @templatekeyword('p1node') | |
459 def showp1node(repo, ctx, templ, **args): | 499 def showp1node(repo, ctx, templ, **args): |
460 """:p1node: String. The identification hash of the changeset's first parent, | 500 """String. The identification hash of the changeset's first parent, |
461 as a 40 digit hexadecimal string. If the changeset has no parents, all | 501 as a 40 digit hexadecimal string. If the changeset has no parents, all |
462 digits are 0.""" | 502 digits are 0.""" |
463 return ctx.p1().hex() | 503 return ctx.p1().hex() |
464 | 504 |
505 @templatekeyword('p2node') | |
465 def showp2node(repo, ctx, templ, **args): | 506 def showp2node(repo, ctx, templ, **args): |
466 """:p2node: String. The identification hash of the changeset's second | 507 """String. The identification hash of the changeset's second |
467 parent, as a 40 digit hexadecimal string. If the changeset has no second | 508 parent, as a 40 digit hexadecimal string. If the changeset has no second |
468 parent, all digits are 0.""" | 509 parent, all digits are 0.""" |
469 return ctx.p2().hex() | 510 return ctx.p2().hex() |
470 | 511 |
512 @templatekeyword('parents') | |
471 def showparents(**args): | 513 def showparents(**args): |
472 """:parents: List of strings. The parents of the changeset in "rev:node" | 514 """List of strings. The parents of the changeset in "rev:node" |
473 format. If the changeset has only one "natural" parent (the predecessor | 515 format. If the changeset has only one "natural" parent (the predecessor |
474 revision) nothing is shown.""" | 516 revision) nothing is shown.""" |
475 repo = args['repo'] | 517 repo = args['repo'] |
476 ctx = args['ctx'] | 518 ctx = args['ctx'] |
477 pctxs = scmutil.meaningfulparents(repo, ctx) | 519 pctxs = scmutil.meaningfulparents(repo, ctx) |
481 ('phase', p.phasestr())] | 523 ('phase', p.phasestr())] |
482 for p in pctxs] | 524 for p in pctxs] |
483 f = _showlist('parent', parents, **args) | 525 f = _showlist('parent', parents, **args) |
484 return _hybrid(f, prevs, lambda x: {'ctx': repo[int(x)], 'revcache': {}}) | 526 return _hybrid(f, prevs, lambda x: {'ctx': repo[int(x)], 'revcache': {}}) |
485 | 527 |
528 @templatekeyword('phase') | |
486 def showphase(repo, ctx, templ, **args): | 529 def showphase(repo, ctx, templ, **args): |
487 """:phase: String. The changeset phase name.""" | 530 """String. The changeset phase name.""" |
488 return ctx.phasestr() | 531 return ctx.phasestr() |
489 | 532 |
533 @templatekeyword('phaseidx') | |
490 def showphaseidx(repo, ctx, templ, **args): | 534 def showphaseidx(repo, ctx, templ, **args): |
491 """:phaseidx: Integer. The changeset phase index.""" | 535 """Integer. The changeset phase index.""" |
492 return ctx.phase() | 536 return ctx.phase() |
493 | 537 |
538 @templatekeyword('rev') | |
494 def showrev(repo, ctx, templ, **args): | 539 def showrev(repo, ctx, templ, **args): |
495 """:rev: Integer. The repository-local changeset revision number.""" | 540 """Integer. The repository-local changeset revision number.""" |
496 return scmutil.intrev(ctx.rev()) | 541 return scmutil.intrev(ctx.rev()) |
497 | 542 |
498 def showrevslist(name, revs, **args): | 543 def showrevslist(name, revs, **args): |
499 """helper to generate a list of revisions in which a mapped template will | 544 """helper to generate a list of revisions in which a mapped template will |
500 be evaluated""" | 545 be evaluated""" |
502 revs = [str(r) for r in revs] # ifcontains() needs a list of str | 547 revs = [str(r) for r in revs] # ifcontains() needs a list of str |
503 f = _showlist(name, revs, **args) | 548 f = _showlist(name, revs, **args) |
504 return _hybrid(f, revs, | 549 return _hybrid(f, revs, |
505 lambda x: {name: x, 'ctx': repo[int(x)], 'revcache': {}}) | 550 lambda x: {name: x, 'ctx': repo[int(x)], 'revcache': {}}) |
506 | 551 |
552 @templatekeyword('subrepos') | |
507 def showsubrepos(**args): | 553 def showsubrepos(**args): |
508 """:subrepos: List of strings. Updated subrepositories in the changeset.""" | 554 """List of strings. Updated subrepositories in the changeset.""" |
509 ctx = args['ctx'] | 555 ctx = args['ctx'] |
510 substate = ctx.substate | 556 substate = ctx.substate |
511 if not substate: | 557 if not substate: |
512 return showlist('subrepo', [], **args) | 558 return showlist('subrepo', [], **args) |
513 psubstate = ctx.parents()[0].substate or {} | 559 psubstate = ctx.parents()[0].substate or {} |
521 return showlist('subrepo', sorted(subrepos), **args) | 567 return showlist('subrepo', sorted(subrepos), **args) |
522 | 568 |
523 # don't remove "showtags" definition, even though namespaces will put | 569 # don't remove "showtags" definition, even though namespaces will put |
524 # a helper function for "tags" keyword into "keywords" map automatically, | 570 # a helper function for "tags" keyword into "keywords" map automatically, |
525 # because online help text is built without namespaces initialization | 571 # because online help text is built without namespaces initialization |
572 @templatekeyword('tags') | |
526 def showtags(**args): | 573 def showtags(**args): |
527 """:tags: List of strings. Any tags associated with the changeset.""" | 574 """List of strings. Any tags associated with the changeset.""" |
528 return shownames('tags', **args) | 575 return shownames('tags', **args) |
529 | |
530 # keywords are callables like: | |
531 # fn(repo, ctx, templ, cache, revcache, **args) | |
532 # with: | |
533 # repo - current repository instance | |
534 # ctx - the changectx being displayed | |
535 # templ - the templater instance | |
536 # cache - a cache dictionary for the whole templater run | |
537 # revcache - a cache dictionary for the current revision | |
538 keywords = { | |
539 'activebookmark': showactivebookmark, | |
540 'author': showauthor, | |
541 'bisect': showbisect, | |
542 'branch': showbranch, | |
543 'branches': showbranches, | |
544 'bookmarks': showbookmarks, | |
545 'changessincelatesttag': showchangessincelatesttag, | |
546 'children': showchildren, | |
547 # currentbookmark is deprecated | |
548 'currentbookmark': showcurrentbookmark, | |
549 'date': showdate, | |
550 'desc': showdescription, | |
551 'diffstat': showdiffstat, | |
552 'extras': showextras, | |
553 'file_adds': showfileadds, | |
554 'file_copies': showfilecopies, | |
555 'file_copies_switch': showfilecopiesswitch, | |
556 'file_dels': showfiledels, | |
557 'file_mods': showfilemods, | |
558 'files': showfiles, | |
559 'graphnode': showgraphnode, | |
560 'latesttag': showlatesttag, | |
561 'latesttagdistance': showlatesttagdistance, | |
562 'manifest': showmanifest, | |
563 'namespaces': shownamespaces, | |
564 'node': shownode, | |
565 'p1rev': showp1rev, | |
566 'p1node': showp1node, | |
567 'p2rev': showp2rev, | |
568 'p2node': showp2node, | |
569 'parents': showparents, | |
570 'phase': showphase, | |
571 'phaseidx': showphaseidx, | |
572 'rev': showrev, | |
573 'subrepos': showsubrepos, | |
574 'tags': showtags, | |
575 } | |
576 | 576 |
577 def loadkeyword(ui, extname, registrarobj): | 577 def loadkeyword(ui, extname, registrarobj): |
578 """Load template keyword from specified registrarobj | 578 """Load template keyword from specified registrarobj |
579 """ | 579 """ |
580 for name, func in registrarobj._table.iteritems(): | 580 for name, func in registrarobj._table.iteritems(): |