Show More
@@ -72,6 +72,11 b' As seen in the above example, ``{templat' | |||
|
72 | 72 | To prevent it from being interpreted, you can use an escape character ``\{`` |
|
73 | 73 | or a raw string prefix, ``r'...'``. |
|
74 | 74 | |
|
75 | The dot operator can be used as a shorthand for accessing a sub item: | |
|
76 | ||
|
77 | - ``expr.member`` is roughly equivalent to ``expr % "{member}"`` if ``expr`` | |
|
78 | returns a non-list/dict. The returned value is not stringified. | |
|
79 | ||
|
75 | 80 | Aliases |
|
76 | 81 | ======= |
|
77 | 82 |
@@ -73,6 +73,7 b' class _mappable(object):' | |||
|
73 | 73 | This class allows us to handle both: |
|
74 | 74 | - "{manifest}" |
|
75 | 75 | - "{manifest % '{rev}:{node}'}" |
|
76 | - "{manifest.rev}" | |
|
76 | 77 | |
|
77 | 78 | Unlike a _hybrid, this does not simulate the behavior of the underling |
|
78 | 79 | value. Use unwrapvalue() or unwraphybrid() to obtain the inner object. |
@@ -35,6 +35,7 b' from . import (' | |||
|
35 | 35 | elements = { |
|
36 | 36 | # token-type: binding-strength, primary, prefix, infix, suffix |
|
37 | 37 | "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None), |
|
38 | ".": (18, None, None, (".", 18), None), | |
|
38 | 39 | "%": (15, None, None, ("%", 15), None), |
|
39 | 40 | "|": (15, None, None, ("|", 15), None), |
|
40 | 41 | "*": (5, None, None, ("*", 5), None), |
@@ -60,7 +61,7 b' def tokenize(program, start, end, term=N' | |||
|
60 | 61 | c = program[pos] |
|
61 | 62 | if c.isspace(): # skip inter-token whitespace |
|
62 | 63 | pass |
|
63 | elif c in "(=,)%|+-*/": # handle simple operators | |
|
64 | elif c in "(=,).%|+-*/": # handle simple operators | |
|
64 | 65 | yield (c, None, pos) |
|
65 | 66 | elif c in '"\'': # handle quoted templates |
|
66 | 67 | s = pos + 1 |
@@ -450,6 +451,26 b' def runmap(context, mapping, data):' | |||
|
450 | 451 | # If so, return the expanded value. |
|
451 | 452 | yield v |
|
452 | 453 | |
|
454 | def buildmember(exp, context): | |
|
455 | darg = compileexp(exp[1], context, methods) | |
|
456 | memb = getsymbol(exp[2]) | |
|
457 | return (runmember, (darg, memb)) | |
|
458 | ||
|
459 | def runmember(context, mapping, data): | |
|
460 | darg, memb = data | |
|
461 | d = evalrawexp(context, mapping, darg) | |
|
462 | if util.safehasattr(d, 'tomap'): | |
|
463 | lm = mapping.copy() | |
|
464 | lm.update(d.tomap()) | |
|
465 | return runsymbol(context, lm, memb) | |
|
466 | # TODO: d.get(memb) if dict-like? | |
|
467 | ||
|
468 | sym = findsymbolicname(darg) | |
|
469 | if sym: | |
|
470 | raise error.ParseError(_("keyword '%s' has no member") % sym) | |
|
471 | else: | |
|
472 | raise error.ParseError(_("%r has no member") % d) | |
|
473 | ||
|
453 | 474 | def buildnegate(exp, context): |
|
454 | 475 | arg = compileexp(exp[1], context, exprmethods) |
|
455 | 476 | return (runnegate, arg) |
@@ -1152,7 +1173,7 b' exprmethods = {' | |||
|
1152 | 1173 | "symbol": lambda e, c: (runsymbol, e[1]), |
|
1153 | 1174 | "template": buildtemplate, |
|
1154 | 1175 | "group": lambda e, c: compileexp(e[1], c, exprmethods), |
|
1155 |
|
|
|
1176 | ".": buildmember, | |
|
1156 | 1177 | "|": buildfilter, |
|
1157 | 1178 | "%": buildmap, |
|
1158 | 1179 | "func": buildfunc, |
@@ -3147,6 +3147,51 b' Test manifest/get() can be join()-ed as ' | |||
|
3147 | 3147 | $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), "")}\n' |
|
3148 | 3148 | default |
|
3149 | 3149 | |
|
3150 | Test dot operator precedence: | |
|
3151 | ||
|
3152 | $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n' | |
|
3153 | (template | |
|
3154 | (| | |
|
3155 | (. | |
|
3156 | (symbol 'manifest') | |
|
3157 | (symbol 'node')) | |
|
3158 | (symbol 'short')) | |
|
3159 | (string '\n')) | |
|
3160 | 89f4071fec70 | |
|
3161 | ||
|
3162 | (the following examples are invalid, but seem natural in parsing POV) | |
|
3163 | ||
|
3164 | $ hg debugtemplate -R latesttag -r0 -v '{foo|bar.baz}\n' 2> /dev/null | |
|
3165 | (template | |
|
3166 | (| | |
|
3167 | (symbol 'foo') | |
|
3168 | (. | |
|
3169 | (symbol 'bar') | |
|
3170 | (symbol 'baz'))) | |
|
3171 | (string '\n')) | |
|
3172 | [255] | |
|
3173 | $ hg debugtemplate -R latesttag -r0 -v '{foo.bar()}\n' 2> /dev/null | |
|
3174 | (template | |
|
3175 | (. | |
|
3176 | (symbol 'foo') | |
|
3177 | (func | |
|
3178 | (symbol 'bar') | |
|
3179 | None)) | |
|
3180 | (string '\n')) | |
|
3181 | [255] | |
|
3182 | ||
|
3183 | Test evaluation of dot operator: | |
|
3184 | ||
|
3185 | $ hg log -R latesttag -l1 -T '{min(revset("0:9")).node}\n' | |
|
3186 | ce3cec86e6c26bd9bdfc590a6b92abc9680f1796 | |
|
3187 | ||
|
3188 | $ hg log -R latesttag -l1 -T '{author.invalid}\n' | |
|
3189 | hg: parse error: keyword 'author' has no member | |
|
3190 | [255] | |
|
3191 | $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n' | |
|
3192 | hg: parse error: 'a' has no member | |
|
3193 | [255] | |
|
3194 | ||
|
3150 | 3195 | Test the sub function of templating for expansion: |
|
3151 | 3196 | |
|
3152 | 3197 | $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n' |
General Comments 0
You need to be logged in to leave comments.
Login now