Grdowns/launch configs (#3215)
* Implement debug configurations that will build the active C/C++ file and launch a debugger (disabled) * Handle compilerPath in build and squiggles.
This commit is contained in:
committed by
Sean McManus
parent
98260f96ea
commit
3d7937feeb
Generated
+41
-65
@@ -16,9 +16,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "8.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.4.tgz",
|
||||
"integrity": "sha512-iSJdm5S6Vhk+Ep38gwxie/5T7+MSip6bu30LsE5VylRKTMxXrvVJGqdxJLs8hsviLqjlCx9o3uRXDkJ+/K0DsQ==",
|
||||
"version": "8.10.40",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.40.tgz",
|
||||
"integrity": "sha512-RRSjdwz63kS4u7edIwJUn8NqKLLQ6LyqF/X4+4jp38MBT3Vwetewi2N4dgJEshLbDwNgOJXNYoOwzVZUSSLhkQ==",
|
||||
"dev": true
|
||||
},
|
||||
"agent-base": {
|
||||
@@ -30,9 +30,9 @@
|
||||
}
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz",
|
||||
"integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==",
|
||||
"version": "6.9.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.2.tgz",
|
||||
"integrity": "sha512-4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
@@ -114,6 +114,16 @@
|
||||
"buffer-equal": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"applicationinsights": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.8.tgz",
|
||||
"integrity": "sha512-KzOOGdphOS/lXWMFZe5440LUdFbrLpMvh2SaRxn7BmiI550KAoSb2gIhiq6kJZ9Ir3AxRRztjhzif+e5P5IXIg==",
|
||||
"requires": {
|
||||
"diagnostic-channel": "0.2.0",
|
||||
"diagnostic-channel-publishers": "0.2.1",
|
||||
"zone.js": "0.7.6"
|
||||
}
|
||||
},
|
||||
"archy": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
|
||||
@@ -1626,8 +1636,7 @@
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
@@ -1648,14 +1657,12 @@
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@@ -1670,20 +1677,17 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@@ -1800,8 +1804,7 @@
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@@ -1813,7 +1816,6 @@
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@@ -1828,7 +1830,6 @@
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@@ -1836,14 +1837,12 @@
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
@@ -1862,7 +1861,6 @@
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@@ -1943,8 +1941,7 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@@ -1956,7 +1953,6 @@
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@@ -2042,8 +2038,7 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
@@ -2079,7 +2074,6 @@
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@@ -2099,7 +2093,6 @@
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
@@ -2143,14 +2136,12 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5109,9 +5100,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz",
|
||||
"integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=",
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
|
||||
"integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
|
||||
"dev": true
|
||||
},
|
||||
"unc-path-regex": {
|
||||
@@ -5426,18 +5417,15 @@
|
||||
}
|
||||
},
|
||||
"vrsource-tslint-rules": {
|
||||
"version": "5.8.2",
|
||||
"resolved": "https://registry.npmjs.org/vrsource-tslint-rules/-/vrsource-tslint-rules-5.8.2.tgz",
|
||||
"integrity": "sha512-wr69FB/S6P8GT+rO/OocCr3biFaX4lT/JH1IZGqd7Jy4A3WaPUs0Jn4ELmTEpbFtYMWTawFACMQh1AyT7YewRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslint": "~5.8.0"
|
||||
}
|
||||
"version": "5.8.3",
|
||||
"resolved": "https://registry.npmjs.org/vrsource-tslint-rules/-/vrsource-tslint-rules-5.8.3.tgz",
|
||||
"integrity": "sha512-3tYS1zn+d9QtgmQIYmQ9e1i0kipmUjp6cvvYWLC+lZ3z8CQUle7rPKsTFMexOTIVXDpBt9JSJlhDWbwljl3DMQ==",
|
||||
"dev": true
|
||||
},
|
||||
"vscode": {
|
||||
"version": "1.1.29",
|
||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.29.tgz",
|
||||
"integrity": "sha512-E6hzqGtCD65BnBxdZzSIi8FPCM4seEEK/bbTeYdJntg+4D5R6GLbdYFySE9DNTtMJF4iB9UGoucKU/p8Guts1g==",
|
||||
"version": "1.1.30",
|
||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.30.tgz",
|
||||
"integrity": "sha512-YDj5w0TGOcS8XLIdekT4q6LlLV6hv1ZvuT2aGT3KJll4gMz6dUPDgo2VVAf0i0E8igbbZthwvmaUGRwW9yPIaw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.2",
|
||||
@@ -5505,23 +5493,11 @@
|
||||
"integrity": "sha512-d+l4lrEz6OP2kmGpweqe37x9H7icAMV8S4m8azTWGAIlNJxBP4rlSTnZa7NMLcbgqWkWG9lTGY7fJ+rSPaW7yg=="
|
||||
},
|
||||
"vscode-extension-telemetry": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.0.tgz",
|
||||
"integrity": "sha512-WVCnP+uLxlqB6UD98yQNV47mR5Rf79LFxpuZhSPhEf0Sb4tPZed3a63n003/dchhOwyCTCBuNN4n8XKJkLEI1Q==",
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz",
|
||||
"integrity": "sha512-TkKKG/B/J94DP5qf6xWB4YaqlhWDg6zbbqVx7Bz//stLQNnfE9XS1xm3f6fl24c5+bnEK0/wHgMgZYKIKxPeUA==",
|
||||
"requires": {
|
||||
"applicationinsights": "1.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"applicationinsights": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.6.tgz",
|
||||
"integrity": "sha512-VQT3kBpJVPw5fCO5n+WUeSx0VHjxFtD7znYbILBlVgOS9/cMDuGFmV2Br3ObzFyZUDGNbEfW36fD1y2/vAiCKw==",
|
||||
"requires": {
|
||||
"diagnostic-channel": "0.2.0",
|
||||
"diagnostic-channel-publishers": "0.2.1",
|
||||
"zone.js": "0.7.6"
|
||||
}
|
||||
}
|
||||
"applicationinsights": "1.0.8"
|
||||
}
|
||||
},
|
||||
"vscode-jsonrpc": {
|
||||
|
||||
@@ -1420,10 +1420,11 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.6",
|
||||
"@types/node": "^8.0.46",
|
||||
"await-notify": "^1.0.1",
|
||||
"@types/node": "^8.10.40",
|
||||
"async-child-process": "^1.1.1",
|
||||
"await-notify": "^1.0.1",
|
||||
"child-process": "^1.0.2",
|
||||
"extend": "3.0.2",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-env": "0.4.0",
|
||||
"gulp-mocha": "5.0.0",
|
||||
@@ -1432,10 +1433,9 @@
|
||||
"tslint": "5.8.0",
|
||||
"tslint-microsoft-contrib": "5.0.1",
|
||||
"tslint-no-unused-expression-chai": "0.0.3",
|
||||
"typescript": "^2.5.3",
|
||||
"vrsource-tslint-rules": "^5.8.2",
|
||||
"vscode": "^1.1.29",
|
||||
"extend": "3.0.2"
|
||||
"typescript": "^2.9.2",
|
||||
"vrsource-tslint-rules": "^5.8.3",
|
||||
"vscode": "^1.1.30"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/minimatch": "^3.0.3",
|
||||
@@ -1448,7 +1448,7 @@
|
||||
"vscode-cpptools": "2.1.1",
|
||||
"vscode-debugadapter": "~1.33.0",
|
||||
"vscode-debugprotocol": "~1.33.0",
|
||||
"vscode-extension-telemetry": "~0.1.0",
|
||||
"vscode-extension-telemetry": "^0.1.1",
|
||||
"vscode-languageclient": "5.1.1",
|
||||
"yauzl": "~2.10.0"
|
||||
},
|
||||
|
||||
@@ -14,5 +14,6 @@
|
||||
"c_cpp.command.pauseParsing.title": "Metti in pausa l'analisi del codice",
|
||||
"c_cpp.command.resumeParsing.title": "Riprendi l'analisi del codice",
|
||||
"c_cpp.command.showParsingCommands.title": "Mostra comandi per l'analisi del codice",
|
||||
"c_cpp.command.takeSurvey.title": "Partecipa al Sondaggio"
|
||||
"c_cpp.command.takeSurvey.title": "Partecipa al Sondaggio",
|
||||
"c_cpp.command.buildAndDebugActiveFile.title": "Compila ed Esegui il debug del file attivo"
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
"c_cpp.command.configurationSelect.title": "Select a configuration...",
|
||||
"c_cpp.command.configurationProviderSelect.title": "Change configuration provider...",
|
||||
"c_cpp.command.configurationEdit.title": "Edit configurations...",
|
||||
"c_cpp.command.goToDeclaration.title": "Go to declaration",
|
||||
"c_cpp.command.peekDeclaration.title": "Peek declaration",
|
||||
"c_cpp.command.goToDeclaration.title": "Go to Declaration",
|
||||
"c_cpp.command.peekDeclaration.title": "Peek Declaration",
|
||||
"c_cpp.command.switchHeaderSource.title": "Switch Header/Source",
|
||||
"c_cpp.command.navigate.title": "Navigate...",
|
||||
"c_cpp.command.toggleErrorSquiggles.title": "Toggle error squiggles",
|
||||
@@ -14,5 +14,6 @@
|
||||
"c_cpp.command.pauseParsing.title": "Pause parsing",
|
||||
"c_cpp.command.resumeParsing.title": "Resume parsing",
|
||||
"c_cpp.command.showParsingCommands.title": "Show parsing commands",
|
||||
"c_cpp.command.takeSurvey.title": "Take survey"
|
||||
"c_cpp.command.takeSurvey.title": "Take survey",
|
||||
"c_cpp.command.buildAndDebugActiveFile.title": "Build and Debug Active File"
|
||||
}
|
||||
@@ -14,5 +14,6 @@
|
||||
"c_cpp.command.pauseParsing.title": "暂停解析",
|
||||
"c_cpp.command.resumeParsing.title": "继续解析",
|
||||
"c_cpp.command.showParsingCommands.title": "查看解析命令",
|
||||
"c_cpp.command.takeSurvey.title": "调查问卷"
|
||||
"c_cpp.command.takeSurvey.title": "调查问卷",
|
||||
"c_cpp.command.buildAndDebugActiveFile.title": "生成和调试当前文件"
|
||||
}
|
||||
@@ -7,11 +7,80 @@ import * as debugUtils from './utils';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import { getBuildTasks, BuildTaskDefinition } from '../LanguageServer/extension';
|
||||
import * as util from '../common';
|
||||
import * as fs from 'fs';
|
||||
import * as assert from 'assert';
|
||||
import * as Telemetry from '../telemetry';
|
||||
import { buildAndDebugActiveFileStr } from './extension';
|
||||
|
||||
import { IConfiguration, IConfigurationSnippet, DebuggerType, MIConfigurations, WindowsConfigurations, WSLConfigurations, PipeTransportConfigurations } from './configurations';
|
||||
import { parse } from 'jsonc-parser';
|
||||
import { PlatformInformation } from '../platform';
|
||||
|
||||
abstract class CppConfigurationProvider implements vscode.DebugConfigurationProvider {
|
||||
function isDebugLaunchStr(str: string): boolean {
|
||||
return str === "(gdb) Launch" || str === "(lldb) Launch" || str === "(Windows) Launch";
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves configurations from a provider and displays them in a quickpick menu to be selected.
|
||||
* Ensures that the selected configuration's preLaunchTask (if existent) is populated in the user's task.json.
|
||||
* Automatically starts debugging for "Build and Debug" configurations.
|
||||
*/
|
||||
export class QuickPickConfigurationProvider implements vscode.DebugConfigurationProvider {
|
||||
private underlyingProvider: vscode.DebugConfigurationProvider;
|
||||
|
||||
public constructor(provider: CppConfigurationProvider) {
|
||||
this.underlyingProvider = provider;
|
||||
}
|
||||
|
||||
async provideDebugConfigurations(folder: vscode.WorkspaceFolder | undefined, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration[]> {
|
||||
const configs: vscode.DebugConfiguration[] = await this.underlyingProvider.provideDebugConfigurations(folder, token);
|
||||
const defaultConfig: vscode.DebugConfiguration = configs.find(config => { return isDebugLaunchStr(config.name); });
|
||||
console.assert(defaultConfig);
|
||||
const editor: vscode.TextEditor = vscode.window.activeTextEditor;
|
||||
if (!editor || !util.fileIsCOrCppSource(editor.document.fileName) || configs.length <= 1) {
|
||||
return [defaultConfig];
|
||||
}
|
||||
interface MenuItem extends vscode.QuickPickItem {
|
||||
configuration: vscode.DebugConfiguration;
|
||||
}
|
||||
|
||||
const items: MenuItem[] = configs.map<MenuItem>(config => {
|
||||
let menuItem: MenuItem = {label: config.name, configuration: config};
|
||||
// Rename the menu item for the default configuration as its name is non-descriptive.
|
||||
if (isDebugLaunchStr(menuItem.label)) {
|
||||
menuItem.label = "Default Configuration";
|
||||
}
|
||||
return menuItem;
|
||||
});
|
||||
|
||||
return vscode.window.showQuickPick(items, {placeHolder: "Select a configuration"}).then(async selection => {
|
||||
// Wrap in new Promise to make sure task kicks off before VS Code switches the active document to launch.json
|
||||
return new Promise<vscode.DebugConfiguration[]>(async resolve => {
|
||||
if (!selection) {
|
||||
return resolve([defaultConfig]); // User canceled it. Choose the default config?
|
||||
}
|
||||
if (selection.label.indexOf(buildAndDebugActiveFileStr()) !== -1 && selection.configuration.preLaunchTask) {
|
||||
try {
|
||||
await util.ensureBuildTaskExists(selection.configuration.preLaunchTask);
|
||||
await vscode.debug.startDebugging(folder, selection.configuration);
|
||||
Telemetry.logDebuggerEvent("buildAndDebug", { "success": "true" });
|
||||
} catch (e) {
|
||||
Telemetry.logDebuggerEvent("buildAndDebug", { "success": "false" });
|
||||
}
|
||||
}
|
||||
return resolve([selection.configuration]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration> {
|
||||
return this.underlyingProvider.resolveDebugConfiguration(folder, config, token);
|
||||
}
|
||||
}
|
||||
|
||||
class CppConfigurationProvider implements vscode.DebugConfigurationProvider {
|
||||
private type: DebuggerType;
|
||||
private provider: IConfigurationAssetProvider;
|
||||
|
||||
@@ -23,8 +92,60 @@ abstract class CppConfigurationProvider implements vscode.DebugConfigurationProv
|
||||
/**
|
||||
* Returns a list of initial debug configurations based on contextual information, e.g. package.json or folder.
|
||||
*/
|
||||
provideDebugConfigurations(folder: vscode.WorkspaceFolder | undefined, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration[]> {
|
||||
return this.provider.getInitialConfigurations(this.type);
|
||||
async provideDebugConfigurations(folder: vscode.WorkspaceFolder | undefined, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration[]> {
|
||||
let buildTasks: vscode.Task[]; // = await getBuildTasks(); // TODO
|
||||
if (!buildTasks || buildTasks.length === 0) {
|
||||
return Promise.resolve(this.provider.getInitialConfigurations(this.type));
|
||||
}
|
||||
const defaultConfig: vscode.DebugConfiguration = this.provider.getInitialConfigurations(this.type).find(config => {
|
||||
return isDebugLaunchStr(config.name);
|
||||
});
|
||||
console.assert(defaultConfig, "Could not find default debug configuration.");
|
||||
|
||||
const platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation();
|
||||
const platform: string = platformInfo.platform;
|
||||
|
||||
// Generate new configurations for each build task.
|
||||
// Generating a task is async, therefore we must *await* *all* map(task => config) Promises to resolve.
|
||||
let configs: vscode.DebugConfiguration[] = await Promise.all(buildTasks.map<Promise<vscode.DebugConfiguration>>(async task => {
|
||||
const definition: BuildTaskDefinition = task.definition as BuildTaskDefinition;
|
||||
const compilerName: string = path.basename(definition.compilerPath);
|
||||
const compilerDirname: string = path.dirname(definition.compilerPath);
|
||||
|
||||
let newConfig: vscode.DebugConfiguration = Object.assign({}, defaultConfig); // Copy enumerables and properties
|
||||
|
||||
newConfig.name = compilerName + buildAndDebugActiveFileStr();
|
||||
newConfig.preLaunchTask = task.name;
|
||||
newConfig.externalConsole = false;
|
||||
const exeName: string = path.join("${fileDirname}", "${fileBasenameNoExtension}");
|
||||
newConfig.program = platform === "win32" ? exeName + ".exe" : exeName;
|
||||
|
||||
let debuggerName: string;
|
||||
if (compilerName.startsWith("clang")) {
|
||||
newConfig.MIMode = "lldb";
|
||||
const suffixIndex: number = compilerName.indexOf("-");
|
||||
const suffix: string = suffixIndex === -1 ? "" : compilerName.substr(suffixIndex);
|
||||
debuggerName = (platform === "darwin" ? "lldb" : "lldb-mi") + suffix;
|
||||
} else {
|
||||
debuggerName = "gdb";
|
||||
}
|
||||
|
||||
const debuggerPath: string = path.join(compilerDirname, debuggerName);
|
||||
return new Promise<vscode.DebugConfiguration>(resolve => {
|
||||
fs.stat(debuggerPath, (err, stats: fs.Stats) => {
|
||||
if (!err && stats && stats.isFile) {
|
||||
newConfig.miDebuggerPath = debuggerPath;
|
||||
} else {
|
||||
// TODO should probably resolve a missing debugger in a more graceful fashion for win32.
|
||||
newConfig.miDebuggerPath = path.join("/usr", "bin", debuggerName);
|
||||
}
|
||||
|
||||
return resolve(newConfig);
|
||||
});
|
||||
});
|
||||
}));
|
||||
configs.push(defaultConfig);
|
||||
return configs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,12 +7,18 @@ import * as vscode from 'vscode';
|
||||
import * as os from 'os';
|
||||
import { AttachPicker, RemoteAttachPicker, AttachItemsProvider } from './attachToProcess';
|
||||
import { NativeAttachItemsProviderFactory } from './nativeAttach';
|
||||
import { ConfigurationAssetProviderFactory, CppVsDbgConfigurationProvider, CppDbgConfigurationProvider, ConfigurationSnippetProvider, IConfigurationAssetProvider } from './configurationProvider';
|
||||
import { QuickPickConfigurationProvider, ConfigurationAssetProviderFactory, CppVsDbgConfigurationProvider, CppDbgConfigurationProvider, ConfigurationSnippetProvider, IConfigurationAssetProvider } from './configurationProvider';
|
||||
import { CppdbgDebugAdapterDescriptorFactory, CppvsdbgDebugAdapterDescriptorFactory } from './debugAdapterDescriptorFactory';
|
||||
import * as util from '../common';
|
||||
import * as Telemetry from '../telemetry';
|
||||
|
||||
// The extension deactivate method is asynchronous, so we handle the disposables ourselves instead of using extensonContext.subscriptions.
|
||||
let disposables: vscode.Disposable[] = [];
|
||||
|
||||
export function buildAndDebugActiveFileStr(): string {
|
||||
return " build and debug active file";
|
||||
}
|
||||
|
||||
export function initialize(context: vscode.ExtensionContext): void {
|
||||
// Activate Process Picker Commands
|
||||
let attachItemsProvider: AttachItemsProvider = NativeAttachItemsProviderFactory.Get();
|
||||
@@ -28,7 +34,70 @@ export function initialize(context: vscode.ExtensionContext): void {
|
||||
if (os.platform() === 'win32') {
|
||||
disposables.push(vscode.debug.registerDebugConfigurationProvider('cppvsdbg', new CppVsDbgConfigurationProvider(configurationProvider)));
|
||||
}
|
||||
disposables.push(vscode.debug.registerDebugConfigurationProvider('cppdbg', new CppDbgConfigurationProvider(configurationProvider)));
|
||||
const provider: CppDbgConfigurationProvider = new CppDbgConfigurationProvider(configurationProvider);
|
||||
disposables.push(vscode.debug.registerDebugConfigurationProvider('cppdbg', provider)); //new QuickPickConfigurationProvider(provider))); // TODO
|
||||
|
||||
disposables.push(vscode.commands.registerTextEditorCommand("C_Cpp.BuildAndDebugActiveFile", async (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => {
|
||||
const folder: vscode.WorkspaceFolder = vscode.workspace.getWorkspaceFolder(textEditor.document.uri);
|
||||
if (!folder) {
|
||||
// Not enabled because we do not react to single-file mode correctly yet.
|
||||
// We get an ENOENT when the user's c_cpp_properties.json is attempted to be parsed.
|
||||
// The DefaultClient will also have its configuration accessed, but since it doesn't exist it errors out.
|
||||
vscode.window.showErrorMessage('This command is not yet available for single-file mode.');
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (!util.fileIsCOrCppSource(textEditor.document.uri.fsPath)) {
|
||||
vscode.window.showErrorMessage('Cannot build and debug because the active file is not a C or C++ source file.');
|
||||
return Promise.resolve();
|
||||
}
|
||||
let configs: vscode.DebugConfiguration[] = (await provider.provideDebugConfigurations(folder)).filter(config => {
|
||||
return config.name.indexOf(buildAndDebugActiveFileStr()) !== -1;
|
||||
});
|
||||
|
||||
interface MenuItem extends vscode.QuickPickItem {
|
||||
configuration: vscode.DebugConfiguration;
|
||||
}
|
||||
|
||||
const items: MenuItem[] = configs.map<MenuItem>(config => {
|
||||
return {label: config.name, configuration: config};
|
||||
});
|
||||
|
||||
vscode.window.showQuickPick(items, {placeHolder: (items.length === 0 ? "No compiler found" : "Select a compiler" )}).then(async selection => {
|
||||
if (!selection) {
|
||||
return; // User canceled it.
|
||||
}
|
||||
if (selection.configuration.preLaunchTask) {
|
||||
if (folder) {
|
||||
try {
|
||||
await util.ensureBuildTaskExists(selection.configuration.preLaunchTask);
|
||||
Telemetry.logDebuggerEvent("buildAndDebug", { "success": "false" });
|
||||
} catch (e) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
// TODO uncomment this when single file mode works correctly.
|
||||
// const buildTasks: vscode.Task[] = await getBuildTasks();
|
||||
// const task: vscode.Task = buildTasks.find(task => task.name === selection.configuration.preLaunchTask);
|
||||
// await vscode.tasks.executeTask(task);
|
||||
// delete selection.configuration.preLaunchTask;
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to use the user's (possibly) modified configuration before using the generated one.
|
||||
try {
|
||||
await vscode.debug.startDebugging(folder, selection.configuration.name);
|
||||
Telemetry.logDebuggerEvent("buildAndDebug", { "success": "true" });
|
||||
} catch (e) {
|
||||
try {
|
||||
vscode.debug.startDebugging(folder, selection.configuration);
|
||||
} catch (e) {
|
||||
Telemetry.logDebuggerEvent("buildAndDebug", { "success": "false" });
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
configurationProvider.getConfigurationSnippets();
|
||||
|
||||
|
||||
@@ -630,6 +630,7 @@ export class CppProperties {
|
||||
// Replace all \<escape character> with \\<character>.
|
||||
// Otherwise, the JSON.parse result will have the \<escape character> missing.
|
||||
readResults = readResults.replace(/\\/g, '\\\\');
|
||||
readResults = readResults.replace(/\\\\"/g, '\\"'); // Need to revert the change to \".
|
||||
|
||||
// Try to use the same configuration as before the change.
|
||||
let newJson: ConfigurationJson = JSON.parse(readResults);
|
||||
@@ -752,11 +753,19 @@ export class CppProperties {
|
||||
paths.add(`"${this.CurrentConfiguration.compileCommands}"`);
|
||||
}
|
||||
|
||||
let compilerPathAndArgs: util.CompilerPathAndArgs;
|
||||
if (this.CurrentConfiguration.compilerPath) {
|
||||
compilerPathAndArgs = util.extractCompilerPathAndArgs(this.CurrentConfiguration.compilerPath);
|
||||
paths.add(`"${compilerPathAndArgs.compilerPath}`); // It may not end with ".
|
||||
}
|
||||
|
||||
// Get the start/end for properties that are file-only.
|
||||
let forcedIncludeStart: number = curText.search(/\s*\"forcedInclude\"\s*:\s*\[/);
|
||||
let forcedeIncludeEnd: number = forcedIncludeStart === -1 ? -1 : curText.indexOf("]", forcedIncludeStart);
|
||||
let compileCommandsStart: number = curText.search(/\s*\"compileCommands\"\s*:\s*\"/);
|
||||
let compileCommandsEnd: number = compileCommandsStart === -1 ? -1 : curText.indexOf('"', curText.indexOf('"', curText.indexOf(":", compileCommandsStart)) + 1);
|
||||
let compilerPathStart: number = curText.search(/\s*\"compilerPath\"\s*:\s*\"/);
|
||||
let compilerPathEnd: number = compilerPathStart === -1 ? -1 : curText.indexOf('"', curText.indexOf('"', curText.indexOf(":", compilerPathStart)) + 1);
|
||||
|
||||
if (this.prevSquiggleMetrics[this.CurrentConfiguration.name] === undefined) {
|
||||
this.prevSquiggleMetrics[this.CurrentConfiguration.name] = { PathNonExistent: 0, PathNotAFile: 0, PathNotADirectory: 0 };
|
||||
@@ -764,7 +773,7 @@ export class CppProperties {
|
||||
let newSquiggleMetrics: { [key: string]: number } = { PathNonExistent: 0, PathNotAFile: 0, PathNotADirectory: 0 };
|
||||
|
||||
for (let curPath of paths) {
|
||||
let resolvedPath: string = curPath.substr(1, curPath.length - 2);
|
||||
let resolvedPath: string = curPath.substr(1, (curPath.endsWith('"') ? curPath.length - 2 : curPath.length - 1));
|
||||
// Resolve special path cases.
|
||||
if (resolvedPath === "${default}") {
|
||||
// TODO: Add squiggles for when the C_Cpp.default.* paths are invalid.
|
||||
@@ -817,7 +826,8 @@ export class CppProperties {
|
||||
} else {
|
||||
// Check for file versus path mismatches.
|
||||
if ((curOffset >= forcedIncludeStart && curOffset <= forcedeIncludeEnd) ||
|
||||
(curOffset >= compileCommandsStart && curOffset <= compileCommandsEnd)) {
|
||||
(curOffset >= compileCommandsStart && curOffset <= compileCommandsEnd) ||
|
||||
(curOffset >= compilerPathStart && curOffset <= compilerPathEnd)) {
|
||||
if (util.checkFileExistsSync(resolvedPath)) {
|
||||
continue;
|
||||
}
|
||||
@@ -832,7 +842,7 @@ export class CppProperties {
|
||||
}
|
||||
}
|
||||
let diagnostic: vscode.Diagnostic = new vscode.Diagnostic(
|
||||
new vscode.Range(document.positionAt(curTextStartOffset + curOffset + 1), document.positionAt(curTextStartOffset + curOffset + curPath.length - 1)),
|
||||
new vscode.Range(document.positionAt(curTextStartOffset + curOffset + 1), document.positionAt(curTextStartOffset + curOffset + (curPath.endsWith('"') ? curPath.length - 1 : curPath.length))),
|
||||
message, vscode.DiagnosticSeverity.Warning);
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ let realActivationOccurred: boolean = false;
|
||||
let tempCommands: vscode.Disposable[] = [];
|
||||
let activatedPreviously: PersistentWorkspaceState<boolean>;
|
||||
const insiderUpdateTimerInterval: number = 1000 * 60 * 60;
|
||||
const taskSourceStr: string = "C/C++";
|
||||
|
||||
let taskProvider: vscode.Disposable;
|
||||
|
||||
@@ -67,7 +68,7 @@ export function activate(activationEventOccurred: boolean): void {
|
||||
return;
|
||||
}
|
||||
|
||||
taskProvider = vscode.tasks.registerTaskProvider('C/Cpp', {
|
||||
taskProvider = vscode.tasks.registerTaskProvider(taskSourceStr, {
|
||||
provideTasks: () => {
|
||||
return getBuildTasks();
|
||||
},
|
||||
@@ -77,7 +78,7 @@ export function activate(activationEventOccurred: boolean): void {
|
||||
}
|
||||
});
|
||||
vscode.tasks.onDidStartTask(event => {
|
||||
if (event.execution.task.source === 'C/Cpp') {
|
||||
if (event.execution.task.source === taskSourceStr) {
|
||||
telemetry.logLanguageServerEvent('buildTaskStarted');
|
||||
}
|
||||
});
|
||||
@@ -105,10 +106,14 @@ export function activate(activationEventOccurred: boolean): void {
|
||||
}
|
||||
}
|
||||
|
||||
export interface BuildTaskDefinition extends vscode.TaskDefinition {
|
||||
compilerPath: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tasks to build the current file based on the user's detected compilers, the user's compilerPath setting, and the current file's extension.
|
||||
*/
|
||||
async function getBuildTasks(): Promise<vscode.Task[]> {
|
||||
export async function getBuildTasks(): Promise<vscode.Task[]> {
|
||||
const editor: vscode.TextEditor = vscode.window.activeTextEditor;
|
||||
if (!editor) {
|
||||
return [];
|
||||
@@ -121,7 +126,7 @@ async function getBuildTasks(): Promise<vscode.Task[]> {
|
||||
|
||||
// Don't offer tasks for header files.
|
||||
const fileExtLower: string = fileExt.toLowerCase();
|
||||
const isHeader: boolean = !fileExt || [".hpp", ".hh", ".hxx", ".h", ""].some(ext => fileExtLower === ext);
|
||||
const isHeader: boolean = !fileExt || [".hpp", ".hh", ".hxx", ".h", ".inl", ""].some(ext => fileExtLower === ext);
|
||||
if (isHeader) {
|
||||
return [];
|
||||
}
|
||||
@@ -133,7 +138,7 @@ async function getBuildTasks(): Promise<vscode.Task[]> {
|
||||
fileIsCpp = true;
|
||||
fileIsC = true;
|
||||
} else {
|
||||
fileIsCpp = [".cpp", ".cc", ".cxx", ".mm", ".ino", ".inl"].some(ext => fileExtLower === ext);
|
||||
fileIsCpp = [".cpp", ".cc", ".cxx", ".mm", ".ino"].some(ext => fileExtLower === ext);
|
||||
fileIsC = fileExtLower === ".c";
|
||||
}
|
||||
if (!(fileIsCpp || fileIsC)) {
|
||||
@@ -143,17 +148,31 @@ async function getBuildTasks(): Promise<vscode.Task[]> {
|
||||
// Get a list of compilers found from the C++ side, then filter them based on the file type to get a reduced list appropriate
|
||||
// for the active file, remove duplicate compiler names, then finally add the user's compilerPath setting.
|
||||
let compilerPaths: string[];
|
||||
const isWindows: boolean = os.platform() === 'win32';
|
||||
const activeClient: Client = getActiveClient();
|
||||
const userCompilerPath: string = await activeClient.getCompilerPath();
|
||||
let userCompilerPath: string = await activeClient.getCompilerPath();
|
||||
if (userCompilerPath) {
|
||||
userCompilerPath = userCompilerPath.trim();
|
||||
if (isWindows && (userCompilerPath.startsWith("/") || userCompilerPath.endsWith("cl.exe"))) { // TODO: Add WSL/cl.exe compiler support.
|
||||
userCompilerPath = null;
|
||||
} else {
|
||||
userCompilerPath = userCompilerPath.replace(/\\\\/g, "\\");
|
||||
}
|
||||
}
|
||||
|
||||
let knownCompilers: configs.KnownCompiler[] = await activeClient.getKnownCompilers();
|
||||
if (knownCompilers) {
|
||||
knownCompilers = knownCompilers.filter(info => { return (fileIsCpp && !info.isC) || (fileIsC && info.isC); });
|
||||
knownCompilers = knownCompilers.filter(info => {
|
||||
return ((fileIsCpp && !info.isC) || (fileIsC && info.isC)) &&
|
||||
(!isWindows || !info.path.startsWith("/")); // TODO: Add WSL compiler support.
|
||||
});
|
||||
compilerPaths = knownCompilers.map<string>(info => { return info.path; });
|
||||
|
||||
let map: Map<string, string> = new Map<string, string>();
|
||||
const insertOrAssignEntry: (compilerPath: string) => void = (compilerPath: string): void => {
|
||||
const basename: string = path.basename(compilerPath);
|
||||
map.has(basename) ? map[basename] = compilerPath : map.set(basename, compilerPath);
|
||||
//map.has(basename) ? map.basename] = compilerPath :
|
||||
map.set(basename, compilerPath);
|
||||
};
|
||||
compilerPaths.forEach(insertOrAssignEntry);
|
||||
|
||||
@@ -173,7 +192,7 @@ async function getBuildTasks(): Promise<vscode.Task[]> {
|
||||
// Display a message prompting the user to install compilers if none were found.
|
||||
// const dontShowAgain: string = "Don't Show Again";
|
||||
// const learnMore: string = "Learn More";
|
||||
// const message: string = "No C/C++ compiler found on the system. Please install a C/C++ compiler to use the C/Cpp: build active file tasks.";
|
||||
// const message: string = "No C/C++ compiler found on the system. Please install a C/C++ compiler to use the C/C++: build active file tasks.";
|
||||
|
||||
// let showNoCompilerFoundMessage: PersistentState<boolean> = new PersistentState<boolean>("CPP.showNoCompilerFoundMessage", true);
|
||||
// if (showNoCompilerFoundMessage) {
|
||||
@@ -194,38 +213,34 @@ async function getBuildTasks(): Promise<vscode.Task[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
// The build task output file should include a '.exe' extension on Windows.
|
||||
let platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation();
|
||||
let exeName: string;
|
||||
if (platformInfo.platform === 'win32') {
|
||||
exeName = '${fileBasenameNoExtension}.exe';
|
||||
} else {
|
||||
exeName = '${fileBasenameNoExtension}';
|
||||
}
|
||||
|
||||
// Generate tasks.
|
||||
let result: vscode.Task[] = [];
|
||||
compilerPaths.forEach(compilerPath => {
|
||||
return compilerPaths.map<vscode.Task>(compilerPath => {
|
||||
// Handle compiler args in compilerPath.
|
||||
let compilerPathAndArgs: util.CompilerPathAndArgs = util.extractCompilerPathAndArgs(compilerPath);
|
||||
compilerPath = compilerPathAndArgs.compilerPath;
|
||||
const taskName: string = path.basename(compilerPath) + " build active file";
|
||||
const args: string[] = ['-g', '${file}', '-o', '${fileDirname}/' + exeName];
|
||||
let args: string[] = ['-g', '${file}', '-o', path.join('${fileDirname}', '${fileBasenameNoExtension}' + (isWindows ? '.exe' : ''))];
|
||||
if (compilerPathAndArgs.additionalArgs) {
|
||||
args = args.concat(compilerPathAndArgs.additionalArgs);
|
||||
}
|
||||
const cwd: string = path.dirname(compilerPath);
|
||||
const kind: vscode.TaskDefinition = {
|
||||
const kind: BuildTaskDefinition = {
|
||||
type: 'shell',
|
||||
label: taskName,
|
||||
command: compilerPath,
|
||||
args: args,
|
||||
options: {"cwd": cwd}
|
||||
options: {"cwd": cwd},
|
||||
compilerPath: compilerPath
|
||||
};
|
||||
|
||||
const command: vscode.ShellExecution = new vscode.ShellExecution(compilerPath, [...args], { cwd: cwd });
|
||||
const target: vscode.WorkspaceFolder = vscode.workspace.getWorkspaceFolder(clients.ActiveClient.RootUri);
|
||||
let task: vscode.Task = new vscode.Task(kind, target, taskName, 'C/Cpp', command, '$gcc');
|
||||
let task: vscode.Task = new vscode.Task(kind, target, taskName, taskSourceStr, command, '$gcc');
|
||||
task.definition = kind; // The constructor for vscode.Task will eat the definition. Reset it by reassigning.
|
||||
task.group = vscode.TaskGroup.Build;
|
||||
|
||||
result.push(task);
|
||||
return task;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function onDidOpenTextDocument(document: vscode.TextDocument): void {
|
||||
|
||||
@@ -16,6 +16,7 @@ import { getOutputChannelLogger, showOutputChannel } from './logger';
|
||||
import * as assert from 'assert';
|
||||
import * as https from 'https';
|
||||
import { ClientRequest, OutgoingHttpHeaders } from 'http';
|
||||
import { getBuildTasks } from './LanguageServer/extension';
|
||||
|
||||
export let extensionContext: vscode.ExtensionContext;
|
||||
export function setExtensionContext(context: vscode.ExtensionContext): void {
|
||||
@@ -36,6 +37,65 @@ export function getRawPackageJson(): any {
|
||||
return rawPackageJson;
|
||||
}
|
||||
|
||||
export function getRawTasksJson(): Promise<any> {
|
||||
const path: string = getTasksJsonPath();
|
||||
if (!path) {
|
||||
return undefined;
|
||||
}
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
fs.exists(path, exists => {
|
||||
if (!exists) {
|
||||
return resolve({});
|
||||
}
|
||||
const fileContents: Buffer = fs.readFileSync(path);
|
||||
let rawTasks: any = {};
|
||||
try {
|
||||
rawTasks = JSON.parse(fileContents.toString());
|
||||
} catch (error) {
|
||||
}
|
||||
resolve(rawTasks);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function ensureBuildTaskExists(taskName: string): Promise<void> {
|
||||
let rawTasksJson: any = await getRawTasksJson();
|
||||
|
||||
// Ensure that the task exists in the user's task.json. Task will not be found otherwise.
|
||||
if (!rawTasksJson.tasks) {
|
||||
rawTasksJson.tasks = new Array();
|
||||
}
|
||||
// Find or create the task which should be created based on the selected "debug configuration".
|
||||
let selectedTask: vscode.Task = rawTasksJson.tasks.find(task => {
|
||||
return task.label && task.label === task;
|
||||
});
|
||||
if (selectedTask) {
|
||||
return;
|
||||
}
|
||||
|
||||
const buildTasks: vscode.Task[] = await getBuildTasks();
|
||||
selectedTask = buildTasks.find(task => task.name === taskName);
|
||||
console.assert(selectedTask);
|
||||
|
||||
let definition: vscode.TaskDefinition = selectedTask.definition as vscode.TaskDefinition;
|
||||
if (definition && definition.compilerPath) {
|
||||
// TODO: add desired properties to empty object, don't delete.
|
||||
delete definition.compilerPath;
|
||||
}
|
||||
|
||||
if (!rawTasksJson.tasks.find(task => { return task.label === selectedTask.definition.label; })) {
|
||||
rawTasksJson.tasks.push(selectedTask.definition);
|
||||
}
|
||||
|
||||
// TODO: It's dangerous to overwrite this file. We could be wiping out comments.
|
||||
await writeFileText(getTasksJsonPath(), JSON.stringify(rawTasksJson, null, 2));
|
||||
}
|
||||
|
||||
export function fileIsCOrCppSource(file: string): boolean {
|
||||
const fileExtLower: string = path.extname(file).toLowerCase();
|
||||
return [".C", ".c", ".cpp", ".cc", ".cxx", ".mm", ".ino", ".inl"].some(ext => fileExtLower === ext);
|
||||
}
|
||||
|
||||
// This function is used to stringify the rawPackageJson.
|
||||
// Do not use with util.packageJson or else the expanded
|
||||
// package.json will be written back.
|
||||
@@ -51,6 +111,15 @@ export function getPackageJsonPath(): string {
|
||||
return getExtensionFilePath("package.json");
|
||||
}
|
||||
|
||||
export function getTasksJsonPath(): string {
|
||||
const editor: vscode.TextEditor = vscode.window.activeTextEditor;
|
||||
const folder: vscode.WorkspaceFolder = vscode.workspace.getWorkspaceFolder(editor.document.uri);
|
||||
if (!folder) {
|
||||
return undefined;
|
||||
}
|
||||
return path.join(folder.uri.fsPath, ".vscode", "tasks.json");
|
||||
}
|
||||
|
||||
export function getVcpkgPathDescriptorFile(): string {
|
||||
if (process.platform === 'win32') {
|
||||
return path.join(process.env.LOCALAPPDATA, "vcpkg/vcpkg.path.txt");
|
||||
@@ -686,4 +755,32 @@ export function downloadFileToStr(urlStr: string, headers?: OutgoingHttpHeaders)
|
||||
request.on('error', (error) => { reject(error); });
|
||||
request.end();
|
||||
});
|
||||
}
|
||||
|
||||
export interface CompilerPathAndArgs {
|
||||
compilerPath: string;
|
||||
additionalArgs: string[];
|
||||
}
|
||||
|
||||
export function extractCompilerPathAndArgs(inputCompilerPath: string): CompilerPathAndArgs {
|
||||
let compilerPath: string = inputCompilerPath;
|
||||
let additionalArgs: string[];
|
||||
if (compilerPath) {
|
||||
if (compilerPath.startsWith("\"")) {
|
||||
let endQuote: number = compilerPath.substr(1).search("\"") + 1;
|
||||
if (endQuote !== -1) {
|
||||
additionalArgs = compilerPath.substr(endQuote + 1).split(" ");
|
||||
additionalArgs = additionalArgs.filter((arg: string) => { return arg.trim().length !== 0; });
|
||||
compilerPath = compilerPath.substr(1, endQuote - 1);
|
||||
}
|
||||
} else {
|
||||
if (compilerPath.includes(" ") && !fs.existsSync(compilerPath)) {
|
||||
let argStart: number = compilerPath.search(" ");
|
||||
additionalArgs = compilerPath.substr(argStart + 1).split(" ");
|
||||
additionalArgs = additionalArgs.filter((arg: string) => { return arg.trim().length !== 0; });
|
||||
compilerPath = compilerPath.substr(0, argStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
return { compilerPath, additionalArgs };
|
||||
}
|
||||
@@ -329,6 +329,7 @@ function rewriteManifest(): Promise<void> {
|
||||
"onLanguage:c",
|
||||
"onCommand:extension.pickNativeProcess",
|
||||
"onCommand:extension.pickRemoteNativeProcess",
|
||||
//"onCommand:C_Cpp.BuildAndDebugActiveFile", // TODO
|
||||
"onCommand:C_Cpp.ConfigurationEdit",
|
||||
"onCommand:C_Cpp.ConfigurationSelect",
|
||||
"onCommand:C_Cpp.ConfigurationProviderSelect",
|
||||
|
||||
Reference in New Issue
Block a user