-
Notifications
You must be signed in to change notification settings - Fork 30.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add !
-prefix parsing to glob util
#134415
Comments
Somewhat related: #869 I think the biggest challenge is how to support conflicting includes / excludes. Maybe some inspiration could be taken from how search handles this where you can configure both include and exclude patterns at the same time. |
Ah, so search is exclude-dominated, in search:
Versus what I described above and what our
Concretely, given the config: "files.exclude": {
"node_modules/**": true,
"!node_modules/@types": true,
} The On the other hand, given this config: "files.exclude": {
"foo.ts": true,
"!*.ts": true,
} The Not really sure what the best option is here. The I lean towards using the cc @roblourens for any thoughts here |
I would definitely not expect a negative exclude to work the same as an include. If I put
Does that mean that if I also have an exclude for Also, do you expect that I'd be able to have negated patterns in settings that override patterns in the gitignore? Last I looked into this area, ripgrep makes gitignore always take precedence. |
Hm, I think maybe this issue needs to split into two issues:
I am not sure the intent of this issue, so asking @JacksonKearl to clarify: is this about making glob patterns aware of a leading vscode/src/vs/base/common/glob.ts Lines 464 to 472 in e80a0ca
|
yes |
It is somewhat easy to add global negate support for glob, see efa5122 for a first stab at it. However, there are a few questions:
[1] Not sure the ripples or adoption cost where it is used, @roblourens in search. Does RipGrep even support these patterns? [2] Take this example: let globExpression = {
'!*.js': true,
'!*.ts': true
}; Since glob expressions are basically a |
Ripgrep supports them, I think the support there will be the same as in gitignore files |
So how is our glob util used in search component then? Are we even requiring it there or are we just passing on patterns to RipGrep and let it deal with it? |
We pass the patterns to ripgrep, and for editors that are open, we interpret the glob patterns. For patterns with sibling clauses, we interpret the patterns. |
After some discussion with Christoph, I concluded that support for I see no practical way how to parse an expression such as: {
"!workspace/*.js": true,
"!workspace/*.ts": true,
"workspace/*.html": true,
"workspace/*.xml": true
} Our normal algorithm is to report a match overall when any of the enabled patterns match. With negated patterns, that doesn't really work anymore because negated patterns match on almost everything and as such, 2 negated patterns in an expression will match everything. Then my naive solution to this was to group all negated patterns together and require them ALL to match and then check the remaining patterns for matches, basically for the above example: Can someone come up with a meaningful expression that combines negated patterns and normal patterns that makes any sense with this rule? So far I could not come up with any example... |
From the gitignore manpage,
In that example, I don't think the negated patterns should change the overall result since they don't intersect with the html/xml patterns. Another example would be like {
"foo/*": true,
"bar/*": true,
"!foo/file.txt": true
} So I think you would check the positive patterns, then check the negative patterns, like The In gitignore, order matters, and I'm not sure whether we would run into trouble by assuming that the negated patterns are always resolved after the positive ones. |
If I understand correctly a path matches the expression when it matches any of the non-negated patterns and then all of the negated patterns? In the example above:
That could work. It is probably not very intuitive because we do not really support processing the expression in an ordered way like |
@JacksonKearl can you maybe chime in as stake holder, you mention it would solve #869 so we should maybe look at examples and build this feature around the needs. If I understand correctly, users would configure |
I guess, but it would probably be worth looking at ripgrep or git source before we get bit by edge cases |
Yes exactly.
We mostly implement their logic here:
Ideally, the following would work:
However that requires some understanding of the ordering that we may not want to rely on, especially given things like settings scope merging. Absent that, it'd be helpful to have this:
where if a file matches some bare expression and no negated expression, it matches the glob and is included. This way ordering isn't important, a simple 2 pass approach works. This is actually what we do already in the ignore file parser. |
Support for negate patterns is essential to fixing a bug with the "Explorer: Exclude Git Ignore" setting. Negate patterns are ignored when hiding files in the explore pane. As mentioned in #175066. That issue was marked as a duplicate of this issue and closed. |
I try to use {
...,
"files.exclude" : {
"Library/" : true,
...
},
"search.exclude" : {
"Library/PackageCache/**" : false,
...
},
...
} And it's not work This below work for some reason {
...,
"files.exclude" : {
"Library/[!(PackageCache)]*/": true,
"library/[!(PackageCache)]*/": true,
"Library/PackageCache/": true,
"library/PackageCache/": true,
...
},
"search.exclude" : {
"Library/PackageCache/": false,
"library/PackageCache/": false
},
...
} Also though it seem the negate syntax only work with one character only |
It'd be potentially useful to have
!
as a prefix added to ourglob.ts
utils. This could function similarly to how we already handle.gitignore
files in the webworker search here:!
-line, exclude it (we do this today)!
-line, include itThis isn't quite as powerful as a real
.gitignore
as there are only two "layers" of include/exclude, whereas ingitignore
each line introduces a new "layer", but I believe it would handle the 99% of cases well enough, for instance every example given to-date in #869.To handle the many-layer case requires either:
files.exclude
andsearch.exclude
, which is undesirable from a backwards/forwards compatibility perspective*.exclude
objects are handled in a key-order sensitive way, which is potentially undesirable from a JSON/JS object semantics compatibility perspectivecc @bpasero for any and all input on this
The text was updated successfully, but these errors were encountered: