# HG changeset patch # User Simon Farnsworth <simon...@fb.com> # Date 1475943860 25200 # Sat Oct 08 09:24:20 2016 -0700 # Node ID e89699ba5c9f0bf883bfae7c485e50219b90b2f9 # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 templater: provide ring operations on integers
The termwidth template keyword is of limited use without some way to ensure that margins are respected. Provide the three core ring operations - addition, subtraction and multiplication. We can extend to division and modulus later if necessary. diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -33,6 +33,9 @@ "|": (5, None, None, ("|", 5), None), "%": (6, None, None, ("%", 6), None), ")": (0, None, None, None, None), + "+": (10, None, None, ("+", 10), None), + "-": (10, None, ("negate", 10), ("-", 10), None), + "*": (12, None, None, ("*", 12), None), "integer": (0, "integer", None, None, None), "symbol": (0, "symbol", None, None, None), "string": (0, "string", None, None, None), @@ -48,7 +51,7 @@ c = program[pos] if c.isspace(): # skip inter-token whitespace pass - elif c in "(,)%|": # handle simple operators + elif c in "(,)%|+-*": # handle simple operators yield (c, None, pos) elif c in '"\'': # handle quoted templates s = pos + 1 @@ -70,7 +73,7 @@ pos += 1 else: raise error.ParseError(_("unterminated string"), s) - elif c.isdigit() or c == '-': + elif c.isdigit(): s = pos if c == '-': # simply take negate operator as part of integer pos += 1 @@ -420,6 +423,29 @@ # If so, return the expanded value. yield i +def buildnegate(exp, context): + arg = compileexp(exp[1], context, exprmethods) + return (runnegate, arg) + +def runnegate(context, mapping, data): + data = evalinteger(context, mapping, data, + _('negation needs an integer argument')) + return -data + + +def buildarithmetic(exp, context, func): + left = compileexp(exp[1], context, exprmethods) + right = compileexp(exp[2], context, exprmethods) + return (runarithmetic, (func, left, right)) + +def runarithmetic(context, mapping, data): + func, left, right = data + left = evalinteger(context, mapping, left, + _('arithmetic only defined on integers')) + right = evalinteger(context, mapping, right, + _('arithmetic only defined on integers')) + return func(left, right) + def buildfunc(exp, context): n = getsymbol(exp[1]) args = [compileexp(x, context, exprmethods) for x in getlist(exp[2])] @@ -906,6 +932,7 @@ # methods to interpret function arguments or inner expressions (e.g. {_(x)}) exprmethods = { "integer": lambda e, c: (runinteger, e[1]), + "negate": lambda e, c: (runinteger, e[1]), "string": lambda e, c: (runstring, e[1]), "symbol": lambda e, c: (runsymbol, e[1]), "template": buildtemplate, @@ -914,6 +941,10 @@ "|": buildfilter, "%": buildmap, "func": buildfunc, + "+": lambda e, c: buildarithmetic(e, c, lambda a, b: a + b), + "-": lambda e, c: buildarithmetic(e, c, lambda a, b: a - b), + "negate": buildnegate, + "*": lambda e, c: buildarithmetic(e, c, lambda a, b: a * b), } # methods to interpret top-level template (e.g. {x}, {x|_}, {x % "y"}) diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -5,6 +5,8 @@ $ echo line 1 > b $ echo line 2 >> b $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>' + $ hg log -T '{date(date, "%s") + 1} {date(date, "%s") - 2 * 1}\n' + 1000001 999998 $ hg add b $ echo other 1 > c @@ -2890,14 +2892,15 @@ $ hg debugtemplate -v '{(-4)}\n' (template (group - ('integer', '-4')) + (negate + ('integer', '4'))) ('string', '\n')) -4 $ hg debugtemplate '{(-)}\n' - hg: parse error at 2: integer literal without digits + hg: parse error at 3: not a prefix: ) [255] $ hg debugtemplate '{(-a)}\n' - hg: parse error at 2: integer literal without digits + hg: parse error: negation needs an integer argument [255] top-level integer literal is interpreted as symbol (i.e. variable name): _______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel