124 def getpattern(x, allkinds, err): |
124 def getpattern(x, allkinds, err): |
125 if x and x[0] == 'kindpat': |
125 if x and x[0] == 'kindpat': |
126 return _getkindpat(x[1], x[2], allkinds, err) |
126 return _getkindpat(x[1], x[2], allkinds, err) |
127 return getstring(x, err) |
127 return getstring(x, err) |
128 |
128 |
|
129 def getlist(x): |
|
130 if not x: |
|
131 return [] |
|
132 if x[0] == 'list': |
|
133 return getlist(x[1]) + [x[2]] |
|
134 return [x] |
|
135 |
|
136 def getargs(x, min, max, err): |
|
137 l = getlist(x) |
|
138 if len(l) < min or len(l) > max: |
|
139 raise error.ParseError(err) |
|
140 return l |
|
141 |
129 def getset(mctx, x): |
142 def getset(mctx, x): |
130 if not x: |
143 if not x: |
131 raise error.ParseError(_("missing argument")) |
144 raise error.ParseError(_("missing argument")) |
132 return methods[x[0]](mctx, *x[1:]) |
145 return methods[x[0]](mctx, *x[1:]) |
133 |
146 |
161 raise error.ParseError(_("can't use negate operator in this context")) |
174 raise error.ParseError(_("can't use negate operator in this context")) |
162 |
175 |
163 def listset(mctx, a, b): |
176 def listset(mctx, a, b): |
164 raise error.ParseError(_("can't use a list in this context"), |
177 raise error.ParseError(_("can't use a list in this context"), |
165 hint=_('see hg help "filesets.x or y"')) |
178 hint=_('see hg help "filesets.x or y"')) |
166 |
|
167 # symbols are callable like: |
|
168 # fun(mctx, x) |
|
169 # with: |
|
170 # mctx - current matchctx instance |
|
171 # x - argument in tree form |
|
172 symbols = {} |
|
173 |
|
174 # filesets using matchctx.status() |
|
175 _statuscallers = set() |
|
176 |
|
177 # filesets using matchctx.existing() |
|
178 _existingcallers = set() |
|
179 |
|
180 predicate = registrar.filesetpredicate() |
|
181 |
|
182 @predicate('modified()', callstatus=True) |
|
183 def modified(mctx, x): |
|
184 """File that is modified according to :hg:`status`. |
|
185 """ |
|
186 # i18n: "modified" is a keyword |
|
187 getargs(x, 0, 0, _("modified takes no arguments")) |
|
188 s = set(mctx.status().modified) |
|
189 return [f for f in mctx.subset if f in s] |
|
190 |
|
191 @predicate('added()', callstatus=True) |
|
192 def added(mctx, x): |
|
193 """File that is added according to :hg:`status`. |
|
194 """ |
|
195 # i18n: "added" is a keyword |
|
196 getargs(x, 0, 0, _("added takes no arguments")) |
|
197 s = set(mctx.status().added) |
|
198 return [f for f in mctx.subset if f in s] |
|
199 |
|
200 @predicate('removed()', callstatus=True) |
|
201 def removed(mctx, x): |
|
202 """File that is removed according to :hg:`status`. |
|
203 """ |
|
204 # i18n: "removed" is a keyword |
|
205 getargs(x, 0, 0, _("removed takes no arguments")) |
|
206 s = set(mctx.status().removed) |
|
207 return [f for f in mctx.subset if f in s] |
|
208 |
|
209 @predicate('deleted()', callstatus=True) |
|
210 def deleted(mctx, x): |
|
211 """Alias for ``missing()``. |
|
212 """ |
|
213 # i18n: "deleted" is a keyword |
|
214 getargs(x, 0, 0, _("deleted takes no arguments")) |
|
215 s = set(mctx.status().deleted) |
|
216 return [f for f in mctx.subset if f in s] |
|
217 |
|
218 @predicate('missing()', callstatus=True) |
|
219 def missing(mctx, x): |
|
220 """File that is missing according to :hg:`status`. |
|
221 """ |
|
222 # i18n: "missing" is a keyword |
|
223 getargs(x, 0, 0, _("missing takes no arguments")) |
|
224 s = set(mctx.status().deleted) |
|
225 return [f for f in mctx.subset if f in s] |
|
226 |
|
227 @predicate('unknown()', callstatus=True) |
|
228 def unknown(mctx, x): |
|
229 """File that is unknown according to :hg:`status`. These files will only be |
|
230 considered if this predicate is used. |
|
231 """ |
|
232 # i18n: "unknown" is a keyword |
|
233 getargs(x, 0, 0, _("unknown takes no arguments")) |
|
234 s = set(mctx.status().unknown) |
|
235 return [f for f in mctx.subset if f in s] |
|
236 |
|
237 @predicate('ignored()', callstatus=True) |
|
238 def ignored(mctx, x): |
|
239 """File that is ignored according to :hg:`status`. These files will only be |
|
240 considered if this predicate is used. |
|
241 """ |
|
242 # i18n: "ignored" is a keyword |
|
243 getargs(x, 0, 0, _("ignored takes no arguments")) |
|
244 s = set(mctx.status().ignored) |
|
245 return [f for f in mctx.subset if f in s] |
|
246 |
|
247 @predicate('clean()', callstatus=True) |
|
248 def clean(mctx, x): |
|
249 """File that is clean according to :hg:`status`. |
|
250 """ |
|
251 # i18n: "clean" is a keyword |
|
252 getargs(x, 0, 0, _("clean takes no arguments")) |
|
253 s = set(mctx.status().clean) |
|
254 return [f for f in mctx.subset if f in s] |
|
255 |
179 |
256 def func(mctx, a, b): |
180 def func(mctx, a, b): |
257 funcname = getsymbol(a) |
181 funcname = getsymbol(a) |
258 if funcname in symbols: |
182 if funcname in symbols: |
259 enabled = mctx._existingenabled |
183 enabled = mctx._existingenabled |
266 keep = lambda fn: getattr(fn, '__doc__', None) is not None |
190 keep = lambda fn: getattr(fn, '__doc__', None) is not None |
267 |
191 |
268 syms = [s for (s, fn) in symbols.items() if keep(fn)] |
192 syms = [s for (s, fn) in symbols.items() if keep(fn)] |
269 raise error.UnknownIdentifier(funcname, syms) |
193 raise error.UnknownIdentifier(funcname, syms) |
270 |
194 |
271 def getlist(x): |
195 # symbols are callable like: |
272 if not x: |
196 # fun(mctx, x) |
273 return [] |
197 # with: |
274 if x[0] == 'list': |
198 # mctx - current matchctx instance |
275 return getlist(x[1]) + [x[2]] |
199 # x - argument in tree form |
276 return [x] |
200 symbols = {} |
277 |
201 |
278 def getargs(x, min, max, err): |
202 # filesets using matchctx.status() |
279 l = getlist(x) |
203 _statuscallers = set() |
280 if len(l) < min or len(l) > max: |
204 |
281 raise error.ParseError(err) |
205 # filesets using matchctx.existing() |
282 return l |
206 _existingcallers = set() |
|
207 |
|
208 predicate = registrar.filesetpredicate() |
|
209 |
|
210 @predicate('modified()', callstatus=True) |
|
211 def modified(mctx, x): |
|
212 """File that is modified according to :hg:`status`. |
|
213 """ |
|
214 # i18n: "modified" is a keyword |
|
215 getargs(x, 0, 0, _("modified takes no arguments")) |
|
216 s = set(mctx.status().modified) |
|
217 return [f for f in mctx.subset if f in s] |
|
218 |
|
219 @predicate('added()', callstatus=True) |
|
220 def added(mctx, x): |
|
221 """File that is added according to :hg:`status`. |
|
222 """ |
|
223 # i18n: "added" is a keyword |
|
224 getargs(x, 0, 0, _("added takes no arguments")) |
|
225 s = set(mctx.status().added) |
|
226 return [f for f in mctx.subset if f in s] |
|
227 |
|
228 @predicate('removed()', callstatus=True) |
|
229 def removed(mctx, x): |
|
230 """File that is removed according to :hg:`status`. |
|
231 """ |
|
232 # i18n: "removed" is a keyword |
|
233 getargs(x, 0, 0, _("removed takes no arguments")) |
|
234 s = set(mctx.status().removed) |
|
235 return [f for f in mctx.subset if f in s] |
|
236 |
|
237 @predicate('deleted()', callstatus=True) |
|
238 def deleted(mctx, x): |
|
239 """Alias for ``missing()``. |
|
240 """ |
|
241 # i18n: "deleted" is a keyword |
|
242 getargs(x, 0, 0, _("deleted takes no arguments")) |
|
243 s = set(mctx.status().deleted) |
|
244 return [f for f in mctx.subset if f in s] |
|
245 |
|
246 @predicate('missing()', callstatus=True) |
|
247 def missing(mctx, x): |
|
248 """File that is missing according to :hg:`status`. |
|
249 """ |
|
250 # i18n: "missing" is a keyword |
|
251 getargs(x, 0, 0, _("missing takes no arguments")) |
|
252 s = set(mctx.status().deleted) |
|
253 return [f for f in mctx.subset if f in s] |
|
254 |
|
255 @predicate('unknown()', callstatus=True) |
|
256 def unknown(mctx, x): |
|
257 """File that is unknown according to :hg:`status`. These files will only be |
|
258 considered if this predicate is used. |
|
259 """ |
|
260 # i18n: "unknown" is a keyword |
|
261 getargs(x, 0, 0, _("unknown takes no arguments")) |
|
262 s = set(mctx.status().unknown) |
|
263 return [f for f in mctx.subset if f in s] |
|
264 |
|
265 @predicate('ignored()', callstatus=True) |
|
266 def ignored(mctx, x): |
|
267 """File that is ignored according to :hg:`status`. These files will only be |
|
268 considered if this predicate is used. |
|
269 """ |
|
270 # i18n: "ignored" is a keyword |
|
271 getargs(x, 0, 0, _("ignored takes no arguments")) |
|
272 s = set(mctx.status().ignored) |
|
273 return [f for f in mctx.subset if f in s] |
|
274 |
|
275 @predicate('clean()', callstatus=True) |
|
276 def clean(mctx, x): |
|
277 """File that is clean according to :hg:`status`. |
|
278 """ |
|
279 # i18n: "clean" is a keyword |
|
280 getargs(x, 0, 0, _("clean takes no arguments")) |
|
281 s = set(mctx.status().clean) |
|
282 return [f for f in mctx.subset if f in s] |
283 |
283 |
284 @predicate('binary()', callexisting=True) |
284 @predicate('binary()', callexisting=True) |
285 def binary(mctx, x): |
285 def binary(mctx, x): |
286 """File that appears to be binary (contains NUL bytes). |
286 """File that appears to be binary (contains NUL bytes). |
287 """ |
287 """ |