--- a/mercurial/fileset.py Mon Dec 21 22:31:16 2015 +0900
+++ b/mercurial/fileset.py Mon Dec 21 22:31:16 2015 +0900
@@ -130,54 +130,79 @@
def listset(mctx, a, b):
raise error.ParseError(_("can't use a list in this context"))
+# symbols are callable like:
+# fun(mctx, x)
+# with:
+# mctx - current matchctx instance
+# x - argument in tree form
+symbols = {}
+
+def predicate(decl):
+ """Return a decorator for fileset predicate function
+
+ 'decl' argument is the declaration (including argument list like
+ 'adds(pattern)') or the name (for internal use only) of predicate.
+ """
+ def decorator(func):
+ i = decl.find('(')
+ if i > 0:
+ name = decl[:i]
+ else:
+ name = decl
+ symbols[name] = func
+ if func.__doc__:
+ func.__doc__ = "``%s``\n %s" % (decl, func.__doc__.strip())
+ return func
+ return decorator
+
+@predicate('modified()')
def modified(mctx, x):
- """``modified()``
- File that is modified according to :hg:`status`.
+ """File that is modified according to :hg:`status`.
"""
# i18n: "modified" is a keyword
getargs(x, 0, 0, _("modified takes no arguments"))
s = mctx.status().modified
return [f for f in mctx.subset if f in s]
+@predicate('added()')
def added(mctx, x):
- """``added()``
- File that is added according to :hg:`status`.
+ """File that is added according to :hg:`status`.
"""
# i18n: "added" is a keyword
getargs(x, 0, 0, _("added takes no arguments"))
s = mctx.status().added
return [f for f in mctx.subset if f in s]
+@predicate('removed()')
def removed(mctx, x):
- """``removed()``
- File that is removed according to :hg:`status`.
+ """File that is removed according to :hg:`status`.
"""
# i18n: "removed" is a keyword
getargs(x, 0, 0, _("removed takes no arguments"))
s = mctx.status().removed
return [f for f in mctx.subset if f in s]
+@predicate('deleted()')
def deleted(mctx, x):
- """``deleted()``
- Alias for ``missing()``.
+ """Alias for ``missing()``.
"""
# i18n: "deleted" is a keyword
getargs(x, 0, 0, _("deleted takes no arguments"))
s = mctx.status().deleted
return [f for f in mctx.subset if f in s]
+@predicate('missing()')
def missing(mctx, x):
- """``missing()``
- File that is missing according to :hg:`status`.
+ """File that is missing according to :hg:`status`.
"""
# i18n: "missing" is a keyword
getargs(x, 0, 0, _("missing takes no arguments"))
s = mctx.status().deleted
return [f for f in mctx.subset if f in s]
+@predicate('unknown()')
def unknown(mctx, x):
- """``unknown()``
- File that is unknown according to :hg:`status`. These files will only be
+ """File that is unknown according to :hg:`status`. These files will only be
considered if this predicate is used.
"""
# i18n: "unknown" is a keyword
@@ -185,9 +210,9 @@
s = mctx.status().unknown
return [f for f in mctx.subset if f in s]
+@predicate('ignored()')
def ignored(mctx, x):
- """``ignored()``
- File that is ignored according to :hg:`status`. These files will only be
+ """File that is ignored according to :hg:`status`. These files will only be
considered if this predicate is used.
"""
# i18n: "ignored" is a keyword
@@ -195,9 +220,9 @@
s = mctx.status().ignored
return [f for f in mctx.subset if f in s]
+@predicate('clean()')
def clean(mctx, x):
- """``clean()``
- File that is clean according to :hg:`status`.
+ """File that is clean according to :hg:`status`.
"""
# i18n: "clean" is a keyword
getargs(x, 0, 0, _("clean takes no arguments"))
@@ -226,33 +251,33 @@
raise error.ParseError(err)
return l
+@predicate('binary()')
def binary(mctx, x):
- """``binary()``
- File that appears to be binary (contains NUL bytes).
+ """File that appears to be binary (contains NUL bytes).
"""
# i18n: "binary" is a keyword
getargs(x, 0, 0, _("binary takes no arguments"))
return [f for f in mctx.existing() if util.binary(mctx.ctx[f].data())]
+@predicate('exec()')
def exec_(mctx, x):
- """``exec()``
- File that is marked as executable.
+ """File that is marked as executable.
"""
# i18n: "exec" is a keyword
getargs(x, 0, 0, _("exec takes no arguments"))
return [f for f in mctx.existing() if mctx.ctx.flags(f) == 'x']
+@predicate('symlink()')
def symlink(mctx, x):
- """``symlink()``
- File that is marked as a symlink.
+ """File that is marked as a symlink.
"""
# i18n: "symlink" is a keyword
getargs(x, 0, 0, _("symlink takes no arguments"))
return [f for f in mctx.existing() if mctx.ctx.flags(f) == 'l']
+@predicate('resolved()')
def resolved(mctx, x):
- """``resolved()``
- File that is marked resolved according to :hg:`resolve -l`.
+ """File that is marked resolved according to :hg:`resolve -l`.
"""
# i18n: "resolved" is a keyword
getargs(x, 0, 0, _("resolved takes no arguments"))
@@ -261,9 +286,9 @@
ms = merge.mergestate.read(mctx.ctx.repo())
return [f for f in mctx.subset if f in ms and ms[f] == 'r']
+@predicate('unresolved()')
def unresolved(mctx, x):
- """``unresolved()``
- File that is marked unresolved according to :hg:`resolve -l`.
+ """File that is marked unresolved according to :hg:`resolve -l`.
"""
# i18n: "unresolved" is a keyword
getargs(x, 0, 0, _("unresolved takes no arguments"))
@@ -272,18 +297,18 @@
ms = merge.mergestate.read(mctx.ctx.repo())
return [f for f in mctx.subset if f in ms and ms[f] == 'u']
+@predicate('hgignore()')
def hgignore(mctx, x):
- """``hgignore()``
- File that matches the active .hgignore pattern.
+ """File that matches the active .hgignore pattern.
"""
# i18n: "hgignore" is a keyword
getargs(x, 0, 0, _("hgignore takes no arguments"))
ignore = mctx.ctx.repo().dirstate._ignore
return [f for f in mctx.subset if ignore(f)]
+@predicate('portable()')
def portable(mctx, x):
- """``portable()``
- File that has a portable name. (This doesn't include filenames with case
+ """File that has a portable name. (This doesn't include filenames with case
collisions.)
"""
# i18n: "portable" is a keyword
@@ -291,9 +316,9 @@
checkwinfilename = util.checkwinfilename
return [f for f in mctx.subset if checkwinfilename(f) is None]
+@predicate('grep(regex)')
def grep(mctx, x):
- """``grep(regex)``
- File contains the given regular expression.
+ """File contains the given regular expression.
"""
try:
# i18n: "grep" is a keyword
@@ -318,9 +343,9 @@
except ValueError:
raise error.ParseError(_("couldn't parse size: %s") % s)
+@predicate('size(expression)')
def size(mctx, x):
- """``size(expression)``
- File size matches the given expression. Examples:
+ """File size matches the given expression. Examples:
- 1k (files from 1024 to 2047 bytes)
- < 20k (files less than 20480 bytes)
@@ -356,9 +381,9 @@
return [f for f in mctx.existing() if m(mctx.ctx[f].size())]
+@predicate('encoding(name)')
def encoding(mctx, x):
- """``encoding(name)``
- File can be successfully decoded with the given character
+ """File can be successfully decoded with the given character
encoding. May not be useful for encodings other than ASCII and
UTF-8.
"""
@@ -379,9 +404,9 @@
return s
+@predicate('eol(style)')
def eol(mctx, x):
- """``eol(style)``
- File contains newlines of the given style (dos, unix, mac). Binary
+ """File contains newlines of the given style (dos, unix, mac). Binary
files are excluded, files with mixed line endings match multiple
styles.
"""
@@ -402,9 +427,9 @@
s.append(f)
return s
+@predicate('copied()')
def copied(mctx, x):
- """``copied()``
- File that is recorded as being copied.
+ """File that is recorded as being copied.
"""
# i18n: "copied" is a keyword
getargs(x, 0, 0, _("copied takes no arguments"))
@@ -415,9 +440,9 @@
s.append(f)
return s
+@predicate('subrepo([pattern])')
def subrepo(mctx, x):
- """``subrepo([pattern])``
- Subrepositories whose paths match the given pattern.
+ """Subrepositories whose paths match the given pattern.
"""
# i18n: "subrepo" is a keyword
getargs(x, 0, 1, _("subrepo takes at most one argument"))
@@ -438,30 +463,6 @@
else:
return [sub for sub in sstate]
-symbols = {
- 'added': added,
- 'binary': binary,
- 'clean': clean,
- 'copied': copied,
- 'deleted': deleted,
- 'encoding': encoding,
- 'eol': eol,
- 'exec': exec_,
- 'grep': grep,
- 'ignored': ignored,
- 'hgignore': hgignore,
- 'missing': missing,
- 'modified': modified,
- 'portable': portable,
- 'removed': removed,
- 'resolved': resolved,
- 'size': size,
- 'symlink': symlink,
- 'unknown': unknown,
- 'unresolved': unresolved,
- 'subrepo': subrepo,
-}
-
methods = {
'string': stringset,
'symbol': stringset,