mercurial/fileset.py
changeset 27461 afa76585c955
parent 27460 11286ac374f3
child 27462 470ea34ba593
equal deleted inserted replaced
27460:11286ac374f3 27461:afa76585c955
   135 # with:
   135 # with:
   136 #  mctx - current matchctx instance
   136 #  mctx - current matchctx instance
   137 #  x - argument in tree form
   137 #  x - argument in tree form
   138 symbols = {}
   138 symbols = {}
   139 
   139 
   140 def predicate(decl):
   140 # filesets using matchctx.status()
       
   141 _statuscallers = []
       
   142 
       
   143 def predicate(decl, callstatus=False):
   141     """Return a decorator for fileset predicate function
   144     """Return a decorator for fileset predicate function
   142 
   145 
   143     'decl' argument is the declaration (including argument list like
   146     'decl' argument is the declaration (including argument list like
   144     'adds(pattern)') or the name (for internal use only) of predicate.
   147     'adds(pattern)') or the name (for internal use only) of predicate.
       
   148 
       
   149     Optional 'callstatus' argument indicates whether predicate implies
       
   150     'matchctx.status()' at runtime or not (False, by default).
   145     """
   151     """
   146     def decorator(func):
   152     def decorator(func):
   147         i = decl.find('(')
   153         i = decl.find('(')
   148         if i > 0:
   154         if i > 0:
   149             name = decl[:i]
   155             name = decl[:i]
   150         else:
   156         else:
   151             name = decl
   157             name = decl
   152         symbols[name] = func
   158         symbols[name] = func
       
   159         if callstatus:
       
   160             _statuscallers.append(name)
   153         if func.__doc__:
   161         if func.__doc__:
   154             func.__doc__ = "``%s``\n    %s" % (decl, func.__doc__.strip())
   162             func.__doc__ = "``%s``\n    %s" % (decl, func.__doc__.strip())
   155         return func
   163         return func
   156     return decorator
   164     return decorator
   157 
   165 
   158 @predicate('modified()')
   166 @predicate('modified()', callstatus=True)
   159 def modified(mctx, x):
   167 def modified(mctx, x):
   160     """File that is modified according to :hg:`status`.
   168     """File that is modified according to :hg:`status`.
   161     """
   169     """
   162     # i18n: "modified" is a keyword
   170     # i18n: "modified" is a keyword
   163     getargs(x, 0, 0, _("modified takes no arguments"))
   171     getargs(x, 0, 0, _("modified takes no arguments"))
   164     s = mctx.status().modified
   172     s = mctx.status().modified
   165     return [f for f in mctx.subset if f in s]
   173     return [f for f in mctx.subset if f in s]
   166 
   174 
   167 @predicate('added()')
   175 @predicate('added()', callstatus=True)
   168 def added(mctx, x):
   176 def added(mctx, x):
   169     """File that is added according to :hg:`status`.
   177     """File that is added according to :hg:`status`.
   170     """
   178     """
   171     # i18n: "added" is a keyword
   179     # i18n: "added" is a keyword
   172     getargs(x, 0, 0, _("added takes no arguments"))
   180     getargs(x, 0, 0, _("added takes no arguments"))
   173     s = mctx.status().added
   181     s = mctx.status().added
   174     return [f for f in mctx.subset if f in s]
   182     return [f for f in mctx.subset if f in s]
   175 
   183 
   176 @predicate('removed()')
   184 @predicate('removed()', callstatus=True)
   177 def removed(mctx, x):
   185 def removed(mctx, x):
   178     """File that is removed according to :hg:`status`.
   186     """File that is removed according to :hg:`status`.
   179     """
   187     """
   180     # i18n: "removed" is a keyword
   188     # i18n: "removed" is a keyword
   181     getargs(x, 0, 0, _("removed takes no arguments"))
   189     getargs(x, 0, 0, _("removed takes no arguments"))
   182     s = mctx.status().removed
   190     s = mctx.status().removed
   183     return [f for f in mctx.subset if f in s]
   191     return [f for f in mctx.subset if f in s]
   184 
   192 
   185 @predicate('deleted()')
   193 @predicate('deleted()', callstatus=True)
   186 def deleted(mctx, x):
   194 def deleted(mctx, x):
   187     """Alias for ``missing()``.
   195     """Alias for ``missing()``.
   188     """
   196     """
   189     # i18n: "deleted" is a keyword
   197     # i18n: "deleted" is a keyword
   190     getargs(x, 0, 0, _("deleted takes no arguments"))
   198     getargs(x, 0, 0, _("deleted takes no arguments"))
   191     s = mctx.status().deleted
   199     s = mctx.status().deleted
   192     return [f for f in mctx.subset if f in s]
   200     return [f for f in mctx.subset if f in s]
   193 
   201 
   194 @predicate('missing()')
   202 @predicate('missing()', callstatus=True)
   195 def missing(mctx, x):
   203 def missing(mctx, x):
   196     """File that is missing according to :hg:`status`.
   204     """File that is missing according to :hg:`status`.
   197     """
   205     """
   198     # i18n: "missing" is a keyword
   206     # i18n: "missing" is a keyword
   199     getargs(x, 0, 0, _("missing takes no arguments"))
   207     getargs(x, 0, 0, _("missing takes no arguments"))
   200     s = mctx.status().deleted
   208     s = mctx.status().deleted
   201     return [f for f in mctx.subset if f in s]
   209     return [f for f in mctx.subset if f in s]
   202 
   210 
   203 @predicate('unknown()')
   211 @predicate('unknown()', callstatus=True)
   204 def unknown(mctx, x):
   212 def unknown(mctx, x):
   205     """File that is unknown according to :hg:`status`. These files will only be
   213     """File that is unknown according to :hg:`status`. These files will only be
   206     considered if this predicate is used.
   214     considered if this predicate is used.
   207     """
   215     """
   208     # i18n: "unknown" is a keyword
   216     # i18n: "unknown" is a keyword
   209     getargs(x, 0, 0, _("unknown takes no arguments"))
   217     getargs(x, 0, 0, _("unknown takes no arguments"))
   210     s = mctx.status().unknown
   218     s = mctx.status().unknown
   211     return [f for f in mctx.subset if f in s]
   219     return [f for f in mctx.subset if f in s]
   212 
   220 
   213 @predicate('ignored()')
   221 @predicate('ignored()', callstatus=True)
   214 def ignored(mctx, x):
   222 def ignored(mctx, x):
   215     """File that is ignored according to :hg:`status`. These files will only be
   223     """File that is ignored according to :hg:`status`. These files will only be
   216     considered if this predicate is used.
   224     considered if this predicate is used.
   217     """
   225     """
   218     # i18n: "ignored" is a keyword
   226     # i18n: "ignored" is a keyword
   219     getargs(x, 0, 0, _("ignored takes no arguments"))
   227     getargs(x, 0, 0, _("ignored takes no arguments"))
   220     s = mctx.status().ignored
   228     s = mctx.status().ignored
   221     return [f for f in mctx.subset if f in s]
   229     return [f for f in mctx.subset if f in s]
   222 
   230 
   223 @predicate('clean()')
   231 @predicate('clean()', callstatus=True)
   224 def clean(mctx, x):
   232 def clean(mctx, x):
   225     """File that is clean according to :hg:`status`.
   233     """File that is clean according to :hg:`status`.
   226     """
   234     """
   227     # i18n: "clean" is a keyword
   235     # i18n: "clean" is a keyword
   228     getargs(x, 0, 0, _("clean takes no arguments"))
   236     getargs(x, 0, 0, _("clean takes no arguments"))
   521 
   529 
   522 def getfileset(ctx, expr):
   530 def getfileset(ctx, expr):
   523     tree = parse(expr)
   531     tree = parse(expr)
   524 
   532 
   525     # do we need status info?
   533     # do we need status info?
   526     if (_intree(['modified', 'added', 'removed', 'deleted',
   534     if (_intree(_statuscallers, tree) or
   527                  'missing', 'unknown', 'ignored', 'clean'], tree) or
       
   528         # Using matchctx.existing() on a workingctx requires us to check
   535         # Using matchctx.existing() on a workingctx requires us to check
   529         # for deleted files.
   536         # for deleted files.
   530         (ctx.rev() is None and _intree(_existingcallers, tree))):
   537         (ctx.rev() is None and _intree(_existingcallers, tree))):
   531         unknown = _intree(['unknown'], tree)
   538         unknown = _intree(['unknown'], tree)
   532         ignored = _intree(['ignored'], tree)
   539         ignored = _intree(['ignored'], tree)