Skip to content
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

Can c_cpp_properties.json support wildcard paths? #723

Closed
bbalp opened this issue May 12, 2017 · 22 comments · Fixed by #10388
Closed

Can c_cpp_properties.json support wildcard paths? #723

bbalp opened this issue May 12, 2017 · 22 comments · Fixed by #10388
Labels
Feature Request fixed Check the Milestone for the release in which the fix is or will be available. help wanted Can be fixed in the public (open source) repo. Language Service
Milestone

Comments

@bbalp
Copy link

bbalp commented May 12, 2017

The scripts I am using to build my projects are generating the dependencies in a folder. It could be very useful in this situation to be able to give a path like this /my/path/*/include to simplify /my/path/dep1/include /my/path/dep2/include /my/path/dep3/include

I would be pleased to have your opinion. :)

@sean-mcmanus sean-mcmanus added help wanted Can be fixed in the public (open source) repo. and removed extension labels Jan 10, 2018
@sean-mcmanus
Copy link
Contributor

This should be implementable in our open source typescript if anyone wants to contribute :)

@bobbrow bobbrow self-assigned this Jan 11, 2018
@bobbrow bobbrow removed the help wanted Can be fixed in the public (open source) repo. label Jan 11, 2018
@bobbrow
Copy link
Member

bobbrow commented Jun 26, 2018

With 0.17.5 you should be able to use /my/path/** and it will add all of the relevant paths. Let us know if that works for you.

@bobbrow bobbrow added the fixed Check the Milestone for the release in which the fix is or will be available. label Jun 26, 2018
@bobbrow bobbrow closed this as completed Jun 26, 2018
@aaronlelevier
Copy link

Hi, is a middle wildcard not supported though? For example:

/Users/aaron/Documents/github/opencv/modules/*/include/**

It's not finding the path, and I'm trying to avoid adding each opencv/modules/<some-module>/include/** to the includePath

Thanks

@BillDenton
Copy link

As far as I can see the middle wildcard doesn't work. Our include files are all "include" & "interface" directories in many places. So this only leaves using everything via "${workspaceFolder}/", or adding each one in turn when required (which may be better where there are duplicated names). I suspect using "${workspaceFolder}/" isn't great for performance.

@bobbrow
Copy link
Member

bobbrow commented Feb 28, 2019

A middle wildcard is not currently supported. I started a branch that would support this a while ago, but I forget what state it was in and now the branch is out of date. If anyone wants to get it back in sync with master and finish it, we can consider taking it. I'll reopen this issue since the original request was not actually addressed.

This is the branch: https://github.com/Microsoft/vscode-cpptools/tree/bobbrow/expand-wildcards

@bobbrow bobbrow reopened this Feb 28, 2019
@bobbrow bobbrow added help wanted Can be fixed in the public (open source) repo. and removed fixed Check the Milestone for the release in which the fix is or will be available. labels Feb 28, 2019
@bobbrow bobbrow added this to the Backlog milestone Oct 17, 2019
@dzchoi
Copy link

dzchoi commented Jan 31, 2020

In my opinion, in addition to supporting the normal "*" it would be also good have "**" as the globstar in bash.

From the bash manpage:

globstar
If set, the pattern ** used in a pathname expansion context will
match all files and zero or more directories and subdirectories.
If the pattern is followed by a /, only directories and
subdirectories match.

Then, we could use, for example,

  • /my/path/**/include
  • /my/path/**/include/**/

@NZSmartie
Copy link

Hey @bobbrow,

A middle wildcard is not currently supported. I started a branch that would support this a while ago, but I forget what state it was in and now the branch is out of date. If anyone wants to get it back in sync with master and finish it, we can consider taking it. I'll reopen this issue since the original request was not actually addressed.

This is the branch: https://github.com/Microsoft/vscode-cpptools/tree/bobbrow/expand-wildcards

Looking into how the wildcard support is added to vscode-cpptools, I've come across a couple PRs (#1896, #2136); Their changes do not make much sense into how the recursive includePath is implemented.
Looking around for uses of IncludePath don't yield much insight apart from UI settings, json settings and verification of it includePath.

It looks like it's all passed off to pre-compiled cpptools binaries. which I can't find the source code for. Are you able to link to the repository so that I may continue investigation and figure out how to implement includePath globbing.

@sean-mcmanus
Copy link
Contributor

sean-mcmanus commented May 18, 2020

@NZSmartie cpptools is closed source. It seems like "*" and/or "**" in paths should be implementable in the TypeScript. The implementation is complicated and tries to filter out unneeded paths in order to reduce the performance impact on cpptools-srv, but usage of "*" and "**" in path segments isn't expected to generate the same performance hit as "**" at the end of a path.

@bobbrow bobbrow removed their assignment Jun 25, 2020
@bobbrow bobbrow changed the title Can c_cpp_properties.json supports wildcard path? Can c_cpp_properties.json support wildcard paths? Jun 25, 2020
asialasr pushed a commit to asialasr/vscode-cpptools that referenced this issue Mar 12, 2021
* Merge OpenDebugAD7 into MIEngine

MIEngine will now create OpenDebugAD7.exe and DebugEngineHost for VSCode
C++ extension.

* Removing Lab.*, Debug/Release builds for new projs

* Fixing active configurations
@BillDenton
Copy link

@sean-mcmanus @bobbrow Any update on this? All my include headers are in "include" or "interface" directories. Hence I would like to use all sub-directories that end in "include" or "interface", and nothing else.

@sean-mcmanus
Copy link
Contributor

@BillDenton No update (the issue hasn't been assigned to a milestone yet). I believe the fix could be implemented in our open source typescript.

@heaths
Copy link
Member

heaths commented May 6, 2021

Seems that way. Off hand I'm not sure of any VSCode-provided APIs, but a package to resolve/expand globstars could be used to format a value to pass to cpptools right from the extension.

@bobbrow bobbrow modified the milestones: 1.8.0, On Deck Nov 16, 2021
@haolly
Copy link

haolly commented Jun 15, 2022

any progress?

@sean-mcmanus
Copy link
Contributor

@haolly Not yet -- it's been pushed back repeatedly. It's currently "On Deck" which means we don't have a definite target Milestone yet. The best case might be September, but it certainly could be delayed further.

@gchen88
Copy link

gchen88 commented Sep 14, 2022

ran across this Issue. also interested. any good news yet?

@sean-mcmanus
Copy link
Contributor

@lifo888 No news. I don't have an ETA.

@yne
Copy link
Contributor

yne commented Jan 2, 2023

Here is a standalone working example of a glob walker

show
import fs from 'fs';
import path from 'path';
import process from 'process'
class Demo {
	globMatch(pattern, str) {// use picomatch ?
		let i = 0;
		let j = 0;
		while (i < pattern.length && j < str.length) {
			if (pattern.charAt(i) == '*') {
				if (i + 1 == pattern.length)
					return true;
				for (let k = j; k < str.length; k++)
					if (this.globMatch(pattern.substring(i + 1), str.substring(k)))
						return true;
				return false;
			} else {
				if (pattern.charAt(i) != str.charAt(j))
					return false;
				i++;
				j++;
			}
		}
		return (i == pattern.length && j == str.length);
	}
	tryReadDir = (dir) => { try { const res = fs.readdirSync(dir); return res; } catch (e) { return []; } };
	globWalkDir(components, i = 0) {
		if (i >= components.length || components[i] == '**') {
			return path.sep + components.join(path.sep); // end of expression
		}
		const cwd = path.sep + components.slice(0, i).join(path.sep);
		return this.tryReadDir(cwd)
			.filter(name => this.globMatch(components[i], name))
			.filter(match => fs.lstatSync(path.join(cwd, match)).isDirectory())
			.map(match => this.globWalkDir([...components.slice(0, i), match, ...components.slice(i + 1)], i + 1));
		//console.log({components,i, cwd, ls, res})
	}
}

if (!process.argv[2] || !path.isAbsolute(process.argv[2])) {
	throw 'USAGE: glob.mjs ABS_GLOB_EXP';
}
const compo = process.argv[2].split(path.sep).slice(1);

console.log(new Demo().globWalkDir(compo).flat(compo.length));

It allow partial matching, for example :

> globWalkDir(['usr','l*','**']); // "/usr/l*/**" pattern
[ '/usr/lib/**', '/usr/lib32/**', '/usr/local/**' ]

and can be used as drop-in replacement of resolveAndSplit() in ~/.vscode/extensions/ms-vscode.cpptools-*/dist/main.js :

    globMatch(pattern, str) { // TODO: use picomatch ?
      let i = 0;
      let j = 0;
      while (i < pattern.length && j < str.length) {
        if (pattern.charAt(i) == '*') {
          if (i + 1 == pattern.length)
            return true;
          for (let k = j; k < str.length; k++)
            if (this.globMatch(pattern.substring(i + 1), str.substring(k)))
              return true;
          return false;
        } else {
          if (pattern.charAt(i) != str.charAt(j))
            return false;
          i++;
          j++;
        }
      }
      return (i == pattern.length && j == str.length);
    }
    tryReadDir(...args) { try { return fs.readdirSync(...args); } catch (e) { return []; } }
    globWalkDir(components, i = 0) {
      if (i >= components.length || components[i] == '**') {
        return path.sep + components.join(path.sep); // end of expression
      }
      const cwd = path.sep + components.slice(0, i).join(path.sep);
      return this.tryReadDir(cwd)
        .filter(name => this.globMatch(components[i], name))
        .filter(match => fs.lstatSync(path.join(cwd, match)).isDirectory())
        .map(match => this.globWalkDir([...components.slice(0, i), match, ...components.slice(i + 1)], i + 1));
    }
    resolveAndSplit(paths, defaultValue, env) { //// <<<<<
      return paths ? this.resolveDefaults(paths, defaultValue).map(entry =>
          util.resolveVariables(entry, env).split(util.envDelimiter).filter(e => e)
          .map(e => e.replace("${workspaceFolder}", this.rootUri.fsPath).split(path.sep).slice(1))
          .map(e => this.globWalkDir(e).flat(e.length))
          .flat()
      ).flat() : [];
    }

Tell me if you have any use-case that doesn't work

@bobbrow I'm currently following the CONTRIBUTING.md in order to send you a PR. Is that okay for you ?

@sean-mcmanus
Copy link
Contributor

@yne Sure, can you submit a PR?

@yne
Copy link
Contributor

yne commented Jan 17, 2023

@sean-mcmanus: I've PR'd a working exemple with * path support.

@BillDenton
Copy link

@sean-mcmanus Slightly confused about the status of this issue and the related issue #10388. What is the status with the latest VS Code 1.79.2 and C/C++ extension v1.16.3? What is the syntax?
Thanks.

@sean-mcmanus sean-mcmanus modified the milestones: On Deck, 1.17.0 Jun 29, 2023
@sean-mcmanus
Copy link
Contributor

@BillDenton It'll be in 1.17.0. Syntax is currently * for wildcards in the middle of a path.

@bobbrow bobbrow added the fixed Check the Milestone for the release in which the fix is or will be available. label Jul 18, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Aug 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Feature Request fixed Check the Milestone for the release in which the fix is or will be available. help wanted Can be fixed in the public (open source) repo. Language Service
Projects
None yet
Development

Successfully merging a pull request may close this issue.