##// END OF EJS Templates
py3: use pycompat.bytestr instead of str...
py3: use pycompat.bytestr instead of str Differential Revision: https://phab.mercurial-scm.org/D2264

File last commit:

r36127:230489fc default
r36204:c1628a5e default
Show More
templatekw.py
929 lines | 31.6 KiB | text/x-python | PythonLexer
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 # templatekw.py - common changeset template keywords
#
# Copyright 2005-2009 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
Matt Mackall
Merge with stable
r10264 # GNU General Public License version 2 or any later version.
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053
Gregory Szorc
templatekw: use absolute_import
r25984 from __future__ import absolute_import
Yuya Nishihara
templater: provide loop counter as "index" keyword...
r31807 from .i18n import _
Yuya Nishihara
scmutil: introduce binnode(ctx) as paired function with intrev(ctx)...
r32656 from .node import (
hex,
nullid,
)
Gregory Szorc
templatekw: use absolute_import
r25984 from . import (
Yuya Nishihara
templatekw: workaround for utf-8 round-trip of {desc}...
r28239 encoding,
Gregory Szorc
templatekw: use absolute_import
r25984 error,
hbisect,
Yuya Nishihara
log: translate column labels at once (issue5750)...
r35213 i18n,
Boris Feld
template: add predecessors template...
r32879 obsutil,
Gregory Szorc
templatekw: use absolute_import
r25984 patch,
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 pycompat,
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 registrar,
Gregory Szorc
templatekw: use absolute_import
r25984 scmutil,
util,
)
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053
Yuya Nishihara
templater: rewrite doc of _hybrid class as docstring
r31879 class _hybrid(object):
"""Wrapper for list or dict to support legacy template
Matt Mackall
templating: make new-style templating features work with command line lists
r17631
Yuya Nishihara
templater: rewrite doc of _hybrid class as docstring
r31879 This class allows us to handle both:
- "{files}" (legacy command-line-specific list hack) and
- "{files % '{file}\n'}" (hgweb-style with inlining and function support)
and to access raw values:
- "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
- "{get(extras, key)}"
Yuya Nishihara
templater: make _hybrid provide more list/dict-like methods...
r31882 - "{files|json}"
Yuya Nishihara
templater: rewrite doc of _hybrid class as docstring
r31879 """
Yuya Nishihara
templater: store revisions as ints so min/max won't compare them as strings...
r34582 def __init__(self, gen, values, makemap, joinfmt, keytype=None):
Yuya Nishihara
templatekw: add default implementation of _hybrid.gen...
r31923 if gen is not None:
Yuya Nishihara
formatter: fix default list/dict generator to be evaluated more than once...
r34426 self.gen = gen # generator or function returning generator
Yuya Nishihara
templater: hide private variable of _hybrid
r31881 self._values = values
Yuya Nishihara
templatekw: keep raw list or dict in _hybrid object...
r24239 self._makemap = makemap
Yuya Nishihara
templatekw: change joinfmt to a mandatory argument of _hybrid object...
r29669 self.joinfmt = joinfmt
Yuya Nishihara
templater: store revisions as ints so min/max won't compare them as strings...
r34582 self.keytype = keytype # hint for 'x in y' where type(x) is unresolved
Yuya Nishihara
templatekw: add default implementation of _hybrid.gen...
r31923 def gen(self):
Yuya Nishihara
formatter: fix default list/dict generator to be evaluated more than once...
r34426 """Default generator to stringify this as {join(self, ' ')}"""
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 for i, x in enumerate(self._values):
Yuya Nishihara
templatekw: add default implementation of _hybrid.gen...
r31923 if i > 0:
yield ' '
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 yield self.joinfmt(x)
Yuya Nishihara
templater: make _hybrid not callable to avoid conflicting semantics...
r27891 def itermaps(self):
Yuya Nishihara
templatekw: keep raw list or dict in _hybrid object...
r24239 makemap = self._makemap
Yuya Nishihara
templater: hide private variable of _hybrid
r31881 for x in self._values:
Yuya Nishihara
templatekw: keep raw list or dict in _hybrid object...
r24239 yield makemap(x)
Yuya Nishihara
templater: implement _hybrid.__contains__ so that ifcontains can accept dict...
r24240 def __contains__(self, x):
Yuya Nishihara
templater: hide private variable of _hybrid
r31881 return x in self._values
Yuya Nishihara
templatekw: export ui.paths as {peerpaths}...
r33414 def __getitem__(self, key):
return self._values[key]
Anton Shestakov
templater: implement __len__ for _hybrid...
r22393 def __len__(self):
Yuya Nishihara
templater: hide private variable of _hybrid
r31881 return len(self._values)
Yuya Nishihara
templater: make _hybrid provide more list/dict-like methods...
r31882 def __iter__(self):
return iter(self._values)
Yuya Nishihara
templatekw: forward _hybrid.get to raw values so that get(extras, key) works...
r24241 def __getattr__(self, name):
Yuya Nishihara
templater: make _hybrid provide more list/dict-like methods...
r31882 if name not in ('get', 'items', 'iteritems', 'iterkeys', 'itervalues',
'keys', 'values'):
Yuya Nishihara
templatekw: forward _hybrid.get to raw values so that get(extras, key) works...
r24241 raise AttributeError(name)
Yuya Nishihara
templater: hide private variable of _hybrid
r31881 return getattr(self._values, name)
Matt Mackall
templating: make new-style templating features work with command line lists
r17631
Yuya Nishihara
templatekw: add new-style template expansion to {manifest}...
r34331 class _mappable(object):
"""Wrapper for non-list/dict object to support map operation
This class allows us to handle both:
- "{manifest}"
- "{manifest % '{rev}:{node}'}"
Yuya Nishihara
templater: add dot operator to easily access a sub item...
r34536 - "{manifest.rev}"
Yuya Nishihara
templatekw: add new-style template expansion to {manifest}...
r34331
Unlike a _hybrid, this does not simulate the behavior of the underling
value. Use unwrapvalue() or unwraphybrid() to obtain the inner object.
"""
Yuya Nishihara
templater: wrap get/min/max result so map operation can apply to element...
r34535 def __init__(self, gen, key, value, makemap):
if gen is not None:
self.gen = gen # generator or function returning generator
self._key = key
Yuya Nishihara
templatekw: add new-style template expansion to {manifest}...
r34331 self._value = value # may be generator of strings
self._makemap = makemap
Yuya Nishihara
templater: wrap get/min/max result so map operation can apply to element...
r34535 def gen(self):
yield pycompat.bytestr(self._value)
Yuya Nishihara
templatekw: add new-style template expansion to {manifest}...
r34331 def tomap(self):
Yuya Nishihara
templater: wrap get/min/max result so map operation can apply to element...
r34535 return self._makemap(self._key)
Yuya Nishihara
templatekw: add new-style template expansion to {manifest}...
r34331
def itermaps(self):
yield self.tomap()
Yuya Nishihara
templatekw: add public function to wrap a dict by _hybrid object
r31925 def hybriddict(data, key='key', value='value', fmt='%s=%s', gen=None):
"""Wrap data to support both dict-like and string-like operations"""
return _hybrid(gen, data, lambda k: {key: k, value: data[k]},
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 lambda k: fmt % (k, data[k]))
Yuya Nishihara
templatekw: add public function to wrap a dict by _hybrid object
r31925
Yuya Nishihara
templatekw: add public function to wrap a list by _hybrid object
r31924 def hybridlist(data, name, fmt='%s', gen=None):
"""Wrap data to support both list-like and string-like operations"""
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 return _hybrid(gen, data, lambda x: {name: x}, lambda x: fmt % x)
Yuya Nishihara
templatekw: add public function to wrap a list by _hybrid object
r31924
Yuya Nishihara
templater: remove __iter__() from _hybrid, resolve it explicitly...
r31880 def unwraphybrid(thing):
"""Return an object which can be stringified possibly by using a legacy
template"""
Yuya Nishihara
formatter: fix default list/dict generator to be evaluated more than once...
r34426 gen = getattr(thing, 'gen', None)
if gen is None:
Yuya Nishihara
templater: remove __iter__() from _hybrid, resolve it explicitly...
r31880 return thing
Yuya Nishihara
formatter: fix default list/dict generator to be evaluated more than once...
r34426 if callable(gen):
return gen()
return gen
Yuya Nishihara
templater: remove __iter__() from _hybrid, resolve it explicitly...
r31880
Yuya Nishihara
templatekw: add new-style template expansion to {manifest}...
r34331 def unwrapvalue(thing):
"""Move the inner value object out of the wrapper"""
if not util.safehasattr(thing, '_value'):
return thing
return thing._value
Yuya Nishihara
templater: wrap get/min/max result so map operation can apply to element...
r34535 def wraphybridvalue(container, key, value):
"""Wrap an element of hybrid container to be mappable
The key is passed to the makemap function of the given container, which
should be an item generated by iter(container).
"""
makemap = getattr(container, '_makemap', None)
if makemap is None:
return value
if util.safehasattr(value, '_makemap'):
# a nested hybrid list/dict, which has its own way of map operation
return value
return _mappable(None, key, value, makemap)
Yuya Nishihara
templatekw: factor out showdict() helper...
r32038 def showdict(name, data, mapping, plural=None, key='key', value='value',
fmt='%s=%s', separator=' '):
c = [{key: k, value: v} for k, v in data.iteritems()]
f = _showlist(name, c, mapping, plural, separator)
return hybriddict(data, key=key, value=value, fmt=fmt, gen=f)
Yuya Nishihara
templatekw: have showlist() take mapping dict with no **kwargs expansion (API)...
r32037 def showlist(name, values, mapping, plural=None, element=None, separator=' '):
Matt Mackall
templating: make new-style templating features work with command line lists
r17631 if not element:
element = name
Yuya Nishihara
templatekw: change _showlist() to take mapping dict with no **kwargs expansion...
r32036 f = _showlist(name, values, mapping, plural, separator)
Yuya Nishihara
templatekw: add public function to wrap a list by _hybrid object
r31924 return hybridlist(values, name=element, gen=f)
Matt Mackall
templating: make new-style templating features work with command line lists
r17631
Yuya Nishihara
templatekw: change _showlist() to take mapping dict with no **kwargs expansion...
r32036 def _showlist(name, values, mapping, plural=None, separator=' '):
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 '''expand set of values.
name is name of key in template map.
values is list of strings or dicts.
plural is plural of name, if not simply name + 's'.
Matt Harbison
templatekw: allow the caller of showlist() to specify the join() separator...
r25726 separator is used to join values as a string
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053
expansion works like this, given name 'foo'.
if values is empty, expand 'no_foos'.
if 'foo' not in template map, return values as a string,
Matt Harbison
templatekw: allow the caller of showlist() to specify the join() separator...
r25726 joined by 'separator'.
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053
expand 'start_foos'.
for each value, expand 'foo'. if 'last_foo' in template
map, expand it instead of 'foo' for last key.
expand 'end_foos'.
'''
Yuya Nishihara
templatekw: rename 'args' to 'mapping' in showlist()...
r32035 templ = mapping['templ']
Pulkit Goyal
py3: convert kwargs' keys' to str using pycompat.strkwargs()...
r33017 strmapping = pycompat.strkwargs(mapping)
Yuya Nishihara
templatekw: eliminate unnecessary temporary variable 'names' from _showlist()...
r32034 if not plural:
plural = name + 's'
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 if not values:
Yuya Nishihara
templatekw: eliminate unnecessary temporary variable 'names' from _showlist()...
r32034 noname = 'no_' + plural
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 if noname in templ:
Pulkit Goyal
py3: convert kwargs' keys' to str using pycompat.strkwargs()...
r33017 yield templ(noname, **strmapping)
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 return
if name not in templ:
Pulkit Goyal
py3: replace str with bytes in isinstance()...
r32970 if isinstance(values[0], bytes):
Matt Harbison
templatekw: allow the caller of showlist() to specify the join() separator...
r25726 yield separator.join(values)
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 else:
for v in values:
Pulkit Goyal
py3: convert kwargs' keys' to str using pycompat.strkwargs()...
r33017 yield dict(v, **strmapping)
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 return
Yuya Nishihara
templatekw: eliminate unnecessary temporary variable 'names' from _showlist()...
r32034 startname = 'start_' + plural
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 if startname in templ:
Pulkit Goyal
py3: convert kwargs' keys' to str using pycompat.strkwargs()...
r33017 yield templ(startname, **strmapping)
Yuya Nishihara
templatekw: rename 'args' to 'mapping' in showlist()...
r32035 vmapping = mapping.copy()
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 def one(v, tag=name):
try:
Yuya Nishihara
templatekw: rename 'args' to 'mapping' in showlist()...
r32035 vmapping.update(v)
Gregory Szorc
py3: catch TypeError during template operations...
r36127 # Python 2 raises ValueError if the type of v is wrong. Python
# 3 raises TypeError.
except (AttributeError, TypeError, ValueError):
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 try:
Gregory Szorc
py3: catch TypeError during template operations...
r36127 # Python 2 raises ValueError trying to destructure an e.g.
# bytes. Python 3 raises TypeError.
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 for a, b in v:
Yuya Nishihara
templatekw: rename 'args' to 'mapping' in showlist()...
r32035 vmapping[a] = b
Gregory Szorc
py3: catch TypeError during template operations...
r36127 except (TypeError, ValueError):
Yuya Nishihara
templatekw: rename 'args' to 'mapping' in showlist()...
r32035 vmapping[name] = v
Pulkit Goyal
py3: convert kwargs' keys' to str using pycompat.strkwargs()...
r33017 return templ(tag, **pycompat.strkwargs(vmapping))
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 lastname = 'last_' + name
if lastname in templ:
last = values.pop()
else:
last = None
for v in values:
yield one(v)
if last is not None:
yield one(last, tag=lastname)
Yuya Nishihara
templatekw: eliminate unnecessary temporary variable 'names' from _showlist()...
r32034 endname = 'end_' + plural
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053 if endname in templ:
Pulkit Goyal
py3: convert kwargs' keys' to str using pycompat.strkwargs()...
r33017 yield templ(endname, **strmapping)
Patrick Mezard
cmdutil: replace showlist() closure with a function
r10053
Patrick Mezard
cmdutil: extract file changes closures into templatekw
r10056 def getfiles(repo, ctx, revcache):
if 'files' not in revcache:
FUJIWARA Katsunori
templatekw: compare target context and its parent exactly (issue4690)...
r25392 revcache['files'] = repo.status(ctx.p1(), ctx)[:3]
Patrick Mezard
cmdutil: extract file changes closures into templatekw
r10056 return revcache['files']
Matt Harbison
templatekw: allow getlatesttags() to match a specific tag pattern...
r26482 def getlatesttags(repo, ctx, cache, pattern=None):
Patrick Mezard
cmdutil: extract latest tags closures in templatekw
r10057 '''return date, distance and name for the latest tag of rev'''
Matt Harbison
templatekw: allow getlatesttags() to match a specific tag pattern...
r26482 cachename = 'latesttags'
if pattern is not None:
cachename += '-' + pattern
match = util.stringmatcher(pattern)[2]
else:
match = util.always
if cachename not in cache:
Patrick Mezard
cmdutil: extract latest tags closures in templatekw
r10057 # Cache mapping from rev to a tuple with tag date, tag
# distance and tag name
Matt Harbison
templatekw: allow getlatesttags() to match a specific tag pattern...
r26482 cache[cachename] = {-1: (0, 0, ['null'])}
latesttags = cache[cachename]
Patrick Mezard
cmdutil: extract latest tags closures in templatekw
r10057
rev = ctx.rev()
todo = [rev]
while todo:
rev = todo.pop()
if rev in latesttags:
continue
ctx = repo[rev]
Andrew Shadura
templatekw: allow tagtypes other than global in getlatesttags...
r20218 tags = [t for t in ctx.tags()
Matt Harbison
templatekw: allow getlatesttags() to match a specific tag pattern...
r26482 if (repo.tagtype(t) and repo.tagtype(t) != 'local'
and match(t))]
Patrick Mezard
cmdutil: extract latest tags closures in templatekw
r10057 if tags:
Matt Harbison
templatekw: use a list of tags in getlatesttags() instead of joining them...
r25700 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
Patrick Mezard
cmdutil: extract latest tags closures in templatekw
r10057 continue
try:
Martin von Zweigbergk
templatekw: choose {latesttag} by len(changes), not date (issue5659)...
r33866 ptags = [latesttags[p.rev()] for p in ctx.parents()]
if len(ptags) > 1:
if ptags[0][2] == ptags[1][2]:
# The tuples are laid out so the right one can be found by
# comparison in this case.
pdate, pdist, ptag = max(ptags)
else:
def key(x):
changessincetag = len(repo.revs('only(%d, %s)',
ctx.rev(), x[2][0]))
# Smallest number of changes since tag wins. Date is
# used as tiebreaker.
return [-changessincetag, x[0]]
pdate, pdist, ptag = max(ptags, key=key)
else:
pdate, pdist, ptag = ptags[0]
Patrick Mezard
cmdutil: extract latest tags closures in templatekw
r10057 except KeyError:
# Cache miss - recurse
todo.append(rev)
todo.extend(p.rev() for p in ctx.parents())
continue
latesttags[rev] = pdate, pdist + 1, ptag
return latesttags[rev]
Patrick Mezard
templatekw: change {file_copies} behaviour, add {file_copies_switch}...
r10060 def getrenamedfn(repo, endrev=None):
rcache = {}
if endrev is None:
endrev = len(repo)
def getrenamed(fn, rev):
'''looks up all renames for a file (up to endrev) the first
time the file is given. It indexes on the changerev and only
parses the manifest if linkrev != changerev.
Returns rename info for fn at changerev rev.'''
if fn not in rcache:
rcache[fn] = {}
fl = repo.file(fn)
for i in fl:
lr = fl.linkrev(i)
renamed = fl.renamed(fl.node(i))
rcache[fn][lr] = renamed
if lr >= endrev:
break
if rev in rcache[fn]:
return rcache[fn][rev]
# If linkrev != rev (i.e. rev not found in rcache) fallback to
# filectx logic.
try:
return repo[rev][fn].renamed()
except error.LookupError:
return None
return getrenamed
Yuya Nishihara
log: translate column labels at once (issue5750)...
r35213 def getlogcolumns():
"""Return a dict of log column labels"""
_ = pycompat.identity # temporarily disable gettext
# i18n: column positioning for "hg log"
columns = _('bookmark: %s\n'
'branch: %s\n'
'changeset: %s\n'
'copies: %s\n'
'date: %s\n'
'extra: %s=%s\n'
'files+: %s\n'
'files-: %s\n'
'files: %s\n'
'instability: %s\n'
'manifest: %s\n'
'obsolete: %s\n'
'parent: %s\n'
'phase: %s\n'
'summary: %s\n'
'tag: %s\n'
'user: %s\n')
return dict(zip([s.split(':', 1)[0] for s in columns.splitlines()],
i18n._(columns).splitlines(True)))
Yuya Nishihara
templatekw: move defaulttmpl constant from changeset_templater...
r31171 # default templates internally used for rendering of lists
defaulttempl = {
'parent': '{rev}:{node|formatnode} ',
'manifest': '{rev}:{node|formatnode}',
'file_copy': '{name} ({source})',
'envvar': '{key}={value}',
'extra': '{key}={value|stringescape}'
}
# filecopy is preserved for compatibility reasons
defaulttempl['filecopy'] = defaulttempl['file_copy']
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 # keywords are callables like:
# fn(repo, ctx, templ, cache, revcache, **args)
# with:
# repo - current repository instance
# ctx - the changectx being displayed
# templ - the templater instance
# cache - a cache dictionary for the whole templater run
# revcache - a cache dictionary for the current revision
keywords = {}
Patrick Mezard
templatekw: change {file_copies} behaviour, add {file_copies_switch}...
r10060
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 templatekeyword = registrar.templatekeyword(keywords)
@templatekeyword('author')
Patrick Mezard
cmdutil: extract repo dependent closures in templatekw
r10055 def showauthor(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """String. The unmodified author of the changeset."""
Patrick Mezard
cmdutil: extract ctx dependent closures into templatekw
r10054 return ctx.user()
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('bisect')
"Yann E. MORIN"
templates: add 'bisect' keyword to return a cset's bisect status...
r15155 def showbisect(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """String. The changeset bisection status."""
"Yann E. MORIN"
templates: add 'bisect' keyword to return a cset's bisect status...
r15155 return hbisect.label(repo, ctx.node())
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('branch')
Eric Eisner
template: add showbranch template for {branch}...
r13156 def showbranch(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """String. The name of the branch on which the changeset was
Patrick Mezard
templates: generate keyword help dynamically
r13585 committed.
"""
Pulkit Goyal
py3: use r'' to access values from kwargs where keys are str...
r32973 return args[r'ctx'].branch()
Eric Eisner
template: add showbranch template for {branch}...
r13156
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('branches')
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 def showbranches(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. The name of the branch on which the
Patrick Mezard
templates: generate keyword help dynamically
r13585 changeset was committed. Will be empty if the branch name was
Yuya Nishihara
templatekw: hide help of "branches" by DEPRECATED marker...
r26437 default. (DEPRECATED)
Patrick Mezard
templates: generate keyword help dynamically
r13585 """
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 branch = args['ctx'].branch()
Patrick Mezard
cmdutil: extract ctx dependent closures into templatekw
r10054 if branch != 'default':
Yuya Nishihara
templatekw: have showlist() take mapping dict with no **kwargs expansion (API)...
r32037 return showlist('branch', [branch], args, plural='branches')
return showlist('branch', [], args, plural='branches')
Patrick Mezard
cmdutil: extract ctx dependent closures into templatekw
r10054
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('bookmarks')
David Soria Parra
templater: add bookmarks to templates and default output...
r13386 def showbookmarks(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. Any bookmarks associated with the
Ryan McElroy
templatekw: introduce active subkeyword from bookmarks keyword...
r25348 changeset. Also sets 'active', the name of the active bookmark.
Patrick Mezard
templates: document missing keywords or filters...
r13592 """
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Durham Goode
template: add 'current' to scope during {bookmarks % ...}...
r20520 repo = args['ctx']._repo
David Soria Parra
templater: add bookmarks to templates and default output...
r13386 bookmarks = args['ctx'].bookmarks()
Ryan McElroy
templatekw: introduce active subkeyword from bookmarks keyword...
r25348 active = repo._activebookmark
makemap = lambda v: {'bookmark': v, 'active': active, 'current': active}
Yuya Nishihara
templatekw: change _showlist() to take mapping dict with no **kwargs expansion...
r32036 f = _showlist('bookmark', bookmarks, args)
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 return _hybrid(f, bookmarks, makemap, pycompat.identity)
David Soria Parra
templater: add bookmarks to templates and default output...
r13386
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('children')
Jason Harris
templates: 'children' keyword...
r11655 def showchildren(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. The children of the changeset."""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Jason Harris
templates: 'children' keyword...
r11655 ctx = args['ctx']
childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
Yuya Nishihara
templatekw: have showlist() take mapping dict with no **kwargs expansion (API)...
r32037 return showlist('children', childrevs, args, element='child')
Jason Harris
templates: 'children' keyword...
r11655
Ryan McElroy
templatekw: introduce activebookmark keyword...
r25013 # Deprecated, but kept alive for help generation a purpose.
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('currentbookmark')
FUJIWARA Katsunori
templatekw: add 'currentbookmark' keyword to show current bookmark easily...
r21896 def showcurrentbookmark(**args):
Yuya Nishihara
help: fix formatting of template keywords...
r34657 """String. The active bookmark, if it is associated with the changeset.
(DEPRECATED)"""
Ryan McElroy
templatekw: introduce activebookmark keyword...
r25013 return showactivebookmark(**args)
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('activebookmark')
Ryan McElroy
templatekw: introduce activebookmark keyword...
r25013 def showactivebookmark(**args):
Yuya Nishihara
help: fix formatting of template keywords...
r34657 """String. The active bookmark, if it is associated with the changeset."""
Pulkit Goyal
py3: use r'' to access values from kwargs where keys are str...
r32973 active = args[r'repo']._activebookmark
if active and active in args[r'ctx'].bookmarks():
Ryan McElroy
templatekw: display active bookmark more consistently (issue4552) (BC)...
r25387 return active
FUJIWARA Katsunori
templatekw: add 'currentbookmark' keyword to show current bookmark easily...
r21896 return ''
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('date')
Patrick Mezard
cmdutil: extract repo dependent closures in templatekw
r10055 def showdate(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """Date information. The date when the changeset was committed."""
Patrick Mezard
cmdutil: extract ctx dependent closures into templatekw
r10054 return ctx.date()
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('desc')
Patrick Mezard
cmdutil: extract repo dependent closures in templatekw
r10055 def showdescription(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """String. The text of the changeset description."""
Yuya Nishihara
templatekw: workaround for utf-8 round-trip of {desc}...
r28239 s = ctx.description()
if isinstance(s, encoding.localstr):
# try hard to preserve utf-8 bytes
return encoding.tolocal(encoding.fromlocal(s).strip())
else:
return s.strip()
Patrick Mezard
cmdutil: extract ctx dependent closures into templatekw
r10054
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('diffstat')
Patrick Mezard
cmdutil: extract repo dependent closures in templatekw
r10055 def showdiffstat(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """String. Statistics of changes with the following format:
Patrick Mezard
templates: generate keyword help dynamically
r13585 "modified files: +added/-removed lines"
"""
Matthieu Laneuville
templatekw: force noprefix=False to insure diffstat consistency (issue4755)...
r30811 stats = patch.diffstatdata(util.iterlines(ctx.diff(noprefix=False)))
Steven Brown
patch: restore the previous output of 'diff --stat'...
r14437 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
Matt Mackall
templatekw: use diffstatsum in diffstat keyword
r14403 return '%s: +%s/-%s' % (len(stats), adds, removes)
Patrick Mezard
cmdutil: extract repo dependent closures in templatekw
r10055
Matt Harbison
templater: add '{envvars}' to access environment variables...
r30833 @templatekeyword('envvars')
def showenvvars(repo, **args):
"""A dictionary of environment variables. (EXPERIMENTAL)"""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Matt Harbison
templater: add '{envvars}' to access environment variables...
r30833 env = repo.ui.exportableenviron()
env = util.sortdict((k, env[k]) for k in sorted(env))
Yuya Nishihara
templatekw: factor out showdict() helper...
r32038 return showdict('envvar', env, args, plural='envvars')
Matt Harbison
templater: add '{envvars}' to access environment variables...
r30833
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('extras')
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 def showextras(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of dicts with key, value entries of the 'extras'
Matthew Turk
help: document about {extras} template keyword...
r20015 field of this changeset."""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Matthew Turk
template: modify showextras to return a hybrid...
r20183 extras = args['ctx'].extra()
Yuya Nishihara
templatekw: convert list of key/value pairs to sortdict...
r24237 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
Yuya Nishihara
templatekw: give name to lambda that constructs variables map of templater...
r24238 makemap = lambda k: {'key': k, 'value': extras[k]}
c = [makemap(k) for k in extras]
Yuya Nishihara
templatekw: change _showlist() to take mapping dict with no **kwargs expansion...
r32036 f = _showlist('extra', c, args, plural='extras')
Yuya Nishihara
templatekw: keep raw list or dict in _hybrid object...
r24239 return _hybrid(f, extras, makemap,
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 lambda k: '%s=%s' % (k, util.escapestr(extras[k])))
Patrick Mezard
cmdutil: extract ctx dependent closures into templatekw
r10054
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('file_adds')
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 def showfileadds(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. Files added by this changeset."""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
Yuya Nishihara
templatekw: have showlist() take mapping dict with no **kwargs expansion (API)...
r32037 return showlist('file_add', getfiles(repo, ctx, revcache)[1], args,
element='file')
Patrick Mezard
cmdutil: extract file changes closures into templatekw
r10056
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('file_copies')
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 def showfilecopies(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. Files copied in this changeset with
Patrick Mezard
templates: generate keyword help dynamically
r13585 their sources.
"""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Benoit Boissinot
fix coding style (reported by pylint)
r10394 cache, ctx = args['cache'], args['ctx']
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 copies = args['revcache'].get('copies')
Patrick Mezard
templatekw: change {file_copies} behaviour, add {file_copies_switch}...
r10060 if copies is None:
if 'getrenamed' not in cache:
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 cache['getrenamed'] = getrenamedfn(args['repo'])
Patrick Mezard
templatekw: change {file_copies} behaviour, add {file_copies_switch}...
r10060 copies = []
getrenamed = cache['getrenamed']
for fn in ctx.files():
rename = getrenamed(fn, ctx.rev())
if rename:
copies.append((fn, rename[0]))
Matt Mackall
many, many trivial check-code fixups
r10282
Yuya Nishihara
templatekw: convert list of key/value pairs to sortdict...
r24237 copies = util.sortdict(copies)
Yuya Nishihara
templatekw: factor out showdict() helper...
r32038 return showdict('file_copy', copies, args, plural='file_copies',
key='name', value='source', fmt='%s (%s)')
Patrick Mezard
templatekw: change {file_copies} behaviour, add {file_copies_switch}...
r10060
# showfilecopiesswitch() displays file copies only if copy records are
# provided before calling the templater, usually with a --copies
# command line switch.
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('file_copies_switch')
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 def showfilecopiesswitch(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. Like "file_copies" but displayed
Patrick Mezard
templates: generate keyword help dynamically
r13585 only if the --copied switch is set.
"""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 copies = args['revcache'].get('copies') or []
Yuya Nishihara
templatekw: convert list of key/value pairs to sortdict...
r24237 copies = util.sortdict(copies)
Yuya Nishihara
templatekw: factor out showdict() helper...
r32038 return showdict('file_copy', copies, args, plural='file_copies',
key='name', value='source', fmt='%s (%s)')
Patrick Mezard
cmdutil: extract file copies closure into templatekw
r10058
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('file_dels')
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 def showfiledels(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. Files removed by this changeset."""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
Yuya Nishihara
templatekw: have showlist() take mapping dict with no **kwargs expansion (API)...
r32037 return showlist('file_del', getfiles(repo, ctx, revcache)[2], args,
element='file')
Patrick Mezard
cmdutil: extract file changes closures into templatekw
r10056
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('file_mods')
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 def showfilemods(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. Files modified by this changeset."""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
Yuya Nishihara
templatekw: have showlist() take mapping dict with no **kwargs expansion (API)...
r32037 return showlist('file_mod', getfiles(repo, ctx, revcache)[0], args,
element='file')
Patrick Mezard
cmdutil: extract file changes closures into templatekw
r10056
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('files')
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 def showfiles(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. All files modified, added, or removed by this
Patrick Mezard
templates: generate keyword help dynamically
r13585 changeset.
"""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Yuya Nishihara
templatekw: have showlist() take mapping dict with no **kwargs expansion (API)...
r32037 return showlist('file', args['ctx'].files(), args)
Patrick Mezard
cmdutil: extract ctx dependent closures into templatekw
r10054
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('graphnode')
Yuya Nishihara
graphlog: extract "graphnode" template keyword that represents node symbol...
r27214 def showgraphnode(repo, ctx, **args):
Yuya Nishihara
help: fix formatting of template keywords...
r34657 """String. The character representing the changeset node in an ASCII
revision graph."""
Yuya Nishihara
templatekw: avoid slow creation of changectx objects in showgraphnode()...
r27215 wpnodes = repo.dirstate.parents()
if wpnodes[1] == nullid:
wpnodes = wpnodes[:1]
Yuya Nishihara
graphlog: extract "graphnode" template keyword that represents node symbol...
r27214 if ctx.node() in wpnodes:
return '@'
elif ctx.obsolete():
return 'x'
av6
graphlog: add another graph node type, unstable, using character "*" (BC)
r35524 elif ctx.isunstable():
return '*'
Yuya Nishihara
graphlog: extract "graphnode" template keyword that represents node symbol...
r27214 elif ctx.closesbranch():
return '_'
else:
return 'o'
Danny Hooper
log: add a "graphwidth" template variable...
r33860 @templatekeyword('graphwidth')
def showgraphwidth(repo, ctx, templ, **args):
"""Integer. The width of the graph drawn by 'log --graph' or zero."""
# The value args['graphwidth'] will be this function, so we use an internal
# name to pass the value through props into this function.
return args.get('_graphwidth', 0)
Yuya Nishihara
templater: provide loop counter as "index" keyword...
r31807 @templatekeyword('index')
def showindex(**args):
"""Integer. The current iteration of the loop. (0 indexed)"""
# just hosts documentation; should be overridden by template mapping
raise error.Abort(_("can't use index in this context"))
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('latesttag')
Matt Harbison
templatekw: make {latesttag} a hybrid list...
r25727 def showlatesttag(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. The global tags on the most recent globally
Matt Harbison
templatekw: clarify the result of {latesttag} when no tag exists...
r31850 tagged ancestor of this changeset. If no such tags exist, the list
consists of the single string "null".
Patrick Mezard
templates: generate keyword help dynamically
r13585 """
Matt Harbison
templatekw: add {changes}, {distance} and {tag} to the {latesttag} keyword
r26486 return showlatesttags(None, **args)
Patrick Mezard
cmdutil: extract latest tags closures in templatekw
r10057
Matt Harbison
templatekw: introduce showlatesttags() to handle {latesttag} keywords...
r26484 def showlatesttags(pattern, **args):
"""helper method for the latesttag keyword and function"""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Matt Harbison
templatekw: introduce showlatesttags() to handle {latesttag} keywords...
r26484 repo, ctx = args['repo'], args['ctx']
cache = args['cache']
latesttags = getlatesttags(repo, ctx, cache, pattern)
# latesttag[0] is an implementation detail for sorting csets on different
# branches in a stable manner- it is the date the tagged cset was created,
# not the date the tag was created. Therefore it isn't made visible here.
makemap = lambda v: {
'changes': _showchangessincetag,
'distance': latesttags[1],
'latesttag': v, # BC with {latesttag % '{latesttag}'}
'tag': v
}
tags = latesttags[2]
Yuya Nishihara
templatekw: change _showlist() to take mapping dict with no **kwargs expansion...
r32036 f = _showlist('latesttag', tags, args, separator=':')
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 return _hybrid(f, tags, makemap, pycompat.identity)
Matt Harbison
templatekw: introduce showlatesttags() to handle {latesttag} keywords...
r26484
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('latesttagdistance')
Patrick Mezard
cmdutil: extract latest tags closures in templatekw
r10057 def showlatesttagdistance(repo, ctx, templ, cache, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """Integer. Longest path to the latest tag."""
Patrick Mezard
cmdutil: extract latest tags closures in templatekw
r10057 return getlatesttags(repo, ctx, cache)[1]
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('changessincelatesttag')
Matt Harbison
templatekw: introduce the changessincelatesttag keyword...
r25724 def showchangessincelatesttag(repo, ctx, templ, cache, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """Integer. All ancestors not in the latest tag."""
Matt Harbison
templatekw: introduce the changessincelatesttag keyword...
r25724 latesttag = getlatesttags(repo, ctx, cache)[2][0]
Matt Harbison
templatekw: factor out the changessincetag calculation to a private method...
r26483
return _showchangessincetag(repo, ctx, tag=latesttag, **args)
def _showchangessincetag(repo, ctx, **args):
Matt Harbison
templatekw: introduce the changessincelatesttag keyword...
r25724 offset = 0
revs = [ctx.rev()]
Pulkit Goyal
py3: use r'' to access values from kwargs where keys are str...
r32973 tag = args[r'tag']
Matt Harbison
templatekw: introduce the changessincelatesttag keyword...
r25724
# The only() revset doesn't currently support wdir()
if ctx.rev() is None:
offset = 1
revs = [p.rev() for p in ctx.parents()]
Matt Harbison
templatekw: factor out the changessincetag calculation to a private method...
r26483 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset
Matt Harbison
templatekw: introduce the changessincelatesttag keyword...
r25724
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('manifest')
Patrick Mezard
templatekw: fix extras, manifest and showlist args (issue1989)...
r10260 def showmanifest(**args):
Pulkit Goyal
py3: use r'' to access values from kwargs where keys are str...
r32973 repo, ctx, templ = args[r'repo'], args[r'ctx'], args[r'templ']
Yuya Nishihara
templatekw: have {manifest} use ctx.manifestnode() for consistency...
r24676 mnode = ctx.manifestnode()
Yuya Nishihara
templatekw: apply manifest template only if ctx.manifestnode() exists...
r25736 if mnode is None:
# just avoid crash, we might want to use the 'ff...' hash in future
return
Yuya Nishihara
templatekw: add new-style template expansion to {manifest}...
r34331 mrev = repo.manifestlog._revlog.rev(mnode)
mhex = hex(mnode)
Patrick Mezard
cmdutil: extract repo dependent closures in templatekw
r10055 args = args.copy()
Yuya Nishihara
templatekw: add new-style template expansion to {manifest}...
r34331 args.update({r'rev': mrev, r'node': mhex})
f = templ('manifest', **args)
# TODO: perhaps 'ctx' should be dropped from mapping because manifest
# rev and node are completely different from changeset's.
Yuya Nishihara
templater: wrap get/min/max result so map operation can apply to element...
r34535 return _mappable(f, None, f, lambda x: {'rev': mrev, 'node': mhex})
Patrick Mezard
cmdutil: extract repo dependent closures in templatekw
r10055
Boris Feld
templatekw: introduce obsfate keyword...
r34848 @templatekeyword('obsfate')
def showobsfate(**args):
# this function returns a list containing pre-formatted obsfate strings.
#
# This function will be replaced by templates fragments when we will have
# the verbosity templatekw available.
succsandmarkers = showsuccsandmarkers(**args)
Pulkit Goyal
py3: fix args handling for obsfate template...
r35143 args = pycompat.byteskwargs(args)
Boris Feld
templatekw: introduce obsfate keyword...
r34848 ui = args['ui']
values = []
for x in succsandmarkers:
values.append(obsutil.obsfateprinter(x['successors'], x['markers'], ui))
return showlist("fate", values, args)
Yuya Nishihara
templatekw: move shownames() helper to be sorted alphabetically...
r27893 def shownames(namespace, **args):
"""helper method to generate a template keyword for a namespace"""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Yuya Nishihara
templatekw: move shownames() helper to be sorted alphabetically...
r27893 ctx = args['ctx']
repo = ctx.repo()
ns = repo.names[namespace]
names = ns.names(repo, ctx.node())
Yuya Nishihara
templatekw: have showlist() take mapping dict with no **kwargs expansion (API)...
r32037 return showlist(ns.templatename, names, args, plural=namespace)
Yuya Nishihara
templatekw: move shownames() helper to be sorted alphabetically...
r27893
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('namespaces')
Yuya Nishihara
templatekw: add {namespaces} keyword...
r27894 def shownamespaces(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """Dict of lists. Names attached to this changeset per
Yuya Nishihara
templatekw: add {namespaces} keyword...
r27894 namespace."""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Yuya Nishihara
templatekw: add {namespaces} keyword...
r27894 ctx = args['ctx']
repo = ctx.repo()
Gregory Szorc
templatekw: expose color name in {namespaces} entries...
r33047
namespaces = util.sortdict()
Yuya Nishihara
templatekw: allow accessing to nested namespace item by its template name...
r34542 def makensmapfn(ns):
# 'name' for iterating over namespaces, templatename for local reference
return lambda v: {'name': v, ns.templatename: v}
Gregory Szorc
templatekw: expose color name in {namespaces} entries...
r33047
for k, ns in repo.names.iteritems():
Yuya Nishihara
templatekw: allow accessing to nested namespace item by its template name...
r34542 names = ns.names(repo, ctx.node())
f = _showlist('name', names, args)
namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
Gregory Szorc
templatekw: expose color name in {namespaces} entries...
r33047
Yuya Nishihara
templatekw: change _showlist() to take mapping dict with no **kwargs expansion...
r32036 f = _showlist('namespace', list(namespaces), args)
Gregory Szorc
templatekw: expose color name in {namespaces} entries...
r33047
def makemap(ns):
return {
'namespace': ns,
'names': namespaces[ns],
Yuya Nishihara
templatekw: get rid of temporary dicts from shownamespaces()
r34541 'builtin': repo.names[ns].builtin,
'colorname': repo.names[ns].colorname,
Gregory Szorc
templatekw: expose color name in {namespaces} entries...
r33047 }
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 return _hybrid(f, namespaces, makemap, pycompat.identity)
Yuya Nishihara
templatekw: add {namespaces} keyword...
r27894
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('node')
Patrick Mezard
cmdutil: extract repo dependent closures in templatekw
r10055 def shownode(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """String. The changeset identification hash, as a 40 hexadecimal
Patrick Mezard
templates: generate keyword help dynamically
r13585 digit string.
"""
Patrick Mezard
cmdutil: extract ctx dependent closures into templatekw
r10054 return ctx.hex()
Denis Laxalde
templatekw: add an "obsolete" keyword...
r31699 @templatekeyword('obsolete')
def showobsolete(repo, ctx, templ, **args):
Yuya Nishihara
help: hide template keywords of obsolescence as they are still experimental
r34658 """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
Denis Laxalde
templatekw: add an "obsolete" keyword...
r31699 if ctx.obsolete():
return 'obsolete'
return ''
Yuya Nishihara
templatekw: rename peerpaths to peerurls per naming convention (BC)...
r34540 @templatekeyword('peerurls')
def showpeerurls(repo, **args):
Yuya Nishihara
templatekw: export ui.paths as {peerpaths}...
r33414 """A dictionary of repository locations defined in the [paths] section
Yuya Nishihara
templatekw: rename peerpaths to peerurls per naming convention (BC)...
r34540 of your configuration file."""
Yuya Nishihara
templatekw: export ui.paths as {peerpaths}...
r33414 # see commands.paths() for naming of dictionary keys
Yuya Nishihara
templatekw: make experimental {peerpaths} return a single-level dict (BC)...
r34539 paths = repo.ui.paths
urls = util.sortdict((k, p.rawloc) for k, p in sorted(paths.iteritems()))
def makemap(k):
p = paths[k]
d = {'name': k, 'url': p.rawloc}
Yuya Nishihara
templatekw: export ui.paths as {peerpaths}...
r33414 d.update((o, v) for o, v in sorted(p.suboptions.iteritems()))
Yuya Nishihara
templatekw: make experimental {peerpaths} return a single-level dict (BC)...
r34539 return d
return _hybrid(None, urls, makemap, lambda k: '%s=%s' % (k, urls[k]))
Yuya Nishihara
templatekw: export ui.paths as {peerpaths}...
r33414
Boris Feld
template: add predecessors template...
r32879 @templatekeyword("predecessors")
def showpredecessors(repo, ctx, **args):
Yuya Nishihara
help: hide template keywords of obsolescence as they are still experimental
r34658 """Returns the list if the closest visible successors. (EXPERIMENTAL)"""
Boris Feld
template: add predecessors template...
r32879 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
predecessors = map(hex, predecessors)
Yuya Nishihara
templatekw: populate all keywords depending on predecessor in map operation...
r32910 return _hybrid(None, predecessors,
lambda x: {'ctx': repo[x], 'revcache': {}},
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 lambda x: scmutil.formatchangeid(repo[x]))
Boris Feld
template: add predecessors template...
r32879
Boris Feld
template: add successors template...
r33276 @templatekeyword("successorssets")
def showsuccessorssets(repo, ctx, **args):
Yuya Nishihara
help: fix formatting of template keywords...
r34657 """Returns a string of sets of successors for a changectx. Format used
is: [ctx1, ctx2], [ctx3] if ctx has been splitted into ctx1 and ctx2
Yuya Nishihara
help: hide template keywords of obsolescence as they are still experimental
r34658 while also diverged into ctx3. (EXPERIMENTAL)"""
Boris Feld
template: add successors template...
r33276 if not ctx.obsolete():
return ''
args = pycompat.byteskwargs(args)
ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
ssets = [[hex(n) for n in ss] for ss in ssets]
data = []
for ss in ssets:
h = _hybrid(None, ss, lambda x: {'ctx': repo[x], 'revcache': {}},
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 lambda x: scmutil.formatchangeid(repo[x]))
Boris Feld
template: add successors template...
r33276 data.append(h)
# Format the successorssets
def render(d):
t = []
Yuya Nishihara
formatter: fix default list/dict generator to be evaluated more than once...
r34426 for i in d.gen():
Boris Feld
template: add successors template...
r33276 t.append(i)
return "".join(t)
def gen(data):
yield "; ".join(render(d) for d in data)
return _hybrid(gen(data), data, lambda x: {'successorset': x},
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 pycompat.identity)
Boris Feld
template: add successors template...
r33276
Boris Feld
template: add minimal obsfate template function...
r33913 @templatekeyword("succsandmarkers")
def showsuccsandmarkers(repo, ctx, **args):
Yuya Nishihara
help: fix formatting of template keywords...
r34657 """Returns a list of dict for each final successor of ctx. The dict
contains successors node id in "successors" keys and the list of
obs-markers from ctx to the set of successors in "markers".
Boris Feld
template: add minimal obsfate template function...
r33913 (EXPERIMENTAL)
"""
values = obsutil.successorsandmarkers(repo, ctx)
if values is None:
values = []
# Format successors and markers to avoid exposing binary to templates
data = []
for i in values:
# Format successors
successors = i['successors']
successors = [hex(n) for n in successors]
successors = _hybrid(None, successors,
lambda x: {'ctx': repo[x], 'revcache': {}},
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 lambda x: scmutil.formatchangeid(repo[x]))
Boris Feld
template: add minimal obsfate template function...
r33913
# Format markers
finalmarkers = []
for m in i['markers']:
hexprec = hex(m[0])
hexsucs = tuple(hex(n) for n in m[1])
hexparents = None
if m[5] is not None:
hexparents = tuple(hex(n) for n in m[5])
newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
finalmarkers.append(newmarker)
data.append({'successors': successors, 'markers': finalmarkers})
f = _showlist('succsandmarkers', data, args)
Yuya Nishihara
templatekw: just pass underlying value (or key) to joinfmt() function...
r34329 return _hybrid(f, data, lambda x: x, pycompat.identity)
Boris Feld
template: add minimal obsfate template function...
r33913
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('p1rev')
epriestley
templatekw: add p1rev, p1node, p2rev, p2node keywords...
r17357 def showp1rev(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """Integer. The repository-local revision number of the changeset's
epriestley
templatekw: add p1rev, p1node, p2rev, p2node keywords...
r17357 first parent, or -1 if the changeset has no parents."""
return ctx.p1().rev()
epriestley
templatekw: add parent1, parent1node, parent2, parent2node keywords...
r17355
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('p2rev')
epriestley
templatekw: add p1rev, p1node, p2rev, p2node keywords...
r17357 def showp2rev(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """Integer. The repository-local revision number of the changeset's
epriestley
templatekw: add p1rev, p1node, p2rev, p2node keywords...
r17357 second parent, or -1 if the changeset has no second parent."""
return ctx.p2().rev()
epriestley
templatekw: add parent1, parent1node, parent2, parent2node keywords...
r17355
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('p1node')
epriestley
templatekw: add p1rev, p1node, p2rev, p2node keywords...
r17357 def showp1node(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """String. The identification hash of the changeset's first parent,
epriestley
templatekw: add p1rev, p1node, p2rev, p2node keywords...
r17357 as a 40 digit hexadecimal string. If the changeset has no parents, all
digits are 0."""
return ctx.p1().hex()
epriestley
templatekw: add parent1, parent1node, parent2, parent2node keywords...
r17355
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('p2node')
epriestley
templatekw: add p1rev, p1node, p2rev, p2node keywords...
r17357 def showp2node(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """String. The identification hash of the changeset's second
epriestley
templatekw: add p1rev, p1node, p2rev, p2node keywords...
r17357 parent, as a 40 digit hexadecimal string. If the changeset has no second
parent, all digits are 0."""
return ctx.p2().hex()
epriestley
templatekw: add parent1, parent1node, parent2, parent2node keywords...
r17355
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('parents')
Yuya Nishihara
templatekw: port implementation of showparents() from changeset_templater...
r26435 def showparents(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. The parents of the changeset in "rev:node"
Yuya Nishihara
templatekw: reorder stub of showparents() function...
r26434 format. If the changeset has only one "natural" parent (the predecessor
revision) nothing is shown."""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Yuya Nishihara
templatekw: port implementation of showparents() from changeset_templater...
r26435 repo = args['repo']
ctx = args['ctx']
Yuya Nishihara
templatekw: switch ctx of list expression to rev of {parents} (BC)...
r28270 pctxs = scmutil.meaningfulparents(repo, ctx)
Yuya Nishihara
templater: store revisions as ints so min/max won't compare them as strings...
r34582 prevs = [p.rev() for p in pctxs]
Yuya Nishihara
templatekw: port implementation of showparents() from changeset_templater...
r26435 parents = [[('rev', p.rev()),
('node', p.hex()),
('phase', p.phasestr())]
Yuya Nishihara
templatekw: switch ctx of list expression to rev of {parents} (BC)...
r28270 for p in pctxs]
Yuya Nishihara
templatekw: change _showlist() to take mapping dict with no **kwargs expansion...
r32036 f = _showlist('parent', parents, args)
Yuya Nishihara
templater: store revisions as ints so min/max won't compare them as strings...
r34582 return _hybrid(f, prevs, lambda x: {'ctx': repo[x], 'revcache': {}},
lambda x: scmutil.formatchangeid(repo[x]), keytype=int)
Yuya Nishihara
templatekw: reorder stub of showparents() function...
r26434
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('phase')
Pierre-Yves David
phases: add a phase template keyword
r15422 def showphase(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """String. The changeset phase name."""
Pierre-Yves David
phases: ``{phase}`` template keyword display the phase name...
r15823 return ctx.phasestr()
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('phaseidx')
Pierre-Yves David
phases: ``{phase}`` template keyword display the phase name...
r15823 def showphaseidx(repo, ctx, templ, **args):
Yuya Nishihara
help: hide phaseidx template keyword...
r34992 """Integer. The changeset phase index. (ADVANCED)"""
Pierre-Yves David
phases: add a phase template keyword
r15422 return ctx.phase()
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('rev')
Patrick Mezard
cmdutil: extract repo dependent closures in templatekw
r10055 def showrev(repo, ctx, templ, **args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """Integer. The repository-local changeset revision number."""
Yuya Nishihara
scmutil: pass ctx object to intrev()...
r32654 return scmutil.intrev(ctx)
Patrick Mezard
cmdutil: extract ctx dependent closures into templatekw
r10054
Yuya Nishihara
templater: switch ctx of list expression to rev of revset() (BC)...
r26234 def showrevslist(name, revs, **args):
"""helper to generate a list of revisions in which a mapped template will
be evaluated"""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Yuya Nishihara
templater: switch ctx of list expression to rev of revset() (BC)...
r26234 repo = args['ctx'].repo()
Yuya Nishihara
templater: store revisions as ints so min/max won't compare them as strings...
r34582 f = _showlist(name, ['%d' % r for r in revs], args)
Yuya Nishihara
templater: switch ctx of list expression to rev of revset() (BC)...
r26234 return _hybrid(f, revs,
Yuya Nishihara
templater: store revisions as ints so min/max won't compare them as strings...
r34582 lambda x: {name: x, 'ctx': repo[x], 'revcache': {}},
pycompat.identity, keytype=int)
Yuya Nishihara
templater: switch ctx of list expression to rev of revset() (BC)...
r26234
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('subrepos')
FUJIWARA Katsunori
templatekw: add 'subrepos' keyword to show updated subrepositories...
r21897 def showsubrepos(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. Updated subrepositories in the changeset."""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
FUJIWARA Katsunori
templatekw: add 'subrepos' keyword to show updated subrepositories...
r21897 ctx = args['ctx']
substate = ctx.substate
if not substate:
Yuya Nishihara
templatekw: have showlist() take mapping dict with no **kwargs expansion (API)...
r32037 return showlist('subrepo', [], args)
FUJIWARA Katsunori
templatekw: add 'subrepos' keyword to show updated subrepositories...
r21897 psubstate = ctx.parents()[0].substate or {}
subrepos = []
for sub in substate:
if sub not in psubstate or substate[sub] != psubstate[sub]:
subrepos.append(sub) # modified or newly added in ctx
for sub in psubstate:
if sub not in substate:
subrepos.append(sub) # removed in ctx
Yuya Nishihara
templatekw: have showlist() take mapping dict with no **kwargs expansion (API)...
r32037 return showlist('subrepo', sorted(subrepos), args)
FUJIWARA Katsunori
templatekw: add 'subrepos' keyword to show updated subrepositories...
r21897
FUJIWARA Katsunori
templatekw: re-add showtags() to list tags keyword up in online help...
r23977 # don't remove "showtags" definition, even though namespaces will put
# a helper function for "tags" keyword into "keywords" map automatically,
# because online help text is built without namespaces initialization
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 @templatekeyword('tags')
FUJIWARA Katsunori
templatekw: re-add showtags() to list tags keyword up in online help...
r23977 def showtags(**args):
FUJIWARA Katsunori
templatekw: use templatekeyword to mark a function as template keyword...
r28539 """List of strings. Any tags associated with the changeset."""
FUJIWARA Katsunori
templatekw: re-add showtags() to list tags keyword up in online help...
r23977 return shownames('tags', **args)
Simon Farnsworth
template: provide a termwidth keyword (issue5395)...
r30088 @templatekeyword('termwidth')
Yuya Nishihara
templatekw: rename termwidth() per convention
r33850 def showtermwidth(repo, ctx, templ, **args):
Simon Farnsworth
template: provide a termwidth keyword (issue5395)...
r30088 """Integer. The width of the current terminal."""
return repo.ui.termwidth()
Boris Feld
template: rename troubles templatekw into instabilities...
r33675 @templatekeyword('instabilities')
def showinstabilities(**args):
"""List of strings. Evolution instabilities affecting the changeset.
Denis Laxalde
templatekw: add a "troubles" template keyword...
r30712 (EXPERIMENTAL)
"""
Pulkit Goyal
py3: convert keys of kwargs in template keywords functions to bytes...
r32972 args = pycompat.byteskwargs(args)
Yuya Nishihara
templatekw: specify plural form of instability...
r33851 return showlist('instability', args['ctx'].instabilities(), args,
plural='instabilities')
Denis Laxalde
templatekw: add a "troubles" template keyword...
r30712
Yuya Nishihara
templatekw: add verbosity keyword to select template by -q/-v/--debug flag...
r34994 @templatekeyword('verbosity')
def showverbosity(ui, **args):
"""String. The current output verbosity in 'debug', 'quiet', 'verbose',
or ''."""
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 # see logcmdutil.changesettemplater for priority of these flags
Yuya Nishihara
templatekw: add verbosity keyword to select template by -q/-v/--debug flag...
r34994 if ui.debugflag:
return 'debug'
elif ui.quiet:
return 'quiet'
elif ui.verbose:
return 'verbose'
return ''
Yuya Nishihara
templatekw: move loadkeyword() to bottom...
r34993 def loadkeyword(ui, extname, registrarobj):
"""Load template keyword from specified registrarobj
"""
for name, func in registrarobj._table.iteritems():
keywords[name] = func
Patrick Mezard
templates: generate keyword help dynamically
r13585 # tell hggettext to extract docstrings from these functions:
Yuya Nishihara
templatekw: remove dockeywords hack...
r26436 i18nfunctions = keywords.values()