diff --git a/mercurial/registrar.py b/mercurial/registrar.py --- a/mercurial/registrar.py +++ b/mercurial/registrar.py @@ -205,3 +205,36 @@ class _funcregistrarbase(object): """Execute exra setup for registered function, if needed """ pass + +class revsetpredicate(_funcregistrarbase): + """Decorator to register revset predicate + + Usage:: + + revsetpredicate = registrar.revsetpredicate() + + @revsetpredicate('mypredicate(arg1, arg2[, arg3])') + def mypredicatefunc(repo, subset, x): + '''Explanation of this revset predicate .... + ''' + pass + + The first string argument is used also in online help. + + Optional argument 'safe' indicates whether a predicate is safe for + DoS attack (False by default). + + 'revsetpredicate' instance in example above can be used to + decorate multiple functions. + + Decorated functions are registered automatically at loading + extension, if an instance named as 'revsetpredicate' is used for + decorating in extension. + + Otherwise, explicit 'revset.loadpredicate()' is needed. + """ + _getname = _funcregistrarbase._parsefuncdecl + _docformat = "``%s``\n %s" + + def _extrasetup(self, name, func, safe=False): + func._safe = safe diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -3628,5 +3628,13 @@ def prettyformatset(revs): p = q return '\n'.join(' ' * l + s for l, s in lines) +def loadpredicate(ui, extname, registrarobj): + """Load revset predicates from specified registrarobj + """ + for name, func in registrarobj._table.iteritems(): + symbols[name] = func + if func._safe: + safesymbols.add(name) + # tell hggettext to extract docstrings from these functions: i18nfunctions = symbols.values()