Compare commits

...
Author SHA1 Message Date
Bob Brown 9604256fb8 Merge pull request #2168 from Microsoft/master
Fix ${config:a.b} https://github.com/Microsoft/vscode-cpptools/issues…
2018-06-21 18:42:58 -07:00
Bob Brown d3f701823d Merge branch 'release' into master 2018-06-21 18:42:44 -07:00
Sean McManus 987347c4b6 Update CHANGELOG.md (#2161)
* Update CHANGELOG.md
2018-06-21 18:04:33 -07:00
Sean McManus 7e7a522603 Fix ${config:a.b} https://github.com/Microsoft/vscode-cpptools/issues… (#2166)
* Fix ${config:a.b} https://github.com/Microsoft/vscode-cpptools/issues/2165 .
2018-06-21 18:04:05 -07:00
Bob Brown 14bc488e5b Merge pull request #2154 from Microsoft/master
merge 0.17.5 release notes
2018-06-19 14:57:20 -07:00
Bob Brown 352745754b update (#2153) 2018-06-19 14:52:37 -07:00
Bob Brown dde3b515db update version numbers (#2152)
* Update package.json

* Update package-lock.json
2018-06-19 12:12:30 -07:00
Bob Brown cc6d7f3cac Merge pull request #2150 from Microsoft/master
0.17.5 merge from master
2018-06-19 12:10:38 -07:00
Bob Brown f8dbe57da7 Merge branch 'release' into master 2018-06-19 11:51:57 -07:00
Sean McManus 4fe877ed26 Update changelog, fwlinks, and fix an issue with abTesting. (#2143)
* Update changelog, fwlinks, and fix an issue with abTesting.
* Adding debugger changes to changelog
2018-06-19 11:41:22 -07:00
Griffin Downs 974ecd3ecb Grdowns/detect compile commands (#2137) 2018-06-19 10:36:01 -07:00
Bob Brown 7be69a0880 Bobbrow/recursive includes (#2136)
* Make recursive includePath the default again. Refactor A/B testing stuff.

* fix initialization dependency bug

* bugfix
2018-06-15 16:39:01 -07:00
Bob Brown d77470f753 make browse.path optional (#2135) 2018-06-15 16:34:57 -07:00
James Hamm 846cdc3a32 Updated the link for creating issues. (#2126)
The current link returns a 301 (permanent redirect) so we may as well just point straight to the site.
2018-06-13 07:41:45 -07:00
Andrew Wang 17c307a369 Adding miDebuggerArgs (#1974)
Fixing GenerateOptionsSchema too, due to linting fixes
2018-06-07 18:26:47 -07:00
Andrew Wang 485d762d70 Updating debugging MI Engine docs (#2103)
* Updating debugging MI Engine docs

* Forgot extensions
2018-06-07 18:18:31 -07:00
Sean McManus 73c025dcee Update dependencies due to vulnerabilities from npm audit. (#2095)
* Update dependencies due to vulnerabilities from npm audit.
2018-06-07 14:24:12 -07:00
Bob Brown 90b1ebd74c update version (#2097)
* Update package.json
* Update package-lock.json
2018-06-07 09:16:50 -07:00
Griffin Downs 3027e18968 Grdowns/inactive region opacity (#2061) 2018-06-06 12:14:19 -07:00
Pierson Lee 7729d0a700 Update issue templates (#2087)
* Update issue templates

* Remove old issues_template.md
2018-06-04 16:54:33 -07:00
Sean McManus c0e32437df Update version. (#2071) 2018-05-31 16:11:05 -07:00
Sean McManus b580b7347f Merge pull request #2069 from Microsoft/master
0.17.4 release
2018-05-31 16:07:20 -07:00
Bob Brown 4b5b086150 Merge branch 'release' into master 2018-05-31 16:01:48 -07:00
Sean McManus c5105f0731 Update for 0.17.4. (#2067) 2018-05-31 15:53:11 -07:00
b5e00c068e disable recursive includePath for ${workspaceFolder} in default c_cpp_properties.json (#2059) 2018-05-31 12:44:44 -07:00
Bob Brown 9b33938293 Fix startup bug (#2065) 2018-05-31 12:16:36 -07:00
Bob Brown a096ec9c6f Update Customizing Default Settings.md
typo
2018-05-25 10:00:42 -07:00
Bob Brown 847a2e3d5a reduce promise reject messages in the standard case (#2041) 2018-05-24 16:32:46 -07:00
Bob Brown 7b91a97ba7 Update extension version (#2035)
* Update package.json

* Update package-lock.json
2018-05-24 12:21:48 -07:00
henrywiechert 306a55da2e Update IntelliSense engine.md (#2040)
fix a link
2018-05-24 12:20:58 -07:00
Sean McManus 7553bb9358 Update ISSUE_TEMPLATE.md (#2030) 2018-05-22 13:34:39 -07:00
Sean McManus d786b0f602 Merge pull request #2029 from Microsoft/seanmcm/0_17_3_release
Seanmcm/0 17 3 release
2018-05-22 13:17:55 -07:00
Bob Brown a60c1c51f5 doc updates (#2028) 2018-05-22 12:58:29 -07:00
Bob Brown 891d590562 add support for ${workspaceFolder:<folder_name>} (#2027) 2018-05-22 12:58:09 -07:00
Sean McManus df7b77b6cf Update for 0.17.3. 2018-05-22 12:54:40 -07:00
Bob Brown 94a2b67e14 add support for ${workspaceFolder:<folder_name>} 2018-05-22 12:49:13 -07:00
Sean McManus 5883747474 Update package-lock.json. (#2024) 2018-05-21 16:49:05 -07:00
Sean McManus 3f62ffd135 Merge pull request #2023 from Microsoft/seanmcm/0_17_2_release
Seanmcm/0 17 2 release
2018-05-21 16:00:03 -07:00
Sean McManus 7de9d166b8 Update version. 2018-05-21 15:19:50 -07:00
Sean McManus 2edf7267e8 Update for 0.17.2. (#2022) 2018-05-21 15:18:37 -07:00
Sean McManus 3f5b0b7220 Update for 0.17.2. (#2022) 2018-05-21 15:14:40 -07:00
Bob Brown baebe0acec Merge pull request #2011 from Microsoft/bobbrow/regression
fix regression from extension API change
2018-05-18 14:20:32 -07:00
Bob Brown 6d1264e6b1 fix regression from extension API change 2018-05-18 14:11:17 -07:00
Bob Brown 7cd7d3422c Update package.json 2018-05-18 13:31:37 -07:00
Bob Brown a4edf98976 Update package.json 2018-05-18 13:31:25 -07:00
Bob Brown bffafc058a Merge branch 'insiders' into master 2018-05-18 13:30:35 -07:00
Sherry Shi 01efb1a584 Allow other VS Code extensions to provide custom intellisense configurations. (#1804) 2018-05-18 11:03:08 -07:00
Sean McManus b1e40a4ccc Merge pull request #2005 from Microsoft/seanmcm/0_17_1_release
Seanmcm/0 17 1 release
2018-05-17 12:10:07 -07:00
Sean McManus 7d4aed2009 Update version. 2018-05-17 11:34:10 -07:00
Sean McManus 20d782349d Merge branch 'master' into release 2018-05-17 11:30:23 -07:00
Sean McManus a3a0572325 Merge branch 'release' 2018-05-17 11:28:44 -07:00
Sean McManus c9473b21d4 Update changelog. (#2003) 2018-05-16 19:57:30 -07:00
Sean McManus 74b5867660 Seanmcm/0 17 1 changelog (#1996)
* Updates for 0.17.1.
* Add C++17 fixes for msvc-x64.
2018-05-15 15:48:06 -07:00
Bob Brown d1e90b507f Remove outdated logic from getConfigIndexForPlatform (#1992) 2018-05-14 23:02:35 -07:00
Bob Brown 7f10e90a6f update https-proxy-agent version (#1984) 2018-05-11 16:38:30 -07:00
Bob Brown fbfb83ac30 Update Enabling logging.md 2018-05-11 14:08:45 -07:00
Bob Brown 8f8ed52aae Fix the file watcher (#1983) 2018-05-11 12:33:42 -07:00
Bob Brown a190707f67 update telemetry for settings changes (#1973)
update telemetry for settings changes
2018-05-09 15:11:29 -07:00
Bob Brown 79871a6587 update c_cpp_properties.json reference 2018-05-08 16:10:30 -07:00
Bob Brown ba65c4877c documentation updates for 0.17.0 (#1952)
* documentation updates for 0.17.0

* updates to logging docs

* PR feedback
2018-05-08 15:01:15 -07:00
Bob Brown 8c6a167787 update package.json for release (#1951)
* update package.json for release

* Update package-lock.json
2018-05-07 13:49:53 -07:00
Bob Brown 0ac4744c11 Merge pull request #1950 from Microsoft/master
Merge master -> release
2018-05-07 13:47:11 -07:00
Bob Brown 7ea61221bc update release notes and don't enable recursive includes by default in new folders (#1948)
* update release notes and don't enable recursive includes by default in new folders.

* changelog bug
2018-05-07 13:44:53 -07:00
Andrew Wang ff31eef0a2 Extension Development Improvements (#1941)
1. Updated tasks.json to 2.0
2. Added tslint problem matcher
   - Weird issue that problem does not disappear when resolved.
3. Adding tslint for class and function names.
   - class must be in PascalCase
   - funcitons must be in camelCase
4. Addressing vulnerability warning
   - https://github.com/Microsoft/vscode/issues/49146
2018-05-07 11:22:12 -07:00
jogo- 842856f08a Fix typo in README.md (#1944) 2018-05-07 10:41:38 -07:00
jogo- 2ded5b241e Fix typo in c_cpp_properties.schema.json (#1945) 2018-05-07 10:40:56 -07:00
Bob Brown 58cfb5ee10 add support for custom variables (#1921)
* add support for custom variables

* support for string[] variables

* rename "variables" to "env"
2018-05-04 20:18:42 -07:00
Andrew Wang 8deee74b68 Adding OptionsSchema generation (#1937)
* Adding OptionsSchema generation

This is to prevent repetitive fields from being copy and pasted
improperly.

* Move tslint to be after compile

* Address PR issues
2018-05-04 16:19:53 -07:00
Sean McManus d6aa178cac Fix issues introduced with VS Code 1.23.0. (#1925) 2018-05-03 16:57:38 -07:00
Bob Brown 264ed5eb23 trim the path before checking if it exists (#1924) 2018-05-03 16:21:52 -07:00
Griffin Downs ded26d66b0 Move settings update into updateToVersion4 function (#1916) 2018-05-03 12:47:45 -07:00
Sean McManus 88a0494ce5 Merge pull request #1766 from Microsoft/master
Merge for 0.16.1 release
2018-03-30 17:08:02 -07:00
Bob Brown 3bbfed643f Merge pull request #1746 from Microsoft/master
Merge to release 0.16.0
2018-03-27 20:36:40 -07:00
Bob Brown d079892710 Merge pull request #1726 from Microsoft/master
Merge to release for 0.16.0
2018-03-22 12:23:03 -07:00
Sean McManus e5976d2656 Merge pull request #1557 from Microsoft/master
Merge for release.
2018-02-14 16:55:56 -08:00
Pierson Lee (PIE) cdab065ded Merge remote-tracking branch 'origin/master' into release 2018-01-17 13:09:00 -08:00
Sean McManus 3f62c3d244 Merge pull request #1458 from Microsoft/master
0.14.6 release
2018-01-16 15:51:11 -08:00
50 changed files with 3645 additions and 2360 deletions
+30
View File
@@ -0,0 +1,30 @@
---
name: Debugger
about: Issues pertaining to debugging such as call stack, breakpoints, watch window,
launching or attaching to a debuggee.
---
Type: Debugger
**Input information below**
**Please review existing issues and our documentation at https://github.com/Microsoft/vscode-cpptools/tree/master/Documentation prior to filing an issue.**
**Describe the bug**
- OS and Version:
- VS Code Version:
- C/C++ Extension Version:
- Other extensions you installed (and if the issue persists after disabling them):
- A clear and concise description of what the bug is.
**To Reproduce**
*Please include a code sample and `launch.json` configuration.*
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Additional context**
*If applicable, please include logging by adding "logging": { "engineLogging": true, "trace": true, "traceResponse": true } in your `launch.json`*
Add any other context about the problem here including log or error messages in your Debug Console or Output windows.
@@ -0,0 +1,34 @@
---
name: General Extension
about: Issues pertaining to downloading, installing, or building the extension.
---
Type: General
**Input information below**
**Please review existing issues and our documentation at https://github.com/Microsoft/vscode-cpptools/tree/master/Documentation prior to filing an issue.**
**Describe the bug**
- OS and Version:
- VS Code Version:
- C/C++ Extension Version:
- Other extensions you installed (and if the issue persists after disabling them):
- A clear and concise description of what the bug is.
**To Reproduce**
*Please include code sample and `task.json` files.*
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here including log messages from the Output window.
@@ -0,0 +1,35 @@
---
name: Language Service
about: 'Issues pertaining to IntelliSense, autocomplete, code editing, etc. '
---
Type: LanguageService
**----- Input information below -----**
**Please review existing issues and our documentation at https://github.com/Microsoft/vscode-cpptools/tree/master/Documentation prior to filing an issue.**
**Describe the bug**
- OS and Version:
- VS Code Version:
- C/C++ Extension Version:
- Other extensions you installed (and if the issue persists after disabling them):
- A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
*Provide a code sample including configuration files such as c_cpp_properties.json*
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
*Call Stacks: For bugs like crashes, deadlocks, infinite loops, etc. that we are not able to repro and for which the call stack may be useful, please attach a debugger and/or create a dmp and provide the call stacks. Starting with 0.17.3, Windows binaries have symbols available in VS Code by setting your "symbolSearchPath" to "http://msdl.microsoft.com/download/symbols".*
Add any other context about the problem here including log messages in your Output window ("C_Cpp.loggingLevel": "Debug" in settings.json).
+1 -1
View File
@@ -31,8 +31,8 @@ script:
# Build and then run tests
- cd Extension
- npm install
- npm run tslint
- npm run compile
- npm run tslint
# pr-check needs to run before test. test modifies package.json.
- npm run pr-check
- npm run test
@@ -1,6 +1,4 @@
# How To Debug MIEngine (Work in Progress)
*This is a work in progress. Please create a pull request with updates if there is anything wrong with it.*
# How To Debug MIEngine
MIEngine is one of the components used to enable the C/C++ debugging scenario with the Microsoft C/C++ extension with VS Code. This document is to help enable users who want to debug and contribute to MIEngine to fix issues or extend functionality. MIEngine is used to communicate with `gdb`/`lldb` using the MI protocol.
@@ -15,28 +13,38 @@ You can open the solution file **MIDebugEngine.sln** located under **src** and c
* Microsoft.MICore.dll
* Microsoft.MICore.XmlSerializers.dll
* Microsoft.MIDebugEngine.dll
* vscode\OpenDebugAD7.exe
* vscode\Microsoft.DebugEngineHost.dll
The symbol files are as follows:
**On Windows**
* Microsoft.MICore.pdb
* Microsoft.MIDebugEngine.dll
* vscode\OpenDebugAD7.pdb
* vscode\Microsoft.DebugEngineHost.pdb
**On Linux/Mac**
* Microsoft.MICore.dll.mdb
* Microsoft.MIDebugEngine.dll.mdb
* vscode\OpenDebugAD7.exe.mdb
* vscode\Microsoft.DebugEngineHost.dll.mdb
### Debugging On Windows
On Windows, the easiest way to debug is to use Visual Studio. Locate the **package.json** file in the **Extension** folder and open it in an editor.
On Windows, the easiest way to debug is to use Visual Studio. Locate the **src\Debugger\extension.ts** file in the **Extension** folder and open it in an editor.
Locate the following line:
If you are not building the extension, Locate the **out\src\Debugger\extension.ts** file in the **.vscode\extensions\ms-vscode.cpptools** folder and open it in an editor.
Locate the following lines:
```json
"program": "./debugAdapters/OpenDebugAD7",
return {
command: command
};
```
and add the following line below it:
and add the following line to the object:
```json
"args": ["--pauseForDebugger"],
args: ["--pauseForDebugger"]
```
This will cause the debugger to look like it has hung once you start debugging, but in reality it is waiting for a debugger to attach. Set your breakpoints and attach your debugger to the `OpenDebugAD7.exe` process. Once the debugger is attached, VS Code should start debugging and you can reproduce your scenario.
@@ -0,0 +1,16 @@
#### Old information (it still works, but is no longer recommended):
Logging is controlled by environment variables and is disabled by default. To enable logging, launch VS Code from an environment that contains the following variables:
```
VSCODE_CPP_LOGDIR=c:\path\to\logfolder
VSCODE_CPP_LOGFILE_LEVEL=5
```
When you open your folder in VS Code, we will create a **vscode.cpp.log.\<pid\>.txt** file for each extension process launched (\<pid\> = process id).
The log file level is a number that determines how much detail we'll log. Level 5 is generally detailed enough to give us information about what is going on in your session. We don't recommend you set this higher than 7 since the log quickly becomes cluttered with information that doesn't really help us diagnose your issues and actually makes it harder for us to spot problems. It may also slow down the extension considerably and make it harder for you to reproduce your problem.
**Note:** You will likely need to reload the window or close VS Code to flush the contents of the log file since we do not flush the log after every call. If your log file seems to be empty, try reloading the window after you have followed the steps to reproduce your issue.
**Don't forget to remove the environment variables when you are finished providing us with the logs.** You wouldn't want the extension to needlessly spend CPU time and disk space writing data you don't need into log files.
@@ -0,0 +1,76 @@
## Extension version 0.16.1 and earlier:
For developers using MinGW on Windows, we recommend you start with the following **c_cpp_properties.json** template. Select "C/Cpp: Edit Configurations" from the command palette to create this file if you haven't already.
In earlier versions of the extension, the `includePath` and a some system defines need to be set in order for IntelliSense to work properly. Note that you may have to change the MinGW version number to match what you have installed. Eg. `C:/MinGW/lib/gcc/mingw32/5.3.0/` instead of `C:/MinGW/lib/gcc/mingw32/6.3.0/`.
```json
{
"configurations": [
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/mingw32",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/backward",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed"
],
"defines": [
"_DEBUG",
"__GNUC__=6",
"__cdecl=__attribute__((__cdecl__))"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
The `includePath` above includes the system header paths that gcc uses in version 6.3.0 for C++ projects and matches the output of `"gcc -v -E -x c++ nul"`. The `intelliSenseMode` should be set to **"clang-x64"** to get MinGW projects to work properly with IntelliSense. The `__GNUC__=#` define should match the major version of the toolchain in your installation (6 in this example).
For C projects, simply remove the C++ lines:
```json
{
"configurations": [
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed"
],
"defines": [
"_DEBUG",
"__GNUC__=6",
"__cdecl=__attribute__((__cdecl__))"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
@@ -0,0 +1,139 @@
# Windows Subsystem for Linux
To use the Windows Subsystem for Linux with this extension you need to add a configuration to your **c_cpp_properties.json** file which adds the necessary header paths from within the WSL filesystem to the `includePath`.
Select "C/Cpp: Edit Configurations" from the command palette to create the **c_cpp_properties.json** file if you haven't already.
## Release
For developers using Ubuntu with the current version of WSL released with the Fall Creators Update, you can add the following configuration template to your **c_cpp_properties.json** file.
```json
{
"name": "WSL",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5/backward",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
Note that `${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/` is the path to the root of the Ubuntu filesystem. This will be different if you are using a different distro. You can discover the paths to your distro's filesystem by using this handy PowerShell command:
```Powershell
PS R:\> ($(get-appxpackage).PackageFamilyName | findstr /i 'SUSE Ubuntu') -replace '^', "$`{localappdata`}/Packages/"
${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc
${localappdata}/Packages/46932SUSE.openSUSELeap42.2_022rs5jcyhyac
${localappdata}/Packages/46932SUSE.SUSELinuxEnterpriseServer12SP2_022rs5jcyhyac
```
For C projects, simply remove the C++ lines:
```json
{
"name": "WSL",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
### Beta
For developers using Bash on Ubuntu on Windows with the beta version of WSL from before the Fall Creators Update, you can add the following configuration template to your **c_cpp_properties.json** file.
```json
{
"name": "WSL (Beta)",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/include/c++/5/backward",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
Note that `${localappdata}/lxss/rootfs/` is the path to the root of the filesystem for Bash on Ubuntu on Windows.
For C projects, simply remove the C++ lines as in the previous example.
---
With these configurations, you should be all set up to use the new IntelliSense engine for linting, memberlist autocomplete, and quick info (tooltips). Add `"C_Cpp.intelliSenseEngine": "Default"` to your **settings.json** file to try out the new IntelliSense engine.
And remember to [heed the warnings of the Windows team about not creating or editing Linux files from a Windows app](https://blogs.msdn.microsoft.com/commandline/2016/11/17/do-not-change-linux-files-using-windows-apps-and-tools/)!
@@ -0,0 +1,99 @@
# Customizing Default Settings
In version 0.17.0 we introduced new settings that allow you to override the extension's default values for properties set in **c_cpp_properties.json**.
## New VS Code settings
The following `C_Cpp.default.*` settings map to each of the properties in a configuration block of **c_cpp_properties.json**. Namely:
```
C_Cpp.default.includePath : string[]
C_Cpp.default.defines : string[]
C_Cpp.default.compileCommands : string
C_Cpp.default.macFrameworkPath : string[]
C_Cpp.default.forcedIncludes : string[]
C_Cpp.default.intelliSenseMode : string
C_Cpp.default.compilerPath : string
C_Cpp.default.cStandard : c89 | c99 | c11
C_Cpp.default.cppStandard : c++98 | c++03 | c++11 | c++14 | c++17
C_Cpp.default.browse.path : string[]
C_Cpp.default.browse.databaseFilename : string
C_Cpp.default.browse.limitSymbolsToIncludedHeaders : boolean
```
These settings have all of the benefits of VS Code settings, meaning that they can have default, "User", "Workspace", and "Folder" values. So you can set a global value for `C_Cpp.default.cppStandard` in your "User" settings and have it apply to all of the folders you open. If any one folder needs a different value, you can override the value by adding a "Folder" or "Workspace" value.
This property of VS Code settings allows you to configure each of your workspaces independently - making the **c_cpp_properties.json** file optional.
## Updated **c_cpp_properties.json** syntax
A special variable has been added to the accepted syntax of **c_cpp_properties.json** that will instruct the extension to insert the value from the VS Code settings mentioned above. If you set the value of any setting in **c_cpp_properties.json** to "${default}" it will instruct the extension to read the VS Code default setting for that property and insert it. For example:
```
"configurations": [
{
"name": "Win32",
"includePath": [
"additional/paths",
"${default}"
],
"defines": [
"${default}",
],
"macFrameworkPath": [
"${default}",
"additional/paths"
],
"forceInclude": [
"${default}",
"additional/paths"
],
"compileCommands": "${default}",
"browse": {
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": "${default}",
"path": [
"${default}",
"additional/paths"
]
},
"intelliSenseMode": "${default}",
"cStandard": "${default}",
"cppStandard": "${default}",
"compilerPath": "${default}"
}
],
```
Take note that for the properties that accept string[], the syntax proposed above allows you to augment the VS Code setting with additional values, thus allowing you to have common paths listed in the VS Code settings and configuration-specific settings in **c_cpp_properties.json**.
If a property is missing from **c_cpp_properties.json**, the extension will use the value in the VS Code setting. If a developer assigns values to all of the settings that apply for a given folder, then **c_cpp_properties.json** could be removed from the .vscode folder as it will no longer be needed.
### System includes
A new setting will be added that allows you specify the system include path separate from the folder's include path. If this setting has a value, then the system include path the extension gets from the compiler specified in the `compilerPath` setting will not be added to the path array that the extension uses for IntelliSense. We may want to provide a VS Code command to populate this value from the compiler's default for users who are interested in using it in case they want to make some modifications to the defaults.
```
C_Cpp.default.systemIncludePath : string[]
```
### System Include Path/Defines Resolution Strategies
The extension determines the system includePath and defines to send to the IntelliSense engine in the following manner:
1. If `compileCommands` has a valid value and the file open in the editor is in the database, use the compile command in the database entry to determine the include path and defines.
* The system include path and defines are determined using the following logic (in order):
1. If `systemIncludePath` has a value, use it (continue to the next step to search for system defines).
2. If `compilerPath` is valid, query it.
3. Interpret the first argument in the command as the compiler and attempt to query it.
4. If `compilerPath` is `""`, use an empty array for system include path and defines.
5. If `compilerPath` is undefined, look for a compiler on the system and query it.
2. If `compileCommands` is invalid or the current file is not listed in the database, use the `includePath` and `defines` properties in the configuration for IntelliSense.
* The system include path and defines are determined using the following logic (in order):
1. If `systemIncludePath` has a value, use it (continue to the next step to search for system defines).
2. If `compilerPath` is valid, query it.
3. If `compilerPath` is `""`, use an empty array for system include path and defines (they are assumed to be in the `includePath` and `defines` for the current config already).
4. If `compilerPath` is undefined, look for a compiler on the system and query it.
System includes should no longer be added to the `"includePath"` or `"browse.path"` variables. If the extension detects any system include paths in the `"includePath"` property it will silently remove them so that it can ensure system include paths are added last and in the correct order (this is especially important for GCC/Clang). In a future update we may add a notification message to the extension to remind developers to remove system include paths from their `"includePath"` and `'browse.path"` as they will be ignored.
@@ -6,19 +6,7 @@ As of version 0.14.0 of the extension, logging information is now delivered dire
![image](https://user-images.githubusercontent.com/12818240/31898313-b32ff284-b7cd-11e7-97f5-89df93b5d9de.png)
#### Old information (it still works, but is no longer recommended):
VS Code organizes the logging from different extensions to improve readability so you must select the "C/C++" option in the log filter selector to see logging from the C/C++ extension:
<del>
Logging is controlled by environment variables and is disabled by default. To enable logging, launch VS Code from an environment that contains the following variables:
![image](https://user-images.githubusercontent.com/12818240/39769357-d6673bea-52a0-11e8-86c6-3be91618e8fc.png)
```
VSCODE_CPP_LOGDIR=c:\path\to\logfolder
VSCODE_CPP_LOGFILE_LEVEL=5
```
When you open your folder in VS Code, we will create a **vscode.cpp.log.\<pid\>.txt** file for each extension process launched (\<pid\> = process id).
The log file level is a number that determines how much detail we'll log. Level 5 is generally detailed enough to give us information about what is going on in your session. We don't recommend you set this higher than 7 since the log quickly becomes cluttered with information that doesn't really help us diagnose your issues and actually makes it harder for us to spot problems. It may also slow down the extension considerably and make it harder for you to reproduce your problem.
**Don't forget to remove the environment variables when you are finished providing us with the logs.** You wouldn't want the extension to needlessly spend CPU time and disk space writing data you don't need into log files.
</del>
+14 -2
View File
@@ -3,6 +3,7 @@
* [How do I get IntelliSense to work correctly?](#how-do-i-get-intellisense-to-work-correctly)
* [Why do I see red squiggles under Standard Library types?](#why-do-i-see-red-squiggles-under-standard-library-types)
* [How do I get the new IntelliSense to work with MinGW on Windows?](#how-do-i-get-the-new-intellisense-to-work-with-mingw-on-windows)
* [How do I get the new IntelliSense to work with the Windows Subsystem for Linux?](#how-do-i-get-the-new-intellisense-to-work-with-the-windows-subsystem-for-linux)
* [What is the difference between `"includePath"` and `"browse.path"` in **c_cpp_properties.json**?](#what-is-the-difference-between-includepath-and-browsepath-in-c_cpp_propertiesjson)
* [How do I re-create the IntelliSense database?](#how-do-i-re-create-the-intellisense-database)
@@ -27,11 +28,22 @@ If you want IntelliSense to operate on your files even when all #include directi
## Why do I see red squiggles under Standard Library types?
The most common reason for this is missing or sorted include paths. If you are using a compiler in the GCC family, the system includes that you add to your `"includePath"` in **c_cpp_properties.json** should match the output of the following command: `gcc -Wp,-v -E -xc -x c++ /dev/null` (replace 'gcc' with whichever compiler you are using). GCC and its relatives require the paths to be in a specific order too, so sorting the paths for aesthetics will likely result in incorrect IntelliSense results.
The most common reason for this is missing include paths and defines. The easiest way to fix this on each platform is as follows:
**Linux/Mac**
* Set `"intelliSenseMode": "clang-x64"` and `"compilerPath"` in **c_cpp_properties.json** to the path to your compiler.
**Windows**
* If you are using a Microsoft compiler from Visual Studio, set `"intelliSenseMode": "msvc-x64"`, but don't add the `"compilerPath"` property to **c_cpp_properties.json**.
* If you are using Clang for Windows, set `"intelliSenseMode": "msvc-x64"`, and `"compilerPath"` in **c_cpp_properties.json** to the path to your compiler.
## How do I get the new IntelliSense to work with MinGW on Windows?
Since MinGW is a relative of GCC, Microsoft mode compilation (which is the default on Windows) doesn't work very well with it. To use GCC/CLang mode, set the `"intelliSenseMode"` property in your **c_cpp_properties.json** file to `"clang-x64"`. An example **c_cpp_properties.json** [is shared here for your convenience](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/MinGW.md).
The page discussing configuration with MinGW is [here](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/MinGW.md).
## How do I get the new IntelliSense to work with the Windows Subsystem for Linux?
The page discussing configuration with WSL is [here](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/Windows%20Subsystem%20for%20Linux.md).
## What is the difference between `"includePath"` and `"browse.path"` in **c_cpp_properties.json**?
@@ -39,6 +39,6 @@ We recommend using the "Default" engine for the best IntelliSense experience. Ho
### See Also
[Configuring includePath for better IntelliSense results](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/Getting%20started.md)
[Configuring includePath for better IntelliSense results](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/Getting%20started%20with%20IntelliSense%20configuration.md)
[**c_cpp_properties.json** reference guide](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/c_cpp_properties.json.md)
+22 -103
View File
@@ -1,113 +1,32 @@
For developers using MinGW on Windows, we recommend you start with the following **c_cpp_properties.json** template. Select "C/Cpp: Edit Configurations" from the command palette to create this file if you haven't already.
# MinGW
## With extension version 0.16.1 and higher:
To use MinGW on Windows, we recommend you add the following configuration to your **c_cpp_properties.json** file. Select "C/Cpp: Edit Configurations" from the command palette to create this file if you haven't already.
Starting with version 0.16.1, if you set the `compilerPath` property and change `intelliSenseMode` to `clang-x64`, you no longer need to copy the system include path or defines to `includePath` and `defines` to enable IntelliSense to work properly. However, `browse.path` still needs to be updated manually to add the system include paths to enable code browsing for system headers. For example:
## Extension version 0.17.0 and higher:
When you set the `compilerPath` property and change `intelliSenseMode` to `clang-x64`, you no longer need to copy the system include path or defines to `includePath`, `browse.path`, or `defines` to enable IntelliSense to work properly. For example:
```json
{
"configurations": [
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"compilerPath": "C:/MinGW/bin/gcc.exe",
"includePath": [
"${workspaceFolder}"
],
"defines": [
"_DEBUG"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*",
"${workspaceFolder}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"cStandard": "c11",
"cppStandard": "c++17"
}
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"compilerPath": "C:/mingw64/bin/gcc.exe",
"includePath": [
"${workspaceFolder}"
],
"version": 3
"defines": [],
"browse": {
"path": [
"${workspaceFolder}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"cStandard": "c11",
"cppStandard": "c++17"
}
```
Note that the `browse.path` setting is not automatically updated at this time and you may have to change the MinGW version number to match what you have installed. If you are using a different MinGW distribution, the values for `compilerPath` and `browse.path` will likely be different than what is written here.
## Extension version 0.16.1 and earlier:
## With extension version 0.16.0 and earlier:
In earlier versions of the extension, the `includePath` and a some system defines need to be set in order for IntelliSense to work properly. Note that you may have to change the MinGW version number to match what you have installed. Eg. `C:/MinGW/lib/gcc/mingw32/5.3.0/` instead of `C:/MinGW/lib/gcc/mingw32/6.3.0/`.
```json
{
"configurations": [
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/mingw32",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/backward",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed"
],
"defines": [
"_DEBUG",
"__GNUC__=6",
"__cdecl=__attribute__((__cdecl__))"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
The `includePath` above includes the system header paths that gcc uses in version 6.3.0 for C++ projects and matches the output of `"gcc -v -E -x c++ nul"`. The `intelliSenseMode` should be set to **"clang-x64"** to get MinGW projects to work properly with IntelliSense. The `__GNUC__=#` define should match the major version of the toolchain in your installation (6 in this example).
For C projects, simply remove the C++ lines:
```json
{
"configurations": [
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed"
],
"defines": [
"_DEBUG",
"__GNUC__=6",
"__cdecl=__attribute__((__cdecl__))"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
If you have an older version of the C/C++ extension installed, use [these instructions](Archive/MinGW.md) instead.
@@ -1,139 +1,43 @@
# Windows Subsystem for Linux
> **Note:** If you are on **build 17110 of Windows or higher**, you must use version 0.17.0 or higher for IntelliSense to work. The Windows team turned on case-sensitive folders for the WSL environment and the C/C++ extension doesn't support case-sensitive folders until version 0.17.0.
To use the Windows Subsystem for Linux with this extension you need to add a configuration to your **c_cpp_properties.json** file which adds the necessary header paths from within the WSL filesystem to the `includePath`.
Select "C/Cpp: Edit Configurations" from the command palette to create the **c_cpp_properties.json** file if you haven't already.
## Release
## With extension version 0.17.0 and higher:
For developers using Ubuntu with the current version of WSL released with the Fall Creators Update, you can add the following configuration template to your **c_cpp_properties.json** file.
In **c_cpp_properties.json** you can directly address your WSL compiler and include paths by using *nix-style paths and we will do the conversion to Windows paths for you. If you have multiple distros installed, we disambiguate the `compilerPath` by picking the one marked as Default when you run `wslconfig.exe /l` in a CMD or PowerShell window. We continue to support Windows-style paths for these properties as outlined in the [archived instructions](Archive/Windows%20Subsystem%20for%20Linux.md) if you prefer to use those.
```json
{
"name": "WSL",
"intelliSenseMode": "clang-x64",
"compilerPath": "/usr/bin/gcc",
"includePath": [
"${workspaceRoot}",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5/backward",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
"${workspaceFolder}",
"/mnt/c/libraries/lib1/include",
"C:/libraries/lib2/include"
],
"defines": [],
"browse": {
"path": [
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
"${workspaceFolder}",
"/mnt/c/libraries"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
},
"cStandard": "c11",
"cppStandard": "c++17"
}
```
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
## Earlier versions of the extension:
Note that `${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/` is the path to the root of the Ubuntu filesystem. This will be different if you are using a different distro. You can discover the paths to your distro's filesystem by using this handy PowerShell command:
```Powershell
PS R:\> ($(get-appxpackage).PackageFamilyName | findstr /i 'SUSE Ubuntu') -replace '^', "$`{localappdata`}/Packages/"
${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc
${localappdata}/Packages/46932SUSE.openSUSELeap42.2_022rs5jcyhyac
${localappdata}/Packages/46932SUSE.SUSELinuxEnterpriseServer12SP2_022rs5jcyhyac
```
For C projects, simply remove the C++ lines:
```json
{
"name": "WSL",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
## Beta
For developers using Bash on Ubuntu on Windows with the beta version of WSL from before the Fall Creators Update, you can add the following configuration template to your **c_cpp_properties.json** file.
```json
{
"name": "WSL (Beta)",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/include/c++/5/backward",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
Note that `${localappdata}/lxss/rootfs/` is the path to the root of the filesystem for Bash on Ubuntu on Windows.
For C projects, simply remove the C++ lines as in the previous example.
If you are on a build of Windows prior to 17110 and you have an older version of the C/C++ extension installed, use [these instructions](Archive/Windows%20Subsystem%20for%20Linux.md) instead.
---
With these configurations, you should be all set up to use the new IntelliSense engine for linting, memberlist autocomplete, and quick info (tooltips). Add `"C_Cpp.intelliSenseEngine": "Default"` to your **settings.json** file to try out the new IntelliSense engine.
And remember to [heed the warnings of the Windows team about not creating or editing Linux files from a Windows app](https://blogs.msdn.microsoft.com/commandline/2016/11/17/do-not-change-linux-files-using-windows-apps-and-tools/)!
Remember to [heed the warnings of the Windows team about not creating or editing Linux files from a Windows app](https://blogs.msdn.microsoft.com/commandline/2016/11/17/do-not-change-linux-files-using-windows-apps-and-tools/)!
@@ -1,14 +1,23 @@
# `c_cpp_properties.json` Reference Guide
> See also: [Customizing Default Settings](Customizing%20Default%20Settings.md)
### Example
```json
{
"env" : {
"myDefaultIncludePath": [
"${workspaceFolder}",
"${workspaceFolder}/include"
],
"myCompilerPath": "/usr/local/bin/gcc-7"
},
"configurations": [
{
"name": "Win32",
"intelliSenseMode": "msvc-x64",
"includePath": [ "${workspaceFolder}" ],
"name": "Mac",
"intelliSenseMode": "clang-x64",
"includePath": [ "${myDefaultIncludePath}", "/another/path" ],
"macFrameworkPath": [ "/System/Library/Frameworks" ],
"defines": [ "FOO", "BAR=100" ],
"forcedInclude": [ "${workspaceFolder}/include/config.h" ],
@@ -23,14 +32,17 @@
}
}
],
"version": 3
"version": 4
}
```
## Top-level properties
* #### `env`
An array of user-defined variables that will be available for substitution in the configurations via the standard environment variable syntax: `${<var>}` or `${env:<var>}`. Strings and arrays of strings are accepted.
* #### `configurations`
An array of configuration objects that provide the IntelliSense engine with information about your project and your preferences. By default, the extension creates 3 configurations for you, one each for Linux, Mac, and Windows, but it is not required to keep them all. You may also add additional configurations if necessary.
An array of configuration objects that provide the IntelliSense engine with information about your project and your preferences. By default, the extension creates a configuration for you based on your operating system. You may also add additional configurations.
* #### `version`
We recommend you don't edit this field. It tracks the current version of the **c_cpp_properties.json** file so that the extension knows what properties and settings should be present and how to upgrade this file to the latest version.
@@ -44,13 +56,13 @@
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this property determines which mode the IntelliSense engine will run in. `"msvc-x64"` maps to Visual Studio mode with 64-bit pointer sizes. `"clang-x64"` maps to GCC/CLang mode with 64-bit pointer sizes. Windows uses `"msvc-x64"` by default and Linux/Mac use `"clang-x64"` by default.
* #### `includePath`
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of paths will be used by IntelliSense to search for headers included by your source files. This is basically the same as the list of paths you pass to your compiler with the `-I` switch; the IntelliSense engine will not do a recursive search in these paths for includes. If a GCC/CLang compiler is specified in the `compilerPath` setting, it is not necessary to list the system include paths in this list.
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of paths will be used by IntelliSense to search for headers included by your source files. This is basically the same as the list of paths you pass to your compiler with the `-I` switch. If a path ends with `/**` the IntelliSense engine will do a recursive search for includes starting from that directory. If on Windows with Visual Studio installed, or if a compiler is specified in the `compilerPath` setting, it is not necessary to list the system include paths in this list.
* #### `macFrameworkPath`
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of paths will be used by IntelliSense to search for framework headers included by your source files. This is basically the same as the list of paths you pass to your compiler with the `-F` switch; the IntelliSense engine will not do a recursive search in these paths for includes.
* #### `defines`
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of preprocessor symbols will be used by IntelliSense during the compilation of your source files. This is basically the same as the list of symbols you pass to your compiler with the `-D` switch.
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of preprocessor symbols will be used by IntelliSense during the compilation of your source files. This is basically the same as the list of symbols you pass to your compiler with the `-D` switch. If on Windows with Visual Studio installed, or if a compiler is specified in the `compilerPath` setting, it is not necessary to list the system include paths in this list.
* #### `forcedInclude` (optional)
A list of files that should be included before any other characters in the source file are processed. Files are included in the order listed.
@@ -67,7 +79,7 @@
* #### `compileCommands` (optional)
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, the includes and defines discovered in this file will be used instead of the values set for `includePath` and `defines`. If the compile commands database does not contain an entry for the translation unit that corresponds to the file you opened in the editor, then a warning message will appear and the extension will use the `includePath` and `defines` settings instead.
*For more information about the file format, see the [Clang documentation](https://clang.llvm.org/docs/JSONCompilationDatabase.html). Some build systems, such as CMake, [simplify generating this file](https://cmake.org/cmake/help/v3.5/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html).*
>For more information about the file format, see the [Clang documentation](https://clang.llvm.org/docs/JSONCompilationDatabase.html). Some build systems, such as CMake, [simplify generating this file](https://cmake.org/cmake/help/v3.5/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html).
* #### `browse`
The set of properties used when `"C_Cpp.intelliSenseEngine"` is set to `"Tag Parser"` (also referred to as "fuzzy" IntelliSense, or the "browse" engine). These properties are also used by the Go To Definition/Declaration features, or when the "Default" IntelliSense engine is unable to resolve the #includes in your source files.
+2 -2
View File
@@ -15,7 +15,7 @@
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "npm"
"preLaunchTask": "compile",
},
{
"name": "Launch Tests",
@@ -31,7 +31,7 @@
"outFiles": [
"${workspaceFolder}/out/test/**/*.js"
],
"preLaunchTask": "npm"
"preLaunchTask": "compile"
},
{
"name": "Node Attach",
+58 -28
View File
@@ -1,30 +1,60 @@
// Available variables which can be used inside of strings.
// ${workspaceRoot}: the root folder of the team
// ${file}: the current opened file
// ${fileBasename}: the current opened file's basename
// ${fileDirname}: the current opened file's dirname
// ${fileExtname}: the current opened file's extension
// ${cwd}: the current working directory of the spawned process
// A task runner that calls a custom npm script that compiles the extension.
{
"version": "0.1.0",
// we want to run npm
"command": "npm",
// the command is a shell script
"isShellCommand": true,
// show the output window only if unrecognized errors occur.
"showOutput": "silent",
// we run the custom script "compile" as defined in package.json
"args": ["run", "compile", "--loglevel", "silent"],
// The tsc compiler is started in watching mode
"isWatching": true,
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
"problemMatcher": "$tsc-watch"
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "TypeScript Compile",
"identifier": "compile",
"group": {
"kind": "build",
"isDefault": true
},
"isBackground": true,
"type": "shell",
"presentation": {
"echo": true,
"reveal": "silent",
"focus": false,
"panel": "shared"
},
"command": "npm",
"args": [
"run",
"compile",
"--loglevel",
"silent"
],
"problemMatcher": "$tsc-watch"
},
{
"label": "TypeScript Lint",
"identifier": "tslint",
"group": "build",
"isBackground": false,
"type": "shell",
"command": "npm",
"args": [
"run",
"tslint"
],
"problemMatcher": {
"fileLocation": "absolute",
"source": "tslint",
"pattern": [
{
"regexp": "(ERROR:) ([a-zA-Z/:\\-\\.]*)\\[(\\d+), (\\d+)\\]: (.*)",
"severity": 1,
"file": 2,
"line": 3,
"column": 4,
"message": 5
}
]
},
"dependsOn": [
"compile"
]
}
]
}
+1
View File
@@ -11,4 +11,5 @@ CMakeLists.txt
debugAdapters/install.lock*
out/src/Debugger/copyScript.js
tools/**
out/tools/**
notices/**
+46 -2
View File
@@ -1,14 +1,58 @@
# C/C++ for Visual Studio Code Change Log
## Version 0.17.5: June 21, 2018
* Detect `compile_commands.json` and show prompt to use it. [#1297](https://github.com/Microsoft/vscode-cpptools/issues/1297)
* Change inactive regions from gray to translucent. [#1907](https://github.com/Microsoft/vscode-cpptools/issues/1907)
* Improve performance of recursive includes paths. [#2068](https://github.com/Microsoft/vscode-cpptools/issues/2068)
* Fix IntelliSense client failure due to `No args provider`. [#1908](https://github.com/Microsoft/vscode-cpptools/issues/1908)
* Fix `#include` completion with headers in the same directory. [#2031](https://github.com/Microsoft/vscode-cpptools/issues/2031)
* Fix non-header files outside the workspace folder not being parsed (i.e. so `Go to Definition` works). [#2053](https://github.com/Microsoft/vscode-cpptools/issues/2053)
* Fix some crashes. [#2080](https://github.com/Microsoft/vscode-cpptools/issues/2080)
* Support asm clobber registers on Windows. [#2090](https://github.com/Microsoft/vscode-cpptools/issues/2090)
* Fix usage of `${config:section.setting}`. [#2165](https://github.com/Microsoft/vscode-cpptools/issues/2165)
* `browse.path` now inherits `includePath` if not set in `c_cpp_properties.json`.
* On Windows, `compilerPath` now populates with the guessed `cl.exe` path, and the `MSVC` include path is based on the `cl.exe` path.
* Fix files under a non-recursive `browse.path` being removed from the database.
* Fix `*` not working in `browse.path` with WSL.
* Fix for -break-insert main returning multiple bind points. [#729](https://github.com/Microsoft/MIEngine/pull/729)
* Use -- instead of -x for gnome-terminal. [#733](https://github.com/Microsoft/MIEngine/pull/733)
* Added `miDebuggerArgs` in order to pass arguments to the program in `miDebuggerPath`. [#720](https://github.com/Microsoft/MIEngine/pull/720)
## Version 0.17.4: May 31, 2018
* Fix infinite loop (caused by deadlock) when using recursive includes. [#2043](https://github.com/Microsoft/vscode-cpptools/issues/2043)
* Stop using recursive includes in the default configuration.
* @Hyzeta [PR #2059](https://github.com/Microsoft/vscode-cpptools/pull/2059)
* Fix various other potential deadlocks and crashes.
* Fix `Go to Definition` on `#include` not filtering out results based on the path. [#1253](https://github.com/Microsoft/vscode-cpptools/issues/1253), [#2033](https://github.com/Microsoft/vscode-cpptools/issues/2033)
* Fix database icon getting stuck. [#1917](https://github.com/Microsoft/vscode-cpptools/issues/1917)
## Version 0.17.3: May 22, 2018
* Add support for `${workspaceFolder:folderName}`. [#1774](https://github.com/Microsoft/vscode-cpptools/issues/1774)
* Fix infinite loop during initialization on Windows. [#1960](https://github.com/Microsoft/vscode-cpptools/issues/1960)
* Fix main process IntelliSense-related crashes. [#2006](https://github.com/Microsoft/vscode-cpptools/issues/2006)
* Fix deadlock after formatting large files. [#2007](https://github.com/Microsoft/vscode-cpptools/issues/2007)
* Fix recursive includes failing to find some system includes. [#2019](https://github.com/Microsoft/vscode-cpptools/issues/2019)
## Version 0.17.1: May 17, 2018
* Fix IntelliSense update slowness when using recursive includes. [#1949](https://github.com/Microsoft/vscode-cpptools/issues/1949)
* Fix code navigation failure after switching between WSL and non-WSL configs. [#1958](https://github.com/Microsoft/vscode-cpptools/issues/1958)
* Fix extension crash when the `includePath` is a file or the root drive. [#1979](https://github.com/Microsoft/vscode-cpptools/issues/1979), [#1965](https://github.com/Microsoft/vscode-cpptools/issues/1965)
* Fix IntelliSense crash in `have_member_access_from_class_scope`. [#1763](https://github.com/Microsoft/vscode-cpptools/issues/1763)
* Fix `#include` completion bugs. [#1959](https://github.com/Microsoft/vscode-cpptools/issues/1959), [#1970](https://github.com/Microsoft/vscode-cpptools/issues/1970)
* Add `Debug` value for `loggingLevel` (previously the hidden value `"6"`).
* Fix C++17 features not being fully enabled with msvc-x64 mode. [#1990](https://github.com/Microsoft/vscode-cpptools/issues/1990)
* Fix IntelliSense interprocess deadlocks. [#1407](https://github.com/Microsoft/vscode-cpptools/issues/1407), [#1777](https://github.com/Microsoft/vscode-cpptools/issues/1777)
## Version 0.17.0: May 7, 2018
* Auto-complete for headers after typing `#include`. [#802](https://github.com/Microsoft/vscode-cpptools/issues/802)
* Add support for recursive `includePath`, e.g. `${workspaceFolder}/**`. [#897](https://github.com/Microsoft/vscode-cpptools/issues/897)
* Configuration improvements. [#1338](https://github.com/Microsoft/vscode-cpptools/issues/1338)
* Potentially addresses: [#368](https://github.com/Microsoft/vscode-cpptools/issues/368), [#410](https://github.com/Microsoft/vscode-cpptools/issues/410), [#1229](https://github.com/Microsoft/vscode-cpptools/issues/1229), [#1270](https://github.com/Microsoft/vscode-cpptools/issues/), [#1404](https://github.com/Microsoft/vscode-cpptools/issues/1404)
* Potentially addresses: [#368](https://github.com/Microsoft/vscode-cpptools/issues/368), [#410](https://github.com/Microsoft/vscode-cpptools/issues/410), [#1229](https://github.com/Microsoft/vscode-cpptools/issues/1229), [#1270](https://github.com/Microsoft/vscode-cpptools/issues/1270), [#1404](https://github.com/Microsoft/vscode-cpptools/issues/1404)
* Add support for querying system includes/defines from WSL and Cygwin compilers. [#1845](https://github.com/Microsoft/vscode-cpptools/issues/1845), [#1736](https://github.com/Microsoft/vscode-cpptools/issues/1736)
* Fix IntelliSense for WSL projects in Windows builds 17110 and greater. [#1694](https://github.com/Microsoft/vscode-cpptools/issues/1694)
* Add snippets. [PR #1823](https://github.com/Microsoft/vscode-cpptools/pull/1823)
* Add support for vcpkg. [PR #1886](https://github.com/Microsoft/vscode-cpptools/pull/1886)
* Add support for custom variables in `c_cpp_properties.json` via `env`. [#1857](https://github.com/Microsoft/vscode-cpptools/issues/1857), [#368](https://github.com/Microsoft/vscode-cpptools/issues/368)
* Stop automatically adding `/usr/include` to the `includePath`. [#1819](https://github.com/Microsoft/vscode-cpptools/issues/1819)
* Fix wrong configuration being used if there are four or more. [#1599](https://github.com/Microsoft/vscode-cpptools/issues/1599)
* Fix `c_cpp_properties.json` requiring write access. [#1790](https://github.com/Microsoft/vscode-cpptools/issues/1790)
@@ -157,7 +201,7 @@
* Light bulbs (code actions) for #include errors now suggest potential paths to add to the `includePath` based on a recursive search of the `browse.path`. [#846](https://github.com/Microsoft/vscode-cpptools/issues/846)
* Browse database now removes old symbols when `browse.path` changes. [#262](https://github.com/Microsoft/vscode-cpptools/issues/262)
* Add `*` on new lines after a multiline comment with `/**` is started. [#579](https://github.com/Microsoft/vscode-cpptools/issues/579)
* Fix Go to Definition, completion, and parameter hints for partially scoped members. [#635](https://github.com/Microsoft/vscode-cpptools/issues/635)
* Fix `Go to Definition`, completion, and parameter hints for partially scoped members. [#635](https://github.com/Microsoft/vscode-cpptools/issues/635)
* Fix bug in `macFrameworkPath` not resolving variables.
## Version 0.12.4: September 12, 2017
+8 -5
View File
@@ -205,9 +205,12 @@
<tr>
<td>
<div>
<h2 class="caption">March 2018 Update</h2>
<div>Thank you for installing the C/C++ extension. In the March update, we finished our implementation of autocomplete for the default IntelliSense engine. We also added additional configuration settings for forced include files, specifying your compiler path and language standard to improve IntelliSense accuracy.<br />
<br />
<h2 class="caption">June 2018 Update</h2>
<div>Thank you for installing the C/C++ extension. In the June update, we focused on workspace configuration improvements.<br/>
<br/>
We dramatically improved the performance of recursive includes (e.g. using <code>${workspaceFolder}/**</code> in your <code>includePath</code>), we will prompt you to
use compile_commands.json if it is found in your workspace, and we made the <code>browse.path</code> setting optional in the case that it is identical to your <code>includePath</code>.<br/>
<br/>
Additional features and bug fixes are detailed in the <a href="https://github.com/Microsoft/vscode-cpptools/releases">full release notes</a>.</div>
</div>
</td>
@@ -231,9 +234,9 @@
<td>
<div>
<h3 class="caption">Blog Posts</h3>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/05/08/visual-studio-code-cc-extension-may-2018-update-intellisense-configuration-just-got-so-much-easier/">May 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/03/29/visual-studio-code-cc-extension-march-2018-update/">March 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/02/20/visual-studio-code-cc-extension-feb-2018-update/">February 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/01/17/visual-studio-code-cc-extension-jan-2018-update/">January 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2017/12/11/visual-studio-code-cc-extension-dec-2017-update-support-for-more-linux-distros/">December 2017 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2016/03/31/cc-extension-for-visual-studio-code/">C/C++ Extension anouncement</a></div>
</div>
</td>
+3 -3
View File
@@ -4,11 +4,11 @@
"--microsoft",
"--microsoft_bugs",
"--microsoft_version",
"1900",
"1914",
"--pack_alignment",
"8",
"-D_MSC_VER=1900",
"-D_MSC_FULL_VER=190024210",
"-D_MSC_VER=1914",
"-D_MSC_FULL_VER=191426428",
"-D_MSC_BUILD=0",
"-D_M_IX86=600",
"-D_M_IX86_FP=2"
+3 -3
View File
@@ -4,12 +4,12 @@
"--microsoft",
"--microsoft_bugs",
"--microsoft_version",
"1900",
"1914",
"--pack_alignment",
"8",
"-D_CPPUNWIND=1",
"-D_MSC_VER=1900",
"-D_MSC_FULL_VER=190024210",
"-D_MSC_VER=1914",
"-D_MSC_FULL_VER=191426428",
"-D_MSC_BUILD=0",
"-D_M_X64=100",
"-D_AMD64=100"
+3 -3
View File
@@ -4,12 +4,12 @@
"--microsoft",
"--microsoft_bugs",
"--microsoft_version",
"1900",
"1914",
"--pack_alignment",
"8",
"-D_CPPUNWIND=1",
"-D_MSC_VER=1900",
"-D_MSC_FULL_VER=190024210",
"-D_MSC_VER=1914",
"-D_MSC_FULL_VER=191426428",
"-D_MSC_BUILD=0",
"-D_M_X64=100",
"-D_AMD64=100"
+3 -3
View File
@@ -4,12 +4,12 @@
"--microsoft",
"--microsoft_bugs",
"--microsoft_version",
"1900",
"1914",
"--pack_alignment",
"8",
"-D_CPPUNWIND=1",
"-D_MSC_VER=1900",
"-D_MSC_FULL_VER=190024210",
"-D_MSC_VER=1914",
"-D_MSC_FULL_VER=191426428",
"-D_MSC_BUILD=0",
"-D_M_X64=100",
"-D_AMD64=100"
+24 -1
View File
@@ -107,6 +107,26 @@
}
}
},
"env": {
"type": "object",
"description": "Custom variables that can be reused anywhere in this file using the ${variable} or ${env:variable} syntax.",
"patternProperties": {
"(?!^workspaceFolder$)(?!^workspaceRoot$)(?!^default$)(^.+$)": {
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}
},
"additionalProperties": false
},
"version": {
"type": "integer",
"description": "Version of the configuration file. This property is managed by the extension. Please do not change it."
@@ -116,6 +136,9 @@
"configurations": {
"$ref": "#/definitions/configurations"
},
"env": {
"$ref": "#/definitions/env"
},
"version": {
"$ref": "#/definitions/version"
}
@@ -124,4 +147,4 @@
"configurations",
"version"
]
}
}
+3 -1
View File
@@ -1,3 +1,5 @@
{
"intelliSenseEngine_default_percentage": 100
"intelliSenseEngine_default_percentage": 100,
"defaultIntelliSenseEngine": 100,
"recursiveIncludes": 100
}
+6
View File
@@ -10,6 +10,7 @@ const env = require('gulp-env')
const tslint = require('gulp-tslint');
const mocha = require('gulp-mocha');
const fs = require('fs');
const optionsSchemaGenerator = require('./out/tools/GenerateOptionsSchema');
gulp.task('allTests', () => {
gulp.start('unitTests');
@@ -51,6 +52,7 @@ gulp.task('integrationTests', () => {
/// Misc Tasks
const allTypeScript = [
'src/**/*.ts',
'tools/**/*.ts',
'!**/*.d.ts',
'!**/typings**'
];
@@ -82,4 +84,8 @@ gulp.task('pr-check', () => {
console.log('Please make sure to not check in package.json that has been rewritten by the extension activation. If you intended to have changes in package.json, please only check-in your changes. If you did not, please run `git checkout -- package.json`.');
process.exit(1);
}
});
gulp.task('generateOptionsSchema', () => {
optionsSchemaGenerator.generateOptionsSchema();
});
+1347 -1686
View File
File diff suppressed because it is too large Load Diff
+49 -20
View File
@@ -2,7 +2,7 @@
"name": "cpptools",
"displayName": "C/C++",
"description": "C/C++ IntelliSense, debugging, and code browsing.",
"version": "0.17.0-insiders2",
"version": "0.17.5",
"publisher": "ms-vscode",
"preview": true,
"icon": "LanguageCCPP_color_128x.png",
@@ -12,7 +12,7 @@
},
"license": "SEE LICENSE IN LICENSE.txt",
"engines": {
"vscode": "^1.22.0"
"vscode": "^1.23.0"
},
"bugs": {
"url": "https://github.com/Microsoft/vscode-cpptools/issues",
@@ -32,7 +32,7 @@
"multi-root ready"
],
"categories": [
"Languages",
"Programming Languages",
"Debuggers",
"Formatters",
"Linters",
@@ -146,6 +146,14 @@
"description": "Controls whether inactive preprocessor blocks are colored differently than active code. This setting is ignored by the Tag Parser engine.",
"scope": "resource"
},
"C_Cpp.inactiveRegionOpacity": {
"type:": "number",
"default": 0.55,
"Description": "Controls the opacity of inactive preprocessor blocks. Scales between 0.1 and 1.0. This setting only applies when inactive region dimming is enabled.",
"scope": "resource",
"minimum": 0.1,
"maximum": 1
},
"C_Cpp.formatting": {
"type": "string",
"enum": [
@@ -168,10 +176,11 @@
"None",
"Error",
"Warning",
"Information"
"Information",
"Debug"
],
"default": "Error",
"description": "The verbosity of logging in the Output Panel. The order of levels from least verbose to most verbose is: None < Error < Warning < Information.",
"description": "The verbosity of logging in the Output Panel. The order of levels from least verbose to most verbose is: None < Error < Warning < Information < Debug.",
"scope": "resource"
},
"C_Cpp.autoAddFileAssociations": {
@@ -533,6 +542,8 @@
},
"configurationAttributes": {
"launch": {
"type": "object",
"default": {},
"required": [
"program"
],
@@ -570,6 +581,7 @@
"description": "One or more GDB/LLDB commands to execute in order to setup the underlying debugger. Example: \"setupCommands\": [ { \"text\": \"-enable-pretty-printing\", \"description\": \"Enable GDB pretty printing\", \"ignoreFailures\": true }].",
"items": {
"type": "object",
"default": {},
"properties": {
"text": {
"type": "string",
@@ -595,6 +607,7 @@
"description": "If provided, this replaces the default commands used to launch a target with some other commands. For example, this can be \"-target-attach\" in order to attach to a target process. An empty command list replaces the launch commands with nothing, which can be useful if the debugger is being provided launch options as command line options. Example: \"customLaunchSetupCommands\": [ { \"text\": \"target-run\", \"description\": \"run target\", \"ignoreFailures\": false }].",
"items": {
"type": "object",
"default": {},
"properties": {
"text": {
"type": "string",
@@ -639,6 +652,7 @@
"description": "Environment variables to add to the environment for the program. Example: [ { \"name\": \"squid\", \"value\": \"clam\" } ].",
"items": {
"type": "object",
"default": {},
"properties": {
"name": "string",
"value": "string"
@@ -661,6 +675,11 @@
"description": "The path to the mi debugger (such as gdb). When unspecified, it will search path first for the debugger.",
"default": "/usr/bin/gdb"
},
"miDebuggerArgs": {
"type": "string",
"description": "Arguments for the mi debugger (such as gdb) to use. When unspecified.",
"default": ""
},
"miDebuggerServerAddress": {
"type": "string",
"description": "Network address of the MI Debugger Server to connect to (example: localhost:1234).",
@@ -719,8 +738,8 @@
}
},
"logging": {
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"type": "object",
"default": {},
"properties": {
"exceptions": {
@@ -759,10 +778,10 @@
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).",
"type": "object",
"default": {
"pipeCwd": "${workspaceRoot}",
"pipeCwd": "/usr/bin",
"pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'",
"pipeArgs": [],
"debuggerPath": "enter the path for the debugger on the target machine, for example /usr/bin/gdb"
"debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
},
"properties": {
"pipeCwd": {
@@ -801,6 +820,8 @@
}
},
"attach": {
"type": "object",
"default": {},
"required": [
"program",
"processId"
@@ -883,8 +904,8 @@
}
},
"logging": {
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"type": "object",
"default": {},
"properties": {
"exceptions": {
@@ -923,10 +944,10 @@
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).",
"type": "object",
"default": {
"pipeCwd": "${workspaceRoot}",
"pipeCwd": "/usr/bin",
"pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'",
"pipeArgs": [],
"debuggerPath": "enter the path for the debugger on the target machine, for example /usr/bin/gdb"
"debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
},
"properties": {
"pipeCwd": {
@@ -967,6 +988,7 @@
"description": "One or more GDB/LLDB commands to execute in order to setup the underlying debugger. Example: \"setupCommands\": [ { \"text\": \"-enable-pretty-printing\", \"description\": \"Enable GDB pretty printing\", \"ignoreFailures\": true }].",
"items": {
"type": "object",
"default": {},
"properties": {
"text": {
"type": "string",
@@ -1007,6 +1029,8 @@
},
"configurationAttributes": {
"launch": {
"type": "object",
"default": {},
"required": [
"program",
"cwd"
@@ -1040,6 +1064,7 @@
"description": "Environment variables to add to the environment for the program. Example: [ { \"name\": \"squid\", \"value\": \"clam\" } ].",
"items": {
"type": "object",
"default": {},
"properties": {
"name": "string",
"value": "string"
@@ -1109,6 +1134,8 @@
}
},
"attach": {
"type": "object",
"default": {},
"required": [
"processId"
],
@@ -1272,6 +1299,7 @@
},
"scripts": {
"compile": "npm run vscode:prepublish",
"generateOptionsSchema": "gulp generateOptionsSchema",
"integrationTests": "gulp integrationTests",
"postinstall": "node ./node_modules/vscode/bin/install",
"pretest": "tsc -p ./",
@@ -1285,20 +1313,21 @@
"devDependencies": {
"@types/mocha": "^2.2.43",
"@types/node": "^8.0.46",
"gulp": "3.9.1",
"gulp-env": "0.4.0",
"gulp-mocha": "5.0.0",
"gulp-tslint": "8.1.2",
"gulp": "3.9.1",
"mocha": "^4.0.1",
"tslint": "5.8.0",
"tslint-microsoft-contrib": "5.0.1",
"tslint-no-unused-expression-chai": "0.0.3",
"tslint": "5.8.0",
"typescript": "^2.5.3",
"vscode": "^1.1.14"
"vrsource-tslint-rules": "^5.8.2",
"vscode": "^1.1.18"
},
"dependencies": {
"http-proxy-agent": "~2.0.0",
"https-proxy-agent": "~2.1.0",
"http-proxy-agent": "~2.1.0",
"https-proxy-agent": "~2.2.0",
"jsonc-parser": "^1.0.0",
"minimatch": "~3.0.4",
"mkdirp": "~0.5.1",
@@ -1312,7 +1341,7 @@
"runtimeDependencies": [
{
"description": "C/C++ language components (Linux / x86_64)",
"url": "https://go.microsoft.com/fwlink/?linkid=872599",
"url": "https://go.microsoft.com/fwlink/?linkid=875587",
"platforms": [
"linux"
],
@@ -1326,7 +1355,7 @@
},
{
"description": "C/C++ language components (Linux / x86)",
"url": "https://go.microsoft.com/fwlink/?linkid=872600",
"url": "https://go.microsoft.com/fwlink/?linkid=875588",
"platforms": [
"linux"
],
@@ -1342,7 +1371,7 @@
},
{
"description": "C/C++ language components (OS X)",
"url": "https://go.microsoft.com/fwlink/?linkid=872601",
"url": "https://go.microsoft.com/fwlink/?linkid=875589",
"platforms": [
"darwin"
],
@@ -1353,7 +1382,7 @@
},
{
"description": "C/C++ language components (Windows)",
"url": "https://go.microsoft.com/fwlink/?linkid=872602",
"url": "https://go.microsoft.com/fwlink/?linkid=875590",
"platforms": [
"win32"
],
+16 -16
View File
@@ -31,7 +31,7 @@ function formatString(format: string, args: string[]): string {
return format;
}
function CreateLaunchString(name: string, type: string, executable: string): string {
function createLaunchString(name: string, type: string, executable: string): string {
return `"name": "${name}",
"type": "${type}",
"request": "launch",
@@ -44,7 +44,7 @@ function CreateLaunchString(name: string, type: string, executable: string): str
`;
}
function CreateAttachString(name: string, type: string, executable: string): string {
function createAttachString(name: string, type: string, executable: string): string {
return formatString(`
"name": "${name}",
"type": "${type}",
@@ -53,7 +53,7 @@ function CreateAttachString(name: string, type: string, executable: string): str
`, [type === "cppdbg" ? `${os.EOL}"program": "${"enter program name, for example $\{workspaceFolder\}/" + executable}",` : ""]);
}
function CreateRemoteAttachString(name: string, type: string, executable: string): string {
function createRemoteAttachString(name: string, type: string, executable: string): string {
return `
"name": "${name}",
"type": "${type}",
@@ -63,7 +63,7 @@ function CreateRemoteAttachString(name: string, type: string, executable: string
`;
}
function CreatePipeTransportString(pipeProgram: string, debuggerProgram: string, pipeArgs: string[] = []): string {
function createPipeTransportString(pipeProgram: string, debuggerProgram: string, pipeArgs: string[] = []): string {
return `
"pipeTransport": {
\t"debuggerPath": "/usr/bin/${debuggerProgram}",
@@ -106,7 +106,7 @@ export class MIConfigurations extends Configuration {
let name: string = `(${this.MIMode}) Launch`;
let body: string = formatString(`{
\t${indentJsonString(CreateLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createLaunchString(name, this.miDebugger, this.executable))},
\t"MIMode": "${this.MIMode}"{0}{1}
}`, [this.miDebugger === "cppdbg" && os.platform() === "win32" ? `,${os.EOL}\t"miDebuggerPath": "/path/to/gdb"` : "",
this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
@@ -124,7 +124,7 @@ this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalPrope
let name: string = `(${this.MIMode}) Attach`;
let body: string = formatString(`{
\t${indentJsonString(CreateAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createAttachString(name, this.miDebugger, this.executable))},
\t"MIMode": "${this.MIMode}"{0}{1}
}`, [this.miDebugger === "cppdbg" && os.platform() === "win32" ? `,${os.EOL}\t"miDebuggerPath": "/path/to/gdb"` : "",
this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
@@ -146,8 +146,8 @@ export class PipeTransportConfigurations extends Configuration {
let body: string = formatString(`
{
\t${indentJsonString(CreateLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.pipeProgram, this.MIMode))},
\t${indentJsonString(createLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.pipeProgram, this.MIMode))},
\t"MIMode": "${this.MIMode}"{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
@@ -165,8 +165,8 @@ export class PipeTransportConfigurations extends Configuration {
let body: string = formatString(`
{
\t${indentJsonString(CreateRemoteAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.pipeProgram, this.MIMode))},
\t${indentJsonString(createRemoteAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.pipeProgram, this.MIMode))},
\t"MIMode": "${this.MIMode}"{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
return {
@@ -186,7 +186,7 @@ export class WindowsConfigurations extends Configuration {
let body: string = `
{
\t${indentJsonString(CreateLaunchString(name, this.windowsDebugger, this.executable))}
\t${indentJsonString(createLaunchString(name, this.windowsDebugger, this.executable))}
}`;
return {
@@ -204,7 +204,7 @@ export class WindowsConfigurations extends Configuration {
let body: string = `
{
\t${indentJsonString(CreateAttachString(name, this.windowsDebugger, this.executable))}
\t${indentJsonString(createAttachString(name, this.windowsDebugger, this.executable))}
}`;
return {
@@ -226,8 +226,8 @@ export class WSLConfigurations extends Configuration {
let body: string = formatString(`
{
\t${indentJsonString(CreateLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0}
\t${indentJsonString(createLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
return {
@@ -243,8 +243,8 @@ export class WSLConfigurations extends Configuration {
let body: string = formatString(`
{
\t${indentJsonString(CreateRemoteAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0}
\t${indentJsonString(createRemoteAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
return {
+1
View File
@@ -34,6 +34,7 @@ export function initialize(): void {
configurationProvider.getConfigurationSnippets();
const launchJsonDocumentSelector: vscode.DocumentSelector = [{
scheme: 'file',
language: 'jsonc',
pattern: '**/launch.json'
}];
+171 -122
View File
@@ -22,6 +22,9 @@ import { DataBinding } from './dataBinding';
import minimatch = require("minimatch");
import * as logger from '../logger';
import { updateLanguageConfigurations } from './extension';
import { CustomConfigurationProvider, SourceFileConfigurationItem } from '../api';
import { CancellationTokenSource } from 'vscode';
import { SettingsTracker, getTracker } from './settingsTracker';
let ui: UI;
@@ -85,6 +88,14 @@ interface DecorationRangesPair {
ranges: vscode.Range[];
}
interface CustomConfigurationParams {
configurationItems: SourceFileConfigurationItem[];
}
interface CompileCommandsPaths {
paths: string[];
}
// Requests
const NavigationListRequest: RequestType<TextDocumentIdentifier, string, void, void> = new RequestType<TextDocumentIdentifier, string, void, void>('cpptools/requestNavigationList');
const GoToDeclarationRequest: RequestType<void, void, void, void> = new RequestType<void, void, void, void>('cpptools/goToDeclaration');
@@ -104,6 +115,7 @@ const ChangeFolderSettingsNotification: NotificationType<FolderSettingsParams, v
const ChangeCompileCommandsNotification: NotificationType<FileChangedParams, void> = new NotificationType<FileChangedParams, void>('cpptools/didChangeCompileCommands');
const ChangeSelectedSettingNotification: NotificationType<FolderSelectedSettingParams, void> = new NotificationType<FolderSelectedSettingParams, void>('cpptools/didChangeSelectedSetting');
const IntervalTimerNotification: NotificationType<void, void> = new NotificationType<void, void>('cpptools/onIntervalTimer');
const CustomConfigurationNotification: NotificationType<CustomConfigurationParams, void> = new NotificationType<CustomConfigurationParams, void>('cpptools/didChangeCustomConfiguration');
// Notifications from the server
const ReloadWindowNotification: NotificationType<void, void> = new NotificationType<void, void>('cpptools/reloadWindow');
@@ -114,98 +126,10 @@ const ReportStatusNotification: NotificationType<ReportStatusNotificationBody, v
const DebugProtocolNotification: NotificationType<OutputNotificationBody, void> = new NotificationType<OutputNotificationBody, void>('cpptools/debugProtocol');
const DebugLogNotification: NotificationType<OutputNotificationBody, void> = new NotificationType<OutputNotificationBody, void>('cpptools/debugLog');
const InactiveRegionNotification: NotificationType<InactiveRegionParams, void> = new NotificationType<InactiveRegionParams, void>('cpptools/inactiveRegions');
const CompileCommandsPathsNotification: NotificationType<CompileCommandsPaths, void> = new NotificationType<CompileCommandsPaths, void>('cpptools/compileCommandsPaths');
const maxSettingLengthForTelemetry: number = 50;
let previousCppSettings: { [key: string]: any } = {};
let failureMessageShown: boolean = false;
/**
* track settings changes for telemetry
*/
function collectSettingsForTelemetry(filter: (key: string, val: string, settings: vscode.WorkspaceConfiguration) => boolean, resource: vscode.Uri): { [key: string]: string } {
let settings: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp", resource);
let result: { [key: string]: string } = {};
for (let key in settings) {
if (settings.inspect(key).defaultValue === undefined) {
continue; // ignore methods and settings that don't exist
}
let val: any = settings.get(key);
if (val instanceof Object) {
val = JSON.stringify(val, null, 2);
}
// Skip values that don't match the setting's enum.
let curSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + key];
if (curSetting) {
let curEnum: any[] = curSetting["enum"];
if (curEnum && curEnum.indexOf(val) === -1) {
continue;
}
}
if (filter(key, val, settings)) {
previousCppSettings[key] = val;
switch (key.toLowerCase()) {
case "clang_format_path": {
continue;
}
case "clang_format_style":
case "clang_format_fallbackstyle": {
let newKey: string = key + "2";
if (val) {
switch (String(val).toLowerCase()) {
case "visual studio":
case "llvm":
case "google":
case "chromium":
case "mozilla":
case "webkit":
case "file":
case "none": {
result[newKey] = String(previousCppSettings[key]);
break;
}
default: {
result[newKey] = "...";
break;
}
}
} else {
result[newKey] = "null";
}
key = newKey;
break;
}
default: {
if (key.startsWith("default.")) {
continue; // Don't log c_cpp_properties.json defaults since they may contain PII.
}
result[key] = String(previousCppSettings[key]);
break;
}
}
if (result[key].length > maxSettingLengthForTelemetry) {
result[key] = result[key].substr(0, maxSettingLengthForTelemetry) + "...";
}
}
}
return result;
}
function initializeSettingsCache(resource: vscode.Uri): void {
collectSettingsForTelemetry(() => true, resource);
}
function getNonDefaultSettings(resource: vscode.Uri): { [key: string]: string } {
let filter: (key: string, val: string, settings: vscode.WorkspaceConfiguration) => boolean = (key: string, val: string, settings: vscode.WorkspaceConfiguration) => {
return val !== settings.inspect(key).defaultValue;
};
initializeSettingsCache(resource);
return collectSettingsForTelemetry(filter, resource);
}
interface ClientModel {
isTagParsing: DataBinding<boolean>;
isUpdatingIntelliSense: DataBinding<boolean>;
@@ -226,13 +150,19 @@ export interface Client {
TrackedDocuments: Set<vscode.TextDocument>;
onDidChangeSettings(): void;
onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void;
onDidChangeCustomConfigurations(provider: CustomConfigurationProvider): void;
takeOwnership(document: vscode.TextDocument): void;
runBlockingTask<T>(task: Thenable<T>): Thenable<T>;
runBlockingThenableWithTimeout(thenable: () => Thenable<any>, ms: number, tokenSource?: CancellationTokenSource): Thenable<any>;
requestWhenReady(request: () => Thenable<any>): Thenable<any>;
notifyWhenReady(notify: () => void): void;
requestGoToDeclaration(): Thenable<void>;
requestSwitchHeaderSource(rootPath: string, fileName: string): Thenable<string>;
requestNavigationList(document: vscode.TextDocument): Thenable<string>;
activeDocumentChanged(document: vscode.TextDocument): void;
activate(): void;
selectionChanged(selection: vscode.Position): void;
sendCustomConfigurations(configs: SourceFileConfigurationItem[]): void;
resetDatabase(): void;
deactivate(): void;
pauseParsing(): void;
@@ -265,6 +195,7 @@ class DefaultClient implements Client {
private crashTimes: number[] = [];
private isSupported: boolean = true;
private inactiveRegionsDecorations = new Map<string, DecorationRangesPair>();
private settingsTracker: SettingsTracker;
// The "model" that is displayed via the UI (status bar).
private model: ClientModel = {
@@ -302,12 +233,14 @@ class DefaultClient implements Client {
}
/**
* All public methods on this class must be guarded by the "onReady" promise. Requests and notifications received before the client is
* ready are executed after this promise is resolved.
* All public methods on this class must be guarded by the "pendingTask" promise. Requests and notifications received before the task is
* complete are executed after this promise is resolved.
* @see requestWhenReady<T>(request)
* @see notifyWhenReady(notify)
*/
private onReadyPromise: Thenable<void>;
private pendingTask: Thenable<any>;
private pendingRequests: number = 0;
constructor(allClients: ClientCollection, workspaceFolder?: vscode.WorkspaceFolder) {
try {
@@ -319,7 +252,8 @@ class DefaultClient implements Client {
ui = getUI();
ui.bind(this);
this.onReadyPromise = languageClient.onReady().then(() => {
// requests/notifications are deferred until this.languageClient is set.
this.runBlockingTask(languageClient.onReady().then(() => {
this.configuration = new configs.CppProperties(this.RootUri);
this.configuration.ConfigurationsChanged((e) => this.onConfigurationsChanged(e));
this.configuration.SelectionChanged((e) => this.onSelectedConfigurationChanged(e));
@@ -332,9 +266,9 @@ class DefaultClient implements Client {
this.configuration.CompilerDefaults = compilerDefaults;
});
// Once this is set, we don't defer any more callbacks.
this.languageClient = languageClient;
telemetry.logLanguageServerEvent("NonDefaultInitialCppSettings", getNonDefaultSettings(this.RootUri));
this.settingsTracker = getTracker(this.RootUri);
telemetry.logLanguageServerEvent("NonDefaultInitialCppSettings", this.settingsTracker.getUserModifiedSettings());
failureMessageShown = false;
// Listen for messages from the language server.
@@ -346,7 +280,7 @@ class DefaultClient implements Client {
failureMessageShown = true;
vscode.window.showErrorMessage("Unable to start the C/C++ language server. IntelliSense features will be disabled. Error: " + String(err));
}
});
}));
} catch (err) {
this.isSupported = false; // Running on an OS we don't support yet.
if (!failureMessageShown) {
@@ -447,13 +381,7 @@ class DefaultClient implements Client {
}
public onDidChangeSettings(): void {
// This relies on getNonDefaultSettings being called first.
console.assert(Object.keys(previousCppSettings).length > 0);
let filter: (key: string, val: string) => boolean = (key: string, val: string) => {
return !(key in previousCppSettings) || val !== previousCppSettings[key];
};
let changedSettings: { [key: string] : string} = collectSettingsForTelemetry(filter, this.RootUri);
let changedSettings: { [key: string] : string} = this.settingsTracker.getChangedSettings();
if (Object.keys(changedSettings).length > 0) {
if (changedSettings["commentContinuationPatterns"]) {
@@ -477,6 +405,23 @@ class DefaultClient implements Client {
}
}
public onDidChangeCustomConfigurations(provider: CustomConfigurationProvider): void {
let documentUris: vscode.Uri[] = [];
this.trackedDocuments.forEach(document => documentUris.push(document.uri));
let tokenSource: CancellationTokenSource = new CancellationTokenSource();
if (documentUris.length === 0) {
return;
}
this.runBlockingThenableWithTimeout(() => {
return provider.provideConfigurations(documentUris, tokenSource.token);
}, 1000, tokenSource).then((configs: SourceFileConfigurationItem[]) => {
this.sendCustomConfigurations(configs);
});
}
/**
* Take ownership of a document that was previously serviced by another client.
* This process involves sending a textDocument/didOpen message to the server so
@@ -497,24 +442,75 @@ class DefaultClient implements Client {
}
/*************************************************************************************
* wait until the language client is ready for use before attempting to send messages
* wait until the all pendingTasks are complete (e.g. language client is ready for use)
* before attempting to send messages
*************************************************************************************/
private requestWhenReady<T>(request: () => Thenable<T>): Thenable<T> {
if (this.languageClient) {
return request();
} else if (this.isSupported && this.onReadyPromise) {
return this.onReadyPromise.then(() => request());
public runBlockingTask(task: Thenable<any>): Thenable<any> {
if (this.pendingTask) {
return this.requestWhenReady(() => { return task; });
} else {
return Promise.reject<T>("Unsupported client");
this.pendingTask = task;
return task.then((result) => {
this.pendingTask = undefined;
return result;
}, (error) => {
this.pendingTask = undefined;
throw error;
});
}
}
private notifyWhenReady(notify: () => void): void {
if (this.languageClient) {
public runBlockingThenableWithTimeout(thenable: () => Thenable<any>, ms: number, tokenSource?: CancellationTokenSource): Thenable<any> {
let timer: NodeJS.Timer;
// Create a promise that rejects in <ms> milliseconds
let timeout: Promise<any> = new Promise((resolve, reject) => {
timer = setTimeout(() => {
clearTimeout(timer);
if (tokenSource) {
tokenSource.cancel();
}
reject("Timed out in " + ms + "ms.");
}, ms);
});
// Returns a race between our timeout and the passed in promise
return this.runBlockingTask(Promise.race([thenable(), timeout]).then((result: any) => {
clearTimeout(timer);
return result;
}, (error: any) => {
throw error;
}));
}
public requestWhenReady(request: () => Thenable<any>): Thenable<any> {
if (this.pendingTask === undefined) {
return request();
} else if (this.isSupported && this.pendingTask) {
this.pendingRequests++;
return this.pendingTask.then(() => {
this.pendingRequests--;
if (this.pendingRequests === 0) {
this.pendingTask = undefined;
}
return request();
});
} else {
return Promise.reject("Unsupported client");
}
}
public notifyWhenReady(notify: () => void): void {
if (this.pendingTask === undefined) {
notify();
} else if (this.isSupported && this.onReadyPromise) {
this.onReadyPromise.then(() => notify());
} else if (this.isSupported && this.pendingTask) {
this.pendingRequests++;
this.pendingTask.then(() => {
this.pendingRequests--;
if (this.pendingRequests === 0) {
this.pendingTask = undefined;
}
notify();
});
}
}
@@ -530,6 +526,7 @@ class DefaultClient implements Client {
this.languageClient.onNotification(ReportStatusNotification, (e) => this.updateStatus(e));
this.languageClient.onNotification(ReportTagParseStatusNotification, (e) => this.updateTagParseStatus(e));
this.languageClient.onNotification(InactiveRegionNotification, (e) => this.updateInactiveRegions(e));
this.languageClient.onNotification(CompileCommandsPathsNotification, (e) => this.promptCompileCommands(e));
this.setupOutputHandlers();
}
@@ -542,7 +539,7 @@ class DefaultClient implements Client {
if (this.rootFolder) {
// WARNING: The default limit on Linux is 8k, so for big directories, this can cause file watching to fail.
this.rootPathFileWatcher = vscode.workspace.createFileSystemWatcher(
path.join(this.RootPath, "*"),
"**/*",
false /*ignoreCreateEvents*/,
true /*ignoreChangeEvents*/,
false /*ignoreDeleteEvents*/);
@@ -714,12 +711,12 @@ class DefaultClient implements Client {
}
private updateInactiveRegions(params: InactiveRegionParams): void {
let renderOptions: vscode.DecorationRenderOptions = {
light: { color: "rgba(175,175,175,1.0)" },
dark: { color: "rgba(155,155,155,1.0)" },
let settings: CppSettings = new CppSettings(this.RootUri);
let decoration: vscode.TextEditorDecorationType = vscode.window.createTextEditorDecorationType({
opacity: settings.inactiveRegionOpacity.toString(),
rangeBehavior: vscode.DecorationRangeBehavior.ClosedOpen
};
let decoration: vscode.TextEditorDecorationType = vscode.window.createTextEditorDecorationType(renderOptions);
});
// We must convert to vscode.Ranges in order to make use of the API's
let ranges: vscode.Range[] = [];
@@ -745,7 +742,6 @@ class DefaultClient implements Client {
this.inactiveRegionsDecorations.set(params.uri, toInsert);
}
let settings: CppSettings = new CppSettings(this.RootUri);
if (settings.dimInactiveRegions) {
// Apply the decorations to all *visible* text editors
let editors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => e.document.uri.toString() === params.uri);
@@ -755,6 +751,46 @@ class DefaultClient implements Client {
}
}
private promptCompileCommands(params: CompileCommandsPaths) : void {
if (this.configuration.Configurations[this.configuration.CurrentConfiguration].compileCommands !== undefined) {
return;
}
let showCompileCommandsSelection: PersistentState<boolean> = new PersistentState<boolean>("CPP.showCompileCommandsSelection", true);
if (!showCompileCommandsSelection.Value) {
return;
}
let compileCommandStr: string = params.paths.length > 1 ? "a compile_commands.json file" : params.paths[0];
let folderStr: string = (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 1) ? "the " + this.Name : "this";
const message: string = `Would you like to use ${compileCommandStr} to auto-configure IntelliSense for ${folderStr} folder?`;
const yes: string = "Yes";
const notNow: string = "Not Now";
const dontAskAgain: string = "Don't Ask Again";
vscode.window.showInformationMessage(message, yes, notNow, dontAskAgain).then((value) => {
switch (value) {
case yes:
if (params.paths.length > 1) {
ui.showCompileCommands(params.paths).then((index) => {
if (index < 0) {
return;
}
this.configuration.setCompileCommands(params.paths[index]);
});
} else {
this.configuration.setCompileCommands(params.paths[0]);
}
break;
case notNow:
break;
case dontAskAgain:
showCompileCommandsSelection.Value = false;
break;
}
});
}
/*********************************************
* requests to the language server
*********************************************/
@@ -855,6 +891,13 @@ class DefaultClient implements Client {
this.notifyWhenReady(() => this.languageClient.sendNotification(ChangeCompileCommandsNotification, params));
}
public sendCustomConfigurations(configs: SourceFileConfigurationItem[]): void {
let params: CustomConfigurationParams = {
configurationItems: configs
};
this.notifyWhenReady(() => this.languageClient.sendNotification(CustomConfigurationNotification, params));
}
/*********************************************
* command handlers
*********************************************/
@@ -945,7 +988,13 @@ class NullClient implements Client {
TrackedDocuments = new Set<vscode.TextDocument>();
onDidChangeSettings(): void {}
onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void {}
onDidChangeCustomConfigurations(provider: CustomConfigurationProvider): void {}
takeOwnership(document: vscode.TextDocument): void {}
runBlockingTask<T>(task: Thenable<T>): Thenable<T> { return; }
runBlockingThenableWithTimeout(thenable: () => Thenable<any>, ms: number, tokenSource?: CancellationTokenSource): Thenable<any> { return; }
requestWhenReady(request: () => Thenable<any>): Thenable<any> { return; }
notifyWhenReady(notify: () => void): void {}
sendCustomConfigurations(configs: SourceFileConfigurationItem[]): void {}
requestGoToDeclaration(): Thenable<void> { return Promise.resolve(); }
requestSwitchHeaderSource(rootPath: string, fileName: string): Thenable<string> { return Promise.resolve(""); }
requestNavigationList(document: vscode.TextDocument): Thenable<string> { return Promise.resolve(""); }
+93 -73
View File
@@ -8,20 +8,22 @@ import * as path from 'path';
import * as fs from "fs";
import * as vscode from 'vscode';
import * as util from '../common';
import * as telemetry from '../telemetry';
import { PersistentFolderState } from './persistentState';
import { CppSettings } from './settings';
const configVersion: number = 3;
import { ABTestSettings, getABTestSettings } from '../abTesting';
const configVersion: number = 4;
// No properties are set in the config since we want to apply vscode settings first (if applicable).
// That code won't trigger if another value is already set.
// The property defaults are moved down to applyDefaultIncludePathsAndFrameworks.
function getDefaultConfig(): Configuration {
if (process.platform === 'darwin') {
return { name: "Mac", browse: {} };
return { name: "Mac" };
} else if (process.platform === 'win32') {
return { name: "Win32", browse: {} };
return { name: "Win32" };
} else {
return { name: "Linux", browse: {} };
return { name: "Linux" };
}
}
@@ -34,6 +36,7 @@ function getDefaultCppProperties(): ConfigurationJson {
interface ConfigurationJson {
configurations: Configuration[];
env?: {[key: string]: string | string[]};
version: number;
}
@@ -205,12 +208,11 @@ export class CppProperties {
if (!settings.defaultIncludePath) {
// We don't add system includes to the includePath anymore. The language server has this information.
configuration.includePath = ["${workspaceFolder}/**"].concat(this.vcpkgIncludes);
}
if (!settings.defaultBrowsePath) {
// We don't add system includes to the includePath anymore. The language server has this information.
configuration.browse.path = ["${workspaceFolder}"].concat(this.vcpkgIncludes);
let abTestSettings: ABTestSettings = getABTestSettings();
let rootFolder: string = abTestSettings.UseRecursiveIncludes ? "${workspaceFolder}/**" : "${workspaceFolder}";
configuration.includePath = [rootFolder].concat(this.vcpkgIncludes);
}
// browse.path is not set by default anymore. When it is not set, the includePath will be used instead.
if (!settings.defaultDefines) {
configuration.defines = (process.platform === 'win32') ? ["_DEBUG", "UNICODE", "_UNICODE"] : [];
}
@@ -265,17 +267,13 @@ export class CppProperties {
}
private getConfigIndexForPlatform(config: any): number {
if (this.configurationJson.configurations.length > 3) {
return this.configurationJson.configurations.length - 1; // Default to the last custom configuration.
}
let nodePlatform: NodeJS.Platform = process.platform;
let plat: string;
if (nodePlatform === 'linux') {
plat = "Linux";
} else if (nodePlatform === 'darwin') {
if (process.platform === 'darwin') {
plat = "Mac";
} else if (nodePlatform === 'win32') {
} else if (process.platform === 'win32') {
plat = "Win32";
} else {
plat = "Linux";
}
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
if (config.configurations[i].name === plat) {
@@ -291,27 +289,17 @@ export class CppProperties {
return "clang-x64";
} else if (name === "Win32") {
return "msvc-x64";
} else {
} else if (process.platform === 'win32') {
// Custom configs default to the OS's preference.
let nodePlatform: NodeJS.Platform = process.platform;
if (nodePlatform === 'linux' || nodePlatform === 'darwin') {
return "clang-x64";
}
return "msvc-x64";
} else {
return "clang-x64";
}
return "msvc-x64";
}
private includePathConverted(): boolean {
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
if (this.configurationJson.configurations[i].browse === undefined || this.configurationJson.configurations[i].browse.path === undefined) {
return false;
}
}
return true;
}
public addToIncludePathCommand(path: string): void {
this.handleConfigurationEditCommand((document: vscode.TextDocument) => {
telemetry.logLanguageServerEvent("addToIncludePath");
this.parsePropertiesFile(); // Clear out any modifications we may have made internally.
let config: Configuration = this.configurationJson.configurations[this.CurrentConfiguration];
if (config.includePath === undefined) {
@@ -323,6 +311,16 @@ export class CppProperties {
});
}
public setCompileCommands(path: string): void {
this.handleConfigurationEditCommand((document: vscode.TextDocument) => {
this.parsePropertiesFile(); // Clear out any modifications we may have made internally.
let config: Configuration = this.configurationJson.configurations[this.CurrentConfiguration];
config.compileCommands = path;
fs.writeFileSync(this.propertiesFile.fsPath, JSON.stringify(this.configurationJson, null, 4));
this.updateServerOnFolderSettingsChange();
});
}
public select(index: number): Configuration {
if (index === this.configurationJson.configurations.length) {
this.handleConfigurationEditCommand(vscode.window.showTextDocument);
@@ -336,7 +334,11 @@ export class CppProperties {
let result: string[] = [];
entries.forEach(entry => {
if (entry === "${default}") {
result = result.concat(defaultValue);
// package.json default values for string[] properties is null.
// If no default is set, return an empty array instead of an array with `null` in it.
if (defaultValue !== null) {
result = result.concat(defaultValue);
}
} else {
result.push(entry);
}
@@ -348,7 +350,7 @@ export class CppProperties {
let result: string[] = [];
if (paths) {
paths.forEach(entry => {
let entries: string[] = util.resolveVariables(entry).split(";").filter(e => e);
let entries: string[] = util.resolveVariables(entry, this.configurationJson.env).split(";").filter(e => e);
entries = this.resolveDefaults(entries, defaultValue);
result = result.concat(entries);
});
@@ -363,7 +365,7 @@ export class CppProperties {
if (typeof input === "boolean") {
return input;
}
return util.resolveVariables(input);
return util.resolveVariables(input, this.configurationJson.env);
}
private updateConfiguration(property: string[], defaultValue: string[]): string[];
@@ -402,7 +404,23 @@ export class CppProperties {
if (!configuration.browse) {
configuration.browse = {};
}
configuration.browse.path = this.updateConfiguration(configuration.browse.path, settings.defaultBrowsePath);
if (!configuration.browse.path) {
if (settings.defaultBrowsePath) {
configuration.browse.path = settings.defaultBrowsePath;
} else if (configuration.includePath) {
// If the user doesn't set browse.path, copy the includePath over. Make sure ${workspaceFolder} is in there though...
configuration.browse.path = configuration.includePath.slice(0);
if (-1 === configuration.includePath.findIndex((value: string, index: number) => {
return !!value.match(/^\$\{(workspaceRoot|workspaceFolder)\}(\\|\\\*\*|\/|\/\*\*)?$/g);
})) {
configuration.browse.path.push("${workspaceFolder}");
}
}
} else {
configuration.browse.path = this.updateConfiguration(configuration.browse.path, settings.defaultBrowsePath);
}
configuration.browse.limitSymbolsToIncludedHeaders = this.updateConfiguration(configuration.browse.limitSymbolsToIncludedHeaders, settings.defaultLimitSymbolsToIncludedHeaders);
configuration.browse.databaseFilename = this.updateConfiguration(configuration.browse.databaseFilename, settings.defaultDatabaseFilename);
}
@@ -451,7 +469,7 @@ export class CppProperties {
let filePath: vscode.Uri = vscode.Uri.parse("untitled:" + fullPathToFile);
vscode.workspace.openTextDocument(filePath).then((document: vscode.TextDocument) => {
let edit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit();
if (this.configurationJson === undefined) {
if (this.configurationJson) {
this.resetToDefaultSettings(true);
}
this.applyDefaultIncludePathsAndFrameworks();
@@ -524,35 +542,18 @@ export class CppProperties {
this.currentConfigurationIndex.Value = this.getConfigIndexForPlatform(newJson);
}
// Remove disallowed variable overrides
if (this.configurationJson.env) {
delete this.configurationJson.env['workspaceRoot'];
delete this.configurationJson.env['workspaceFolder'];
delete this.configurationJson.env['default'];
}
// Warning: There is a chance that this is incorrect in the event that the c_cpp_properties.json file was created before
// the system includes were available.
this.configurationIncomplete = false;
// Update intelliSenseMode, compilerPath, cStandard, and cppStandard with the defaults if they're missing.
// If VS Code settings exist for these properties, don't add them to c_cpp_properties.json
let dirty: boolean = false;
let settings: CppSettings = new CppSettings(this.rootUri);
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let config: Configuration = this.configurationJson.configurations[i];
if (config.intelliSenseMode === undefined && !settings.defaultIntelliSenseMode) {
dirty = true;
config.intelliSenseMode = this.getIntelliSenseModeForPlatform(config.name);
}
// Don't set the default if compileCommands exist, until it is fixed to have the correct value.
if (config.compilerPath === undefined && this.defaultCompilerPath && !config.compileCommands && !settings.defaultCompilerPath) {
config.compilerPath = this.defaultCompilerPath;
dirty = true;
}
if (!config.cStandard && this.defaultCStandard && !settings.defaultCStandard) {
config.cStandard = this.defaultCStandard;
dirty = true;
}
if (!config.cppStandard && this.defaultCppStandard && !settings.defaultCppStandard) {
config.cppStandard = this.defaultCppStandard;
dirty = true;
}
}
if (this.configurationJson.version !== configVersion) {
dirty = true;
if (this.configurationJson.version === undefined) {
@@ -561,6 +562,10 @@ export class CppProperties {
if (this.configurationJson.version === 2) {
this.updateToVersion3();
}
if (this.configurationJson.version === 3) {
this.updateToVersion4();
} else {
this.configurationJson.version = configVersion;
vscode.window.showErrorMessage('Unknown version number found in c_cpp_properties.json. Some features may not work as expected.');
@@ -583,17 +588,8 @@ export class CppProperties {
private updateToVersion2(): void {
this.configurationJson.version = 2;
if (!this.includePathConverted()) {
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let config: Configuration = this.configurationJson.configurations[i];
if (config.browse === undefined) {
config.browse = {};
}
if (config.browse.path === undefined && (this.defaultIncludes !== undefined || config.includePath !== undefined)) {
config.browse.path = (config.includePath === undefined) ? this.defaultIncludes.slice(0) : config.includePath.slice(0);
}
}
}
// no-op. We don't automatically populate the browse.path anymore.
// We use includePath if browse.path is not present which is what this code used to do.
}
private updateToVersion3(): void {
@@ -601,7 +597,7 @@ export class CppProperties {
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let config: Configuration = this.configurationJson.configurations[i];
// Look for Mac configs and extra configs on Mac systems
if (config.name === "Mac" || (process.platform === "darwin" && config.name !== "Win32" && config.name !== "Linux")) {
if (config.name === "Mac" || (process.platform === 'darwin' && config.name !== "Win32" && config.name !== "Linux")) {
if (config.macFrameworkPath === undefined) {
config.macFrameworkPath = [
"/System/Library/Frameworks",
@@ -612,6 +608,30 @@ export class CppProperties {
}
}
private updateToVersion4(): void {
this.configurationJson.version = 4;
// Update intelliSenseMode, compilerPath, cStandard, and cppStandard with the defaults if they're missing.
// If VS Code settings exist for these properties, don't add them to c_cpp_properties.json
let settings: CppSettings = new CppSettings(this.rootUri);
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let config: Configuration = this.configurationJson.configurations[i];
if (config.intelliSenseMode === undefined && !settings.defaultIntelliSenseMode) {
config.intelliSenseMode = this.getIntelliSenseModeForPlatform(config.name);
}
// Don't set the default if compileCommands exist, until it is fixed to have the correct value.
if (config.compilerPath === undefined && this.defaultCompilerPath && !config.compileCommands && !settings.defaultCompilerPath) {
config.compilerPath = this.defaultCompilerPath;
}
if (!config.cStandard && this.defaultCStandard && !settings.defaultCStandard) {
config.cStandard = this.defaultCStandard;
}
if (!config.cppStandard && this.defaultCppStandard && !settings.defaultCppStandard) {
config.cppStandard = this.defaultCppStandard;
}
}
}
public checkCppProperties(): void {
// Check for change properties in case of file watcher failure.
let propertiesFile: string = path.join(this.configFolder, "c_cpp_properties.json");
+48 -7
View File
@@ -6,6 +6,7 @@
import * as path from 'path';
import * as vscode from 'vscode';
import { CancellationTokenSource } from "vscode-jsonrpc";
import * as fs from 'fs';
import * as util from '../common';
import * as telemetry from '../telemetry';
@@ -15,6 +16,7 @@ import { ClientCollection } from './clientCollection';
import { CppSettings } from './settings';
import { PersistentWorkspaceState } from './persistentState';
import { getLanguageConfig } from './languageConfig';
import { CustomConfigurationProvider, SourceFileConfigurationItem } from '../api';
import * as os from 'os';
let prevCrashFile: string;
@@ -27,6 +29,7 @@ let intervalTimer: NodeJS.Timer;
let realActivationOccurred: boolean = false;
let tempCommands: vscode.Disposable[] = [];
let activatedPreviously: PersistentWorkspaceState<boolean>;
let customConfigurationProviders: CustomConfigurationProvider[] = [];
/**
* activate: set up the extension for language services
@@ -41,7 +44,7 @@ export function activate(activationEventOccurred: boolean): void {
activatedPreviously.Value = false;
realActivation();
}
registerCommands();
tempCommands.push(vscode.workspace.onDidOpenTextDocument(d => onDidOpenTextDocument(d)));
@@ -74,6 +77,40 @@ export function activate(activationEventOccurred: boolean): void {
}
}
export function registerCustomConfigurationProvider(provider: CustomConfigurationProvider): void {
customConfigurationProviders.push(provider);
// Request for configurations from the provider only if realActivationOccurred.
// Otherwise, the request will be sent when realActivation is called.
if (realActivationOccurred) {
onDidChangeCustomConfiguration(provider);
}
}
export async function provideCustomConfiguration(document: vscode.TextDocument, client: Client): Promise<void> {
let tokenSource: CancellationTokenSource = new CancellationTokenSource();
if (customConfigurationProviders.length === 0) {
return Promise.resolve();
}
return client.runBlockingThenableWithTimeout(async () => {
// Loop through registered providers until one is able to service the current document
for (let i: number = 0; i < customConfigurationProviders.length; i++) {
if (await customConfigurationProviders[i].canProvideConfiguration(document.uri)) {
return customConfigurationProviders[i].provideConfigurations([document.uri]);
}
}
return Promise.reject("No providers found for " + document.uri);
}, 1000, tokenSource).then((configs: SourceFileConfigurationItem[]) => {
if (configs && configs.length > 0) {
client.sendCustomConfigurations(configs);
}
});
}
export function onDidChangeCustomConfiguration(customConfigurationProvider: CustomConfigurationProvider): void {
clients.forEach((client: Client) => client.onDidChangeCustomConfigurations(customConfigurationProvider));
}
function onDidOpenTextDocument(document: vscode.TextDocument): void {
if (document.languageId === "c" || document.languageId === "cpp") {
onActivationEvent();
@@ -108,6 +145,10 @@ function realActivation(): void {
onDidChangeActiveTextEditor(vscode.window.activeTextEditor);
}
// There may have already been registered CustomConfigurationProviders.
// Request for configurations from those providers.
customConfigurationProviders.forEach(provider => onDidChangeCustomConfiguration(provider));
disposables.push(vscode.workspace.onDidChangeConfiguration(onDidChangeSettings));
disposables.push(vscode.workspace.onDidSaveTextDocument(onDidSaveTextDocument));
disposables.push(vscode.window.onDidChangeActiveTextEditor(onDidChangeActiveTextEditor));
@@ -172,7 +213,7 @@ function onDidChangeTextEditorSelection(event: vscode.TextEditorSelectionChangeE
if (!event.textEditor || !vscode.window.activeTextEditor || event.textEditor.document.uri !== vscode.window.activeTextEditor.document.uri ||
(event.textEditor.document.languageId !== "cpp" && event.textEditor.document.languageId !== "c")) {
return;
}
}
if (activeDocument !== event.textEditor.document.uri.toString()) {
// For some strange (buggy?) reason we don't reliably get onDidChangeActiveTextEditor callbacks.
@@ -304,7 +345,7 @@ function selectClient(): Thenable<Client> {
function onResetDatabase(): void {
onActivationEvent();
/* need to notify the affected client(s) */
selectClient().then(client => client.resetDatabase(), rejected => {});
selectClient().then(client => client.resetDatabase(), rejected => { });
}
function onSelectConfiguration(): void {
@@ -323,7 +364,7 @@ function onEditConfiguration(): void {
if (!isFolderOpen()) {
vscode.window.showInformationMessage('Open a folder first to edit configurations');
} else {
selectClient().then(client => client.handleConfigurationEditCommand(), rejected => {});
selectClient().then(client => client.handleConfigurationEditCommand(), rejected => { });
}
}
@@ -406,17 +447,17 @@ function onShowReleaseNotes(): void {
function onPauseParsing(): void {
onActivationEvent();
selectClient().then(client => client.pauseParsing(), rejected => {});
selectClient().then(client => client.pauseParsing(), rejected => { });
}
function onResumeParsing(): void {
onActivationEvent();
selectClient().then(client => client.resumeParsing(), rejected => {});
selectClient().then(client => client.resumeParsing(), rejected => { });
}
function onShowParsingCommands(): void {
onActivationEvent();
selectClient().then(client => client.handleShowParsingCommands(), rejected => {});
selectClient().then(client => client.handleShowParsingCommands(), rejected => { });
}
function onTakeSurvey(): void {
+14 -9
View File
@@ -7,30 +7,35 @@
import { Middleware } from 'vscode-languageclient';
import { ClientCollection } from './clientCollection';
import { Client } from './client';
import { provideCustomConfiguration } from './extension';
export function createProtocolFilter(me: Client, clients: ClientCollection): Middleware {
// Disabling lint for invoke handlers
/* tslint:disable */
let defaultHandler: (data: any, callback: (data: any) => void) => void = (data, callback: (data) => void) => { if (clients.ActiveClient === me) { callback(data); } };
let invoke1 = (a, callback: (a) => any) => { if (clients.ActiveClient === me) { return callback(a); } return null; };
let invoke2 = (a, b, callback: (a, b) => any) => { if (clients.ActiveClient === me) { return callback(a, b); } return null; };
let invoke3 = (a, b, c, callback: (a, b, c) => any) => { if (clients.ActiveClient === me) { return callback(a, b, c); } return null; };
let invoke4 = (a, b, c, d, callback: (a, b, c, d) => any) => { if (clients.ActiveClient === me) { return callback(a, b, c, d); } return null; };
let invoke5 = (a, b, c, d, e, callback: (a, b, c, d, e) => any) => { if (clients.ActiveClient === me) { return callback(a, b, c, d, e); } return null; };
let defaultHandler: (data: any, callback: (data: any) => void) => void = (data, callback: (data) => void) => { if (clients.ActiveClient === me) {me.notifyWhenReady(() => callback(data));}};
let invoke1 = (a, callback: (a) => any) => { if (clients.ActiveClient === me) { return me.requestWhenReady(() => callback(a)); } return null; };
let invoke2 = (a, b, callback: (a, b) => any) => { if (clients.ActiveClient === me) { return me.requestWhenReady(() => callback(a, b)); } return null; };
let invoke3 = (a, b, c, callback: (a, b, c) => any) => { if (clients.ActiveClient === me) { return me.requestWhenReady(() => callback(a, b, c)); } return null; };
let invoke4 = (a, b, c, d, callback: (a, b, c, d) => any) => { if (clients.ActiveClient === me) { return me.requestWhenReady(() => callback(a, b, c, d)); } return null; };
let invoke5 = (a, b, c, d, e, callback: (a, b, c, d, e) => any) => { if (clients.ActiveClient === me) { return me.requestWhenReady(() => callback(a, b, c, d, e)); } return null; };
/* tslint:enable */
return {
didOpen: (document, sendMessage) => {
if (clients.checkOwnership(me, document)) {
me.TrackedDocuments.add(document);
sendMessage(document);
provideCustomConfiguration(document, me).then(() => {
sendMessage(document);
}, () => {
sendMessage(document);
});
}
},
didChange: defaultHandler,
willSave: defaultHandler,
willSaveWaitUntil: (event, sendMessage) => {
if (clients.ActiveClient === me) {
return sendMessage(event);
return me.requestWhenReady(() => sendMessage(event));
}
return Promise.resolve([]);
},
@@ -39,7 +44,7 @@ export function createProtocolFilter(me: Client, clients: ClientCollection): Mid
if (clients.ActiveClient === me) {
console.assert(me.TrackedDocuments.has(document));
me.TrackedDocuments.delete(document);
sendMessage(document);
me.notifyWhenReady(() => sendMessage(document));
}
},
+1
View File
@@ -40,6 +40,7 @@ export class CppSettings extends Settings {
public get intelliSenseEngineFallback(): string { return super.Section.get<string>("intelliSenseEngineFallback"); }
public get errorSquiggles(): string { return super.Section.get<string>("errorSquiggles"); }
public get dimInactiveRegions(): boolean { return super.Section.get<boolean>("dimInactiveRegions"); }
public get inactiveRegionOpacity(): number { return super.Section.get<number>("inactiveRegionOpacity"); }
public get autoComplete(): string { return super.Section.get<string>("autocomplete"); }
public get loggingLevel(): string { return super.Section.get<string>("loggingLevel"); }
public get navigationLength(): number { return super.Section.get<number>("navigation.length", 60); }
@@ -0,0 +1,190 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
import * as vscode from 'vscode';
import * as util from '../common';
/**
* track settings changes for telemetry
*/
type FilterFunction = (key: string, val: string, settings: vscode.WorkspaceConfiguration) => boolean;
type KeyValuePair = { key: string; value: string };
const maxSettingLengthForTelemetry: number = 50;
let cache: SettingsTracker = undefined;
export class SettingsTracker {
private previousCppSettings: { [key: string]: any } = {};
private resource: vscode.Uri;
constructor(resource: vscode.Uri) {
this.resource = resource;
this.collectSettings(() => true);
}
public getUserModifiedSettings(): { [key: string]: string } {
let filter: FilterFunction = (key: string, val: string, settings: vscode.WorkspaceConfiguration) => {
return !this.areEqual(val, settings.inspect(key).defaultValue);
};
return this.collectSettings(filter);
}
public getChangedSettings(): { [key: string]: string } {
let filter: FilterFunction = (key: string, val: string) => {
return !(key in this.previousCppSettings) || !this.areEqual(val, this.previousCppSettings[key]);
};
return this.collectSettings(filter);
}
private collectSettings(filter: FilterFunction): { [key: string]: string } {
let settings: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp", this.resource);
let result: { [key: string]: string } = {};
for (let key in settings) {
let val: any = this.getSetting(settings, key);
if (val === undefined) {
continue;
}
if (val instanceof Object && !(val instanceof Array)) {
for (let subKey in val) {
let newKey: string = key + "." + subKey;
let subVal: any = this.getSetting(settings, newKey);
if (subVal === undefined) {
continue;
}
let entry: KeyValuePair = this.filterAndSanitize(newKey, subVal, settings, filter);
if (entry && entry.key && entry.value) {
result[entry.key] = entry.value;
}
}
continue;
}
let entry: KeyValuePair = this.filterAndSanitize(key, val, settings, filter);
if (entry && entry.key && entry.value) {
result[entry.key] = entry.value;
}
}
return result;
}
private getSetting(settings: vscode.WorkspaceConfiguration, key: string): any {
// Ignore methods and settings that don't exist
if (settings.inspect(key).defaultValue !== undefined) {
let val: any = settings.get(key);
if (val instanceof Object) {
return val; // It's a sub-section.
}
// Only return values that match the setting's type and enum (if applicable).
let curSetting: any = util.packageJson.contributes.configuration.properties["C_Cpp." + key];
if (curSetting) {
let type: string = this.typeMatch(val, curSetting["type"]);
if (type) {
if (type !== "string") {
return val;
}
let curEnum: any[] = curSetting["enum"];
if (curEnum && curEnum.indexOf(val) === -1) {
return "<invalid>";
}
return val;
}
}
}
return undefined;
}
private typeMatch(value: any, type?: string | string[]): string {
if (type) {
if (type instanceof Array) {
for (let i: number = 0; i < type.length; i++) {
let t: string = type[i];
if (t) {
if (typeof value === t) {
return t;
}
if (t === "array" && value instanceof Array) {
return t;
}
if (t === "null" && value === null) {
return t;
}
}
}
} else if (typeof type === "string" && typeof value === type) {
return type;
}
}
return undefined;
}
private filterAndSanitize(key: string, val: any, settings: vscode.WorkspaceConfiguration, filter: FilterFunction): KeyValuePair {
if (filter(key, val, settings)) {
let value: string;
this.previousCppSettings[key] = val;
switch (key) {
case "clang_format_style":
case "clang_format_fallbackStyle": {
let newKey: string = key + "2";
if (val) {
switch (String(val).toLowerCase()) {
case "visual studio":
case "llvm":
case "google":
case "chromium":
case "mozilla":
case "webkit":
case "file":
case "none": {
value = String(this.previousCppSettings[key]);
break;
}
default: {
value = "...";
break;
}
}
} else {
value = "null";
}
key = newKey;
break;
}
case "commentContinuationPatterns": {
value = this.areEqual(val, settings.inspect(key).defaultValue) ? "<default>" : "..."; // Track whether it's being used, but nothing specific about it.
break;
}
default: {
if (key === "clang_format_path" || key.startsWith("default.")) {
value = this.areEqual(val, settings.inspect(key).defaultValue) ? "<default>" : "..."; // Track whether it's being used, but nothing specific about it.
} else {
value = String(this.previousCppSettings[key]);
}
}
}
if (value && value.length > maxSettingLengthForTelemetry) {
value = value.substr(0, maxSettingLengthForTelemetry) + "...";
}
return {key: key, value: value};
}
}
private areEqual(value1: any, value2: any): boolean {
if (value1 instanceof Object && value2 instanceof Object) {
return JSON.stringify(value1) === JSON.stringify(value2);
}
return value1 === value2;
}
}
export function getTracker(resource: vscode.Uri): SettingsTracker {
if (!cache) {
cache = new SettingsTracker(resource);
}
return cache;
}
+18
View File
@@ -168,6 +168,24 @@ export class UI {
});
}
public showCompileCommands(paths: string[]): Thenable<number> {
let options: vscode.QuickPickOptions = {};
options.placeHolder = "Select a compile_commands.json...";
let items: IndexableQuickPickItem[] = [];
for (let i: number = 0; i < paths.length; i++) {
items.push({label: paths[i], description: "", index: i});
}
return vscode.window.showQuickPick(items, options)
.then(selection => {
if (!selection) {
return -1;
}
return selection.index;
});
}
public showWorkspaces(workspaceNames: { name: string; key: string }[]): Thenable<string> {
let options: vscode.QuickPickOptions = {};
options.placeHolder = "Select a Workspace...";
+119 -72
View File
@@ -9,88 +9,135 @@ import * as https from 'https';
import { ClientRequest } from 'http';
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as util from './common';
import * as util from './common';
import * as Telemetry from './telemetry';
import { PersistentState } from './LanguageServer/persistentState';
const userBucketMax: number = 100;
const userBucketString: string = "CPP.UserBucket";
const localConfigFile: string = "cpptools.json";
export function activate(context: vscode.ExtensionContext): void {
if (context.globalState.get<number>(userBucketString, -1) === -1) {
let bucket: number = Math.floor(Math.random() * userBucketMax) + 1; // Range is [1, userBucketMax].
context.globalState.update(userBucketString, bucket);
}
interface Settings {
defaultIntelliSenseEngine?: number;
recursiveIncludes?: number;
}
export class ABTestSettings {
private settings: Settings;
private intelliSenseEngineDefault: PersistentState<number>;
private recursiveIncludesDefault: PersistentState<number>;
private bucket: PersistentState<number>;
constructor() {
this.intelliSenseEngineDefault = new PersistentState<number>("ABTest.1", 100);
this.recursiveIncludesDefault = new PersistentState<number>("ABTest.2", 100);
this.settings = {
defaultIntelliSenseEngine: this.intelliSenseEngineDefault.Value,
recursiveIncludes: this.recursiveIncludesDefault.Value
};
this.bucket = new PersistentState<number>(userBucketString, -1);
if (this.bucket.Value === -1) {
this.bucket.Value = Math.floor(Math.random() * userBucketMax) + 1; // Range is [1, userBucketMax].
}
this.updateSettingsAsync().then(() => {
// Redownload cpptools.json after initialization so it's not blocked.
// It'll be used the next time the extension reloads.
this.downloadCpptoolsJsonPkgAsync();
});
setInterval(() => {
// Redownload occasionally to prevent an extra reload during long sessions.
downloadCpptoolsJsonPkg();
}, 30 * 60 * 1000); // 30 minutes.
}
setInterval(() => { this.downloadCpptoolsJsonPkgAsync(); }, 30 * 60 * 1000); // 30 minutes.
}
// NOTE: Code is copied from DownloadPackage in packageManager.ts, but with ~75% fewer lines.
function downloadCpptoolsJson(urlString): Promise<void> {
return new Promise<void>((resolve, reject) => {
let parsedUrl: url.Url = url.parse(urlString);
let request: ClientRequest = https.request({
host: parsedUrl.host,
path: parsedUrl.path,
agent: util.GetHttpsProxyAgent(),
rejectUnauthorized: vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true)
}, (response) => {
if (response.statusCode === 301 || response.statusCode === 302) {
let redirectUrl: string | string[];
if (typeof response.headers.location === "string") {
redirectUrl = response.headers.location;
} else {
redirectUrl = response.headers.location[0];
public get UseDefaultIntelliSenseEngine(): boolean {
return this.settings.defaultIntelliSenseEngine ? this.settings.defaultIntelliSenseEngine >= this.bucket.Value : true;
}
public get UseRecursiveIncludes(): boolean {
return this.settings.recursiveIncludes ? this.settings.recursiveIncludes >= this.bucket.Value : true;
}
private async updateSettingsAsync(): Promise<void> {
const cpptoolsJsonFile: string = util.getExtensionFilePath(localConfigFile);
try {
const exists: boolean = await util.checkFileExists(cpptoolsJsonFile);
if (exists) {
const fileContent: string = await util.readFileText(cpptoolsJsonFile);
let newSettings: Settings = <Settings>JSON.parse(fileContent);
if (newSettings.defaultIntelliSenseEngine) {
this.intelliSenseEngineDefault.Value = newSettings.defaultIntelliSenseEngine;
}
return resolve(downloadCpptoolsJson(redirectUrl)); // Redirect - download from new location
if (newSettings.recursiveIncludes) {
this.recursiveIncludesDefault.Value = newSettings.recursiveIncludes;
}
this.settings = {
defaultIntelliSenseEngine: this.intelliSenseEngineDefault.Value,
recursiveIncludes: this.recursiveIncludesDefault.Value
};
}
if (response.statusCode !== 200) {
return reject();
}
let downloadedBytes = 0; // tslint:disable-line
let cppToolsJsonFile: fs.WriteStream = fs.createWriteStream(util.getExtensionFilePath("cpptools.json"));
response.on('data', (data) => { downloadedBytes += data.length; });
response.on('end', () => { cppToolsJsonFile.close(); });
cppToolsJsonFile.on('close', () => { resolve(); });
response.on('error', (error) => { reject(); });
response.pipe(cppToolsJsonFile, { end: false });
});
request.on('error', (error) => { reject(); });
request.end();
});
}
export function downloadCpptoolsJsonPkg(): Promise<void> {
let hasError: boolean = false;
let telemetryProperties: { [key: string]: string } = {};
return downloadCpptoolsJson("https://go.microsoft.com/fwlink/?linkid=852750")
.catch((error) => {
// More specific error info is not likely to be helpful, and we get detailed download data from the initial install.
hasError = true;
})
.then(() => {
telemetryProperties['success'] = (!hasError).toString();
Telemetry.logDebuggerEvent("cpptoolsJsonDownload", telemetryProperties);
});
}
export function processCpptoolsJson(cpptoolsString: string): Promise<void> {
let cpptoolsObject: any = JSON.parse(cpptoolsString);
let intelliSenseEnginePercentage: number = cpptoolsObject.intelliSenseEngine_default_percentage;
let packageJson: any = util.getRawPackageJson();
if (!packageJson.extensionFolderPath.includes(".vscode-insiders")) {
let prevIntelliSenseEngineDefault: any = packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default;
if (util.extensionContext.globalState.get<number>(userBucketString, userBucketMax + 1) <= intelliSenseEnginePercentage) {
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Default";
} else {
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Tag Parser";
}
if (prevIntelliSenseEngineDefault !== packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default) {
return util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson));
} catch (error) {
// Ignore any cpptoolsJsonFile errors
}
}
}
// NOTE: Code is copied from DownloadPackage in packageManager.ts, but with ~75% fewer lines.
private downloadCpptoolsJsonAsync(urlString): Promise<void> {
return new Promise<void>((resolve, reject) => {
let parsedUrl: url.Url = url.parse(urlString);
let request: ClientRequest = https.request({
host: parsedUrl.host,
path: parsedUrl.path,
agent: util.getHttpsProxyAgent(),
rejectUnauthorized: vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true)
}, (response) => {
if (response.statusCode === 301 || response.statusCode === 302) {
let redirectUrl: string | string[];
if (typeof response.headers.location === "string") {
redirectUrl = response.headers.location;
} else {
redirectUrl = response.headers.location[0];
}
return resolve(this.downloadCpptoolsJsonAsync(redirectUrl)); // Redirect - download from new location
}
if (response.statusCode !== 200) {
return reject();
}
let downloadedBytes = 0; // tslint:disable-line
let cppToolsJsonFile: fs.WriteStream = fs.createWriteStream(util.getExtensionFilePath(localConfigFile));
response.on('data', (data) => { downloadedBytes += data.length; });
response.on('end', () => { cppToolsJsonFile.close(); });
cppToolsJsonFile.on('close', () => { resolve(); this.updateSettingsAsync(); });
response.on('error', (error) => { reject(); });
response.pipe(cppToolsJsonFile, { end: false });
});
request.on('error', (error) => { reject(); });
request.end();
});
}
private downloadCpptoolsJsonPkgAsync(): Promise<void> {
let hasError: boolean = false;
let telemetryProperties: { [key: string]: string } = {};
return this.downloadCpptoolsJsonAsync("https://go.microsoft.com/fwlink/?linkid=852750")
.catch((error) => {
// More specific error info is not likely to be helpful, and we get detailed download data from the initial install.
hasError = true;
})
.then(() => {
telemetryProperties['success'] = (!hasError).toString();
Telemetry.logDebuggerEvent("cpptoolsJsonDownload", telemetryProperties);
});
}
}
let settings: ABTestSettings;
export function getABTestSettings(): ABTestSettings {
if (!settings) {
settings = new ABTestSettings();
}
return settings;
}
+112
View File
@@ -0,0 +1,112 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
import * as vscode from 'vscode';
import { CancellationToken } from 'vscode-jsonrpc';
/**
* An interface to allow Custom Configuration Provider extensions to communicate with this extension.
*/
export interface CppToolsApi {
/**
* Register the Custom Configuration Provider.
* This must be called as soon as the provider extension is ready. This is necessary for cpptools
* to request configurations from the provider.
* @param provider An instance of the [CustomConfigurationProvider](#CustomConfigurationProvider)
* instance representing the provider extension.
*/
registerCustomConfigurationProvider(provider: CustomConfigurationProvider): void;
/**
* Notifies cpptools that the current configuration has changed. Upon receiving this notification,
* cpptools will request the new configurations.
* @param provider An instance of the [CustomConfigurationProvider](#CustomConfigurationProvider)
* instance representing the provider extension.
*/
didChangeCustomConfiguration(provider: CustomConfigurationProvider): void;
}
/**
* An interface to allow this extension to communicate with Custom Configuration Provider extensions.
*/
export interface CustomConfigurationProvider {
/**
* The name of the Custom Configuration Provider extension.
*/
name: string;
/**
* A request to determine whether this provider can provide IntelliSense configurations for the given document.
* @param uri The URI of the document.
* @param token (optional) The cancellation token.
* @returns 'true' if this provider can provide IntelliSense configurations for the given document.
*/
canProvideConfiguration(uri: vscode.Uri, token?: CancellationToken): Thenable<boolean>;
/**
* A request to get Intellisense configurations for the given files.
* @param uris A list of one of more URIs for the files to provide configurations for.
* @param token (optional) The cancellation token.
* @returns A list of [SourceFileConfigurationItem](#SourceFileConfigurationItem) for the documents that this provider
* is able to provide IntelliSense configurations for.
* Note: If this provider cannot provide configurations for a file in `uris`, then the file will not be included
* in the return value. An empty list will be returned if the provider cannot provide configurations for any of the files.
*/
provideConfigurations(uris: vscode.Uri[], token?: CancellationToken): Thenable<SourceFileConfigurationItem[]>;
}
/**
* The model representing the custom IntelliSense configurations for a source file.
*/
export interface SourceFileConfiguration {
/**
* This must also include the system include path (compiler defaults) unless
* [compilerPath](#SourceFileConfiguration.compilerPath) is specified.
*/
includePath: string[];
/**
* This must also include the compiler default defines (__cplusplus, etc) unless
* [compilerPath](#SourceFileConfiguration.compilerPath) is specified.
*/
defines: string[];
/**
* Currently, "msvc-x64" or "clang-x64".
*/
intelliSenseMode: string;
/**
* The C or C++ standard. See `package.json` for valid values.
*/
standard: string;
/**
* Any files that need to be included before the source file is parsed.
*/
forcedInclude?: string[];
/**
* The full path to the compiler. If specified, the extension will query it for default includes and defines and
* add them to [includePath](#SourceFileConfiguration.includePath) and [defines](#SourceFileConfiguration.defines).
*/
compilerPath?: string;
}
/**
* A model representing a source file and its corresponding configuration.
*/
export interface SourceFileConfigurationItem {
/**
* The URI of the source file.
*/
uri: string;
/**
* The IntelliSense configuration for [uri](#SourceFileConfigurationItem.uri)
*/
configuration: SourceFileConfiguration;
}
+35 -9
View File
@@ -143,13 +143,16 @@ export function showReleaseNotes(): void {
vscode.commands.executeCommand('vscode.previewHtml', vscode.Uri.file(getExtensionFilePath("ReleaseNotes.html")), vscode.ViewColumn.One, "C/C++ Extension Release Notes");
}
export function resolveVariables(input: string): string {
export function resolveVariables(input: string, additionalEnvironment: {[key: string]: string | string[]}): string {
if (!input) {
return "";
}
if (!additionalEnvironment) {
additionalEnvironment = {};
}
// Replace environment and configuration variables.
let regexp: RegExp = /\$\{((env|config)(.|:))?(.*?)\}/g;
let regexp: RegExp = /\$\{((env|config|workspaceFolder)(.|:))?(.*?)\}/g;
let ret: string = input.replace(regexp, (match: string, ignored1: string, varType: string, ignored2: string, name: string) => {
// Historically, if the variable didn't have anything before the "." or ":"
// it was assumed to be an environment variable
@@ -158,12 +161,35 @@ export function resolveVariables(input: string): string {
}
let newValue: string = undefined;
switch (varType) {
case "env": { newValue = process.env[name]; break; }
case "env": {
let v: string | string[] = additionalEnvironment[name];
if (typeof v === "string") {
newValue = v;
} else if (input === match && v instanceof Array) {
newValue = v.join(";");
}
if (!newValue) {
newValue = process.env[name];
}
break;
}
case "config": {
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
let keys: string[] = name.split('.');
keys.forEach((key: string) => { config = (config) ? config.get(key) : config; });
newValue = (config) ? config.toString() : undefined;
if (config) {
newValue = config.get<string>(name);
}
break;
}
case "workspaceFolder": {
// Only replace ${workspaceFolder:name} variables for now.
// We may consider doing replacement of ${workspaceFolder} here later, but we would have to update the language server and also
// intercept messages with paths in them and add the ${workspaceFolder} variable back in (e.g. for light bulb suggestions)
if (name && vscode.workspace && vscode.workspace.workspaceFolders) {
let folder: vscode.WorkspaceFolder = vscode.workspace.workspaceFolders.find(folder => folder.name.toLocaleLowerCase() === name.toLocaleLowerCase());
if (folder) {
newValue = folder.uri.fsPath;
}
}
break;
}
default: { assert.fail("unknown varType matched"); }
@@ -206,7 +232,7 @@ export function getDebugAdaptersPath(file: string): string {
return path.resolve(getExtensionFilePath("debugAdapters"), file);
}
export function GetHttpsProxyAgent(): HttpsProxyAgent {
export function getHttpsProxyAgent(): HttpsProxyAgent {
let proxy: string = vscode.workspace.getConfiguration().get<string>('http.proxy');
if (!proxy) {
proxy = process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy;
@@ -336,7 +362,7 @@ export function getInstallLockPath(): string {
export function getReadmeMessage(): string {
const readmePath: string = getExtensionFilePath("README.md");
const readmeMessage: string = `Please refer to ${readmePath} for troubleshooting information. Issues can be created at https://github.com/Microsoft/vscppsamples/issues`;
const readmeMessage: string = `Please refer to ${readmePath} for troubleshooting information. Issues can be created at https://github.com/Microsoft/vscode-cpptools/issues`;
return readmeMessage;
}
@@ -476,4 +502,4 @@ export async function renamePromise(oldName: string, newName: string): Promise<v
return resolve();
});
});
}
}
+18
View File
@@ -0,0 +1,18 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
import { CppToolsApi, CustomConfigurationProvider } from './api';
import * as LanguageServer from './LanguageServer/extension';
export class CppTools implements CppToolsApi {
registerCustomConfigurationProvider(provider: CustomConfigurationProvider): void {
LanguageServer.registerCustomConfigurationProvider(provider);
}
didChangeCustomConfiguration(provider: CustomConfigurationProvider): void {
LanguageServer.onDidChangeCustomConfiguration(provider);
}
}
+23 -18
View File
@@ -19,21 +19,25 @@ import { PackageManager, PackageManagerError, PackageManagerWebResponseError, IP
import { PersistentState } from './LanguageServer/persistentState';
import { initializeInstallationInformation, getInstallationInformationInstance, InstallationInformation, setInstallationStage } from './installationInformation';
import { Logger, getOutputChannelLogger, showOutputChannel } from './logger';
import { CppTools } from './cppTools';
import { CppToolsApi } from './api';
const releaseNotesVersion: number = 3;
const cppTools: CppTools = new CppTools();
export function activate(context: vscode.ExtensionContext): void | Promise<void> {
export async function activate(context: vscode.ExtensionContext): Promise<CppToolsApi> {
initializeTemporaryCommandRegistrar();
util.setExtensionContext(context);
Telemetry.activate();
util.setProgress(0);
cpptoolsJsonUtils.activate(context);
initializeInstallationInformation();
// Initialize the DebuggerExtension and register the related commands and providers.
DebuggerExtension.initialize();
return processRuntimeDependencies();
await processRuntimeDependencies();
return cppTools;
}
export function deactivate(): Thenable<void> {
@@ -270,23 +274,24 @@ async function postInstall(info: PlatformInformation): Promise<void> {
}
async function finalizeExtensionActivation(): Promise<void> {
const cpptoolsJsonFile: string = util.getExtensionFilePath("cpptools.json");
try {
const exists: boolean = await util.checkFileExists(cpptoolsJsonFile);
if (exists) {
const cpptoolsString: string = await util.readFileText(cpptoolsJsonFile);
await cpptoolsJsonUtils.processCpptoolsJson(cpptoolsString);
}
} catch (error) {
// Ignore any cpptoolsJsonFile errors
}
getTemporaryCommandRegistrarInstance().activateLanguageServer();
// Redownload cpptools.json after activation so it's not blocked.
// It'll be used after the extension reloads.
cpptoolsJsonUtils.downloadCpptoolsJsonPkg();
// Update default for C_Cpp.intelliSenseEngine based on A/B testing settings.
// (this may result in rewriting the package.json file)
let abTestSettings: cpptoolsJsonUtils.ABTestSettings = cpptoolsJsonUtils.getABTestSettings();
let packageJson: any = util.getRawPackageJson();
if (util.packageJson.extensionLocation && !util.packageJson.extensionLocation.path.includes(".vscode-insiders")) {
let prevIntelliSenseEngineDefault: any = packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default;
if (abTestSettings.UseDefaultIntelliSenseEngine) {
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Default";
} else {
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Tag Parser";
}
if (prevIntelliSenseEngineDefault !== packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default) {
return util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson));
}
}
}
function rewriteManifest(): Promise<void> {
+1 -1
View File
@@ -223,7 +223,7 @@ export class PackageManager {
let options: https.RequestOptions = {
host: parsedUrl.host,
path: parsedUrl.path,
agent: util.GetHttpsProxyAgent(),
agent: util.getHttpsProxyAgent(),
rejectUnauthorized: proxyStrictSSL
};
+125
View File
@@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as fs from 'fs';
import * as os from 'os';
function appendFieldsToObject(reference: any, obj: any): any {
// Make sure it is an object type
if (typeof obj === 'object') {
for (let referenceKey in reference) {
// If key exists in original object and is an object.
if (obj.hasOwnProperty(referenceKey)) {
obj[referenceKey] = appendFieldsToObject(reference[referenceKey], obj[referenceKey]);
} else {
// Does not exist in current object context
obj[referenceKey] = reference[referenceKey];
}
}
}
return obj;
}
// Combines two object's fields, giving the parentDefault a higher precedence.
function mergeDefaults(parentDefault: any, childDefault: any): any {
let newDefault: any = {};
for (let attrname in childDefault) {
newDefault[attrname] = childDefault[attrname];
}
for (let attrname in parentDefault) {
newDefault[attrname] = parentDefault[attrname];
}
return newDefault;
}
function updateDefaults(object: any, defaults: any): any {
if (defaults !== null) {
for (let key in object) {
if (object[key].hasOwnProperty('type') && object[key].type === 'object' && object[key].properties !== null) {
object[key].properties = updateDefaults(object[key].properties, mergeDefaults(defaults, object[key].default));
} else if (key in defaults) {
object[key].default = defaults[key];
}
}
}
return object;
}
function refReplace(definitions: any, ref: any): any {
// $ref is formatted as "#/definitions/ObjectName"
let referenceStringArray: string[] = ref['$ref'].split('/');
// Getting "ObjectName"
let referenceName: string = referenceStringArray[referenceStringArray.length - 1];
// Make sure reference has replaced its own $ref fields and hope there are no recursive references.
definitions[referenceName] = replaceReferences(definitions, definitions[referenceName]);
// Retrieve ObjectName from definitions. (TODO: Does not retrieve inner objects)
// Need to deep copy, there are no functions in these objects.
let reference: any = JSON.parse(JSON.stringify(definitions[referenceName]));
ref = appendFieldsToObject(reference, ref);
// Remove $ref field
delete ref['$ref'];
return ref;
}
function replaceReferences(definitions: any, objects: any): any {
for (let key in objects) {
if (objects[key].hasOwnProperty('$ref')) {
objects[key] = refReplace(definitions, objects[key]);
}
// Recursively replace references if this object has properties.
if (objects[key].hasOwnProperty('type') && objects[key].type === 'object' && objects[key].properties !== null) {
objects[key].properties = replaceReferences(definitions, objects[key].properties);
objects[key].properties = updateDefaults(objects[key].properties, objects[key].default);
}
// Recursively replace references if the array has objects in items.
if (objects[key].hasOwnProperty('type') && objects[key].type === "array" && objects[key].items !== null && objects[key].items.hasOwnProperty('$ref')) {
objects[key].items = refReplace(definitions, objects[key].items);
}
}
return objects;
}
export function generateOptionsSchema(): void {
let packageJSON: any = JSON.parse(fs.readFileSync('package.json').toString());
let schemaJSON: any = JSON.parse(fs.readFileSync('tools/OptionsSchema.json').toString());
schemaJSON.definitions = replaceReferences(schemaJSON.definitions, schemaJSON.definitions);
// Hard Code adding in configurationAttributes launch and attach.
// cppdbg
packageJSON.contributes.debuggers[0].configurationAttributes.launch = schemaJSON.definitions.CppdbgLaunchOptions;
packageJSON.contributes.debuggers[0].configurationAttributes.attach = schemaJSON.definitions.CppdbgAttachOptions;
// cppvsdbg
packageJSON.contributes.debuggers[1].configurationAttributes.launch = schemaJSON.definitions.CppvsdbgLaunchOptions;
packageJSON.contributes.debuggers[1].configurationAttributes.attach = schemaJSON.definitions.CppvsdbgAttachOptions;
let content: string = JSON.stringify(packageJSON, null, 2);
if (os.platform() === 'win32') {
content = content.replace(/\n/gm, "\r\n");
}
// We use '\u200b' (unicode zero-length space character) to break VS Code's URL detection regex for URLs that are examples. This process will
// convert that from the readable espace sequence, to just an invisible character. Convert it back to the visible espace sequence.
content = content.replace(/\u200b/gm, "\\u200b");
fs.writeFileSync('package.json', content);
}
generateOptionsSchema();
+557
View File
@@ -0,0 +1,557 @@
{
"_comment": "See README.md for information about this file",
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "VS Code launch/attach options",
"description": "A json schema for the VS Code attach and launch options",
"type": "object",
"definitions": {
"PipeTransport": {
"type": "object",
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).",
"default": {
"pipeCwd": "/usr/bin",
"pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'",
"pipeArgs": [],
"debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
},
"properties": {
"pipeCwd": {
"type": "string",
"description": "The fully qualified path to the working directory for the pipe program.",
"default": "/usr/bin"
},
"pipeProgram": {
"type": "string",
"description": "The fully qualified pipe command to execute.",
"default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'"
},
"pipeArgs": {
"type": "array",
"description": "Command line arguments passed to the pipe program to configure the connection.",
"items": {
"type": "string"
},
"default": []
},
"debuggerPath": {
"type": "string",
"description": "The full path to the debugger on the target machine, for example /usr/bin/gdb.",
"default": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
},
"pipeEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Environment variables passed to the pipe program.",
"default": {}
}
}
},
"Logging": {
"type": "object",
"default": {},
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"properties": {
"exceptions": {
"type": "boolean",
"description": "Optional flag to determine whether exception messages should be logged to the Debug Console. Defaults to true.",
"default": true
},
"moduleLoad": {
"type": "boolean",
"description": "Optional flag to determine whether module load events should be logged to the Debug Console. Defaults to true.",
"default": true
},
"programOutput": {
"type": "boolean",
"description": "Optional flag to determine whether program output should be logged to the Debug Console. Defaults to true.",
"default": true
},
"engineLogging": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic engine logs should be logged to the Debug Console. Defaults to false.",
"default": false
},
"trace": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic adapter command tracing should be logged to the Debug Console. Defaults to false.",
"default": false
},
"traceResponse": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic adapter command and response tracing should be logged to the Debug Console. Defaults to false.",
"default": false
}
}
},
"SetupCommandsConfiguration": {
"type": "object",
"default": {},
"properties": {
"text": {
"type": "string",
"description": "The debugger command to execute.",
"default": ""
},
"description": {
"type": "string",
"description": "Optional description for the command.",
"default": ""
},
"ignoreFailures": {
"type": "boolean",
"description": "If true, failures from the command should be ignored. Default value is false.",
"default": false
}
}
},
"KeyValuePair": {
"type": "object",
"default": {},
"properties": {
"name": "string",
"value": "string"
}
},
"CppdbgLaunchOptions": {
"type": "object",
"default": {},
"required": [
"program"
],
"properties": {
"program": {
"type": "string",
"description": "Full path to program executable.",
"default": "${workspaceRoot}/a.out"
},
"args": {
"type": "array",
"description": "Command line arguments passed to the program.",
"items": {
"type": "string"
},
"default": []
},
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppdbg\".",
"default": "cppdbg"
},
"targetArchitecture": {
"type": "string",
"description": "The architecture of the debuggee. This will automatically be detected unless this parameter is set. Allowed values are x86, arm, arm64, mips, x64, amd64, x86_64.",
"default": "x64"
},
"cwd": {
"type": "string",
"description": "The working directory of the target",
"default": "."
},
"setupCommands": {
"type": "array",
"description": "One or more GDB/LLDB commands to execute in order to setup the underlying debugger. Example: \"setupCommands\": [ { \"text\": \"-enable-pretty-printing\", \"description\": \"Enable GDB pretty printing\", \"ignoreFailures\": true }].",
"items": {
"$ref": "#/definitions/SetupCommandsConfiguration"
},
"default": []
},
"customLaunchSetupCommands": {
"type": "array",
"description": "If provided, this replaces the default commands used to launch a target with some other commands. For example, this can be \"-target-attach\" in order to attach to a target process. An empty command list replaces the launch commands with nothing, which can be useful if the debugger is being provided launch options as command line options. Example: \"customLaunchSetupCommands\": [ { \"text\": \"target-run\", \"description\": \"run target\", \"ignoreFailures\": false }].",
"items": {
"$ref": "#/definitions/SetupCommandsConfiguration"
},
"default": []
},
"launchCompleteCommand": {
"enum": [
"exec-run",
"exec-continue",
"None"
],
"description": "The command to execute after the debugger is fully setup in order to cause the target process to run. Allowed values are \"exec-run\", \"exec-continue\", \"None\". The default value is \"exec-run\".",
"default": "exec-run"
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process. This option is not compatible with GDB pretty printing. Please also see \"showDisplayString\" if using this setting.",
"default": ""
},
"showDisplayString": {
"type": "boolean",
"description": "When a visualizerFile is specified, showDisplayString will enable the display string. Turning this option on can cause slower performance during debugging.",
"default": true
},
"environment": {
"type": "array",
"description": "Environment variables to add to the environment for the program. Example: [ { \"name\": \"squid\", \"value\": \"clam\" } ].",
"items": {
"$ref": "#/definitions/KeyValuePair"
},
"default": []
},
"additionalSOLibSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for .so files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"MIMode": {
"type": "string",
"description": "Indicates the console debugger that the MIDebugEngine will connect to. Allowed values are \"gdb\" \"lldb\".",
"default": "gdb"
},
"miDebuggerPath": {
"type": "string",
"description": "The path to the mi debugger (such as gdb). When unspecified, it will search path first for the debugger.",
"default": "/usr/bin/gdb"
},
"miDebuggerArgs": {
"type": "string",
"description": "Arguments for the mi debugger (such as gdb) to use. When unspecified.",
"default": ""
},
"miDebuggerServerAddress": {
"type": "string",
"description": "Network address of the MI Debugger Server to connect to (example: localhost:1234).",
"default": "serveraddress:port"
},
"stopAtEntry": {
"type": "boolean",
"description": "Optional parameter. If true, the debugger should stop at the entrypoint of the target. If processId is passed, has no effect.",
"default": false
},
"debugServerPath": {
"type": "string",
"description": "Optional full path to debug server to launch. Defaults to null.",
"default": ""
},
"debugServerArgs": {
"type": "string",
"description": "Optional debug server args. Defaults to null.",
"default": ""
},
"serverStarted": {
"type": "string",
"description": "Optional server-started pattern to look for in the debug server output. Defaults to null.",
"default": ""
},
"filterStdout": {
"type": "boolean",
"description": "Search stdout stream for server-started pattern and log stdout to debug output. Defaults to true.",
"default": true
},
"filterStderr": {
"type": "boolean",
"description": "Search stderr stream for server-started pattern and log stderr to debug output. Defaults to false.",
"default": false
},
"serverLaunchTimeout": {
"type": "integer",
"description": "Optional time, in milliseconds, for the debugger to wait for the debugServer to start up. Default is 10000.",
"default": "10000"
},
"coreDumpPath": {
"type": "string",
"description": "Optional full path to a core dump file for the specified program. Defaults to null.",
"default": ""
},
"externalConsole": {
"type": "boolean",
"description": "If true, a console is launched for the debuggee. If false, no console is launched. Note this option is ignored in some cases for technical reasons.",
"default": false
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"$ref": "#/definitions/Logging",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console."
},
"pipeTransport": {
"$ref": "#/definitions/PipeTransport",
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb)."
}
}
},
"CppdbgAttachOptions": {
"type": "object",
"default": {},
"required": [
"program",
"processId"
],
"properties": {
"program": {
"type": "string",
"description": "Full path to program executable.",
"default": "${workspaceRoot}/a.out"
},
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppdbg\".",
"default": "cppdbg"
},
"targetArchitecture": {
"type": "string",
"description": "The architecture of the debuggee. This will automatically be detected unless this parameter is set. Allowed values are x86, arm, arm64, mips, x64, amd64, x86_64.",
"default": "x64"
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process. This option is not compatible with GDB pretty printing. Please also see \"showDisplayString\" if using this setting.",
"default": ""
},
"showDisplayString": {
"type": "boolean",
"description": "When a visualizerFile is specified, showDisplayString will enable the display string. Turning this option on can cause slower performance during debugging.",
"default": true
},
"additionalSOLibSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for .so files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"MIMode": {
"type": "string",
"description": "Indicates the console debugger that the MIDebugEngine will connect to. Allowed values are \"gdb\" \"lldb\".",
"default": "gdb"
},
"miDebuggerPath": {
"type": "string",
"description": "The path to the mi debugger (such as gdb). When unspecified, it will search path first for the debugger.",
"default": "/usr/bin/gdb"
},
"miDebuggerServerAddress": {
"type": "string",
"description": "Network address of the MI Debugger Server to connect to (example: localhost:1234).",
"default": "serveraddress:port"
},
"processId": {
"anyOf": [
{
"type": "string",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": "${command:pickProcess}"
},
{
"type": "integer",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": 0
}
]
},
"filterStdout": {
"type": "boolean",
"description": "Search stdout stream for server-started pattern and log stdout to debug output. Defaults to true.",
"default": true
},
"filterStderr": {
"type": "boolean",
"description": "Search stderr stream for server-started pattern and log stderr to debug output. Defaults to false.",
"default": false
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"$ref": "#/definitions/Logging",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console."
},
"pipeTransport": {
"$ref": "#/definitions/PipeTransport",
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb)."
},
"setupCommands": {
"type": "array",
"description": "One or more GDB/LLDB commands to execute in order to setup the underlying debugger. Example: \"setupCommands\": [ { \"text\": \"-enable-pretty-printing\", \"description\": \"Enable GDB pretty printing\", \"ignoreFailures\": true }].",
"items": {
"$ref": "#/definitions/SetupCommandsConfiguration"
},
"default": []
}
}
},
"CppvsdbgLaunchOptions": {
"type": "object",
"default": {},
"required": [
"program",
"cwd"
],
"properties": {
"program": {
"type": "string",
"description": "Full path to program executable.",
"default": "${workspaceRoot}/program.exe"
},
"args": {
"type": "array",
"description": "Command line arguments passed to the program.",
"items": {
"type": "string"
},
"default": []
},
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppvsdbg\".",
"default": "cppvsdbg"
},
"cwd": {
"type": "string",
"description": "The working directory of the target.",
"default": "${workspaceRoot}"
},
"environment": {
"type": "array",
"description": "Environment variables to add to the environment for the program. Example: [ { \"name\": \"squid\", \"value\": \"clam\" } ].",
"items": {
"$ref": "#/definitions/KeyValuePair"
},
"default": []
},
"symbolSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for symbol (that is, pdb) files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"stopAtEntry": {
"type": "boolean",
"description": "Optional parameter. If true, the debugger should stop at the entrypoint of the target. If processId is passed, has no effect.",
"default": false
},
"dumpPath": {
"type": "string",
"description": "Optional full path to a dump file for the specified program. Example: \"c:\\temp\\app.dmp\". Defaults to null.",
"default": ""
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process.",
"default": ""
},
"externalConsole": {
"type": "boolean",
"description": "If true, a console is launched for the debuggee. If false, no console is launched.",
"default": false
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"default": {},
"properties": {
"exceptions": {
"type": "boolean",
"description": "Optional flag to determine whether exception messages should be logged to the Debug Console. Defaults to true.",
"default": true
},
"moduleLoad": {
"type": "boolean",
"description": "Optional flag to determine whether module load events should be logged to the Debug Console. Defaults to true.",
"default": true
},
"programOutput": {
"type": "boolean",
"description": "Optional flag to determine whether program output should be logged to the Debug Console. Defaults to true.",
"default": true
},
"engineLogging": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic debug engine messages should be logged to the Debug Console. Defaults to false.",
"default": false
}
}
}
}
},
"CppvsdbgAttachOptions": {
"type": "object",
"default": {},
"required": [
"processId"
],
"properties": {
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppvsdbg\".",
"default": "cppvsdbg"
},
"symbolSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for symbol (that is, pdb) files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"processId": {
"anyOf": [
{
"type": "string",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": "${command:pickProcess}"
},
{
"type": "integer",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": 0
}
]
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process.",
"default": ""
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"default": {},
"properties": {
"exceptions": {
"type": "boolean",
"description": "Optional flag to determine whether exception messages should be logged to the Debug Console. Defaults to true.",
"default": true
},
"moduleLoad": {
"type": "boolean",
"description": "Optional flag to determine whether module load events should be logged to the Debug Console. Defaults to true.",
"default": true
},
"programOutput": {
"type": "boolean",
"description": "Optional flag to determine whether program output should be logged to the Debug Console. Defaults to true.",
"default": true
},
"trace": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic adapter command tracing should be logged to the Debug Console. Defaults to false.",
"default": false
}
}
}
}
}
}
}
+14
View File
@@ -0,0 +1,14 @@
# OptionsSchema
OptionsSchema.json defines the type for Launch/Attach options.
# GenerateOptionsSchema
If there are any modifications to the OptionsSchema.json file. Please run `npm run generateOptionsSchema` at the repo root.
This will call GenerateOptionsSchema and update the package.json file.
### Important notes:
1. Any manual changes to package.json's object.contributes.debuggers[0].configurationAttributes (cppdbg) or object.contributes.debuggers[0].configurationAttributes (cppvsdbg) will be
replaced by this generator.
If there is any other type of options added in the future, you will need to modify the GenerateOptionsSchema function
to have it appear in package.json. It only adds launch and attach.
+10 -1
View File
@@ -1,6 +1,11 @@
{
"rules": {
"curly": true,
"ext-variable-name": [
true,
["class", "pascal"],
["function", "camel"]
],
"file-header": [true, ".*"],
"indent": [true, "spaces", 4],
"new-parens": true,
@@ -18,5 +23,9 @@
"typedef": [true, "variable-declaration", "call-signature"],
"whitespace": [true, "check-branch", "check-operator", "check-separator", "check-preblock", "check-type"]
},
"rulesDirectory": ["node_modules/tslint-microsoft-contrib", "node_modules/tslint-no-unused-expression-chai/rules"]
"rulesDirectory": [
"node_modules/tslint-microsoft-contrib",
"node_modules/tslint-no-unused-expression-chai/rules",
"node_modules/vrsource-tslint-rules/rules"
]
}
-24
View File
@@ -1,24 +0,0 @@
<!--
If this is a performance issue report, please use the VS Code Issue reporter via command palette (f1 -> Help: Report Issue).
Set the field 'This is a' to be 'Performance Issue', the field 'File on' to be 'An Extension', and set 'Extension' to be 'C/C++'.
You may toggle off the data you wish to not send, but with more information we can help.
Fill out the title and steps to reproduce with as much info as you can.
Clicking on 'Preview on GitHub' will open up a webpage for you to submit your issue.
If this is a bug report, please give us as much information as possible so we can reproduce your issue.
Examples of information that can help us find and fix bugs:
* Operating System and version
* VS Code version and if you are using the Insiders build
* C/C++ extension version
* Other extensions you installed and if the issue persists after disabling them
* step-by-step instructions to reproduce the issue
* A small code sample, zipped up project, or open source repo we can use to verify the bug
* Relevant settings from your settings.json, c_cpp_properties.json, and/or launch.json files
* Any log messages present in the Output window (use "C_Cpp.loggingLevel": "Information" in settings.json)
* Debugger logs (use "logging": { "engineLogging": true } in your launch.json)
Please also take a look at our documentation, as we may already have answers for your questions:
* https://github.com/Microsoft/vscode-cpptools/tree/master/Documentation
Thank you!
-->
+1 -1
View File
@@ -16,7 +16,7 @@ You can learn how to use the extension at [VS Code for C/C++](https://code.visua
If you clone this repository, you can also try out our [Code Samples](Code%20Samples).
If you have any questions, check out our our [**Documentation**](Documentation) folder. If you do not find your answer there, feel free to ask it in our [issues page](https://github.com/Microsoft/vscode-cpptools/issues).
If you have any questions, check out our [**Documentation**](Documentation) folder. If you do not find your answer there, feel free to ask it in our [issues page](https://github.com/Microsoft/vscode-cpptools/issues).
### Contribution