├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── vcse.yml ├── .gitignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── FUNDING.yml ├── LICENSE ├── README.md ├── image ├── diff.png ├── logo_cppinsights.info ├── logo_cppinsights.png └── show.png ├── package.json ├── src ├── extension.ts └── test │ ├── runTest.ts │ └── suite │ ├── escape test.cpp │ ├── escape. %folder'test │ └── escape. %test.cpp │ ├── extension.test.ts │ ├── index.ts │ └── test.cpp └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:@typescript-eslint/recommended" 9 | ], 10 | "parser": "@typescript-eslint/parser", 11 | "parserOptions": { 12 | "ecmaVersion": 12 13 | }, 14 | "plugins": [ 15 | "@typescript-eslint" 16 | ], 17 | "rules": { 18 | "@typescript-eslint/no-inferrable-types": "off" 19 | } 20 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Summary** 11 | - What went wrong? 12 | - What was expected behavior? (if not obvious) 13 | 14 | **How to reproduce** 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 19 | **Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **Additional context** 23 | Add any other context about the problem here. 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you would like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you have considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/vcse.yml: -------------------------------------------------------------------------------- 1 | name: NodeJS build and package 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | matrix: 15 | node-version: [14.x] 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v1 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | 25 | - name: Build 26 | run: | 27 | npm install 28 | npm install -g vsce 29 | 30 | - name: Pretest 31 | run: | 32 | npm install -g eslint 33 | npm run pretest 34 | 35 | # - name: Map insights to cat 36 | # run: | 37 | # shopt -s expand_aliases 38 | # alias insights="cat" 39 | 40 | # - name: Test 41 | # run: | 42 | # npm install -g eslint 43 | # npm test 44 | 45 | - name: Package 46 | run: 47 | vsce package 48 | 49 | - name: Archive package 50 | uses: actions/upload-artifact@v2 51 | with: 52 | name: vsix 53 | path: vscode-cppinsights-*.vsix 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript output 48 | out/ 49 | 50 | # TypeScript cache 51 | *.tsbuildinfo 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Microbundle cache 60 | .rpt2_cache/ 61 | .rts2_cache_cjs/ 62 | .rts2_cache_es/ 63 | .rts2_cache_umd/ 64 | 65 | # Optional REPL history 66 | .node_repl_history 67 | 68 | # Output of 'npm pack' 69 | *.tgz 70 | 71 | # Yarn Integrity file 72 | .yarn-integrity 73 | 74 | # dotenv environment variables file 75 | .env 76 | .env.test 77 | 78 | # parcel-bundler cache (https://parceljs.org/) 79 | .cache 80 | 81 | # Next.js build output 82 | .next 83 | 84 | # Nuxt.js build / generate output 85 | .nuxt 86 | dist 87 | 88 | # Gatsby files 89 | .cache/ 90 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 91 | # https://nextjs.org/blog/next-9-1#public-directory-support 92 | # public 93 | 94 | # vuepress build output 95 | .vuepress/dist 96 | 97 | # Serverless directories 98 | .serverless/ 99 | 100 | # FuseBox cache 101 | .fusebox/ 102 | 103 | # DynamoDB Local files 104 | .dynamodb/ 105 | 106 | # TernJS port file 107 | .tern-port 108 | 109 | # Misc 110 | .vscode-test/ 111 | package-lock.json 112 | .eslintrc.json -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "args": [ 13 | "${workspaceFolder}/src/test/suite/test.cpp", 14 | "--extensionDevelopmentPath=${workspaceFolder}" 15 | ], 16 | "outFiles": [ 17 | "${workspaceFolder}/out/**/*.js" 18 | ], 19 | "preLaunchTask": "${defaultBuildTask}" 20 | }, 21 | { 22 | "name": "Extension Tests", 23 | "type": "extensionHost", 24 | "request": "launch", 25 | "args": [ 26 | "${workspaceFolder}/src/test/suite/test.cpp", 27 | "--extensionDevelopmentPath=${workspaceFolder}", 28 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 29 | ], 30 | "outFiles": [ 31 | "${workspaceFolder}/out/test/**/*.js" 32 | ], 33 | "preLaunchTask": "${defaultBuildTask}" 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off" 11 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | 5 | src/** 6 | .gitignore 7 | .yarnrc 8 | vsc-extension-quickstart.md 9 | **/tsconfig.json 10 | **/.eslintrc.json 11 | **/*.map 12 | **/*.ts 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the "vscode-cppinsights" extension will be documented in this file. 4 | 5 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 6 | 7 | ## [Pre-release] -------------------------------------------------------------------------------- /FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: devtbi 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C++ Insights for Visual Studio Code (VSCode) 2 | 3 | 4 | 5 | 12 | 13 | ## Features 14 | This extension allows you to view C++ Insights inside of vscode: 15 |

16 | Show C++ insights 17 |

18 | 19 | or diff the Insights with your original source: 20 |

21 | Diff source with C++ insights 22 |

23 | 24 | The extension can utilize a compilation database/compile commands for easy use in existing environments. You can specify a directory containing the compilation database, aka the build directory, with `vscode-cppinsights.buildDirectory`. 25 | If the active file is part of a workspace, and `vscode-cppinsights.buildDirectoryPrioritizeCMake` is set, the `cmake.buildDirectory` is used to determine the build directory. 26 | 27 | ## Requirements 28 | This extension requires @andreasfertig's C++ Insights. 29 | C++ Insights can be found here: 30 | https://github.com/andreasfertig/cppinsights. 31 | Build or download the latest release and specify the path to the cppinsights binary in `vscode-cppinsights.path`. 32 | 33 | ## Commands 34 | * `vscode-cppinsights.insights`: Show C++ insights 35 | * `vscode-cppinsights.insightsDiff`: Show C++ insights diff with original 36 | 37 | ## Extension Settings 38 | This extension contributes the following settings: 39 | (You can find descriptions in the settings UI) 40 | * `vscode-cppinsights.path` 41 | * `vscode-cppinsights.buildDirectory` 42 | * `vscode-cppinsights.buildDirectoryPrioritizeCMake` 43 | * `vscode-cppinsights.args` 44 | * `vscode-cppinsights.format` 45 | * `vscode-cppinsights.experimental` 46 | 47 | ## Contribute 48 | If you want to contribute, have an idea for a feature, or want to report an issue, please visit the [GitHub repository](https://github.com/devtbi/vscode-cppinsights). 49 | 50 | ## Known Issues 51 | ### Compiler Error on Windows 52 | * Using Microsoft/Visual Studio STL with C++ Insights might report "#error STL1000: Unexpected compiler version". You can define _ALLOW_COMPILER_AND_STL_VERSION_MISMATCH (before any includes) as a workaround ([C++ Insights Issue](https://github.com/andreasfertig/cppinsights/issues/422)). 53 | ### Formatting (`vscode-cppinsights.format`) 54 | * Enabling the option disables the "preview" property of the output editor 55 | * When using the `insightsDiff` command, the output is not formatted like the original source 56 | -------------------------------------------------------------------------------- /image/diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devtbi/vscode-cppinsights/a1a8c808b2e821eb0c00823e58769cd678baf9b6/image/diff.png -------------------------------------------------------------------------------- /image/logo_cppinsights.info: -------------------------------------------------------------------------------- 1 | Logo from https://github.com/andreasfertig/cppinsights/blob/main/artwork/logo_cppinsights.png -------------------------------------------------------------------------------- /image/logo_cppinsights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devtbi/vscode-cppinsights/a1a8c808b2e821eb0c00823e58769cd678baf9b6/image/logo_cppinsights.png -------------------------------------------------------------------------------- /image/show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devtbi/vscode-cppinsights/a1a8c808b2e821eb0c00823e58769cd678baf9b6/image/show.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-cppinsights", 3 | "displayName": "C++ Insights", 4 | "description": "vscode extension for C++ Insights", 5 | "version": "1.0.3", 6 | "author": { 7 | "name": "Tobias Fuchs", 8 | "url": "http://devtbi.io" 9 | }, 10 | "icon": "image/logo_cppinsights.png", 11 | "publisher": "devtbi", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/devtbi/vscode-cppinsights.git" 15 | }, 16 | "engines": { 17 | "vscode": "^1.54.0" 18 | }, 19 | "keywords": [ 20 | "C++", 21 | "Cpp", 22 | "Insight", 23 | "Insights" 24 | ], 25 | "categories": [ 26 | "Education", 27 | "Other" 28 | ], 29 | "activationEvents": [ 30 | "onCommand:vscode-cppinsights.insights", 31 | "onCommand:vscode-cppinsights.insightsDiff" 32 | ], 33 | "main": "./out/extension.js", 34 | "contributes": { 35 | "commands": [ 36 | { 37 | "command": "vscode-cppinsights.insights", 38 | "title": "Show C++ Insights" 39 | }, 40 | { 41 | "command": "vscode-cppinsights.insightsDiff", 42 | "title": "Show C++ Insights diff with original" 43 | } 44 | ], 45 | "configuration": [ 46 | { 47 | "title": "C++ Insights", 48 | "properties": { 49 | "vscode-cppinsights.buildDirectory": { 50 | "type": "string", 51 | "default": [], 52 | "description": "Build directory of the compilation database.", 53 | "scope": "resource" 54 | }, 55 | "vscode-cppinsights.buildDirectoryPrioritizeCMake": { 56 | "type": "boolean", 57 | "default": true, 58 | "description": "If a workspace is active for the source, prioritize the cmake.buildDirectory setting over vscode-cppinsights.buildDirectory.", 59 | "scope": "resource" 60 | }, 61 | "vscode-cppinsights.path": { 62 | "type": "string", 63 | "default": "insights", 64 | "description": "Path to the cppinsights executable (insights).", 65 | "scope": "resource" 66 | }, 67 | "vscode-cppinsights.format": { 68 | "type": "boolean", 69 | "default": true, 70 | "description": "Format the cppinsights output.", 71 | "scope": "resource" 72 | }, 73 | "vscode-cppinsights.args": { 74 | "type": "array", 75 | "default": [], 76 | "description": "Additional arguments (e.g. -std=c++17). The final call to insights will look like this: -p --extra-arg --extra-arg ... .", 77 | "scope": "resource" 78 | }, 79 | "vscode-cppinsights.experimental": { 80 | "type": "boolean", 81 | "description": "Enable experimental features, if available.", 82 | "scope": "application" 83 | } 84 | } 85 | } 86 | ] 87 | }, 88 | "scripts": { 89 | "vscode:prepublish": "npm run compile", 90 | "compile": "tsc -p ./", 91 | "watch": "tsc -watch -p ./", 92 | "pretest": "npm run compile && npm run lint", 93 | "lint": "eslint src --ext ts", 94 | "test": "node ./out/test/runTest.js" 95 | }, 96 | "devDependencies": { 97 | "@types/glob": "^7.1.3", 98 | "@types/mocha": "^8.2.2", 99 | "@types/node": "14.x", 100 | "@types/vscode": "^1.54.0", 101 | "@typescript-eslint/eslint-plugin": "^4.31.1", 102 | "@typescript-eslint/parser": "^4.31.1", 103 | "eslint": "^7.27.0", 104 | "glob": "^7.1.7", 105 | "mocha": "^8.4.0", 106 | "typescript": "^4.3.2", 107 | "vscode-test": "^1.5.2" 108 | }, 109 | "dependencies": { 110 | "@types/tmp": "^0.1.0", 111 | "tmp": "^0.1.0", 112 | "vsce": "^1.99.0" 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import * as fs from 'fs'; 3 | import * as tmp from 'tmp'; 4 | import path = require('path'); 5 | 6 | const taskSource = "C++ insights"; 7 | 8 | export function activate(context: vscode.ExtensionContext) { 9 | 10 | console.log('Activating "vscode-cppinsights"'); 11 | 12 | 13 | registerCommands(context); 14 | } 15 | 16 | /** 17 | * Register all commands 18 | */ 19 | function registerCommands(context: vscode.ExtensionContext) { 20 | vscode.commands.registerTextEditorCommand('vscode-cppinsights.insights', () => { 21 | executeInsights(); 22 | }); 23 | 24 | vscode.commands.registerTextEditorCommand('vscode-cppinsights.insightsDiff', () => { 25 | executeInsights(true); 26 | }); 27 | // TODO format, diff as parameter to command instead of extra commands, no-build-dir 28 | } 29 | 30 | /** 31 | * Create the skeleton insights command from the configuration 32 | */ 33 | export function createCall(config: vscode.WorkspaceConfiguration, cmake_build_dir: string | undefined, filePath: string, outputPath: string | undefined): { path: vscode.ShellQuotedString, args: (string | vscode.ShellQuotedString)[] } { 34 | const build_dir = cmake_build_dir || config.get('buildDirectory'); 35 | 36 | if (!config.get('path')) { 37 | vscode.window.showErrorMessage('Missing value for vscode-cppinsights.path'); 38 | throw vscode.CancellationError; 39 | } 40 | 41 | let args: (string | vscode.ShellQuotedString)[] = [{ value: filePath, quoting: vscode.ShellQuoting.Escape }]; 42 | if (build_dir && build_dir.length > 0) 43 | args.push({ 44 | value: "-p=" + build_dir, quoting: vscode.ShellQuoting.Escape 45 | }); 46 | 47 | if ((config.get('args')?.length ?? 0) > 0) { 48 | const extra_args = config.get('args')!.map(x => ["--extra-arg", x]); 49 | 50 | let extra_args_flat: string[] = []; 51 | extra_args_flat = extra_args_flat.concat(...extra_args); 52 | 53 | args = [...args, ...extra_args_flat]; 54 | } 55 | 56 | if (outputPath) { 57 | args.push(">"); 58 | args.push({ value: outputPath, quoting: vscode.ShellQuoting.Escape }); 59 | } 60 | 61 | return { 62 | path: { value: config.get('path')!, quoting: vscode.ShellQuoting.Escape }, args: args 63 | }; 64 | } 65 | 66 | export function callToString(insights_call: { path: vscode.ShellQuotedString, args: (string | vscode.ShellQuotedString)[] }): string { 67 | return insights_call.path + ' ' + insights_call.args.join(' '); 68 | } 69 | 70 | /** 71 | * Execute insights command 72 | */ 73 | function executeInsights(show_diff: boolean = false) { 74 | // TODO on save 75 | 76 | // TODO Impl as TextDocumentProvider 77 | // TODO QuickDiffProvider? 78 | // TODO inhibit insights command exec when no editor active via enablement 79 | 80 | 81 | const input_editor = vscode.window.activeTextEditor; 82 | 83 | if (input_editor) { 84 | const options = input_editor!.options; 85 | const input_document = input_editor!.document; 86 | 87 | if (input_editor.document.isUntitled || input_editor.document.isDirty) { 88 | tmp.file({ prefix: path.basename("untitled"), postfix: '.cpp', keep: false }, function (err: string, input_path: string) { 89 | fs.writeFileSync(input_path, input_editor.document.getText()); 90 | executeInsights2(show_diff, input_document, options, input_path); 91 | }); 92 | } 93 | else { 94 | executeInsights2(show_diff, input_document, options, input_document.fileName); 95 | } 96 | } 97 | } 98 | 99 | /** 100 | * Execute insights command 101 | */ 102 | function executeInsights2(show_diff: boolean = false, input_document: vscode.TextDocument, options: vscode.TextEditorOptions, input_path: string) { 103 | const configuration = vscode.workspace.getConfiguration('vscode-cppinsights'); 104 | 105 | // TODO are code variables resolved, e.g. workspaceFolder? 106 | 107 | // discardDescriptor is required, otherwise cmd is not executed b/c file is used by another process 108 | // TODO maybe delete tmp file 109 | tmp.file({ prefix: path.basename(input_path), postfix: '.cpp', keep: false, discardDescriptor: true }, function (err, output_path) { 110 | const insights_command = createCall(configuration, vscode.workspace.getWorkspaceFolder(input_document.uri) && configuration.get("buildDirectoryPrioritizeCMake") ? vscode.workspace.getConfiguration('cmake').get('buildDirectory') : undefined, input_path, output_path); 111 | 112 | console.log("Executing " + JSON.stringify(insights_command)); 113 | 114 | const sh = new vscode.ShellExecution(insights_command.path, insights_command.args); 115 | //const sh = new vscode.ProcessExecution(insights_command.path, insights_command.args) 116 | 117 | const tsk = new vscode.Task({} as vscode.TaskDefinition, vscode.TaskScope.Global, "insights task", taskSource, sh, undefined /*matcher*/); 118 | tsk.runOptions = { reevaluateOnRerun: true } as vscode.RunOptions; 119 | tsk.presentationOptions = { reveal: vscode.TaskRevealKind.Silent } as vscode.TaskPresentationOptions; 120 | 121 | vscode.tasks.executeTask(tsk).then(() => { 122 | console.log("Task executeTask"); 123 | }, (rejection_reason) => { 124 | console.error(rejection_reason); 125 | }); 126 | 127 | const disposable = vscode.tasks.onDidEndTaskProcess((event) => { 128 | if (event.execution.task.source === taskSource) { 129 | console.log("Task onDidEndTaskProcess") 130 | try { 131 | if (event.exitCode != 0) { 132 | vscode.window.showErrorMessage("Insights task failed \nCheck task pane for more info."); 133 | console.error("Task failed"); 134 | return; 135 | } else { 136 | openInsightsOutput(input_document, output_path, configuration, options, show_diff); 137 | } 138 | } finally { 139 | disposable.dispose(); 140 | } 141 | } 142 | }); 143 | }); 144 | // child.exec(exec_command, (error: child.ExecException | null, stdout: string, stderr: string) => { 145 | // if (error) { 146 | // vscode.window.showErrorMessage('insights failed:\n' + exec_command + '\n' + stderr + '\n' + stdout); 147 | // console.error(error); 148 | // console.error(stderr); 149 | // return; 150 | // } 151 | 152 | // // store output in temporary as workaround for annoying save dialog on close 153 | // tmp.file({ prefix: path.basename(input_path), postfix: '.cpp', keep: false }, function (err: string, output_path: string) { 154 | // if (err) { 155 | // vscode.window.showErrorMessage('Failed to create temporary file (' + err + ')'); 156 | // return; 157 | // } 158 | // fs.writeFileSync(output_path, stdout); 159 | // openInsightsOutput(input_document, output_path, configuration, options, show_diff); 160 | // }); 161 | // }); 162 | } 163 | 164 | /** 165 | * Open the output. Either show it in an editor besides the source, or open a diff. 166 | */ 167 | function openInsightsOutput(input_document: vscode.TextDocument, output_path: string, configuration: vscode.WorkspaceConfiguration, options: vscode.TextEditorOptions, show_diff: boolean) { 168 | const output_uri = vscode.Uri.file(output_path); 169 | 170 | // TODO clarify if formatting requires open TextEditor->visually bad, but seems more reliable 171 | const formatting = (doc: vscode.TextDocument) => { (configuration.get("format") ?? true) ? format(doc, options, (configuration.get("experimental") ?? false)) : () => { return; } }; 172 | 173 | 174 | // was { language: vscode.window.activeTextEditor?.document.languageId, content: stdout } 175 | console.log("Openning insights output"); 176 | vscode.workspace.openTextDocument(output_uri).then((output_document) => { 177 | if (!show_diff) { 178 | show(output_document, formatting, options); 179 | } 180 | else { 181 | diff(input_document, output_document, formatting); 182 | } 183 | 184 | }); 185 | } 186 | 187 | /** 188 | * Format the output. 189 | */ 190 | function format(doc: vscode.TextDocument, options: vscode.TextEditorOptions, experimental: boolean) { 191 | const format_options = { tabSize: options.tabSize != undefined ? options.tabSize : 4, insertSpaces: options.insertSpaces || false } as vscode.FormattingOptions; 192 | console.log("Formatting " + doc.uri + ' ' + JSON.stringify(format_options)); 193 | 194 | // TODO format options are ignored, only TextEditor options are applied, investigate 195 | vscode.commands.executeCommand('vscode.executeFormatDocumentProvider', doc.uri, format_options).then((textEdits) => { 196 | console.log("Format command"); 197 | const edits = textEdits as vscode.TextEdit[] || undefined; 198 | const jobs: Thenable[] = []; 199 | if (edits) { 200 | console.log("Applying format"); 201 | const edit = new vscode.WorkspaceEdit(); 202 | for (const textEdit of edits) { 203 | edit.replace(doc.uri, textEdit.range, textEdit.newText); 204 | } 205 | jobs.push(vscode.workspace.applyEdit(edit)); 206 | Promise.all(jobs).then(() => { 207 | console.log("Saving format"); 208 | doc.save(); 209 | }); 210 | } 211 | else { 212 | console.log("No format edits"); 213 | } 214 | }, (rejection_reason) => { 215 | console.log("Format command failed"); 216 | console.log(rejection_reason); 217 | }); 218 | } 219 | 220 | /** 221 | * Show the output. 222 | */ 223 | function show(doc: vscode.TextDocument, format: (doc: vscode.TextDocument) => void, options: vscode.TextEditorOptions) { 224 | console.log("Showing " + doc.uri); 225 | 226 | // TODO preview gets lost when formatting 227 | vscode.window.showTextDocument(doc, { viewColumn: vscode.ViewColumn.Beside, preserveFocus: true, preview: true }).then((editor) => { 228 | editor.options = options; 229 | format(doc); 230 | }); 231 | } 232 | 233 | /** 234 | * Diff the source and output. 235 | */ 236 | function diff(left: vscode.TextDocument, right: vscode.TextDocument, format: (doc: vscode.TextDocument) => void) { 237 | console.log("Diffing " + left.uri + ' - ' + right.uri); 238 | 239 | vscode.commands.executeCommand('vscode.diff', left.uri, right.uri).then(() => { 240 | format(right); 241 | console.log("Diff command"); 242 | }, (rejection_reason) => { 243 | console.log(rejection_reason); 244 | }); 245 | } 246 | 247 | export function deactivate() { 248 | console.log("Goodbye 👋"); 249 | } 250 | -------------------------------------------------------------------------------- /src/test/runTest.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | 3 | import { runTests } from 'vscode-test'; 4 | 5 | async function main() { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 10 | 11 | // The path to test runner 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 14 | 15 | // Download VS Code, unzip it and run the integration test 16 | await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: ["${workspaceFolder}/src/test/suite/test.cpp"] }); 17 | } catch (err) { 18 | console.error('Failed to run tests'); 19 | process.exit(1); 20 | } 21 | } 22 | 23 | main(); 24 | -------------------------------------------------------------------------------- /src/test/suite/escape test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | template 6 | class Call final 7 | { 8 | public: 9 | F const f_; 10 | Call(F const f) : f_{f} {} 11 | }; 12 | 13 | int main() 14 | { 15 | std::atomic x{int{2}}; 16 | auto f{ 17 | [&x]() 18 | { 19 | x = 2; 20 | return; 21 | }}; 22 | 23 | Call k{std::move(f)}; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/test/suite/escape. %folder'test/escape. %test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | template 6 | class Call final 7 | { 8 | public: 9 | F const f_; 10 | Call(F const f) : f_{f} {} 11 | }; 12 | 13 | int main() 14 | { 15 | std::atomic x{int{2}}; 16 | auto f{ 17 | [&x]() 18 | { 19 | x = 2; 20 | return; 21 | }}; 22 | 23 | Call k{std::move(f)}; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/test/suite/extension.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import * as child from 'child_process'; 3 | import * as tmp from 'tmp'; 4 | import * as path from 'path'; 5 | 6 | // You can import and use all API from the 'vscode' module 7 | // as well as import your extension to test it 8 | import * as vscode from 'vscode'; 9 | import * as ins from '../../extension'; 10 | import { EIDRM } from 'constants'; 11 | 12 | export function getCppFile(): vscode.Uri { 13 | const configuration = vscode.workspace.getConfiguration('vscode-cppinsights'); 14 | const doc = vscode.workspace.textDocuments.find((doc) => { 15 | return doc.fileName.endsWith("cpp"); 16 | }); 17 | return doc!.uri; 18 | } 19 | 20 | suite('Extension Test Suite', () => { 21 | vscode.window.showInformationMessage('Start all tests.'); 22 | 23 | test('Execute command', () => { 24 | return vscode.commands.executeCommand('vscode-cppinsights.insights').then(() => { 25 | console.log("Command success"); 26 | }, (rejection_reason) => { 27 | assert.fail("Unable to run command"); 28 | }); 29 | }); 30 | 31 | test('Run executable', () => { 32 | const configuration = vscode.workspace.getConfiguration('vscode-cppinsights'); 33 | const uri = getCppFile(); 34 | 35 | const insights_command = ins.createCall(configuration, undefined, uri.path, undefined); 36 | 37 | const exec_command = ins.callToString(insights_command); 38 | return child.exec(exec_command, (error: child.ExecException | null, stdout: string, stderr: string) => { 39 | if (error) { 40 | assert.fail("Unable to run insights"); 41 | } 42 | }); 43 | }); 44 | 45 | test('Run executable tmp path', () => { 46 | const configuration = vscode.workspace.getConfiguration('vscode-cppinsights'); 47 | const uri = getCppFile(); 48 | 49 | tmp.file({ prefix: path.basename("test"), postfix: '.cpp', keep: false, discardDescriptor: true }, function (err, output_path) { 50 | const insights_command = ins.createCall(configuration, undefined, uri.path, output_path); 51 | 52 | const exec_command = ins.callToString(insights_command); 53 | return child.exec(exec_command, (error: child.ExecException | null, stdout: string, stderr: string) => { 54 | if (error) { 55 | assert.fail("Unable to run insights"); 56 | } 57 | }); 58 | }); 59 | }); 60 | 61 | }); 62 | -------------------------------------------------------------------------------- /src/test/suite/index.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as Mocha from 'mocha'; 3 | import * as glob from 'glob'; 4 | 5 | export function run(): Promise { 6 | // Create the mocha test 7 | const mocha = new Mocha({ 8 | ui: 'tdd', 9 | color: true 10 | }); 11 | 12 | const testsRoot = path.resolve(__dirname, '..'); 13 | 14 | return new Promise((c, e) => { 15 | glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { 16 | if (err) { 17 | return e(err); 18 | } 19 | 20 | // Add files to the test suite 21 | files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); 22 | 23 | try { 24 | // Run the mocha test 25 | mocha.run(failures => { 26 | if (failures > 0) { 27 | e(new Error(`${failures} tests failed.`)); 28 | } else { 29 | c(); 30 | } 31 | }); 32 | } catch (err) { 33 | console.error(err); 34 | e(err); 35 | } 36 | }); 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /src/test/suite/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::cout << "showcase of cpp-insights vscode extension"; 7 | 8 | std::array arr = {2, 4, 6, 8, '\0', '\0', '\0', '\0', '\0', '\0'}; 9 | 10 | for(const char& c : arr) { 11 | printf("c=%c\n", c); 12 | } 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src", 11 | "strict": true /* enable all strict type-checking options */ 12 | /* Additional Checks */ 13 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 14 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 15 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 16 | }, 17 | "exclude": [ 18 | "node_modules", 19 | ".vscode-test" 20 | ] 21 | } 22 | --------------------------------------------------------------------------------