Mercurial > public > mercurial-scm > hg
diff mercurial/revset.py @ 14098:9f5a0acb0056
revset aliases
author | Alexander Solovyov <alexander@solovyov.net> |
---|---|
date | Sat, 30 Apr 2011 18:30:14 +0200 |
parents | 72c84f24b420 |
children | f8047a059ca0 |
line wrap: on
line diff
--- 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)