From 37f87e7d950953c74f2dc84d5d84290194e35ddb Mon Sep 17 00:00:00 2001 From: "Bob Brown (DEVDIV)" Date: Wed, 10 Jan 2018 21:40:20 -0800 Subject: [PATCH] support wildcards in the path (but only 1 per path). This is not meant to be used for recursive directory inclusion. --- .../src/LanguageServer/configurations.ts | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/Extension/src/LanguageServer/configurations.ts b/Extension/src/LanguageServer/configurations.ts index e318de4f1..de18a485f 100644 --- a/Extension/src/LanguageServer/configurations.ts +++ b/Extension/src/LanguageServer/configurations.ts @@ -108,6 +108,7 @@ interface ConfigurationJson { export class CppProperties { private propertiesFile: vscode.Uri = null; + private workspaceRoot: string; private readonly configFolder: string; private configurationJson: ConfigurationJson = null; private currentConfigurationIndex: PersistentFolderState; @@ -130,6 +131,7 @@ export class CppProperties { console.assert(rootPath !== undefined); this.currentConfigurationIndex = new PersistentFolderState("CppProperties.currentConfigurationIndex", -1, rootPath); this.configFolder = path.join(rootPath, ".vscode"); + this.workspaceRoot = rootPath; this.resetToDefaultSettings(this.currentConfigurationIndex.Value === -1); let configFilePath: string = path.join(this.configFolder, "c_cpp_properties.json"); @@ -274,26 +276,61 @@ export class CppProperties { this.onSelectionChanged(); } - private resolveAndSplit(paths: string[]): string[] { + private expandPath(path1: string): Promise { + return new Promise((resolve, reject) => { + let index: number = path1.indexOf("/*/"); + if (index >= 0) { + let paths: string[] = []; + let basePath: string = path1.substr(0, index).replace("${workspaceRoot}", this.workspaceRoot); + let remainingPath: string = path1.substr(index + 3); + try { + let items: string[] = fs.readdirSync(basePath); + items.forEach(directory => { + let potentialPath: string = path.join(basePath, directory, remainingPath); + try { + let stats: fs.Stats = fs.statSync(potentialPath.endsWith("*") ? potentialPath.substr(0, potentialPath.length - 1) : potentialPath); + if (stats && stats.isDirectory()) { + paths.push(potentialPath.replace(this.workspaceRoot, "${workspaceRoot}")); + } + } catch { + // potentialPath is not a valid path. Ignore it. + } + }); + } catch { + // basePath is not a valid path. Ignore it. + } + resolve(paths); + } else { + resolve([path1]); + } + }); + } + + private resolveAndSplit(paths: string[]): Promise { + let promises: Promise[] = []; let result: string[] = []; paths.forEach(entry => { let entries: string[] = util.resolveVariables(entry).split(";").filter(e => e); - result = result.concat(entries); + entries.forEach(path => { + promises.push(this.expandPath(path).then(paths => { + result = result.concat(paths); + })); + }); }); - return result; + return Promise.all(promises).then(() => result); } - private updateServerOnFolderSettingsChange(): void { + private async updateServerOnFolderSettingsChange(): Promise { for (let i: number = 0; i < this.configurationJson.configurations.length; i++) { let configuration: Configuration = this.configurationJson.configurations[i]; if (configuration.includePath !== undefined) { - configuration.includePath = this.resolveAndSplit(configuration.includePath); + configuration.includePath = await this.resolveAndSplit(configuration.includePath); } if (configuration.browse !== undefined && configuration.browse.path !== undefined) { - configuration.browse.path = this.resolveAndSplit(configuration.browse.path); + configuration.browse.path = await this.resolveAndSplit(configuration.browse.path); } if (configuration.macFrameworkPath !== undefined) { - configuration.macFrameworkPath = this.resolveAndSplit(configuration.macFrameworkPath); + configuration.macFrameworkPath = await this.resolveAndSplit(configuration.macFrameworkPath); } if (configuration.compileCommands !== undefined) { configuration.compileCommands = util.resolveVariables(configuration.compileCommands);