From 3da2f7600c6bcb9b4b66dcbfb6b82a23e9c9dd7f Mon Sep 17 00:00:00 2001 From: Uli Franke Date: Fri, 7 Feb 2020 02:55:26 +0100 Subject: [PATCH] IntelliSense on/off configuration and compiler parser injection preparation * Added a global configuration switch which allows the IntelliSense auto-configuration to be turned off * Prepared the compiler parser code to be injected into "upload" and "upload using programmer" without overhead * Updated branch documentation --- BRANCHNOTES.md | 35 +++++++++++---------- package.json | 5 +++ src/arduino/arduino.ts | 58 ++++++++++++++++++++++++++--------- src/arduino/intellisense.ts | 11 ++++++- src/arduino/vscodeSettings.ts | 6 ++++ 5 files changed, 83 insertions(+), 32 deletions(-) diff --git a/BRANCHNOTES.md b/BRANCHNOTES.md index e9a84633..5f99989f 100644 --- a/BRANCHNOTES.md +++ b/BRANCHNOTES.md @@ -40,7 +40,9 @@ src/arduino/arduino.ts | | :heavy_check_mark: Basic file output | | | :white_check_mark: Merging of parsing result and existing file content | | | :white_check_mark: Handling inexistent files and folders | -| **Configuration flags** | :white_check_mark: | +| **Configuration flags** | :heavy_check_mark: Disable flag for IntelliSense auto-config | +| | :white_check_mark: Perhaps a general IntelliSense flag `{off/manual, auto, oldstyle}` whereas the old can be removed at some point | +| | :white_check_mark: Fine grained IntelliSense control: Global en-/disable and project override. This is probably more useful since the most boards will hopefully work and for the very special cases the user can disable the feature for this single project but still can enjoy it within his regular projects. | | **Unit tests** | :white_check_mark: Basic parser (known boards, match/no match)| | | :white_check_mark: Querying of compiler built-in includes | | | :white_check_mark: Throwing arbitrary data at parser engines | @@ -48,7 +50,7 @@ src/arduino/arduino.ts | | :white_check_mark: JSON output | | | :white_check_mark: Configuration merging | | **General** | :white_check_mark: Review and remove previous attempts messing with `c_cpp_properties.json` | -| | :white_check_mark: Auto-run verify after setting a board to generate a valid `c_cpp_properties.json`, identify other occasions where this applies | +| | :white_check_mark: Auto-run verify after setting a board to generate a valid `c_cpp_properties.json`, identify other occasions where this applies (usually when adding new libraries), hint the user to run *verify*? | `*` not committed to branch yet @@ -139,30 +141,31 @@ As one can see with the ESP32-gcc not all include directories are named `include ### Settings -Global user settings, on linux under `~/.config/Code/User/settings.json`, for instance: +#### Global Settings +Under linux at `~/.config/Code/User/settings.json`, for instance: ```json { "arduino.additionalUrls": "", "arduino.logLevel": "verbose", - "C_Cpp.default.cppStandard": "c++11", - "C_Cpp.default.cStandard": "c11", "arduino.disableTestingOpen": true, "workbench.editor.enablePreview": false } ``` -Project settings in `.vscode/arduino.json` +Code: [src/arduino/arduinoSettings.ts](src/arduino/arduinoSettings.ts) +Code: [src/arduino/vscodeSettings.ts](src/arduino/vscodeSettings.ts) +Validator: [package.json](package.json) + +#### Project Settings +Path in project `.vscode/arduino.json` ```json { - "board": "arduino:avr:nano", - "configuration": "cpu=atmega328old", - "sketch": "examples/lcdpong-butenc/lcdpong-butenc.ino", - "port": "/dev/ttyUSB0" -} -``` -The global settings are [here](src/arduino/vscodeSettings.ts) -```ts -if (VscodeSettings.getInstance().logLevel === "verbose") { - args.push("--verbose"); + "board": "arduino:avr:nano", + "configuration": "cpu=atmega328old", + "sketch": "examples/lcdpong-butenc/lcdpong-butenc.ino", + "port": "/dev/ttyUSB0" } ``` +Code: [src/deviceContext.ts](src/deviceContext.ts) +Validator: [misc/arduinoValidator.json](misc/arduinoValidator.json) + ### Global Tasks in vscode-arduino diff --git a/package.json b/package.json index dd27fa3f..24b961ec 100644 --- a/package.json +++ b/package.json @@ -504,6 +504,11 @@ "arduino.defaultBaudRate": { "type": "number", "default": 115200 + }, + "arduino.disableIntelliSenseAutoGen": { + "type": "boolean", + "default": false, + "description": "When disabled vscode-arduino will not auto-generate an IntelliSense configuration (i.e. c_cpp_properties.json) by analyzing the compiler output." } } }, diff --git a/src/arduino/arduino.ts b/src/arduino/arduino.ts index a558a9cf..6c70285f 100644 --- a/src/arduino/arduino.ts +++ b/src/arduino/arduino.ts @@ -255,29 +255,19 @@ export class ArduinoApp { } arduinoChannel.show(); - // we need to return the result of verify + try { - const gccParserEngine = new CompilerCmdParserEngineGcc(dc.sketch); - const compilerParser = new CompilerCmdParser([gccParserEngine]); + const compilerParserContext = this.makeCompilerParserContext(dc); await util.spawn(this._settings.commandPath, arduinoChannel.channel, args, undefined, - compilerParser.callback); + compilerParserContext.callback); - // Write compiler command parser result to IntelliSense - // configuration file in case parsing was successful. - if (compilerParser.result) { - const cppPropsPath = path.join(ArduinoWorkspace.rootPath, constants.CPP_CONFIG_FILE); - const cppProps = new CCppProperties(cppPropsPath); - cppProps.merge(compilerParser.result); - cppProps.write(); - arduinoChannel.info("IntelliSense configuration generated successfully."); - } else { - arduinoChannel.warning("Failed to generate IntelliSense configuration."); + if (compilerParserContext.conclude) { + compilerParserContext.conclude(); } - arduinoChannel.end(`Finished verify sketch - ${dc.sketch}${os.EOL}`); return true; } catch (reason) { @@ -803,6 +793,44 @@ export class ArduinoApp { // return VscodeSettings.getInstance().useArduinoCli; } + /** + * Creates a context which is used for compiler command parsing + * during building (verify, upload, ...). + * + * This context makes sure that it can be used in those sections + * without having to check whether this feature is en- or disabled + * and keeps the calling context more readable. + * + * @param dc The device context of the caller. + */ + private makeCompilerParserContext(dc: DeviceContext) + : { callback: (s: string) => void; conclude: () => void; } { + if (!VscodeSettings.getInstance().disableIntelliSenseAutoGen) { + + // setup the parser with its engines + const gccParserEngine = new CompilerCmdParserEngineGcc(dc.sketch); + const compilerParser = new CompilerCmdParser([gccParserEngine]); + + // set up the function to be called after parsing + const _conclude = () => { + const cppPropsPath = path.join(ArduinoWorkspace.rootPath, constants.CPP_CONFIG_FILE); + if (compilerParser.processResult(cppPropsPath)) { + arduinoChannel.info("IntelliSense configuration generated successfully."); + } else { + arduinoChannel.warning("Failed to generate IntelliSense configuration."); + } + }; + return { + callback: compilerParser.callback, + conclude: _conclude, + }; + } + return { + callback: undefined, + conclude: undefined, + } + }; + private getProgrammerString(): string { const selectProgrammer = this.programmerManager.currentProgrammer; if (!selectProgrammer) { diff --git a/src/arduino/intellisense.ts b/src/arduino/intellisense.ts index 706104e7..8b322056 100644 --- a/src/arduino/intellisense.ts +++ b/src/arduino/intellisense.ts @@ -26,7 +26,7 @@ export class CompilerCmdParserResult { public defines: Array = []; public options: Array = []; public compiler: string = ""; - /** Dropped arguments like -c -Ox */ + /** Dropped arguments like -c -Ox -o, the input and output file. */ public trash: Array = []; }; @@ -276,6 +276,15 @@ export class CompilerCmdParser { } } } + public processResult(configPath: string): boolean { + if (this._result) { + const cppProps = new CCppProperties(configPath); + cppProps.merge(this._result); + cppProps.write(); + return true; + } + return false; + } } /** diff --git a/src/arduino/vscodeSettings.ts b/src/arduino/vscodeSettings.ts index 14726cd8..74f7bedb 100644 --- a/src/arduino/vscodeSettings.ts +++ b/src/arduino/vscodeSettings.ts @@ -16,6 +16,7 @@ const configKeys = { SKIP_HEADER_PROVIDER: "arduino.skipHeaderProvider", DEFAULT_BAUD_RATE: "arduino.defaultBaudRate", USE_ARDUINO_CLI: "arduino.useArduinoCli", + DISABLE_INTELLISENSE_AUTO_GEN: "arduino.disableIntelliSenseAutoGen", }; export interface IVscodeSettings { @@ -30,6 +31,7 @@ export interface IVscodeSettings { skipHeaderProvider: boolean; defaultBaudRate: number; useArduinoCli: boolean; + disableIntelliSenseAutoGen: boolean; updateAdditionalUrls(urls: string | string[]): void; } @@ -93,6 +95,10 @@ export class VscodeSettings implements IVscodeSettings { return this.getConfigValue(configKeys.SKIP_HEADER_PROVIDER); } + public get disableIntelliSenseAutoGen(): boolean { + return this.getConfigValue(configKeys.DISABLE_INTELLISENSE_AUTO_GEN); + } + public async updateAdditionalUrls(value) { await this.setConfigValue(configKeys.ADDITIONAL_URLS, value, true); }