Show More
@@ -393,9 +393,7 b' def templatelabel(context, mapping, args' | |||||
393 | if isinstance(repo, str): |
|
393 | if isinstance(repo, str): | |
394 | return thing |
|
394 | return thing | |
395 |
|
395 | |||
396 |
label = templater. |
|
396 | label = templater._evalifliteral(args[0], context, mapping) | |
397 | label = templater.runtemplate(context, mapping, |
|
|||
398 | templater.compiletemplate(label, context)) |
|
|||
399 |
|
397 | |||
400 | thing = templater.stringify(thing) |
|
398 | thing = templater.stringify(thing) | |
401 | label = templater.stringify(label) |
|
399 | label = templater.stringify(label) |
@@ -21,6 +21,7 b' elements = {' | |||||
21 | ")": (0, None, None), |
|
21 | ")": (0, None, None), | |
22 | "symbol": (0, ("symbol",), None), |
|
22 | "symbol": (0, ("symbol",), None), | |
23 | "string": (0, ("string",), None), |
|
23 | "string": (0, ("string",), None), | |
|
24 | "rawstring": (0, ("rawstring",), None), | |||
24 | "end": (0, None, None), |
|
25 | "end": (0, None, None), | |
25 | } |
|
26 | } | |
26 |
|
27 | |||
@@ -50,7 +51,7 b' def tokenizer(data):' | |||||
50 | continue |
|
51 | continue | |
51 | if d == c: |
|
52 | if d == c: | |
52 | if not decode: |
|
53 | if not decode: | |
53 |
yield ('string', program[s:pos] |
|
54 | yield ('rawstring', program[s:pos], s) | |
54 | break |
|
55 | break | |
55 | yield ('string', program[s:pos], s) |
|
56 | yield ('string', program[s:pos], s) | |
56 | break |
|
57 | break | |
@@ -76,23 +77,22 b' def tokenizer(data):' | |||||
76 | pos += 1 |
|
77 | pos += 1 | |
77 | yield ('end', None, pos) |
|
78 | yield ('end', None, pos) | |
78 |
|
79 | |||
79 | def compiletemplate(tmpl, context): |
|
80 | def compiletemplate(tmpl, context, strtoken="string"): | |
80 | parsed = [] |
|
81 | parsed = [] | |
81 | pos, stop = 0, len(tmpl) |
|
82 | pos, stop = 0, len(tmpl) | |
82 | p = parser.parser(tokenizer, elements) |
|
83 | p = parser.parser(tokenizer, elements) | |
83 | while pos < stop: |
|
84 | while pos < stop: | |
84 | n = tmpl.find('{', pos) |
|
85 | n = tmpl.find('{', pos) | |
85 | if n < 0: |
|
86 | if n < 0: | |
86 |
parsed.append(( |
|
87 | parsed.append((strtoken, tmpl[pos:])) | |
87 | break |
|
88 | break | |
88 | if n > 0 and tmpl[n - 1] == '\\': |
|
89 | if n > 0 and tmpl[n - 1] == '\\': | |
89 | # escaped |
|
90 | # escaped | |
90 |
parsed.append((" |
|
91 | parsed.append((strtoken, (tmpl[pos:n - 1] + "{"))) | |
91 | (tmpl[pos:n - 1] + "{").decode("string-escape"))) |
|
|||
92 | pos = n + 1 |
|
92 | pos = n + 1 | |
93 | continue |
|
93 | continue | |
94 | if n > pos: |
|
94 | if n > pos: | |
95 |
parsed.append(( |
|
95 | parsed.append((strtoken, tmpl[pos:n])) | |
96 |
|
96 | |||
97 | pd = [tmpl, n + 1, stop] |
|
97 | pd = [tmpl, n + 1, stop] | |
98 | parseres, pos = p.parse(pd) |
|
98 | parseres, pos = p.parse(pd) | |
@@ -127,13 +127,16 b' def getfilter(exp, context):' | |||||
127 | return context._filters[f] |
|
127 | return context._filters[f] | |
128 |
|
128 | |||
129 | def gettemplate(exp, context): |
|
129 | def gettemplate(exp, context): | |
130 | if exp[0] == 'string': |
|
130 | if exp[0] == 'string' or exp[0] == 'rawstring': | |
131 | return compiletemplate(exp[1], context) |
|
131 | return compiletemplate(exp[1], context, strtoken=exp[0]) | |
132 | if exp[0] == 'symbol': |
|
132 | if exp[0] == 'symbol': | |
133 | return context._load(exp[1]) |
|
133 | return context._load(exp[1]) | |
134 | raise error.ParseError(_("expected template specifier")) |
|
134 | raise error.ParseError(_("expected template specifier")) | |
135 |
|
135 | |||
136 | def runstring(context, mapping, data): |
|
136 | def runstring(context, mapping, data): | |
|
137 | return data.decode("string-escape") | |||
|
138 | ||||
|
139 | def runrawstring(context, mapping, data): | |||
137 | return data |
|
140 | return data | |
138 |
|
141 | |||
139 | def runsymbol(context, mapping, key): |
|
142 | def runsymbol(context, mapping, key): | |
@@ -234,12 +237,8 b' def fill(context, mapping, args):' | |||||
234 | except ValueError: |
|
237 | except ValueError: | |
235 | raise error.ParseError(_("fill expects an integer width")) |
|
238 | raise error.ParseError(_("fill expects an integer width")) | |
236 | try: |
|
239 | try: | |
237 |
initindent = stringify(args[2] |
|
240 | initindent = stringify(_evalifliteral(args[2], context, mapping)) | |
238 |
|
|
241 | hangindent = stringify(_evalifliteral(args[3], context, mapping)) | |
239 | compiletemplate(initindent, context))) |
|
|||
240 | hangindent = stringify(args[3][0](context, mapping, args[3][1])) |
|
|||
241 | hangindent = stringify(runtemplate(context, mapping, |
|
|||
242 | compiletemplate(hangindent, context))) |
|
|||
243 | except IndexError: |
|
242 | except IndexError: | |
244 | pass |
|
243 | pass | |
245 |
|
244 | |||
@@ -285,8 +284,9 b' def get(context, mapping, args):' | |||||
285 |
|
284 | |||
286 | def _evalifliteral(arg, context, mapping): |
|
285 | def _evalifliteral(arg, context, mapping): | |
287 | t = stringify(arg[0](context, mapping, arg[1])) |
|
286 | t = stringify(arg[0](context, mapping, arg[1])) | |
288 | if arg[0] == runstring: |
|
287 | if arg[0] == runstring or arg[0] == runrawstring: | |
289 |
yield runtemplate(context, mapping, |
|
288 | yield runtemplate(context, mapping, | |
|
289 | compiletemplate(t, context, strtoken='rawstring')) | |||
290 | else: |
|
290 | else: | |
291 | yield t |
|
291 | yield t | |
292 |
|
292 | |||
@@ -338,7 +338,7 b' def join(context, mapping, args):' | |||||
338 |
|
338 | |||
339 | joiner = " " |
|
339 | joiner = " " | |
340 | if len(args) > 1: |
|
340 | if len(args) > 1: | |
341 | joiner = args[1][0](context, mapping, args[1][1]) |
|
341 | joiner = stringify(args[1][0](context, mapping, args[1][1])) | |
342 |
|
342 | |||
343 | first = True |
|
343 | first = True | |
344 | for x in joinset: |
|
344 | for x in joinset: | |
@@ -447,9 +447,9 b' def strip(context, mapping, args):' | |||||
447 | if not (1 <= len(args) <= 2): |
|
447 | if not (1 <= len(args) <= 2): | |
448 | raise error.ParseError(_("strip expects one or two arguments")) |
|
448 | raise error.ParseError(_("strip expects one or two arguments")) | |
449 |
|
449 | |||
450 | text = args[0][0](context, mapping, args[0][1]) |
|
450 | text = stringify(args[0][0](context, mapping, args[0][1])) | |
451 | if len(args) == 2: |
|
451 | if len(args) == 2: | |
452 | chars = args[1][0](context, mapping, args[1][1]) |
|
452 | chars = stringify(args[1][0](context, mapping, args[1][1])) | |
453 | return text.strip(chars) |
|
453 | return text.strip(chars) | |
454 | return text.strip() |
|
454 | return text.strip() | |
455 |
|
455 | |||
@@ -460,13 +460,12 b' def sub(context, mapping, args):' | |||||
460 |
|
460 | |||
461 | pat = stringify(args[0][0](context, mapping, args[0][1])) |
|
461 | pat = stringify(args[0][0](context, mapping, args[0][1])) | |
462 | rpl = stringify(args[1][0](context, mapping, args[1][1])) |
|
462 | rpl = stringify(args[1][0](context, mapping, args[1][1])) | |
463 |
src = stringify(args[2] |
|
463 | src = stringify(_evalifliteral(args[2], context, mapping)) | |
464 | src = stringify(runtemplate(context, mapping, |
|
|||
465 | compiletemplate(src, context))) |
|
|||
466 | yield re.sub(pat, rpl, src) |
|
464 | yield re.sub(pat, rpl, src) | |
467 |
|
465 | |||
468 | methods = { |
|
466 | methods = { | |
469 | "string": lambda e, c: (runstring, e[1]), |
|
467 | "string": lambda e, c: (runstring, e[1]), | |
|
468 | "rawstring": lambda e, c: (runrawstring, e[1]), | |||
470 | "symbol": lambda e, c: (runsymbol, e[1]), |
|
469 | "symbol": lambda e, c: (runsymbol, e[1]), | |
471 | "group": lambda e, c: compileexp(e[1], c), |
|
470 | "group": lambda e, c: compileexp(e[1], c), | |
472 | # ".": buildmember, |
|
471 | # ".": buildmember, |
@@ -1633,6 +1633,92 b' Test string escaping:' | |||||
1633 | <>\n<]> |
|
1633 | <>\n<]> | |
1634 | <>\n< |
|
1634 | <>\n< | |
1635 |
|
1635 | |||
|
1636 | "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice) | |||
|
1637 | ||||
|
1638 | $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n' | |||
|
1639 | \x6e | |||
|
1640 | $ hg log -R a -r 0 --template '{if("1", r"\x5c\x786e", "NG")}\n' | |||
|
1641 | \x5c\x786e | |||
|
1642 | $ hg log -R a -r 0 --template '{if("", "NG", "\x5c\x786e")}\n' | |||
|
1643 | \x6e | |||
|
1644 | $ hg log -R a -r 0 --template '{if("", "NG", r"\x5c\x786e")}\n' | |||
|
1645 | \x5c\x786e | |||
|
1646 | ||||
|
1647 | $ hg log -R a -r 2 --template '{ifeq("no perso\x6e", desc, "\x5c\x786e", "NG")}\n' | |||
|
1648 | \x6e | |||
|
1649 | $ hg log -R a -r 2 --template '{ifeq(r"no perso\x6e", desc, "NG", r"\x5c\x786e")}\n' | |||
|
1650 | \x5c\x786e | |||
|
1651 | $ hg log -R a -r 2 --template '{ifeq(desc, "no perso\x6e", "\x5c\x786e", "NG")}\n' | |||
|
1652 | \x6e | |||
|
1653 | $ hg log -R a -r 2 --template '{ifeq(desc, r"no perso\x6e", "NG", r"\x5c\x786e")}\n' | |||
|
1654 | \x5c\x786e | |||
|
1655 | ||||
|
1656 | $ hg log -R a -r 8 --template '{join(files, "\n")}\n' | |||
|
1657 | fourth | |||
|
1658 | second | |||
|
1659 | third | |||
|
1660 | $ hg log -R a -r 8 --template '{join(files, r"\n")}\n' | |||
|
1661 | fourth\nsecond\nthird | |||
|
1662 | ||||
|
1663 | $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", "htm\x6c")}' | |||
|
1664 | <p> | |||
|
1665 | 1st | |||
|
1666 | </p> | |||
|
1667 | <p> | |||
|
1668 | 2nd | |||
|
1669 | </p> | |||
|
1670 | $ hg log -R a -r 2 --template '{rstdoc(r"1st\n\n2nd", "html")}' | |||
|
1671 | <p> | |||
|
1672 | 1st\n\n2nd | |||
|
1673 | </p> | |||
|
1674 | $ hg log -R a -r 2 --template '{rstdoc("1st\n\n2nd", r"htm\x6c")}' | |||
|
1675 | 1st | |||
|
1676 | ||||
|
1677 | 2nd | |||
|
1678 | ||||
|
1679 | $ hg log -R a -r 2 --template '{strip(desc, "\x6e")}\n' | |||
|
1680 | o perso | |||
|
1681 | $ hg log -R a -r 2 --template '{strip(desc, r"\x6e")}\n' | |||
|
1682 | no person | |||
|
1683 | $ hg log -R a -r 2 --template '{strip("no perso\x6e", "\x6e")}\n' | |||
|
1684 | o perso | |||
|
1685 | $ hg log -R a -r 2 --template '{strip(r"no perso\x6e", r"\x6e")}\n' | |||
|
1686 | no perso | |||
|
1687 | ||||
|
1688 | $ hg log -R a -r 2 --template '{sub("\\x6e", "\x2d", desc)}\n' | |||
|
1689 | -o perso- | |||
|
1690 | $ hg log -R a -r 2 --template '{sub(r"\\x6e", "-", desc)}\n' | |||
|
1691 | no person | |||
|
1692 | $ hg log -R a -r 2 --template '{sub("n", r"\x2d", desc)}\n' | |||
|
1693 | \x2do perso\x2d | |||
|
1694 | $ hg log -R a -r 2 --template '{sub("n", "\x2d", "no perso\x6e")}\n' | |||
|
1695 | -o perso- | |||
|
1696 | $ hg log -R a -r 2 --template '{sub("n", r"\x2d", r"no perso\x6e")}\n' | |||
|
1697 | \x2do perso\x6e | |||
|
1698 | ||||
|
1699 | $ hg log -R a -r 8 --template '{files % "{file}\n"}' | |||
|
1700 | fourth | |||
|
1701 | second | |||
|
1702 | third | |||
|
1703 | $ hg log -R a -r 8 --template '{files % r"{file}\n"}\n' | |||
|
1704 | fourth\nsecond\nthird\n | |||
|
1705 | ||||
|
1706 | Test string escapeing in nested expression: | |||
|
1707 | ||||
|
1708 | $ hg log -R a -r 8 --template '{ifeq(r"\x6e", if("1", "\x5c\x786e"), join(files, "\x5c\x786e"))}\n' | |||
|
1709 | fourth\x6esecond\x6ethird | |||
|
1710 | $ hg log -R a -r 8 --template '{ifeq(if("1", r"\x6e"), "\x5c\x786e", join(files, "\x5c\x786e"))}\n' | |||
|
1711 | fourth\x6esecond\x6ethird | |||
|
1712 | ||||
|
1713 | $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", "\x5c\x786e"))}\n' | |||
|
1714 | fourth\x6esecond\x6ethird | |||
|
1715 | $ hg log -R a -r 8 --template '{join(files, ifeq(branch, "default", r"\x5c\x786e"))}\n' | |||
|
1716 | fourth\x5c\x786esecond\x5c\x786ethird | |||
|
1717 | ||||
|
1718 | $ hg log -R a -r 3:4 --template '{rev}:{sub(if("1", "\x6e"), ifeq(branch, "foo", r"\x5c\x786e", "\x5c\x786e"), desc)}\n' | |||
|
1719 | 3:\x6eo user, \x6eo domai\x6e | |||
|
1720 | 4:\x5c\x786eew bra\x5c\x786ech | |||
|
1721 | ||||
1636 | Test recursive evaluation: |
|
1722 | Test recursive evaluation: | |
1637 |
|
1723 | |||
1638 | $ hg init r |
|
1724 | $ hg init r | |
@@ -1645,6 +1731,39 b' Test recursive evaluation:' | |||||
1645 | $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n' |
|
1731 | $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n' | |
1646 | test 0 |
|
1732 | test 0 | |
1647 |
|
1733 | |||
|
1734 | $ hg branch -q 'text.{rev}' | |||
|
1735 | $ echo aa >> aa | |||
|
1736 | $ hg ci -u '{node|short}' -m 'desc to be wrapped desc to be wrapped' | |||
|
1737 | ||||
|
1738 | $ hg log -l1 --template '{fill(desc, "20", author, branch)}' | |||
|
1739 | {node|short}desc to | |||
|
1740 | text.{rev}be wrapped | |||
|
1741 | text.{rev}desc to be | |||
|
1742 | text.{rev}wrapped (no-eol) | |||
|
1743 | $ hg log -l1 --template '{fill(desc, "20", "{node|short}:", "text.{rev}:")}' | |||
|
1744 | bcc7ff960b8e:desc to | |||
|
1745 | text.1:be wrapped | |||
|
1746 | text.1:desc to be | |||
|
1747 | text.1:wrapped (no-eol) | |||
|
1748 | ||||
|
1749 | $ hg log -l 1 --template '{sub(r"[0-9]", "-", author)}' | |||
|
1750 | {node|short} (no-eol) | |||
|
1751 | $ hg log -l 1 --template '{sub(r"[0-9]", "-", "{node|short}")}' | |||
|
1752 | bcc-ff---b-e (no-eol) | |||
|
1753 | ||||
|
1754 | $ cat >> .hg/hgrc <<EOF | |||
|
1755 | > [extensions] | |||
|
1756 | > color= | |||
|
1757 | > [color] | |||
|
1758 | > mode=ansi | |||
|
1759 | > text.{rev} = red | |||
|
1760 | > text.1 = green | |||
|
1761 | > EOF | |||
|
1762 | $ hg log --color=always -l 1 --template '{label(branch, "text\n")}' | |||
|
1763 | \x1b[0;31mtext\x1b[0m (esc) | |||
|
1764 | $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}' | |||
|
1765 | \x1b[0;32mtext\x1b[0m (esc) | |||
|
1766 | ||||
1648 | Test branches inside if statement: |
|
1767 | Test branches inside if statement: | |
1649 |
|
1768 | |||
1650 | $ hg log -r 0 --template '{if(branches, "yes", "no")}\n' |
|
1769 | $ hg log -r 0 --template '{if(branches, "yes", "no")}\n' | |
@@ -1655,43 +1774,56 b' Test shortest(node) function:' | |||||
1655 | $ echo b > b |
|
1774 | $ echo b > b | |
1656 | $ hg ci -qAm b |
|
1775 | $ hg ci -qAm b | |
1657 | $ hg log --template '{shortest(node)}\n' |
|
1776 | $ hg log --template '{shortest(node)}\n' | |
1658 | d97c |
|
1777 | e777 | |
|
1778 | bcc7 | |||
1659 | f776 |
|
1779 | f776 | |
1660 | $ hg log --template '{shortest(node, 10)}\n' |
|
1780 | $ hg log --template '{shortest(node, 10)}\n' | |
1661 | d97c383ae3 |
|
1781 | e777603221 | |
|
1782 | bcc7ff960b | |||
1662 | f7769ec2ab |
|
1783 | f7769ec2ab | |
1663 |
|
1784 | |||
1664 | Test pad function |
|
1785 | Test pad function | |
1665 |
|
1786 | |||
1666 | $ hg log --template '{pad(rev, 20)} {author|user}\n' |
|
1787 | $ hg log --template '{pad(rev, 20)} {author|user}\n' | |
1667 |
|
|
1788 | 2 test | |
|
1789 | 1 {node|short} | |||
1668 | 0 test |
|
1790 | 0 test | |
1669 |
|
1791 | |||
1670 | $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n' |
|
1792 | $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n' | |
1671 |
|
|
1793 | 2 test | |
|
1794 | 1 {node|short} | |||
1672 | 0 test |
|
1795 | 0 test | |
1673 |
|
1796 | |||
1674 | $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n' |
|
1797 | $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n' | |
1675 |
|
|
1798 | 2------------------- test | |
|
1799 | 1------------------- {node|short} | |||
1676 | 0------------------- test |
|
1800 | 0------------------- test | |
1677 |
|
1801 | |||
1678 | Test ifcontains function |
|
1802 | Test ifcontains function | |
1679 |
|
1803 | |||
1680 | $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n' |
|
1804 | $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n' | |
|
1805 | 2 did not add a | |||
1681 | 1 did not add a |
|
1806 | 1 did not add a | |
1682 | 0 added a |
|
1807 | 0 added a | |
1683 |
|
1808 | |||
1684 | Test revset function |
|
1809 | Test revset function | |
1685 |
|
1810 | |||
1686 | $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n' |
|
1811 | $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n' | |
1687 |
|
|
1812 | 2 current rev | |
|
1813 | 1 not current rev | |||
1688 | 0 not current rev |
|
1814 | 0 not current rev | |
1689 |
|
1815 | |||
1690 | $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n' |
|
1816 | $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n' | |
|
1817 | 2 Parents: 1 | |||
1691 | 1 Parents: 0 |
|
1818 | 1 Parents: 0 | |
1692 | 0 Parents: |
|
1819 | 0 Parents: | |
1693 |
|
1820 | |||
1694 | $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n' |
|
1821 | $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n' | |
|
1822 | Rev: 2 | |||
|
1823 | Ancestor: 0 | |||
|
1824 | Ancestor: 1 | |||
|
1825 | Ancestor: 2 | |||
|
1826 | ||||
1695 | Rev: 1 |
|
1827 | Rev: 1 | |
1696 | Ancestor: 0 |
|
1828 | Ancestor: 0 | |
1697 | Ancestor: 1 |
|
1829 | Ancestor: 1 | |
@@ -1704,5 +1836,15 b' Test current bookmark templating' | |||||
1704 | $ hg book foo |
|
1836 | $ hg book foo | |
1705 | $ hg book bar |
|
1837 | $ hg book bar | |
1706 | $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}\n" |
|
1838 | $ hg log --template "{rev} {bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}\n" | |
1707 |
|
|
1839 | 2 bar* foo | |
|
1840 | 1 | |||
1708 | 0 |
|
1841 | 0 | |
|
1842 | ||||
|
1843 | Test stringify on sub expressions | |||
|
1844 | ||||
|
1845 | $ cd .. | |||
|
1846 | $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n' | |||
|
1847 | fourth, second, third | |||
|
1848 | $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n' | |||
|
1849 | abc | |||
|
1850 |
General Comments 0
You need to be logged in to leave comments.
Login now