microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
162.45k stars 28.63k forks source link

Exclude all files except for... #869

Open TheColorRed opened 8 years ago

TheColorRed commented 8 years ago

The files exclude allows you to set true/false values, but it doesn't seem to take them completely into account.

For example, I would like to hide everything except for the scripts folder. You might then assume that this would do this:

{
    "files.exclude":
    {
        "**/*": true,
        "**/Scripts": false
    }
}

It does not do that, it just hides everything. In order to achieve this, you must list every file and directory except for the Scripts directory, and who knows how many directories there are and if a new directory/file gets added you then must edit the list to exclude those.

In the end, their should be a way to hide everything except for xxx.

plantain-00 commented 8 years ago

The comments above the files.exclude says Configure glob patterns for excluding files and folders.. the glob can use ! to exclude files and folders(which is not implemented by vscode now). for example:

{
    // Configure glob patterns for excluding files and folders.
    "files.exclude": {
        "*.js": true,
        "!gulpfile.js": true
    }
}
dhirschfeld commented 8 years ago

Can an option be added to exclude everything in the .gitignore?

bpasero commented 8 years ago

Using negated glob patterns with "!" is currently not supported.

TheColorRed commented 8 years ago

.gitignore will only hide the items from a commit, not hide them within the Editor

hellogavin commented 8 years ago

It's grate!!!

xfoxfu commented 8 years ago

:+1: I also want negated glob patterns since I use Jakefile.js to describe Jake tasks for my TypeScript project.

JAForbes commented 8 years ago

:+1: I need negated glob files as we store our many services in node_modules under the same repo. We hide node_modules because it slows down the editor, and clutters the workspace. But we have to use directory symlinks so we can edit the specific services in another folder.

If we could exclude these folders from being ignored, we could remove the symlinks and significantly reduce the complexity of our project. (Another issue is, debugging node in a symlinked folder doesn't work in vscode, this would be solved by this feature also.)

AdamAndersonFalafelSoftware commented 8 years ago

Yes, we need negated glob exclusions. In Node, the built-in place to put application-wide modules is in a node_modules folder. You would want to be able to exclude node_modules except for your project's modules under e.g. node_modules/_local so that you can easily navigate to your own modules without also including all the imported ones.

Edit: this glob already works for the scenario above:

{
    "search.exclude": {
        "**/node_modules": false,
        "**/node_modules/!(.local)": true,
        "**/bower_components": true
    }
}
skyaddict commented 8 years ago

Would this feature allow me to exclude /.css but not /.cssx.css? Can anyone think of a way this could be done now?

AdamAndersonFalafelSoftware commented 8 years ago

@skyaddict My last comment above should work for your scenario as well

skyaddict commented 8 years ago

Sorry to bother, but I have tried many derivations of the following, and I still can't seem to find the secret sauce.

"/Css": false, "/Css/*!(.cssx).css":true

"/Css": false, "/Css/!(*.cssx.css)":true

JAForbes commented 8 years ago

@skyaddict it hasn't been implemented yet in vscode

AdamAndersonFalafelSoftware commented 8 years ago

@JAForbes, @skyaddict: I was about to write a reply saying that it already works, but then a mystery was revealed. I can confirm that the search.excludes setting above works for excluding all subfolders of node_modules except for a folder named .local. That is 100% definitely working. However, I was not able to get the same set of patterns to work on a folder other than node_modules, or on individual files. So this issue definitely still needs attention.

CreepGin commented 8 years ago

So right now, vscode is not supporting extended globbing for their exclude options. Can someone briefly explain what the holdup is?

J-Siu commented 8 years ago

I won't say it is a deal breaker but getting annoying not able to do this.

In angular 2 project we usually exclude all js file but still want to see a few js setting files, like webpack.config.js, systemjs.config.js, etc.

chase-moskal commented 8 years ago

Aw man, I'd sure love to see this working!

"files.exclude": {
  "node_modules/*": true,
  "!node_modules/susa": true,
}

Or maybe this:

"files.exclude": {
  "node_modules/*": true,
  "node_modules/susa": false,
}

Not sure if false could be equivalent to prefixing with "!". Maybe.

bladnman commented 8 years ago

always having Sublime open so I can search specific files that VSC won't let me is quite painful. A negative pattern here sounds rather straight-forward.

the-spyke commented 7 years ago

Yes, the issue with own modules in "node_modules" is really annoying...

ywmail commented 7 years ago

Yes - I also want the feature...

TobiasKoller commented 7 years ago

i wanted to hide all _.js-files if there is an equal *.ts file. I just added "_/.js": { "when": "$(basename).ts"}, which excludes all js-files except js-files like gulpfile.js etc

RandScullard commented 7 years ago

@TobiasKoller you are a genius, sir, and I thank you! I only needed to modify it slightly to get it to work in my project:

"**/*.js": { "when": "$(basename).ts" },
AdamAndersonFalafelSoftware commented 7 years ago

Some documentation on the behavior and syntax of the when-object would be greatly appreciated.

Zjaaspoer commented 7 years ago

yes negating pattern would be very welcome, exactly because of the use case described several times above (node_modules folder with private libraries that need to be accessable)

otjutt commented 7 years ago

Still not?

it6 commented 7 years ago

I created a work around, in my case I want to hide all node_modules except folders starting with "ap"

  "search.exclude": {
    "**/node_modules": false,
    "**/node_modules/.*": true,
    // hide all folders that doesn't start with letter 'a'
    "**/node_modules/[bcdefghijklmnopqrstuvwxyz]*": true,
    // hide all folders that doesn't start with 'ap'
    "**/node_modules/a[abcdefghijklmnoqrstuvwxyz]*": true
  }
  "files.exclude": {
    "**/node_modules": false,
    "**/node_modules/.*": true,
    // hide all folders that doesn't start with letter 'a'
    "**/node_modules/[bcdefghijklmnopqrstuvwxyz]*": true,
    // hide all folders that doesn't start with 'ap'
    "**/node_modules/a[abcdefghijklmnoqrstuvwxyz]*": true
  }

but having a negation ! is invaluable

bpasero commented 7 years ago

I am not understanding how a configuration like this:

"files.exclude": {
   "node_modules/*": true,
   "!node_modules/susa": true,
}

or this:

"files.exclude": {
   "*.js": true,
   "!gulpfile.js": true
}

Would make any sense or is even readable. What you are basically expressing is to (case 1) "exclude everything that is inside node_modules folder and also everything which is not node_modules/susa" and (case 2) "exclude every JS file and every file that is not gulpfile.js".

However I think using the boolean flag as a way to force something to not be excluded works better.

"files.exclude": {
   "node_modules/*": true,
   "node_modules/susa": false
}

and

"files.exclude": {
   "*.js": true,
   "gulpfile.js": false
}

One problem that I see with our implementation of this glob matching is that in many cases we are heavily optimizing when we traverse a tree structure. Imagine the following configuration:

"files.exclude": {
   "node_modules": true,
   "node_modules/susa": false
}

When we run our search algorithm we walk the file system and reach the node_modules folder. We check for configured rules to exclude this folder and see that it is configured to be excluded. At this point we have no other pattern matching this folder so we ignore it and continue. Of course we then fail to pick up the susa folder which was intended to be shown.

This is just an example for search, it applies equally to the explorer which is also representing a tree structure.

erichiller commented 7 years ago

Yes, to allow more specific items to override less specific items is what I thought the behavior would be, I spent hours until I gave up, and now found it was impossible. I was thinking this would work:

{
    "search.exclude": {
        "**/system": true,
        "**/system/**/*.ps*":false
    }
}

Where everything in system is ignore except those files that are .ps* (ie. ps1, psm1, etc...)

I hope this is supported in the near term.

Thanks guys-Eric

csholmq commented 7 years ago

@bpasero I don't know about you, but my ruleset is limited to 5-10 lines. So "heavily optimizing when we traverse" seems like a waste as it takes away from the configuration possibilities.

goblinfactory commented 7 years ago

Having users on my team accidentally edit something because it's json and everywhere else we're editing files by hand, except this 1 or 2 files that are generated as part of the build is very bad.

It would be valuable to be able to hide these files. The work around is of course to place the files in specific folders, that the exclude pattern doesn't match, but that's not always possible, or smart.

Is there anywhere I can go to cast my (+1) vote for this as a valuable feature?

txs, Alan

rmunn commented 7 years ago

In the example that @bpasero mentioned (where the user wants to exclude all of node_modules except for node_modules/susa), there might be a way to split the difference and get the benefit of heavy optimization in most cases, while still allowing the "show node_modules/susa" use case. Let's look at a sample case where we want to exclude the entire output directory, and all of node_modules except for node_modules/susa:

"files.exclude": {
   "node_modules": true,
   "node_modules/susa": false,
   "output": true
}

The algorithm I have in mind would go something like this:

  1. Parse the files.exclude configuration and analyze it, looking for the following two categories of folder exclusions:
    • Ones with no overrides deeper in the tree (e.g., output)
    • Ones that are overridden deeper in the tree (e.g, node_modules)
  2. Build a list of excludes to pass to the tree-search algorithm, with those two categories kept separated. (Different properties on the object passed to the algorithm, one for foldersToCompletelySkip and one for foldersToSkipExceptForCertainExceptions. With much better names than that, of course. The foldersToSkipExceptForCertainExceptions list might also have two different subcategories:
    • Exceptions where the direct path to the non-skipped descendant folder can be determined ahead of time (the path contains no * or ** parts), as in the node_modules/susa example
    • Exceptions where the direct path cannot be determined ahead of time, as in the **/system/**/*.ps* example from a previous comment
  3. Inside the tree-search function, any folder that can be completely skipped uses the current algorithm's approach, where its children aren't even parsed.
  4. Any folder that should be skipped except for certain descendants whose path can be determined ahead of time (e.g., node_modules/susa) then looks exclusively for the known path to those non-skipped descendants, ignoring all other folders and files. This is almost as fast as skipping the entire folder.
  5. Any folder that should be skipped except for a wildcard description of descendants (e.g, **/system/**/*.ps* when **/system is otherwise supposed to be skipped) cannot take an optimized approach, and must take the slower approach of searching the skipped folder for all non-skipped descendants.

This approach would allow keeping the optimized speed for some of the use cases mentioned here (skipping all of node_modules except for node_modules/one/specific/path/to/file.txt would still be very fast, for example). Examples like "include all **/system/**/*.ps* files" would still be slow, though, as I can see no way to get around the requirement to search the entire tree in those cases.

bpasero commented 7 years ago

This is a simple example, but I can easily come up with a glob pattern that has overlap with another glob pattern that is not so obvious. E.g. out/some/*.js has overlap with **/*.js. Unless you have a way to express order (similar to how .gitignore files work), I do not think you could give a clear answer.

pypmannetjies commented 7 years ago

Any news on this issue?

asthana86 commented 7 years ago

@egamma @bpasero is there an update on this issue, we are looking for a way to exclude a folder but add one subfolder using glob patterns. We are currently speculating of adding an option to specifically exclude, include headers in our extension as a workaround for header paths, perhaps a better workaround exists.

jonathantneal commented 7 years ago

I would like this functionality for white-listing as well. Our .gitignore files take advantage of it like this:

.*
!.editorconfig
!.gitignore

It is otherwise a reactive hassle to manage every possible dot file that might want to slip into our project. I hope you can appreciate how much easier it is to only react to new allowable dot files.

Also, resolving this would get us one step closer to resolving #78.

wclr commented 7 years ago

What about this? Quite an old request and useful feature.

fr43nk commented 7 years ago

I also think this would be a helpful feature. Beside that, why is there no folders.include option? This would make life much more easier for me, since I can define what folder should be displayed and searched, too.

wclr commented 7 years ago

Beside that, why is there no folders.include option

By default I believe all the files/folder included, so it is quite logical to have only exclude

   "**.js": true, //exclude all the js files
   "js_folder/*": false // except from exclusion this folder
fr43nk commented 7 years ago

Ok, perhaps it can work this way. But why doesn't something like the following work?

"d:\*\folder": true

What I want is, to exclude folders that are located at drive d and in the second level of the folder hierarchy. How can I get this work?

wclr commented 7 years ago

I believe you can only manage paths that are in the project filesystem scope.

tobia commented 7 years ago

Like others, I also thought something like this would work, but apparently it does not:

"files.exclude": {
    "node_modules/*": true,
    "node_modules/foobar": false,
}

This does work though:

"files.exclude": {
    "node_modules/[^f]*": true,
    "node_modules/f[^o]*": true,
    "node_modules/fo[^o]*": true,
    "node_modules/foo[^b]*": true,
    "node_modules/foob[^a]*": true,
    "node_modules/fooba[^r]*": true,
    "node_modules/foobar?*": true,
}

Here's a more complex example, excluding all Node modules except foo, bar, and bit:

"files.exclude": {
    "node_modules/[^fb]*"  : true,
    "node_modules/f[^o]*"  : true,
    "node_modules/fo[^o]*" : true,
    "node_modules/foo?*"   : true,
    "node_modules/b[^ai]*" : true,
    "node_modules/ba[^r]*" : true,
    "node_modules/bar?*"   : true,
    "node_modules/bi[^t]*" : true,
    "node_modules/bit?*"   : true,
}

You only need the final patterns such as foo?* if you want to exclude modules starting with foo that are not foo. In fact, you can write these interactively and stop as soon as they are enough for your particular directory content.

balazser commented 7 years ago

I'm looking forward to using Extended Globbing in settings.exclude :)

erichiller commented 7 years ago

@tobia that is a good tip - but it only works for the last path item correct? I tried playing around for mid-path items and could not get it to function. Ie.

I'm trying to get this to work.

    "!/system/psmodules/**/*.ps*": true,
    "/system/**": true

or this

    "/system/psmodules/**/*.ps*": false
    "/system/**": true

I really , really hope negation comes soon.

tobia commented 7 years ago

@erichiller why not? Something like this should work:

/system/[^p]**
/system/p[^s]**
/system/ps[^m]**
...
/system/psmodules/**/*.[^p]*
/system/psmodules/**/*.p[^s]*
erichiller commented 7 years ago

@tobia

So I just found out that as far as I can tell this should be fixed -- now that vscode is using ripgrep at least, the format is gitignore style

I've tested this and it works:

// Place your settings in this file to overwrite default and user settings.
{
    "search.exclude": {
        "**/system/**": true,
        "!/system/psmodules/*.ps*": true
    }
}

by works I mean: that all the files within system/ are ignored EXCEPT for the files in /system/psmodules/ ending in .ps

BillDenton commented 7 years ago

@erichiller I tried your suggestion in "files.exclude", but can't make it work. Are you it works?

csholmq commented 7 years ago

@BillDenton As far as I know, it is only search.exclude that actually supports this syntax as ripgrep handles search and not files.

@erichiller I couldn't get this to work:

"search.exclude": {
    "**/obj/*": true,
    "!**/obj/*.h": true
},

First rule takes effect, but second rule (negating) doesn't do anything.

grrowl commented 7 years ago

according to the vscode jsconfig documentation, it seems to be exclude: Array now?

tangorboyz commented 7 years ago

Can this feature be associated with particular extension? Like for python, I would like to hide all *.pyc file. Or maybe all in folder __pycache__

tangorboyz commented 7 years ago

Or associated with particular workspace.

nahuelhds commented 7 years ago

We definitively need the ! symbol for make it work like .gitignore