##// END OF EJS Templates
revset: introduce new operator "##" to concatenate strings/symbols at runtime...
FUJIWARA Katsunori -
r23742:3a4d8a6c default
parent child Browse files
Show More
@@ -2840,6 +2840,10 b' def debugrevspec(ui, repo, expr, **opts)'
2840 newtree = revset.findaliases(ui, tree)
2840 newtree = revset.findaliases(ui, tree)
2841 if newtree != tree:
2841 if newtree != tree:
2842 ui.note(revset.prettyformat(newtree), "\n")
2842 ui.note(revset.prettyformat(newtree), "\n")
2843 tree = newtree
2844 newtree = revset.foldconcat(tree)
2845 if newtree != tree:
2846 ui.note(revset.prettyformat(newtree), "\n")
2843 if opts["optimize"]:
2847 if opts["optimize"]:
2844 weight, optimizedtree = revset.optimize(newtree, True)
2848 weight, optimizedtree = revset.optimize(newtree, True)
2845 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
2849 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
@@ -81,6 +81,19 b' For example,'
81 defines three aliases, ``h``, ``d``, and ``rs``. ``rs(0:tip, author)`` is
81 defines three aliases, ``h``, ``d``, and ``rs``. ``rs(0:tip, author)`` is
82 exactly equivalent to ``reverse(sort(0:tip, author))``.
82 exactly equivalent to ``reverse(sort(0:tip, author))``.
83
83
84 An infix operator ``##`` can concatenate strings and identifiers into
85 one string. For example::
86
87 [revsetalias]
88 issue($1) = grep(r'\bissue[ :]?' ## $1 ## r'\b|\bbug\(' ## $1 ## r'\)')
89
90 ``issue(1234)`` is equivalent to ``grep(r'\bissue[ :]?1234\b|\bbug\(1234\)')``
91 in this case. This matches against all of "issue 1234", "issue:1234",
92 "issue1234" and "bug(1234)".
93
94 All other prefix, infix and postfix operators have lower priority than
95 ``##``. For example, ``$1 ## $2~2`` is equivalent to ``($1 ## $2)~2``.
96
84 Command line equivalents for :hg:`log`::
97 Command line equivalents for :hg:`log`::
85
98
86 -f -> ::.
99 -f -> ::.
@@ -102,7 +102,8 b' def _revsbetween(repo, roots, heads):'
102 return baseset(sorted(reachable))
102 return baseset(sorted(reachable))
103
103
104 elements = {
104 elements = {
105 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
105 "(": (21, ("group", 1, ")"), ("func", 1, ")")),
106 "##": (20, None, ("_concat", 20)),
106 "~": (18, None, ("ancestor", 18)),
107 "~": (18, None, ("ancestor", 18)),
107 "^": (18, None, ("parent", 18), ("parentpost", 18)),
108 "^": (18, None, ("parent", 18), ("parentpost", 18)),
108 "-": (5, ("negate", 19), ("minus", 5)),
109 "-": (5, ("negate", 19), ("minus", 5)),
@@ -148,6 +149,9 b' def tokenize(program, lookup=None):'
148 elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
149 elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
149 yield ('..', None, pos)
150 yield ('..', None, pos)
150 pos += 1 # skip ahead
151 pos += 1 # skip ahead
152 elif c == '#' and program[pos:pos + 2] == '##': # look ahead carefully
153 yield ('##', None, pos)
154 pos += 1 # skip ahead
151 elif c in "():,-|&+!~^": # handle simple operators
155 elif c in "():,-|&+!~^": # handle simple operators
152 yield (c, None, pos)
156 yield (c, None, pos)
153 elif (c in '"\'' or c == 'r' and
157 elif (c in '"\'' or c == 'r' and
@@ -2156,6 +2160,27 b' def findaliases(ui, tree, showwarning=No'
2156 alias.warned = True
2160 alias.warned = True
2157 return tree
2161 return tree
2158
2162
2163 def foldconcat(tree):
2164 """Fold elements to be concatenated by `##`
2165 """
2166 if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
2167 return tree
2168 if tree[0] == '_concat':
2169 pending = [tree]
2170 l = []
2171 while pending:
2172 e = pending.pop()
2173 if e[0] == '_concat':
2174 pending.extend(reversed(e[1:]))
2175 elif e[0] in ('string', 'symbol'):
2176 l.append(e[1])
2177 else:
2178 msg = _("\"##\" can't concatenate \"%s\" element") % (e[0])
2179 raise error.ParseError(msg)
2180 return ('string', ''.join(l))
2181 else:
2182 return tuple(foldconcat(t) for t in tree)
2183
2159 def parse(spec, lookup=None):
2184 def parse(spec, lookup=None):
2160 p = parser.parser(tokenize, elements)
2185 p = parser.parser(tokenize, elements)
2161 return p.parse(spec, lookup=lookup)
2186 return p.parse(spec, lookup=lookup)
@@ -2171,6 +2196,7 b' def match(ui, spec, repo=None):'
2171 raise error.ParseError(_("invalid token"), pos)
2196 raise error.ParseError(_("invalid token"), pos)
2172 if ui:
2197 if ui:
2173 tree = findaliases(ui, tree, showwarning=ui.warn)
2198 tree = findaliases(ui, tree, showwarning=ui.warn)
2199 tree = foldconcat(tree)
2174 weight, tree = optimize(tree, True)
2200 weight, tree = optimize(tree, True)
2175 def mfunc(repo, subset):
2201 def mfunc(repo, subset):
2176 if util.safehasattr(subset, 'isascending'):
2202 if util.safehasattr(subset, 'isascending'):
@@ -1123,6 +1123,54 b' 3. more than local specified sp'
1123 $ cd ../repo
1123 $ cd ../repo
1124 $ log 'remote(".a.b.c.", "../remote3")'
1124 $ log 'remote(".a.b.c.", "../remote3")'
1125
1125
1126 tests for concatenation of strings/symbols by "##"
1127
1128 $ try "278 ## '5f5' ## 1ee ## 'ce5'"
1129 (_concat
1130 (_concat
1131 (_concat
1132 ('symbol', '278')
1133 ('string', '5f5'))
1134 ('symbol', '1ee'))
1135 ('string', 'ce5'))
1136 ('string', '2785f51eece5')
1137 0
1138
1139 $ echo 'cat4($1, $2, $3, $4) = $1 ## $2 ## $3 ## $4' >> .hg/hgrc
1140 $ try "cat4(278, '5f5', 1ee, 'ce5')"
1141 (func
1142 ('symbol', 'cat4')
1143 (list
1144 (list
1145 (list
1146 ('symbol', '278')
1147 ('string', '5f5'))
1148 ('symbol', '1ee'))
1149 ('string', 'ce5')))
1150 (_concat
1151 (_concat
1152 (_concat
1153 ('symbol', '278')
1154 ('string', '5f5'))
1155 ('symbol', '1ee'))
1156 ('string', 'ce5'))
1157 ('string', '2785f51eece5')
1158 0
1159
1160 (check concatenation in alias nesting)
1161
1162 $ echo 'cat2($1, $2) = $1 ## $2' >> .hg/hgrc
1163 $ echo 'cat2x2($1, $2, $3, $4) = cat2($1 ## $2, $3 ## $4)' >> .hg/hgrc
1164 $ log "cat2x2(278, '5f5', 1ee, 'ce5')"
1165 0
1166
1167 (check operator priority)
1168
1169 $ echo 'cat2n2($1, $2, $3, $4) = $1 ## $2 or $3 ## $4~2' >> .hg/hgrc
1170 $ log "cat2n2(2785f5, 1eece5, 24286f, 4ae135)"
1171 0
1172 4
1173
1126 $ cd ..
1174 $ cd ..
1127
1175
1128 test author/desc/keyword in problematic encoding
1176 test author/desc/keyword in problematic encoding
General Comments 0
You need to be logged in to leave comments. Login now