##// END OF EJS Templates
templater: load and expand aliases by template engine (API) (issue4842)...
Yuya Nishihara -
r28957:d813132e default
parent child Browse files
Show More
@@ -197,7 +197,8 b' def gettemplater(ui, topic, spec):'
197
197
198 def maketemplater(ui, topic, tmpl, filters=None, cache=None):
198 def maketemplater(ui, topic, tmpl, filters=None, cache=None):
199 """Create a templater from a string template 'tmpl'"""
199 """Create a templater from a string template 'tmpl'"""
200 t = templater.templater(filters=filters, cache=cache)
200 aliases = ui.configitems('templatealias')
201 t = templater.templater(filters=filters, cache=cache, aliases=aliases)
201 if tmpl:
202 if tmpl:
202 t.cache[topic] = tmpl
203 t.cache[topic] = tmpl
203 return t
204 return t
@@ -1488,6 +1488,11 b' Relative subrepository paths are first m'
1488 rewrite rules are then applied on the full (absolute) path. The rules
1488 rewrite rules are then applied on the full (absolute) path. The rules
1489 are applied in definition order.
1489 are applied in definition order.
1490
1490
1491 ``templatealias``
1492 -----------------
1493
1494 Alias definitions for templates. See :hg:`help templates` for details.
1495
1491 ``trusted``
1496 ``trusted``
1492 -----------
1497 -----------
1493
1498
@@ -51,6 +51,26 b' As seen in the above example, ``{templat'
51 To prevent it from being interpreted, you can use an escape character ``\{``
51 To prevent it from being interpreted, you can use an escape character ``\{``
52 or a raw string prefix, ``r'...'``.
52 or a raw string prefix, ``r'...'``.
53
53
54 New keywords and functions can be defined in the ``templatealias`` section of
55 a Mercurial configuration file::
56
57 <alias> = <definition>
58
59 Arguments of the form `a1`, `a2`, etc. are substituted from the alias into
60 the definition.
61
62 For example,
63
64 ::
65
66 [templatealias]
67 r = rev
68 rn = "{r}:{node|short}"
69 leftpad(s, w) = pad(s, w, ' ', True)
70
71 defines two symbol aliases, ``r`` and ``rn``, and a function alias
72 ``leftpad()``.
73
54 Some sample command line templates:
74 Some sample command line templates:
55
75
56 - Format lists, e.g. files::
76 - Format lists, e.g. files::
@@ -936,7 +936,7 b' class engine(object):'
936 filter uses function to transform value. syntax is
936 filter uses function to transform value. syntax is
937 {key|filter1|filter2|...}.'''
937 {key|filter1|filter2|...}.'''
938
938
939 def __init__(self, loader, filters=None, defaults=None):
939 def __init__(self, loader, filters=None, defaults=None, aliases=()):
940 self._loader = loader
940 self._loader = loader
941 if filters is None:
941 if filters is None:
942 filters = {}
942 filters = {}
@@ -944,6 +944,7 b' class engine(object):'
944 if defaults is None:
944 if defaults is None:
945 defaults = {}
945 defaults = {}
946 self._defaults = defaults
946 self._defaults = defaults
947 self._aliasmap = _aliasrules.buildmap(aliases)
947 self._cache = {} # key: (func, data)
948 self._cache = {} # key: (func, data)
948
949
949 def _load(self, t):
950 def _load(self, t):
@@ -953,6 +954,8 b' class engine(object):'
953 self._cache[t] = (_runrecursivesymbol, t)
954 self._cache[t] = (_runrecursivesymbol, t)
954 try:
955 try:
955 x = parse(self._loader(t))
956 x = parse(self._loader(t))
957 if self._aliasmap:
958 x = _aliasrules.expand(self._aliasmap, x)
956 self._cache[t] = compileexp(x, self, methods)
959 self._cache[t] = compileexp(x, self, methods)
957 except: # re-raises
960 except: # re-raises
958 del self._cache[t]
961 del self._cache[t]
@@ -1014,11 +1017,13 b' class TemplateNotFound(error.Abort):'
1014
1017
1015 class templater(object):
1018 class templater(object):
1016
1019
1017 def __init__(self, filters=None, defaults=None, cache=None,
1020 def __init__(self, filters=None, defaults=None, cache=None, aliases=(),
1018 minchunk=1024, maxchunk=65536):
1021 minchunk=1024, maxchunk=65536):
1019 '''set up template engine.
1022 '''set up template engine.
1020 filters is dict of functions. each transforms a value into another.
1023 filters is dict of functions. each transforms a value into another.
1021 defaults is dict of default map definitions.'''
1024 defaults is dict of default map definitions.
1025 aliases is list of alias (name, replacement) pairs.
1026 '''
1022 if filters is None:
1027 if filters is None:
1023 filters = {}
1028 filters = {}
1024 if defaults is None:
1029 if defaults is None:
@@ -1030,6 +1035,7 b' class templater(object):'
1030 self.filters = templatefilters.filters.copy()
1035 self.filters = templatefilters.filters.copy()
1031 self.filters.update(filters)
1036 self.filters.update(filters)
1032 self.defaults = defaults
1037 self.defaults = defaults
1038 self._aliases = aliases
1033 self.minchunk, self.maxchunk = minchunk, maxchunk
1039 self.minchunk, self.maxchunk = minchunk, maxchunk
1034 self.ecache = {}
1040 self.ecache = {}
1035
1041
@@ -1037,7 +1043,7 b' class templater(object):'
1037 def frommapfile(cls, mapfile, filters=None, defaults=None, cache=None,
1043 def frommapfile(cls, mapfile, filters=None, defaults=None, cache=None,
1038 minchunk=1024, maxchunk=65536):
1044 minchunk=1024, maxchunk=65536):
1039 """Create templater from the specified map file"""
1045 """Create templater from the specified map file"""
1040 t = cls(filters, defaults, cache, minchunk, maxchunk)
1046 t = cls(filters, defaults, cache, [], minchunk, maxchunk)
1041 cache, tmap = _readmapfile(mapfile)
1047 cache, tmap = _readmapfile(mapfile)
1042 t.cache.update(cache)
1048 t.cache.update(cache)
1043 t.map = tmap
1049 t.map = tmap
@@ -1066,7 +1072,8 b' class templater(object):'
1066 ecls = engines[ttype]
1072 ecls = engines[ttype]
1067 except KeyError:
1073 except KeyError:
1068 raise error.Abort(_('invalid template engine: %s') % ttype)
1074 raise error.Abort(_('invalid template engine: %s') % ttype)
1069 self.ecache[ttype] = ecls(self.load, self.filters, self.defaults)
1075 self.ecache[ttype] = ecls(self.load, self.filters, self.defaults,
1076 self._aliases)
1070 proc = self.ecache[ttype]
1077 proc = self.ecache[ttype]
1071
1078
1072 stream = proc.process(t, mapping)
1079 stream = proc.process(t, mapping)
@@ -3693,8 +3693,7 b' Templater supports aliases of symbol and'
3693 ('string', 'UTC')))
3693 ('string', 'UTC')))
3694 ('symbol', 'isodate'))
3694 ('symbol', 'isodate'))
3695 ('string', '\n'))
3695 ('string', '\n'))
3696 hg: parse error: unknown function 'utcdate'
3696 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3697 [255]
3698
3697
3699 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
3698 $ hg debugtemplate -vr0 '{status("A", file_adds)}'
3700 (template
3699 (template
@@ -3712,8 +3711,7 b' Templater supports aliases of symbol and'
3712 ('string', ' ')
3711 ('string', ' ')
3713 ('symbol', 'file')
3712 ('symbol', 'file')
3714 ('string', '\n'))))
3713 ('string', '\n'))))
3715 hg: parse error: unknown function 'status'
3714 A a
3716 [255]
3717
3715
3718 A unary function alias can be called as a filter:
3716 A unary function alias can be called as a filter:
3719
3717
@@ -3735,8 +3733,28 b' A unary function alias can be called as '
3735 ('string', 'UTC')))
3733 ('string', 'UTC')))
3736 ('symbol', 'isodate'))
3734 ('symbol', 'isodate'))
3737 ('string', '\n'))
3735 ('string', '\n'))
3738 hg: parse error: unknown function 'utcdate'
3736 1970-01-12 13:46 +0000
3739 [255]
3737
3738 Aliases should be applied only to command arguments and templates in hgrc.
3739 Otherwise, our stock styles and web templates could be corrupted:
3740
3741 $ hg log -r0 -T '{rn} {utcdate(date)|isodate}\n'
3742 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3743
3744 $ hg log -r0 --config ui.logtemplate='"{rn} {utcdate(date)|isodate}\n"'
3745 0:1e4e1b8f71e0 1970-01-12 13:46 +0000
3746
3747 $ cat <<EOF > tmpl
3748 > changeset = 'nothing expanded:{rn}\n'
3749 > EOF
3750 $ hg log -r0 --style ./tmpl
3751 nothing expanded:
3752
3753 Aliases in formatter:
3754
3755 $ hg branches -T '{pad(branch, 7)} {rn}\n'
3756 default 6:d41e714fe50d
3757 foo 4:bbe44766e73d
3740
3758
3741 Unparsable alias:
3759 Unparsable alias:
3742
3760
@@ -3745,6 +3763,9 b' Unparsable alias:'
3745 ('symbol', 'bad'))
3763 ('symbol', 'bad'))
3746 abort: failed to parse the definition of template alias "bad": at 2: not a prefix: end
3764 abort: failed to parse the definition of template alias "bad": at 2: not a prefix: end
3747 [255]
3765 [255]
3766 $ hg log --config templatealias.bad='x(' -T '{bad}'
3767 abort: failed to parse the definition of template alias "bad": at 2: not a prefix: end
3768 [255]
3748
3769
3749 $ cd ..
3770 $ cd ..
3750
3771
@@ -4,7 +4,7 b''
4 > from mercurial import templater
4 > from mercurial import templater
5 >
5 >
6 > class mytemplater(object):
6 > class mytemplater(object):
7 > def __init__(self, loader, filters, defaults):
7 > def __init__(self, loader, filters, defaults, aliases):
8 > self.loader = loader
8 > self.loader = loader
9 >
9 >
10 > def process(self, t, map):
10 > def process(self, t, map):
General Comments 0
You need to be logged in to leave comments. Login now