changeset 38863 | 61ab546b71c3 |
parent 38830 | bfd5def3fe02 |
child 38865 | 899b4c74209c |
38862:1ff45c518e6f | 38863:61ab546b71c3 |
---|---|
23 ) |
23 ) |
24 from .utils import ( |
24 from .utils import ( |
25 stringutil, |
25 stringutil, |
26 ) |
26 ) |
27 |
27 |
28 # common weight constants |
|
29 _WEIGHT_CHECK_FILENAME = filesetlang.WEIGHT_CHECK_FILENAME |
|
30 _WEIGHT_READ_CONTENTS = filesetlang.WEIGHT_READ_CONTENTS |
|
31 _WEIGHT_STATUS = filesetlang.WEIGHT_STATUS |
|
32 _WEIGHT_STATUS_THOROUGH = filesetlang.WEIGHT_STATUS_THOROUGH |
|
33 |
|
28 # helpers for processing parsed tree |
34 # helpers for processing parsed tree |
29 getsymbol = filesetlang.getsymbol |
35 getsymbol = filesetlang.getsymbol |
30 getstring = filesetlang.getstring |
36 getstring = filesetlang.getstring |
31 _getkindpat = filesetlang.getkindpat |
37 _getkindpat = filesetlang.getkindpat |
32 getpattern = filesetlang.getpattern |
38 getpattern = filesetlang.getpattern |
86 # filesets using matchctx.status() |
92 # filesets using matchctx.status() |
87 _statuscallers = set() |
93 _statuscallers = set() |
88 |
94 |
89 predicate = registrar.filesetpredicate() |
95 predicate = registrar.filesetpredicate() |
90 |
96 |
91 @predicate('modified()', callstatus=True, weight=10) |
97 @predicate('modified()', callstatus=True, weight=_WEIGHT_STATUS) |
92 def modified(mctx, x): |
98 def modified(mctx, x): |
93 """File that is modified according to :hg:`status`. |
99 """File that is modified according to :hg:`status`. |
94 """ |
100 """ |
95 # i18n: "modified" is a keyword |
101 # i18n: "modified" is a keyword |
96 getargs(x, 0, 0, _("modified takes no arguments")) |
102 getargs(x, 0, 0, _("modified takes no arguments")) |
97 s = set(mctx.status().modified) |
103 s = set(mctx.status().modified) |
98 return mctx.predicate(s.__contains__, predrepr='modified') |
104 return mctx.predicate(s.__contains__, predrepr='modified') |
99 |
105 |
100 @predicate('added()', callstatus=True, weight=10) |
106 @predicate('added()', callstatus=True, weight=_WEIGHT_STATUS) |
101 def added(mctx, x): |
107 def added(mctx, x): |
102 """File that is added according to :hg:`status`. |
108 """File that is added according to :hg:`status`. |
103 """ |
109 """ |
104 # i18n: "added" is a keyword |
110 # i18n: "added" is a keyword |
105 getargs(x, 0, 0, _("added takes no arguments")) |
111 getargs(x, 0, 0, _("added takes no arguments")) |
106 s = set(mctx.status().added) |
112 s = set(mctx.status().added) |
107 return mctx.predicate(s.__contains__, predrepr='added') |
113 return mctx.predicate(s.__contains__, predrepr='added') |
108 |
114 |
109 @predicate('removed()', callstatus=True, weight=10) |
115 @predicate('removed()', callstatus=True, weight=_WEIGHT_STATUS) |
110 def removed(mctx, x): |
116 def removed(mctx, x): |
111 """File that is removed according to :hg:`status`. |
117 """File that is removed according to :hg:`status`. |
112 """ |
118 """ |
113 # i18n: "removed" is a keyword |
119 # i18n: "removed" is a keyword |
114 getargs(x, 0, 0, _("removed takes no arguments")) |
120 getargs(x, 0, 0, _("removed takes no arguments")) |
115 s = set(mctx.status().removed) |
121 s = set(mctx.status().removed) |
116 return mctx.predicate(s.__contains__, predrepr='removed') |
122 return mctx.predicate(s.__contains__, predrepr='removed') |
117 |
123 |
118 @predicate('deleted()', callstatus=True, weight=10) |
124 @predicate('deleted()', callstatus=True, weight=_WEIGHT_STATUS) |
119 def deleted(mctx, x): |
125 def deleted(mctx, x): |
120 """Alias for ``missing()``. |
126 """Alias for ``missing()``. |
121 """ |
127 """ |
122 # i18n: "deleted" is a keyword |
128 # i18n: "deleted" is a keyword |
123 getargs(x, 0, 0, _("deleted takes no arguments")) |
129 getargs(x, 0, 0, _("deleted takes no arguments")) |
124 s = set(mctx.status().deleted) |
130 s = set(mctx.status().deleted) |
125 return mctx.predicate(s.__contains__, predrepr='deleted') |
131 return mctx.predicate(s.__contains__, predrepr='deleted') |
126 |
132 |
127 @predicate('missing()', callstatus=True, weight=10) |
133 @predicate('missing()', callstatus=True, weight=_WEIGHT_STATUS) |
128 def missing(mctx, x): |
134 def missing(mctx, x): |
129 """File that is missing according to :hg:`status`. |
135 """File that is missing according to :hg:`status`. |
130 """ |
136 """ |
131 # i18n: "missing" is a keyword |
137 # i18n: "missing" is a keyword |
132 getargs(x, 0, 0, _("missing takes no arguments")) |
138 getargs(x, 0, 0, _("missing takes no arguments")) |
133 s = set(mctx.status().deleted) |
139 s = set(mctx.status().deleted) |
134 return mctx.predicate(s.__contains__, predrepr='deleted') |
140 return mctx.predicate(s.__contains__, predrepr='deleted') |
135 |
141 |
136 @predicate('unknown()', callstatus=True, weight=50) |
142 @predicate('unknown()', callstatus=True, weight=_WEIGHT_STATUS_THOROUGH) |
137 def unknown(mctx, x): |
143 def unknown(mctx, x): |
138 """File that is unknown according to :hg:`status`.""" |
144 """File that is unknown according to :hg:`status`.""" |
139 # i18n: "unknown" is a keyword |
145 # i18n: "unknown" is a keyword |
140 getargs(x, 0, 0, _("unknown takes no arguments")) |
146 getargs(x, 0, 0, _("unknown takes no arguments")) |
141 s = set(mctx.status().unknown) |
147 s = set(mctx.status().unknown) |
142 return mctx.predicate(s.__contains__, predrepr='unknown') |
148 return mctx.predicate(s.__contains__, predrepr='unknown') |
143 |
149 |
144 @predicate('ignored()', callstatus=True, weight=50) |
150 @predicate('ignored()', callstatus=True, weight=_WEIGHT_STATUS_THOROUGH) |
145 def ignored(mctx, x): |
151 def ignored(mctx, x): |
146 """File that is ignored according to :hg:`status`.""" |
152 """File that is ignored according to :hg:`status`.""" |
147 # i18n: "ignored" is a keyword |
153 # i18n: "ignored" is a keyword |
148 getargs(x, 0, 0, _("ignored takes no arguments")) |
154 getargs(x, 0, 0, _("ignored takes no arguments")) |
149 s = set(mctx.status().ignored) |
155 s = set(mctx.status().ignored) |
150 return mctx.predicate(s.__contains__, predrepr='ignored') |
156 return mctx.predicate(s.__contains__, predrepr='ignored') |
151 |
157 |
152 @predicate('clean()', callstatus=True, weight=10) |
158 @predicate('clean()', callstatus=True, weight=_WEIGHT_STATUS) |
153 def clean(mctx, x): |
159 def clean(mctx, x): |
154 """File that is clean according to :hg:`status`. |
160 """File that is clean according to :hg:`status`. |
155 """ |
161 """ |
156 # i18n: "clean" is a keyword |
162 # i18n: "clean" is a keyword |
157 getargs(x, 0, 0, _("clean takes no arguments")) |
163 getargs(x, 0, 0, _("clean takes no arguments")) |
163 """File that is under Mercurial control.""" |
169 """File that is under Mercurial control.""" |
164 # i18n: "tracked" is a keyword |
170 # i18n: "tracked" is a keyword |
165 getargs(x, 0, 0, _("tracked takes no arguments")) |
171 getargs(x, 0, 0, _("tracked takes no arguments")) |
166 return mctx.predicate(mctx.ctx.__contains__, predrepr='tracked') |
172 return mctx.predicate(mctx.ctx.__contains__, predrepr='tracked') |
167 |
173 |
168 @predicate('binary()', weight=30) |
174 @predicate('binary()', weight=_WEIGHT_READ_CONTENTS) |
169 def binary(mctx, x): |
175 def binary(mctx, x): |
170 """File that appears to be binary (contains NUL bytes). |
176 """File that appears to be binary (contains NUL bytes). |
171 """ |
177 """ |
172 # i18n: "binary" is a keyword |
178 # i18n: "binary" is a keyword |
173 getargs(x, 0, 0, _("binary takes no arguments")) |
179 getargs(x, 0, 0, _("binary takes no arguments")) |
190 # i18n: "symlink" is a keyword |
196 # i18n: "symlink" is a keyword |
191 getargs(x, 0, 0, _("symlink takes no arguments")) |
197 getargs(x, 0, 0, _("symlink takes no arguments")) |
192 ctx = mctx.ctx |
198 ctx = mctx.ctx |
193 return mctx.predicate(lambda f: ctx.flags(f) == 'l', predrepr='symlink') |
199 return mctx.predicate(lambda f: ctx.flags(f) == 'l', predrepr='symlink') |
194 |
200 |
195 @predicate('resolved()', weight=10) |
201 @predicate('resolved()', weight=_WEIGHT_STATUS) |
196 def resolved(mctx, x): |
202 def resolved(mctx, x): |
197 """File that is marked resolved according to :hg:`resolve -l`. |
203 """File that is marked resolved according to :hg:`resolve -l`. |
198 """ |
204 """ |
199 # i18n: "resolved" is a keyword |
205 # i18n: "resolved" is a keyword |
200 getargs(x, 0, 0, _("resolved takes no arguments")) |
206 getargs(x, 0, 0, _("resolved takes no arguments")) |
202 return mctx.never() |
208 return mctx.never() |
203 ms = merge.mergestate.read(mctx.ctx.repo()) |
209 ms = merge.mergestate.read(mctx.ctx.repo()) |
204 return mctx.predicate(lambda f: f in ms and ms[f] == 'r', |
210 return mctx.predicate(lambda f: f in ms and ms[f] == 'r', |
205 predrepr='resolved') |
211 predrepr='resolved') |
206 |
212 |
207 @predicate('unresolved()', weight=10) |
213 @predicate('unresolved()', weight=_WEIGHT_STATUS) |
208 def unresolved(mctx, x): |
214 def unresolved(mctx, x): |
209 """File that is marked unresolved according to :hg:`resolve -l`. |
215 """File that is marked unresolved according to :hg:`resolve -l`. |
210 """ |
216 """ |
211 # i18n: "unresolved" is a keyword |
217 # i18n: "unresolved" is a keyword |
212 getargs(x, 0, 0, _("unresolved takes no arguments")) |
218 getargs(x, 0, 0, _("unresolved takes no arguments")) |
214 return mctx.never() |
220 return mctx.never() |
215 ms = merge.mergestate.read(mctx.ctx.repo()) |
221 ms = merge.mergestate.read(mctx.ctx.repo()) |
216 return mctx.predicate(lambda f: f in ms and ms[f] == 'u', |
222 return mctx.predicate(lambda f: f in ms and ms[f] == 'u', |
217 predrepr='unresolved') |
223 predrepr='unresolved') |
218 |
224 |
219 @predicate('hgignore()', weight=10) |
225 @predicate('hgignore()', weight=_WEIGHT_STATUS) |
220 def hgignore(mctx, x): |
226 def hgignore(mctx, x): |
221 """File that matches the active .hgignore pattern. |
227 """File that matches the active .hgignore pattern. |
222 """ |
228 """ |
223 # i18n: "hgignore" is a keyword |
229 # i18n: "hgignore" is a keyword |
224 getargs(x, 0, 0, _("hgignore takes no arguments")) |
230 getargs(x, 0, 0, _("hgignore takes no arguments")) |
225 return mctx.ctx.repo().dirstate._ignore |
231 return mctx.ctx.repo().dirstate._ignore |
226 |
232 |
227 @predicate('portable()', weight=0.5) |
233 @predicate('portable()', weight=_WEIGHT_CHECK_FILENAME) |
228 def portable(mctx, x): |
234 def portable(mctx, x): |
229 """File that has a portable name. (This doesn't include filenames with case |
235 """File that has a portable name. (This doesn't include filenames with case |
230 collisions.) |
236 collisions.) |
231 """ |
237 """ |
232 # i18n: "portable" is a keyword |
238 # i18n: "portable" is a keyword |
233 getargs(x, 0, 0, _("portable takes no arguments")) |
239 getargs(x, 0, 0, _("portable takes no arguments")) |
234 return mctx.predicate(lambda f: util.checkwinfilename(f) is None, |
240 return mctx.predicate(lambda f: util.checkwinfilename(f) is None, |
235 predrepr='portable') |
241 predrepr='portable') |
236 |
242 |
237 @predicate('grep(regex)', weight=30) |
243 @predicate('grep(regex)', weight=_WEIGHT_READ_CONTENTS) |
238 def grep(mctx, x): |
244 def grep(mctx, x): |
239 """File contains the given regular expression. |
245 """File contains the given regular expression. |
240 """ |
246 """ |
241 try: |
247 try: |
242 # i18n: "grep" is a keyword |
248 # i18n: "grep" is a keyword |
286 else: |
292 else: |
287 a = util.sizetoint(expr) |
293 a = util.sizetoint(expr) |
288 b = _sizetomax(expr) |
294 b = _sizetomax(expr) |
289 return lambda x: x >= a and x <= b |
295 return lambda x: x >= a and x <= b |
290 |
296 |
291 @predicate('size(expression)', weight=10) |
297 @predicate('size(expression)', weight=_WEIGHT_STATUS) |
292 def size(mctx, x): |
298 def size(mctx, x): |
293 """File size matches the given expression. Examples: |
299 """File size matches the given expression. Examples: |
294 |
300 |
295 - size('1k') - files from 1024 to 2047 bytes |
301 - size('1k') - files from 1024 to 2047 bytes |
296 - size('< 20k') - files less than 20480 bytes |
302 - size('< 20k') - files less than 20480 bytes |
301 expr = getstring(x, _("size requires an expression")) |
307 expr = getstring(x, _("size requires an expression")) |
302 m = sizematcher(expr) |
308 m = sizematcher(expr) |
303 return mctx.fpredicate(lambda fctx: m(fctx.size()), |
309 return mctx.fpredicate(lambda fctx: m(fctx.size()), |
304 predrepr=('size(%r)', expr), cache=True) |
310 predrepr=('size(%r)', expr), cache=True) |
305 |
311 |
306 @predicate('encoding(name)', weight=30) |
312 @predicate('encoding(name)', weight=_WEIGHT_READ_CONTENTS) |
307 def encoding(mctx, x): |
313 def encoding(mctx, x): |
308 """File can be successfully decoded with the given character |
314 """File can be successfully decoded with the given character |
309 encoding. May not be useful for encodings other than ASCII and |
315 encoding. May not be useful for encodings other than ASCII and |
310 UTF-8. |
316 UTF-8. |
311 """ |
317 """ |
323 except UnicodeDecodeError: |
329 except UnicodeDecodeError: |
324 return False |
330 return False |
325 |
331 |
326 return mctx.fpredicate(encp, predrepr=('encoding(%r)', enc), cache=True) |
332 return mctx.fpredicate(encp, predrepr=('encoding(%r)', enc), cache=True) |
327 |
333 |
328 @predicate('eol(style)', weight=30) |
334 @predicate('eol(style)', weight=_WEIGHT_READ_CONTENTS) |
329 def eol(mctx, x): |
335 def eol(mctx, x): |
330 """File contains newlines of the given style (dos, unix, mac). Binary |
336 """File contains newlines of the given style (dos, unix, mac). Binary |
331 files are excluded, files with mixed line endings match multiple |
337 files are excluded, files with mixed line endings match multiple |
332 styles. |
338 styles. |
333 """ |
339 """ |
357 def copiedp(fctx): |
363 def copiedp(fctx): |
358 p = fctx.parents() |
364 p = fctx.parents() |
359 return p and p[0].path() != fctx.path() |
365 return p and p[0].path() != fctx.path() |
360 return mctx.fpredicate(copiedp, predrepr='copied', cache=True) |
366 return mctx.fpredicate(copiedp, predrepr='copied', cache=True) |
361 |
367 |
362 @predicate('revs(revs, pattern)', weight=10) |
368 @predicate('revs(revs, pattern)', weight=_WEIGHT_STATUS) |
363 def revs(mctx, x): |
369 def revs(mctx, x): |
364 """Evaluate set in the specified revisions. If the revset match multiple |
370 """Evaluate set in the specified revisions. If the revset match multiple |
365 revs, this will return file matching pattern in any of the revision. |
371 revs, this will return file matching pattern in any of the revision. |
366 """ |
372 """ |
367 # i18n: "revs" is a keyword |
373 # i18n: "revs" is a keyword |
379 return mctx.never() |
385 return mctx.never() |
380 if len(matchers) == 1: |
386 if len(matchers) == 1: |
381 return matchers[0] |
387 return matchers[0] |
382 return matchmod.unionmatcher(matchers) |
388 return matchmod.unionmatcher(matchers) |
383 |
389 |
384 @predicate('status(base, rev, pattern)', weight=10) |
390 @predicate('status(base, rev, pattern)', weight=_WEIGHT_STATUS) |
385 def status(mctx, x): |
391 def status(mctx, x): |
386 """Evaluate predicate using status change between ``base`` and |
392 """Evaluate predicate using status change between ``base`` and |
387 ``rev``. Examples: |
393 ``rev``. Examples: |
388 |
394 |
389 - ``status(3, 7, added())`` - matches files added from "3" to "7" |
395 - ``status(3, 7, added())`` - matches files added from "3" to "7" |