--- a/mercurial/revset.py Sat Apr 30 19:41:53 2011 +0200
+++ b/mercurial/revset.py Sat Apr 30 18:30:14 2011 +0200
@@ -889,14 +889,89 @@
return w + wa, (op, x[1], ta)
return 1, x
+class revsetalias(object):
+ funcre = re.compile('^([^(]+)\(([^)]+)\)$')
+ args = ()
+
+ def __init__(self, token, value):
+ '''Aliases like:
+
+ h = heads(default)
+ b($1) = ancestors($1) - ancestors(default)
+ '''
+ if isinstance(token, tuple):
+ self.type, self.name = token
+ else:
+ m = self.funcre.search(token)
+ if m:
+ self.type = 'func'
+ self.name = m.group(1)
+ self.args = [x.strip() for x in m.group(2).split(',')]
+ else:
+ self.type = 'symbol'
+ self.name = token
+
+ if isinstance(value, str):
+ for arg in self.args:
+ value = value.replace(arg, repr(arg))
+ self.replacement, pos = parse(value)
+ if pos != len(value):
+ raise error.ParseError('invalid token', pos)
+ else:
+ self.replacement = value
+
+ def match(self, tree):
+ if not tree:
+ return False
+ if tree == (self.type, self.name):
+ return True
+ if tree[0] != self.type:
+ return False
+ if len(tree) > 1 and tree[1] != ('symbol', self.name):
+ return False
+ # 'func' + funcname + args
+ if ((self.args and len(tree) != 3) or
+ (len(self.args) == 1 and tree[2][0] == 'list') or
+ (len(self.args) > 1 and (tree[2][0] != 'list' or
+ len(tree[2]) - 1 != len(self.args)))):
+ raise error.ParseError('invalid amount of arguments', len(tree) - 2)
+ return True
+
+ def replace(self, tree):
+ if tree == (self.type, self.name):
+ return self.replacement
+ result = self.replacement
+ def getsubtree(i):
+ if tree[2][0] == 'list':
+ return tree[2][i + 1]
+ return tree[i + 2]
+ for i, v in enumerate(self.args):
+ valalias = revsetalias(('string', v), getsubtree(i))
+ result = valalias.process(result)
+ return result
+
+ def process(self, tree):
+ if self.match(tree):
+ return self.replace(tree)
+ if isinstance(tree, tuple):
+ return tuple(map(self.process, tree))
+ return tree
+
+def findaliases(ui, tree):
+ for k, v in ui.configitems('revsetalias'):
+ alias = revsetalias(k, v)
+ tree = alias.process(tree)
+ return tree
+
parse = parser.parser(tokenize, elements).parse
-def match(spec):
+def match(ui, spec):
if not spec:
raise error.ParseError(_("empty query"))
tree, pos = parse(spec)
if (pos != len(spec)):
raise error.ParseError("invalid token", pos)
+ tree = findaliases(ui, tree)
weight, tree = optimize(tree, True)
def mfunc(repo, subset):
return getset(repo, subset, tree)