Compare commits

...
62 Commits
Author SHA1 Message Date
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
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 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 00008a2d80 Dev/seanmcm/update changelog master0 17 0 insiders2 (#1920)
* Update changelog.

* Update changelog with snippets/vcpkg change.
2018-05-02 22:09:52 -07:00
Bob Brown 9396786be8 update changelog (#1918)
* update changelog

* PR feedback
2018-05-02 16:59:44 -07:00
Jim Griesmer da17254c03 Provide user hint through IntelliSense fallback msg that vcpkg is installed and is being used. (#1910) 2018-05-02 15:42:06 -07:00
Andrew Wang 3ddc2292cd Improve README, issue template, and test error output (#1898)
* Improve README and test error output

* Adding popular feature requests

* Feature Requests gets thumbs up, not issues.

* Adding info for issues
2018-05-02 13:47:04 -07:00
Sean McManus f58217f03f Recursive includePath changes. (#1896)
* Recursive includePath changes.
* Keep config/icons visible with settings json files.
2018-04-30 14:16:51 -07:00
Jim Griesmer f2d328161e Slight tweak for what vcpkg will do. (#1897) 2018-04-30 14:04:41 -07:00
Jim Griesmer 947fb78e9a Users/jimgries/snippets (#1823) 2018-04-30 13:55:01 -07:00
Bob Brown 0521bbec32 additional logging for language server spawn failure (#1895)
* additional logging for language server spawn failure
* Show the client failure message once per session instead of once in forever
2018-04-30 08:11:00 -07:00
Jim Griesmer 9249e27df5 Initial implementation for supporting vcpkg (#1886)
* Initial implementation for supporting vcpkg
2018-04-27 14:50:24 -07:00
Bob Brown 063c4bd753 shouldn't be attempting to re-register vscode's commands (#1893) 2018-04-27 13:30:48 -07:00
Andrew Wang 7c34669c60 Updating License.txt (#1879)
* Updating EULA

* Fix text

* Updated fwlink for vsdbg
2018-04-27 12:09:37 -07:00
Bob Brown 7f2fa088d8 remove bad bracket 2018-04-24 21:00:57 -07:00
Bob Brown 548d32f21b workspaceFolder 2018-04-24 20:58:44 -07:00
Bob Brown e55ef6e153 fix commas 2018-04-24 20:57:37 -07:00
Bob Brown fdff9df795 wrong name for enum (#1872) 2018-04-24 08:31:39 -07:00
Sean McManus 80da21f199 Seanmcm/update changelog0 17 insiders1 (#1867)
* Update changelog.md.

* Added the clang-format 6.0 update.
2018-04-23 15:19:14 -07:00
Sean McManus b60b17b6a5 Update changelog.md. (#1866) 2018-04-23 15:02:39 -07:00
Bob Brown 6faac1071f Fixing issues found while testing settings changes (#1865)
* Fixing issues found while testing settings changes

* missed a property in the schema

* additional safety around config updates
2018-04-23 14:13:34 -07:00
Sean McManus 6648c400b7 Add preferredPathSeparator setting and update package.json version and fwlinks (#1854)
* Add preferredPathSeparator setting
* Update package.json version and fwlinks.
2018-04-20 14:15:56 -07:00
Bob Brown 8f21515eeb Add VS Code settings for configuration properties (#1848)
* Add VS Code settings for configuration properties
2018-04-19 15:20:20 -07:00
Sean McManus 313ce1928f Update c_cpp_properties.json.md (#1851) 2018-04-19 14:52:40 -07:00
Bob Brown 999aad5633 fix typo 2018-04-18 14:40:01 -07:00
Bob Brown 136091e8ce Updates to MinGW documentation (#1844)
* documentation update for mingw
2018-04-17 13:32:24 -07:00
Sean McManus 91e4f64f3d Update MinGW.md (#1841) 2018-04-16 08:44:25 -07:00
Andrew Wang 1318cce09f Adding snippet to fix pipeProgram in pipeTransport (#1829)
* Adding snippet to fix pipeProgram in pipeTransport

Now with VSCode 64 bit, WSL users need to use the correct pipeProgram in
the correct folder. We will attempt to help users with this.

* Fix tslint issue

* Remove 64 bit check and check for relative path
2018-04-13 18:02:21 -07:00
Andrew Wang 308e5a5c13 Download and Install Progress Window for Packages (#1806)
* Adding progress bar

* Updating vscode requirement and package version

* Updating message
2018-04-10 16:19:39 -07:00
Bob Brown e2b5bf9fbc Address config issues: #1599, #1790 (#1807)
* addresses #1599, #1790

* Update all configs when c_cpp_properties.json is parsed
2018-04-10 14:34:43 -07:00
Andrew Wang 7cff0f175d Prevent package.json rewrite from being checked in with test (#1809)
* Fix up package.json rewrite

VSCode package.json is readonly.

Rewriting package.json will use the disk package.json to prevent getting
expanded fields from VSCode. It will only read from disk once.

Added `gulp pr-check` to make sure that package.json activationEvents has
not been rewritten for open source contributers.

* run pr-check needs to be before run test

* Update log message
2018-04-10 12:04:29 -07:00
Pierson Lee 6517b8e395 Update launch.md for args to include comment about doublequoting (#1794)
* Update launch.md

* Update launch.md
2018-04-10 11:05:01 -07:00
Sean McManus a44bab5589 Fix https://github.com/Microsoft/vscode-cpptools/issues/1792 . (#1793) 2018-04-04 17:10:40 -07:00
Sean McManus 28102494b1 Update CONTRIBUTING.md (#1776)
Fix broken link.
2018-04-03 15:22:20 -07:00
53 changed files with 2956 additions and 1175 deletions
+4 -6
View File
@@ -31,13 +31,11 @@ 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
after_failure:
- find ~ -name "integrationTests.log" -type f -exec cat {} \;
after_success:
# Dump integrationTest.log output
- find ~ -name "integrationTests.log" -type f -exec cat {} \;
+1 -1
View File
@@ -2,7 +2,7 @@
## Contribution Steps
* [Build and debug the extension](Documentation/Getting%20started.md#build-and-debug-the-cpptools-extension).
* [Build and debug the extension](Documentation/Building%20the%20Extension.md).
* File an [issue](https://github.com/Microsoft/vscode-cpptools/issues) and a [pull request](https://github.com/Microsoft/vscode-cpptools/pulls) with the change and we will review it.
* If the change affects functionality, add a line describing the change to [**CHANGELOG.md**](Extension/CHANGELOG.md).
* Try and add a test in [**test/extension.test.ts**](Extension/test/unitTests/extension.test.ts).
@@ -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[]
```
### Include Path Resolution Strategies
The extension determines the includePath 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 seach 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 seach 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**?
+24 -68
View File
@@ -1,76 +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
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/`.
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.
## 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": "Win32",
"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",
"UNICODE",
"__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/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"compilerPath": "C:/mingw64/bin/gcc.exe",
"includePath": [
"${workspaceFolder}"
],
"defines": [],
"browse": {
"path": [
"${workspaceFolder}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"cStandard": "c11",
"cppStandard": "c++17"
}
```
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++ -`. 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).
## Extension version 0.16.1 and earlier:
For C projects, simply remove the C++ lines:
```json
{
"configurations": [
{
"name": "Win32",
"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",
"UNICODE",
"__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/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
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.
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" : {
"defaultIncludePath": [
"${workspaceFolder}",
"${workspaceFolder}/include"
],
"myCompilerPath": "/usr/local/bin/gcc-7"
},
"configurations": [
{
"name": "Win32",
"intelliSenseMode": "msvc-x64",
"includePath": [ "${workspaceFolder}" ],
"includePath": [ "${defaultIncludePath}", "/another/path" ],
"macFrameworkPath": [ "/System/Library/Frameworks" ],
"defines": [ "FOO", "BAR=100" ],
"forcedInclude": [ "${workspaceFolder}/include/config.h" ],
@@ -23,12 +32,15 @@
}
}
],
"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.
@@ -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.
@@ -78,7 +90,7 @@
This list of paths will be used by the Tag Parser to search for headers included by your source files. The Tag Parser will automatically search all subfolders in these paths unless the path ends with a `/*` or `\*`. For example, `/usr/include` directs the Tag Parser to search the `include` folder and its subfolders for headers while `/usr/include/*` directs the Tag Parser not to look in any subfolders of `/usr/include`.
* #### `limitSymbolsToIncludedHeaders`
When true, the Tag Parser will only parse code files that have been directly or indirectly included by a source file in `${workspaceRoot}`. When false, the Tag Parser will parse all code files found in the paths specified in the **path** list.
When true, the Tag Parser will only parse code files that have been directly or indirectly included by a source file in `${workspaceFolder}`. When false, the Tag Parser will parse all code files found in the paths specified in the **path** list.
* #### `databaseFilename`
When set, this instructs the extension to save the Tag Parser's symbol database somewhere other than the workspace's default storage location. If a relative path is specified, it will be made relative to the workspace's default storage location, not the workspace folder itself. The `${workspaceRoot}` variable can be used to specify a path relative to the workspace folder (e.g. `$[workspaceRoot}/.vscode/browse.vc.db`)
When set, this instructs the extension to save the Tag Parser's symbol database somewhere other than the workspace's default storage location. If a relative path is specified, it will be made relative to the workspace's default storage location, not the workspace folder itself. The `${workspaceFolder}` variable can be used to specify a path relative to the workspace folder (e.g. `${workspaceFolder}/.vscode/browse.vc.db`)
+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/**
+36
View File
@@ -1,5 +1,41 @@
# C/C++ for Visual Studio Code Change Log
## 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/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)
* Change file not found in `compile_commands.json` message from an error to a warning. [#1783](https://github.com/Microsoft/vscode-cpptools/issues/1783)
* Fix an IntelliSense crash during completion requests. [#1782](https://github.com/Microsoft/vscode-cpptools/issues/1782)
* Update the installed clang-format to 6.0.
* Fix bug with `compile_commands.json` when "arguments" have both a switch and a value in the arg. [#1890](https://github.com/Microsoft/vscode-cpptools/issues/1890)
* Fix bug with garbage data appearing in tooltips on Linux/Mac. [#1577](https://github.com/Microsoft/vscode-cpptools/issues/1577)
## Version 0.16.1: March 30, 2018
* Fix random deadlock caused by logging code on Linux/Mac. [#1759](https://github.com/Microsoft/vscode-cpptools/issues/1759)
* Fix compiler from `compileCommands` not being queried for includes/defines if `compilerPath` isn't set on Windows. [#1754](https://github.com/Microsoft/vscode-cpptools/issues/1754)
+174 -49
View File
@@ -1,78 +1,203 @@
# License
MICROSOFT PRE-RELEASE SOFTWARE LICENSE TERMS
MICROSOFT C/C++ EXTENSION FOR VISUAL STUDIO CODE
**MICROSOFT PRE-RELEASE SOFTWARE LICENSE TERMS**
**MICROSOFT C/C++ EXTENSION FOR VISUAL STUDIO CODE**
These license terms are an agreement between Microsoft Corporation (or
based on where you live, one of its affiliates) and you. They apply to
the pre-release software named above. The terms also apply to any
Microsoft services or updates for the software, except to the extent
those have additional terms.
---
These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the pre-release software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have additional terms.
IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
---
**IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.**
1. INSTALLATION AND USE RIGHTS. You may only use the C/C++ Extension
for Visual Studio Code with Visual Studio Code, Visual Studio or
Xamarin Studio software to help you develop and test your
applications.
1. **INSTALLATION AND USE RIGHTS.**
You may only use the C/C++ Extension for Visual Studio Code with Visual Studio Code, Visual Studio or Xamarin Studio software to help you develop and test your applications.
2. TERMS FOR SPECIFIC COMPONENTS
a. Third Party Components. The software may include third party
components with separate legal notices or governed by other
agreements, as may be described in the ThirdPartyNotices file(s)
accompanying the software.
b. Package Managers. The software may include package managers, like
Nuget, that give you the option to download other Microsoft and third
party software packages to use with your application. Those packages
are under their own licenses, and not this agreement. Microsoft does
not distribute, license or provide any warranties for any of the third
party packages.
2. **TERMS FOR SPECIFIC COMPONENTS.**
**a. Third Party components.** The software may include third party components with separate legal notices or governed by other agreements, as described in the ThirdPartyNotices file accompanying the software. Even if such components are governed by other agreements, the disclaimers and the limitations on and exclusions of damages below also apply.
**b. Package Managers.** The software may include package managers, like Nuget, that give you the option to download other Microsoft and third party software packages to use with your application. Those packages are under their own licenses, and not this agreement. Microsoft does not distribute, license or provide any warranties for any of the third party packages.
3. DATA.
a. Data Collection. The software may collect information about you and
your use of the software, and send that to Microsoft. Microsoft may
use this information to provide services and improve our products and
services. You may opt-out of many of these scenarios, but not all, as
described in the product documentation. There are also some features
in the software that may enable you and Microsoft to collect data from
users of your applications. If you use these features, you must comply
with applicable law, including providing appropriate notices to users
of your applications together with a copy of Microsofts privacy
statement. Our privacy statement is located at
https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more
about data collection and use in the help documentation and our
privacy statement. Your use of the software operates as your consent
to these practices.
b. Processing of Personal Data. To the extent Microsoft is a processor
or subprocessor of personal data in connection with the software,
Microsoft makes the commitments in the European Union General Data
Protection Regulation Terms of the Online Services Terms to all
customers effective May 25, 2018, at
http://go.microsoft.com/?linkid=9840733.
3. **DATA**. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the product documentation. There are also some features in the software that may enable you to collect data from users of your applications. If you use these features to enable data collection in your applications, you must comply with applicable law, including providing appropriate notices to users of your applications. You can learn more about data collection and use in the help documentation and the privacy statement at https://go.microsoft.com/fwlink/?LinkID=528096. Your use of the software operates as your consent to these practices.
4. PRE-RELEASE SOFTWARE. This software is a pre-release version. It
may not work the way a final version of the software will. We may
change it for the final, commercial version. We also may not release a
commercial version.
4. **PRE-RELEASE SOFTWARE**. This software is a pre-release version. It may not work the way a final version of the software will. We may change it for the final, commercial version. We also may not release a commercial version.
5. FEEDBACK. If you give feedback about the software to Microsoft, you
give to Microsoft, without charge, the right to use, share and
commercialize your feedback in any way and for any purpose. You will
not give feedback that is subject to a license that requires Microsoft
to license its software or documentation to third parties because we
include your feedback in them. These rights survive this agreement.
5. **FEEDBACK**. If you give feedback about the software to Microsoft, you give to Microsoft, without charge, the right to use, share and commercialize your feedback in any way and for any purpose. You will not give feedback that is subject to a license that requires Microsoft to license its software or documentation to third parties because we include your feedback in them. These rights survive this agreement.
6. SCOPE OF LICENSE. The software is licensed, not sold. This
agreement only gives you some rights to use the software. Microsoft
reserves all other rights. Unless applicable law gives you more rights
despite this limitation, you may use the software only as expressly
permitted in this agreement. In doing so, you must comply with any
technical limitations in the software that only allow you to use it in
certain ways. You may not
* work around any technical limitations in the software;
* reverse engineer, decompile or disassemble the software, or attempt
to derive the source code for the software, except and to the extent
required by third party licensing terms governing use of certain open
source components that may be included with the software;
* remove, minimize, block or modify any notices of Microsoft or its
suppliers in the software;
* use the software in any way that is against the law; or
* share, publish, rent, or lease the software, or provide the software
as a stand-alone hosted solution for others to use.
6. **SCOPE OF LICENSE**. The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. For more information, see http://www.microsoftvolumelicensing.com/. You may not
* work around any technical limitations in the software;
* reverse engineer, decompile or disassemble the software, or attempt to do so, except and only to the extent required by third party licensing terms governing use of certain open-source components that may be included with the software;
* remove, minimize, block or modify any notices of Microsoft or its suppliers in the software;
* use the software in any way that is against the law; or
* share, publish, rent, or lease the software, or provide the software as a stand-alone hosted as solution for others to use.
7. EXPORT RESTRICTIONS. You must comply with all domestic and
international export laws and regulations that apply to the software,
which include restrictions on destinations, end users and end use.
For further information on export restrictions, visit
(aka.ms/exporting).
7. **EXPORT RESTRICTIONS.** You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users and end use. For further information on export restrictions, visit https://aka.ms/exporting.
8. SUPPORT SERVICES. Because this software is “as is,” we may not
provide support services for it.
8. **SUPPORT SERVICES.** Because this software is “as is,” we may not provide support services for it.
9. ENTIRE AGREEMENT. This agreement, and the terms for supplements,
updates, Internet-based services and support services that you use,
are the entire agreement for the software and support services.
9. **ENTIRE AGREEMENT.** This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.
10. APPLICABLE LAW. If you acquired the software in the United
States, Washington law applies to interpretation of and claims for
breach of this agreement, and the laws of the state where you live
apply to all other claims. If you acquired the software in any other
country, its laws apply.
10. **APPLICABLE LAW.** If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
11. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes
certain legal rights. You may have other rights, including consumer
rights, under the laws of your state or country. Separate and apart
from your relationship with Microsoft, you may also have rights with
respect to the party from which you acquired the software. This
agreement does not change those other rights if the laws of your state
or country do not permit it to do so. For example, if you acquired the
software in one of the below regions, or mandatory country law
applies, then the following provisions apply to you:
11. **CONSUMER RIGHTS; REGIONAL VARIATIONS.** This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
a. Australia. You have statutory guarantees under the Australian
Consumer Law and nothing in this agreement is intended to affect those
rights.
**a. Australia.** You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
b. Canada. If you acquired this software in Canada, you may stop
receiving updates by turning off the automatic update feature,
disconnecting your device from the Internet (if and when you re-
connect to the Internet, however, the software will resume checking
for and installing updates), or uninstalling the software. The product
documentation, if any, may also specify how to turn off updates for
your specific device or software.
**b. Canada.** If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software.
c. Germany and Austria.
(i) Warranty. The properly licensed software will perform
substantially as described in any Microsoft materials that accompany
the software. However, Microsoft gives no contractual guarantee in
relation to the licensed software.
(ii) Limitation of Liability. In case of intentional conduct, gross
negligence, claims based on the Product Liability Act, as well as, in
case of death or personal or physical injury, Microsoft is liable
according to the statutory law.
Subject to the foregoing clause (ii), Microsoft will only be liable
for slight negligence if Microsoft is in breach of such material
contractual obligations, the fulfillment of which facilitate the due
performance of this agreement, the breach of which would endanger the
purpose of this agreement and the compliance with which a party may
constantly trust in (so-called "cardinal obligations"). In other cases
of slight negligence, Microsoft will not be liable for slight
negligence.
**c. Germany and Austria.**
12. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.” YOU
BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES,
GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL
LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
**(i)** **Warranty**. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.
13. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM
MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU
CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST
PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
**(ii)** **Limitation of Liability**. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law.
This limitation applies to (a) anything related to the software,
services, content (including code) on third party Internet sites, or
third party applications; and (b) claims for breach of contract,
breach of warranty, guarantee or condition, strict liability,
negligence, or other tort to the extent permitted by applicable law.
Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.
It also applies even if Microsoft knew or should have known about the
possibility of the damages. The above limitation or exclusion may not
apply to you because your country may not allow the exclusion or
limitation of incidental, consequential or other damages.
12. **DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.” YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.**
Please note: As this software is distributed in Quebec, Canada, some
of the clauses in this agreement are provided below in French.
13. **LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.**
Remarque : Ce logiciel étant distribué au Québec, Canada, certaines
des clauses dans ce contrat sont fournies ci-dessous en français.
This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert
« tel quel ». Toute utilisation de ce logiciel est à votre seule
risque et péril. Microsoft naccorde aucune autre garantie
expresse. Vous pouvez bénéficier de droits additionnels en vertu du
droit local sur la protection des consommateurs, que ce contrat ne
peut modifier. La ou elles sont permises par le droit locale, les
garanties implicites de qualité marchande, dadéquation à un
usage particulier et dabsence de contrefaçon sont exclues.
It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.
**Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.**
**Remarque : Ce logiciel étant distribué au Québec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en français.**
**EXONÉRATION DE GARANTIE.** Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de ce logiciel est à votre seule risque et péril. Microsoft naccorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, dadéquation à un usage particulier et dabsence de contrefaçon sont exclues.
**LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES.** Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.
LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ
POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses
fournisseurs une indemnisation en cas de dommages directs uniquement
à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune
indemnisation pour les autres dommages, y compris les dommages
spéciaux, indirects ou accessoires et pertes de bénéfices.
Cette limitation concerne:
* tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et
* tout ce qui est relié au logiciel, aux services ou au contenu (y
compris le code) figurant sur des sites Internet tiers ou dans des
programmes tiers ; et
* les réclamations au titre de violation de contrat ou de garantie,
ou au titre de responsabilité stricte, de négligence ou dune
autre faute dans la limite autorisée par la loi en vigueur.
* les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou dune autre faute dans la limite autorisée par la loi en vigueur.
Elle sapplique également, même si Microsoft connaissait ou
devrait connaître l’éventualité dun tel dommage. Si votre pays
nautorise pas lexclusion ou la limitation de responsabilité
pour les dommages indirects, accessoires ou de quelque nature que ce
soit, il se peut que la limitation ou lexclusion ci-dessus ne
sappliquera pas à votre égard.
Elle sapplique également, même si Microsoft connaissait ou devrait connaître l’éventualité dun tel dommage. Si votre pays nautorise pas lexclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou lexclusion ci-dessus ne sappliquera pas à votre égard.
**EFFET JURIDIQUE.** Le présent contrat décrit certains droits juridiques. Vous pourriez avoir dautres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas.
EFFET JURIDIQUE. Le présent contrat décrit certains droits
juridiques. Vous pourriez avoir dautres droits prévus par les lois
de votre pays. Le présent contrat ne modifie pas les droits que vous
confèrent les lois de votre pays si celles-ci ne le permettent pas.
+6 -3
View File
@@ -205,8 +205,11 @@
<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 />
<h2 class="caption">April 2018 Update</h2>
<div>Thank you for installing the C/C++ extension. In the April update, we added autocomplete suggestions for <code>#include</code> statements.<br/>
<br/>
We also added settings for configuration defaults and made some changes to improve the automatic configuration experience. If you set the <code>"compilerPath"</code>
property in c_cpp_properties.json, you no longer need to add system includes and defines to <code>"includePath"</code> or <code>"defines"</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>
@@ -231,9 +234,9 @@
<td>
<div>
<h3 class="caption">Blog Posts</h3>
<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>
+39 -33
View File
@@ -7,40 +7,41 @@ Microsoft C/C++ Extension for Visual Studio Code incorporates components from th
1. agent-base (https://github.com/TooTallNate/node-agent-base)
2. ANTLR (http://www.antlr2.org/)
3. Boost (http://www.boost.org)
4. Clang (https://clang.llvm.org/)
5. debug (https://github.com/visionmedia/debug)
6. extend (https://github.com/justmoon/node-extend)
7. fd-slicer (https://github.com/andrewrk/node-fd-slicer)
8. gcc-6/libgcc (http://packages.ubuntu.com/yakkety/main/gcc-6)
9. Guidelines Support Library (https://github.com/Microsoft/GSL)
10. http-proxy-agent (https://github.com/TooTallNate/node-http-proxy-agent)
11. https-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
12. jsonc-parser (https://github.com/Microsoft/node-jsonc-parser)
13. libc++ (https://libcxx.llvm.org/index.html)
14. LLDB (https://lldb.llvm.org/)
15. LLVM (http://llvm.org/)
16. MI Debug Engine (https://github.com/Microsoft/MIEngine)
17. Minimatch (https://github.com/isaacs/minimatch)
18. minimist (https://github.com/substack/minimist)
19. mkdirp (https://github.com/substack/node-mkdirp)
20. Mono (https://github.com/mono/mono)
21. ms (https://github.com/rauchg/ms.js)
22. msgpack for C/C++ (https://github.com/msgpack/msgpack-c)
23. node-http-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
24. node-https-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
25. os-tmpdir (https://github.com/sindresorhus/os-tmpdir)
26. Pend (https://github.com/andrewrk/node-pend)
27. pevents (https://github.com/neosmart/pevents)
28. RapidJSON (https://github.com/miloyip/rapidjson)
29. semver (https://github.com/npm/node-semver)
30. SQLite (https://www.sqlite.org/)
4. C++11 Sublime Text Snippets (https://github.com/Rapptz/cpp-sublime-snippet)
5. Clang (https://clang.llvm.org/)
6. debug (https://github.com/visionmedia/debug)
7. extend (https://github.com/justmoon/node-extend)
8. fd-slicer (https://github.com/andrewrk/node-fd-slicer)
9. gcc-6/libgcc (http://packages.ubuntu.com/yakkety/main/gcc-6)
10. Guidelines Support Library (https://github.com/Microsoft/GSL)
11. http-proxy-agent (https://github.com/TooTallNate/node-http-proxy-agent)
12. https-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
13. jsonc-parser (https://github.com/Microsoft/node-jsonc-parser)
14. libc++ (https://libcxx.llvm.org/index.html)
15. LLDB (https://lldb.llvm.org/)
16. LLVM (http://llvm.org/)
17. MI Debug Engine (https://github.com/Microsoft/MIEngine)
18. Minimatch (https://github.com/isaacs/minimatch)
19. minimist (https://github.com/substack/minimist)
20. mkdirp (https://github.com/substack/node-mkdirp)
21. Mono (https://github.com/mono/mono)
22. ms (https://github.com/rauchg/ms.js)
23. msgpack for C/C++ (https://github.com/msgpack/msgpack-c)
24. node-http-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
25. node-https-proxy-agent (https://github.com/TooTallNate/node-https-proxy-agent)
26. os-tmpdir (https://github.com/sindresorhus/os-tmpdir)
27. Pend (https://github.com/andrewrk/node-pend)
28. pevents (https://github.com/neosmart/pevents)
29. RapidJSON (https://github.com/miloyip/rapidjson)
30. semver (https://github.com/npm/node-semver)
31. SQLite (https://www.sqlite.org/)
Includes:functions (from fossil) (https://fossil-scm.org)
31. Tmp (https://github.com/raszi/node-tmp)
32. Tmp (https://github.com/raszi/node-tmp)
Includes:sample code (https://blog.tompawlak.org/generate-random-values-nodejs-javascript)
32. vscode-debugadapter (https://github.com/Microsoft/vscode-debugadapter-node)
33. vscode-extension-telemetry (https://github.com/Microsoft/vscode-extension-telemetry)
34. vscode-languageserver-node (https://github.com/Microsoft/vscode-languageserver-node)
35. yauzl (https://github.com/thejoshwolfe/yauzl)
33 vscode-debugadapter (https://github.com/Microsoft/vscode-debugadapter-node)
34. vscode-extension-telemetry (https://github.com/Microsoft/vscode-extension-telemetry)
35. vscode-languageserver-node (https://github.com/Microsoft/vscode-languageserver-node)
36. yauzl (https://github.com/thejoshwolfe/yauzl)
%% agent-base NOTICES AND INFORMATION BEGIN HERE
@@ -1412,6 +1413,11 @@ SOFTWARE.
=========================================
END OF yauzl NOTICES AND INFORMATION
%% C++11 Sublime Text Snippets NOTICES AND INFORMATION BEGIN HERE
=========================================
C++ Snippets for Sublime Text (https://packagecontrol.io/packages/C%2B%2B%20Snippets)
Individual snippets based on those from the C++ Snippets for Sublime Text collection are licensed under CC0 1.0 Universal
=========================================
END OF C++11 Sublime Text Snippets NOTICES AND INFORMATION
+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"
+37 -8
View File
@@ -11,7 +11,7 @@
],
"properties": {
"name": {
"description": "Configuration identifier. Mac, Linux, or Win32 are special identifiers for configurations that will be auto-selected on those platforms, but the identifier can be anything.",
"description": "Configuration identifier. Mac, Linux, and Win32 are special identifiers for configurations that will be auto-selected on those platforms, but the identifier can be anything.",
"type": "string"
},
"compilerPath": {
@@ -24,7 +24,8 @@
"enum": [
"c89",
"c99",
"c11"
"c11",
"${default}"
]
},
"cppStandard": {
@@ -35,7 +36,8 @@
"c++03",
"c++11",
"c++14",
"c++17"
"c++17",
"${default}"
]
},
"compileCommands": {
@@ -64,12 +66,13 @@
}
},
"intelliSenseMode": {
"description": "If set, it overrides the default mode used by the IntelliSense engine. Windows defaults to msvc-x64 and Linux/Mac default to clang-x64.",
"type": "string",
"enum": [
"msvc-x64",
"clang-x64"
],
"description": "If set, it overrides the default mode used by the IntelliSense engine. Windows defaults to msvc-x64 and Linux/Mac default to clang-x64."
"clang-x64",
"${default}"
]
},
"forcedInclude": {
"description": "A list of files that should be included before any include file in a translation unit.",
@@ -83,7 +86,10 @@
"properties": {
"limitSymbolsToIncludedHeaders": {
"description": "true to process only those files directly or indirectly included as headers, false to process all files under the specified include paths.",
"type": "boolean"
"type": [
"boolean",
"string"
]
},
"databaseFilename": {
"description": "Path to the generated symbol database. If a relative path is specified, it will be made relative to the workspace's default storage location.",
@@ -101,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."
@@ -110,6 +136,9 @@
"configurations": {
"$ref": "#/definitions/configurations"
},
"env": {
"$ref": "#/definitions/env"
},
"version": {
"$ref": "#/definitions/version"
}
@@ -118,4 +147,4 @@
"configurations",
"version"
]
}
}
+140
View File
@@ -0,0 +1,140 @@
{
"class": {
"prefix": "class",
"body": "\nclass ${1:${TM_FILENAME_BASE}}\n{\nprivate:\n\t${2:/* data */}\npublic:\n\t${1}(${3:/* args */});\n\t~${1}();\n};\n\n${1}::${1}(${3})\n{\n}\n\n${1}::~${1}()\n{\n}\n",
"description": "Code snippet for class",
"scope": "source.c++, source.objc++"
},
"classi": {
"prefix": "classi",
"body": "\nclass ${1:${TM_FILENAME_BASE}}\n{\nprivate:\n\t${2:/* data */}\npublic:\n\t${1}(${3:/* args */}) { $0}\n\t~${1}() { }\n};",
"description": "Code snippet for class with inlined constructor/destructor",
"scope": "source.c++, source.objc++"
},
"classt": {
"prefix": "classt",
"body": "\ntemplate<typename T>\nclass ${1:${TM_FILENAME_BASE}}\n{\nprivate:\n\tT ${2:/* data */}\npublic:\n\t${1}(T ${3:/* args */});\n};\n",
"description": "Code snippet for class template",
"scope": "source.c++, source.objc++"
},
"struct": {
"prefix": "struct",
"body": "\nstruct ${1:${TM_FILENAME_BASE}}\n{\n\t${0:/* data */}\n};\n",
"description": "Code snippet for struct",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"union": {
"prefix": "union",
"body": "\nunion ${1:${TM_FILENAME_BASE}}\n{\n\t${0:/* data */}\n};\n",
"description": "Code snippet for union",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"if": {
"prefix": "if",
"body": "\nif (${1:/* condition */}) {\n\t${0:/* code */}\n}\n",
"description": "Code snippet for if()",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"ifel": {
"prefix": "ifel",
"body": "\nif (${1:/* condition */}) {\n\t${2:/* code */}\n}\nelse {\n\t${0:/* code */}\n}\n",
"description": "Code snippet for if() else",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"ifelif": {
"prefix": "ifelif",
"body": "\nif (${1:/* condition */}) {\n\t${2:/* code */}\n}\nelse if(${3:/* condition */}) {\n\t${4:/* code */}\n}\nelse {\n\t${0:/* code */}\n}\n",
"description": "Code snippet for if() else if() else",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"else": {
"prefix": "else",
"body": "\nelse\n{\n\t${0:/* code */}\n}\n",
"description": "Code snippet for else",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"elif": {
"prefix": "elif",
"body": "\nelse if (${1:/* condition */})\n{\n\t${0:/* code */}\n}\n",
"description": "Code snippet for else if ()",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"switch": {
"prefix": "switch",
"body": "\nswitch (${1:expression})\n{\n\tcase ${2:/* constant-expression */}:\n\t\t${3:/* code */}\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n}",
"description": "Code snippet for switch",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"main": {
"prefix": "main",
"body": "\nint main(int argc, char const *argv[])\n{\n\t${1:/* code */}\n\treturn 0;\n}\n",
"description": "Code snippet for main()",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"do": {
"prefix": "do_",
"body": "\ndo\n{\n\t${0:/* code */}\n} while (${1:/* condition */});\n",
"description": "Code snippet for do while loop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"for": {
"prefix": "for",
"body": "\nfor(${1:size_t} ${2:i} = 0; $2 < ${3:count}; ${4:$2++})\n{\n\t${0:/* code */}\n}\n",
"description": "Code snippet for for loop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"forr": {
"prefix": "forr",
"body": "\nfor(int ${1:i} = ${2:length} - 1; $1 >= 0; ${3:$1--})\n{\n\t${0:/* code */}\n}\n",
"description": "Code snippet for reverse for loop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"foreach": {
"prefix": "foreach",
"body": "\nfor(${1:object} = ${2:var} in ${3:collection})\n{\n\t${0:/* code */}\n}\n",
"description": "Code snippet for foreach loop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"forrange": {
"prefix": "forrange",
"body": "\nfor(auto&& ${1:i} : ${2:v})\n{\n\t$0\n}\n",
"description": "Code snippet for range-based forloop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"while": {
"prefix": "while",
"body": "\nwhile(${1:/* condition */}){\n\t${2:/* code */}\n}\n",
"description": "Code snippet for while loop",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"ifd": {
"prefix": "ifnd",
"body": "\n#if defined($1)\n\n${0}\n\n#endif // $1\n",
"description": "Code snippet for if defined()",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"ifnd": {
"prefix": "ifnd",
"body": "\n#if !defined($1)\n#define ${1:MACRO}\n\n${0}\n\n#endif // $1\n",
"description": "Code snippet for if !defined()",
"scope": "source.c, source.objc, source.c++, source.objc++"
},
"mitl": {
"prefix": "mitl",
"body": "\n// The MIT License (MIT)\n\n// Copyright (c) ${1:YEAR} ${2:NAME}\n\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the \"Software\"),\n// to deal in the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n${0:/* code */}\n",
"description": "Code snippet for MIT License",
"scope": ""
},
"namesp": {
"prefix": "namesp",
"body": "\nnamespace ${1:name}\n{\n\t$0\n} // $1\n",
"description": "Code snippet for namespace",
"scope": "source.c++, source.objc++"
},
"try": {
"prefix": "try",
"body": "\ntry\n{\n\t${1:/* code */}\n}\ncatch(${2:const std::exception& e})\n{\n\t${0:std::cerr << e.what() << '\\n';}\n}\n",
"description": "Code snippet for try catch block",
"scope": "source.c++, source.objc++, source.c++11"
}
}
+15
View File
@@ -9,6 +9,8 @@ const gulp = require('gulp');
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');
@@ -50,6 +52,7 @@ gulp.task('integrationTests', () => {
/// Misc Tasks
const allTypeScript = [
'src/**/*.ts',
'tools/**/*.ts',
'!**/*.d.ts',
'!**/typings**'
];
@@ -73,4 +76,16 @@ gulp.task('tslint', () => {
summarizeFailureOutput: false,
emitError: false
}))
});
gulp.task('pr-check', () => {
const packageJson = JSON.parse(fs.readFileSync('./package.json').toString());
if (packageJson.activationEvents.length !== 1 && packageJson.activationEvents[0] !== '*') {
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();
});
+215 -422
View File
File diff suppressed because it is too large Load Diff
+209 -35
View File
@@ -2,7 +2,7 @@
"name": "cpptools",
"displayName": "C/C++",
"description": "C/C++ IntelliSense, debugging, and code browsing.",
"version": "0.16.1",
"version": "0.17.3",
"publisher": "ms-vscode",
"preview": true,
"icon": "LanguageCCPP_color_128x.png",
@@ -12,7 +12,7 @@
},
"license": "SEE LICENSE IN LICENSE.txt",
"engines": {
"vscode": "^1.17.0"
"vscode": "^1.22.0"
},
"bugs": {
"url": "https://github.com/Microsoft/vscode-cpptools/issues",
@@ -32,10 +32,11 @@
"multi-root ready"
],
"categories": [
"Languages",
"Programming Languages",
"Debuggers",
"Formatters",
"Linters"
"Linters",
"Snippets"
],
"activationEvents": [
"*"
@@ -167,10 +168,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": {
@@ -201,6 +203,16 @@
"description": "Instructs the extension when to use the \"files.exclude\" setting when determining which files should be added to the code navigation database while traversing through the paths in the \"browse.path\" array. \"checkFolders\" means that the exclusion filters will only be evaluated once per folder (individual files are not checked). \"checkFilesAndFolders\" means that the exclusion filters will be evaluated against every file and folder encountered. If your \"files.exclude\" setting only contains folders, then \"checkFolders\" is the best choice and will increase the speed at which the extension can initialize the code navigation database.",
"scope": "resource"
},
"C_Cpp.preferredPathSeparator": {
"type": "string",
"enum": [
"Forward Slash",
"Backslash"
],
"default": "Forward Slash",
"description": "The character used as a path separator for #include auto-completion results.",
"scope": "resource"
},
"C_Cpp.commentContinuationPatterns": {
"type": "array",
"default": [
@@ -229,6 +241,154 @@
},
"description": "Defines the editor behavior for when the Enter key is pressed inside a multiline or single line comment block.",
"scope": "resource"
},
"C_Cpp.default.includePath": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use in a configuration if \"includePath\" is not specified, or the values to insert if \"${default}\" is present in \"includePath\".",
"scope": "resource"
},
"C_Cpp.default.defines": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use in a configuration if \"defines\" is not specified, or the values to insert if \"${default}\" is present in \"defines\".",
"scope": "resource"
},
"C_Cpp.default.macFrameworkPath": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use in a configuration if \"macFrameworkPath\" is not specified, or the values to insert if \"${default}\" is present in \"macFrameworkPath\".",
"scope": "resource"
},
"C_Cpp.default.compileCommands": {
"type": [
"string",
"null"
],
"default": null,
"description": "The value to use in a configuration if \"compileCommands\" is either not specified, or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.forcedInclude": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use in a configuration if \"forcedInclude\" is not specified, or the values to insert if \"${default}\" is present in \"forcedInclude\".",
"scope": "resource"
},
"C_Cpp.default.intelliSenseMode": {
"type": [
"string",
"null"
],
"enum": [
"msvc-x64",
"clang-x64"
],
"default": null,
"description": "The value to use in a configuration if \"intelliSenseMode\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.compilerPath": {
"type": [
"string",
"null"
],
"default": null,
"description": "The value to use in a configuration if \"compilerPath\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.cStandard": {
"type": [
"string",
"null"
],
"enum": [
"c89",
"c99",
"c11"
],
"default": null,
"description": "The value to use in a configuration if \"cStandard\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.cppStandard": {
"type": [
"string",
"null"
],
"enum": [
"c++98",
"c++03",
"c++11",
"c++14",
"c++17"
],
"default": null,
"description": "The value to use in a configuration if \"cppStandard\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.browse.path": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use in a configuration if \"browse.path\" is not specified, or the values to insert if \"${default}\" is present in \"browse.path\".",
"scope": "resource"
},
"C_Cpp.default.browse.databaseFilename": {
"type": [
"string",
"null"
],
"default": null,
"description": "The value to use in a configuration if \"browse.databaseFilename\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.browse.limitSymbolsToIncludedHeaders": {
"type": "boolean",
"default": true,
"description": "The value to use in a configuration if \"browse.limitSymbolsToIncludedHeaders\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.systemIncludePath": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"default": null,
"description": "The value to use for the system include path. If set, it overrides the system include path acquired via \"compilerPath\" and \"compileCommands\" settings.",
"scope": "resource"
}
}
},
@@ -263,6 +423,11 @@
"title": "Navigate...",
"category": "C/Cpp"
},
{
"command": "C_Cpp.ToggleSnippets",
"title": "Toggle Snippets",
"category": "C/Cpp"
},
{
"command": "C_Cpp.ToggleErrorSquiggles",
"title": "Toggle Error Squiggles",
@@ -278,14 +443,6 @@
"title": "Toggle Inactive Region Colorization",
"category": "C/Cpp"
},
{
"command": "workbench.action.gotoSymbol",
"title": "Go to Symbol in File..."
},
{
"command": "workbench.action.showAllSymbols",
"title": "Go to Symbol in Workspace..."
},
{
"command": "C_Cpp.ShowReleaseNotes",
"title": "Show Release Notes",
@@ -377,6 +534,7 @@
},
"configurationAttributes": {
"launch": {
"type": "object",
"required": [
"program"
],
@@ -563,8 +721,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": {
@@ -603,10 +761,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": {
@@ -645,6 +803,7 @@
}
},
"attach": {
"type": "object",
"required": [
"program",
"processId"
@@ -727,8 +886,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": {
@@ -767,10 +926,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": {
@@ -851,6 +1010,7 @@
},
"configurationAttributes": {
"launch": {
"type": "object",
"required": [
"program",
"cwd"
@@ -953,6 +1113,7 @@
}
},
"attach": {
"type": "object",
"required": [
"processId"
],
@@ -1102,13 +1263,25 @@
"[c]": {
"editor.autoIndent": false
}
}
},
"snippets": [
{
"language": "cpp",
"path": "./cpp_snippets.json"
},
{
"language": "c",
"path": "./cpp_snippets.json"
}
]
},
"scripts": {
"compile": "npm run vscode:prepublish",
"generateOptionsSchema": "gulp generateOptionsSchema",
"integrationTests": "gulp integrationTests",
"postinstall": "node ./node_modules/vscode/bin/install",
"pretest": "tsc -p ./",
"pr-check": "gulp pr-check",
"test": "gulp allTests",
"tslint": "gulp tslint",
"unitTests": "gulp unitTests",
@@ -1118,20 +1291,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.6"
"vrsource-tslint-rules": "^5.8.2",
"vscode": "^1.1.17"
},
"dependencies": {
"http-proxy-agent": "~2.0.0",
"https-proxy-agent": "~2.1.0",
"https-proxy-agent": "~2.2.0",
"jsonc-parser": "^1.0.0",
"minimatch": "~3.0.4",
"mkdirp": "~0.5.1",
@@ -1139,13 +1313,13 @@
"vscode-debugadapter": "~1.24.0",
"vscode-debugprotocol": "~1.24.0",
"vscode-extension-telemetry": "~0.0.11",
"vscode-languageclient": "~3.4.5",
"vscode-languageclient": "3.5.1",
"yauzl": "~2.8.0"
},
"runtimeDependencies": [
{
"description": "C/C++ language components (Linux / x86_64)",
"url": "https://go.microsoft.com/fwlink/?linkid=871264",
"url": "https://go.microsoft.com/fwlink/?linkid=874519",
"platforms": [
"linux"
],
@@ -1159,7 +1333,7 @@
},
{
"description": "C/C++ language components (Linux / x86)",
"url": "https://go.microsoft.com/fwlink/?linkid=871265",
"url": "https://go.microsoft.com/fwlink/?linkid=874520",
"platforms": [
"linux"
],
@@ -1175,7 +1349,7 @@
},
{
"description": "C/C++ language components (OS X)",
"url": "https://go.microsoft.com/fwlink/?linkid=871266",
"url": "https://go.microsoft.com/fwlink/?linkid=874521",
"platforms": [
"darwin"
],
@@ -1186,7 +1360,7 @@
},
{
"description": "C/C++ language components (Windows)",
"url": "https://go.microsoft.com/fwlink/?linkid=871267",
"url": "https://go.microsoft.com/fwlink/?linkid=874522",
"platforms": [
"win32"
],
@@ -1194,7 +1368,7 @@
},
{
"description": "ClangFormat (Linux / x86_64)",
"url": "https://go.microsoft.com/fwlink/?LinkID=848955",
"url": "https://go.microsoft.com/fwlink/?LinkID=872607",
"platforms": [
"linux"
],
@@ -1207,7 +1381,7 @@
},
{
"description": "ClangFormat (Linux / x86)",
"url": "https://go.microsoft.com/fwlink/?LinkID=864640",
"url": "https://go.microsoft.com/fwlink/?LinkID=872608",
"platforms": [
"linux"
],
@@ -1222,7 +1396,7 @@
},
{
"description": "ClangFormat (OS X)",
"url": "https://go.microsoft.com/fwlink/?LinkID=848956",
"url": "https://go.microsoft.com/fwlink/?LinkID=872609",
"platforms": [
"darwin"
],
@@ -1232,7 +1406,7 @@
},
{
"description": "ClangFormat (Windows)",
"url": "https://go.microsoft.com/fwlink/?LinkID=848957",
"url": "https://go.microsoft.com/fwlink/?LinkID=872610",
"platforms": [
"win32"
],
@@ -1300,7 +1474,7 @@
},
{
"description": "Visual Studio Windows Debugger",
"url": "https://go.microsoft.com/fwlink/?linkid=852926",
"url": "https://go.microsoft.com/fwlink/?linkid=872985",
"platforms": [
"win32"
],
+36 -4
View File
@@ -3,10 +3,15 @@
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import * as vscode from 'vscode';
import { execChildProcess } from '../common';
import { PsProcessParser } from './nativeAttach';
import * as debugUtils from './utils';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import * as util from '../common';
import * as vscode from 'vscode';
export interface AttachItem extends vscode.QuickPickItem {
id: string;
@@ -49,20 +54,47 @@ export class RemoteAttachPicker {
private _channel: vscode.OutputChannel = null;
public ShowAttachEntries(args: any): Promise<string> {
public ShowAttachEntries(config: any): Promise<string> {
return util.isExtensionReady().then(ready => {
if (!ready) {
util.displayExtensionNotReadyPrompt();
} else {
this._channel.clear();
let pipeTransport: any = args ? args.pipeTransport : null;
let pipeTransport: any = config ? config.pipeTransport : null;
if (pipeTransport === null) {
return Promise.reject<string>(new Error("Chosen debug configuration does not contain pipeTransport"));
}
let pipeProgram: string = pipeTransport.pipeProgram;
let pipeProgram: string = null;
if (os.platform() === 'win32' &&
pipeTransport.pipeProgram &&
!fs.existsSync(pipeTransport.pipeProgram)) {
const pipeProgramStr: string = pipeTransport.pipeProgram.toLowerCase().trim();
const expectedArch: debugUtils.ArchType = debugUtils.ArchType[process.arch];
// Check for pipeProgram
if (!fs.existsSync(config.pipeTransport.pipeProgram)) {
pipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(pipeProgramStr, expectedArch);
}
// If pipeProgram does not get replaced and there is a pipeCwd, concatenate with pipeProgramStr and attempt to replace.
if (!pipeProgram && config.pipeTransport.pipeCwd) {
const pipeCwdStr: string = config.pipeTransport.pipeCwd.toLowerCase().trim();
const newPipeProgramStr: string = path.join(pipeCwdStr, pipeProgramStr);
if (!fs.existsSync(newPipeProgramStr)) {
pipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(newPipeProgramStr, expectedArch);
}
}
}
if (!pipeProgram) {
pipeProgram = pipeTransport.pipeProgram;
}
let pipeArgs: string[] = pipeTransport.pipeArgs;
let argList: string = RemoteAttachPicker.createArgumentList(pipeArgs);
@@ -3,8 +3,11 @@
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import * as debugUtils from './utils';
import * as os from 'os';
import * as path from 'path';
import * as vscode from 'vscode';
import { IConfiguration, IConfigurationSnippet, DebuggerType, MIConfigurations, WindowsConfigurations, WSLConfigurations, PipeTransportConfigurations } from './configurations';
import { parse } from 'jsonc-parser';
@@ -34,6 +37,29 @@ abstract class CppConfigurationProvider implements vscode.DebugConfigurationProv
return undefined;
}
// Modify WSL config for OpenDebugAD7
if (os.platform() === 'win32' &&
config.pipeTransport &&
config.pipeTransport.pipeProgram) {
let replacedPipeProgram: string = null;
const pipeProgramStr: string = config.pipeTransport.pipeProgram.toLowerCase().trim();
// OpenDebugAD7 is a 32-bit process. Make sure the WSL pipe transport is using the correct program.
replacedPipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(pipeProgramStr, debugUtils.ArchType.ia32);
// If pipeProgram does not get replaced and there is a pipeCwd, concatenate with pipeProgramStr and attempt to replace.
if (!replacedPipeProgram && !path.isAbsolute(pipeProgramStr) && config.pipeTransport.pipeCwd) {
const pipeCwdStr: string = config.pipeTransport.pipeCwd.toLowerCase().trim();
const newPipeProgramStr: string = path.join(pipeCwdStr, pipeProgramStr);
replacedPipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(newPipeProgramStr, debugUtils.ArchType.ia32);
}
if (replacedPipeProgram) {
config.pipeTransport.pipeProgram = replacedPipeProgram;
}
}
return config;
}
}
+18 -17
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 {
@@ -218,15 +218,16 @@ export class WindowsConfigurations extends Configuration {
}
export class WSLConfigurations extends Configuration {
public bashPipeProgram = "C:\\\\Windows\\\\sysnative\\\\bash.exe";
// Detects if the current VSCode is 32-bit and uses the correct bash.exe
public bashPipeProgram = process.arch === 'ia32' ? "${env:windir}\\\\sysnative\\\\bash.exe" : "${env:windir}\\\\system32\\\\bash.exe";
public GetLaunchConfiguration(): IConfigurationSnippet {
let name: string = `(${this.MIMode}) Bash on Windows Launch`;
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 {
@@ -242,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'
}];
+49
View File
@@ -0,0 +1,49 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
export enum ArchType {
ia32,
x64
}
export class ArchitectureReplacer {
public static checkAndReplaceWSLPipeProgram(pipeProgramStr: string, expectedArch: ArchType): string {
let replacedPipeProgram: string = null;
const winDir: string = process.env.WINDIR ? process.env.WINDIR.toLowerCase() : null;
const winDirAltDirSep: string = process.env.WINDIR ? process.env.WINDIR.replace('\\', '/').toLowerCase() : null;
const winDirEnv: string = "${env:windir}";
if (winDir && winDirAltDirSep && (pipeProgramStr.indexOf(winDir) === 0 || pipeProgramStr.indexOf(winDirAltDirSep) === 0 || pipeProgramStr.indexOf(winDirEnv) === 0)) {
if (expectedArch === ArchType.x64) {
const pathSep: string = ArchitectureReplacer.checkForFolderInPath(pipeProgramStr, "sysnative");
if (pathSep) {
// User has sysnative but we expect 64 bit. Should be using System32 since sysnative is a 32bit concept.
replacedPipeProgram = pipeProgramStr.replace(`${pathSep}sysnative${pathSep}`, `${pathSep}system32${pathSep}`);
}
} else if (expectedArch === ArchType.ia32) {
const pathSep: string = ArchitectureReplacer.checkForFolderInPath(pipeProgramStr, "system32");
if (pathSep) {
// User has System32 but we expect 32 bit. Should be using sysnative
replacedPipeProgram = pipeProgramStr.replace(`${pathSep}system32${pathSep}`, `${pathSep}sysnative${pathSep}`);
}
}
}
return replacedPipeProgram;
}
// Checks to see if the folder name is in the path using both win and unix style path seperators.
// Returns the path seperator it detected if the folder is in the path.
// Or else it returns empty string to indicate it did not find it in the path.
public static checkForFolderInPath(path: string, folder: string): string {
if (path.indexOf(`/${folder}/`) >= 0) {
return '/';
} else if (path.indexOf(`\\${folder}\\`) >= 0) {
return '\\';
}
return "";
}
}
+33 -108
View File
@@ -22,6 +22,7 @@ import { DataBinding } from './dataBinding';
import minimatch = require("minimatch");
import * as logger from '../logger';
import { updateLanguageConfigurations } from './extension';
import { SettingsTracker, getTracker } from './settingsTracker';
let ui: UI;
@@ -115,92 +116,7 @@ const DebugProtocolNotification: NotificationType<OutputNotificationBody, void>
const DebugLogNotification: NotificationType<OutputNotificationBody, void> = new NotificationType<OutputNotificationBody, void>('cpptools/debugLog');
const InactiveRegionNotification: NotificationType<InactiveRegionParams, void> = new NotificationType<InactiveRegionParams, void>('cpptools/inactiveRegions');
const maxSettingLengthForTelemetry: number = 50;
let previousCppSettings: { [key: string]: any } = {};
/**
* 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 (String(key).toLowerCase()) {
case "clang_format_path": {
continue;
}
case "clang_format_style":
case "clang_format_fallbackstyle": {
let newKey: string = 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: {
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);
}
let failureMessageShown: boolean = false;
interface ClientModel {
isTagParsing: DataBinding<boolean>;
@@ -259,9 +175,9 @@ class DefaultClient implements Client {
private outputChannel: vscode.OutputChannel;
private debugChannel: vscode.OutputChannel;
private crashTimes: number[] = [];
private failureMessageShown = new PersistentState<boolean>("DefaultClient.failureMessageShown", false);
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 = {
@@ -317,7 +233,7 @@ class DefaultClient implements Client {
ui.bind(this);
this.onReadyPromise = languageClient.onReady().then(() => {
this.configuration = new configs.CppProperties(this.RootPath);
this.configuration = new configs.CppProperties(this.RootUri);
this.configuration.ConfigurationsChanged((e) => this.onConfigurationsChanged(e));
this.configuration.SelectionChanged((e) => this.onSelectedConfigurationChanged(e));
this.configuration.CompileCommandsChanged((e) => this.onCompileCommandsChanged(e));
@@ -331,24 +247,31 @@ class DefaultClient implements Client {
// Once this is set, we don't defer any more callbacks.
this.languageClient = languageClient;
telemetry.logLanguageServerEvent("NonDefaultInitialCppSettings", getNonDefaultSettings(this.RootUri));
this.failureMessageShown.Value = false;
this.settingsTracker = getTracker(this.RootUri);
telemetry.logLanguageServerEvent("NonDefaultInitialCppSettings", this.settingsTracker.getUserModifiedSettings());
failureMessageShown = false;
// Listen for messages from the language server.
this.registerNotifications();
this.registerFileWatcher();
}, () => {
}, (err) => {
this.isSupported = false; // Running on an OS we don't support yet.
if (!this.failureMessageShown.Value) {
this.failureMessageShown.Value = true;
vscode.window.showErrorMessage("Unable to start the C/C++ language server. IntelliSense features will be disabled.");
if (!failureMessageShown) {
failureMessageShown = true;
vscode.window.showErrorMessage("Unable to start the C/C++ language server. IntelliSense features will be disabled. Error: " + String(err));
}
});
} catch {
} catch (err) {
this.isSupported = false; // Running on an OS we don't support yet.
if (!this.failureMessageShown.Value) {
this.failureMessageShown.Value = true;
vscode.window.showErrorMessage("Unable to start the C/C++ language server. IntelliSense features will be disabled.");
if (!failureMessageShown) {
failureMessageShown = true;
let additionalInfo: string;
if (err.code === "EPERM") {
additionalInfo = `EPERM: Check permissions for '${getLanguageServerFileName()}'`;
} else {
additionalInfo = String(err);
}
vscode.window.showErrorMessage("Unable to start the C/C++ language server. IntelliSense features will be disabled. Error: " + additionalInfo);
}
}
}
@@ -397,7 +320,11 @@ class DefaultClient implements Client {
dimInactiveRegions: settings.dimInactiveRegions,
loggingLevel: settings.loggingLevel,
workspaceParsingPriority: settings.workspaceParsingPriority,
exclusionPolicy: settings.exclusionPolicy
exclusionPolicy: settings.exclusionPolicy,
preferredPathSeparator: settings.preferredPathSeparator,
default: {
systemIncludePath: settings.defaultSystemIncludePath
}
},
middleware: createProtocolFilter(this, allClients), // Only send messages directed at this client.
errorHandler: {
@@ -434,18 +361,13 @@ 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"]) {
updateLanguageConfigurations();
}
this.configuration.onDidChangeSettings();
telemetry.logLanguageServerEvent("CppSettingsChange", changedSettings, null);
}
}
@@ -528,7 +450,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*/);
@@ -672,7 +594,10 @@ class DefaultClient implements Client {
if (showIntelliSenseFallbackMessage.Value) {
let learnMorePanel: string = "Learn More";
let dontShowAgain: string = "Don't Show Again";
vscode.window.showInformationMessage("Configure includePath for better IntelliSense results.", learnMorePanel, dontShowAgain).then((value) => {
let fallbackMsg: string = this.configuration.VcpkgInstalled ?
"Update your IntelliSense settings or use Vcpkg to install libraries to help find missing headers." :
"Configure your IntelliSense settings to help find missing headers.";
vscode.window.showInformationMessage(fallbackMsg, learnMorePanel, dontShowAgain).then((value) => {
switch (value) {
case learnMorePanel:
let uri: vscode.Uri = vscode.Uri.parse(`https://go.microsoft.com/fwlink/?linkid=864631`);
@@ -8,6 +8,7 @@ import * as vscode from 'vscode';
import * as util from '../common';
import * as telemetry from '../telemetry';
import * as cpptools from './client';
import * as path from 'path';
const defaultClientKey: string = "@@default@@";
export interface ClientKey {
@@ -82,7 +83,7 @@ export class ClientCollection {
public checkOwnership(client: cpptools.Client, document: vscode.TextDocument): boolean {
let owners: cpptools.Client[] = [];
this.languageClients.forEach(languageClient => {
if (document.uri.fsPath.startsWith(languageClient.RootPath)) {
if (document.uri.fsPath.startsWith(languageClient.RootPath + path.sep)) {
owners.push(languageClient);
}
});
+249 -156
View File
@@ -8,83 +8,35 @@ 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';
const configVersion: number = 3;
import { CppSettings } from './settings';
const configVersion: number = 4;
let defaultSettings: string = `{
"configurations": [
{
"name": "Mac",
"includePath": [
"/usr/include",
"/usr/local/include",
"$\{workspaceFolder\}"
],
"defines": [],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"$\{workspaceFolder\}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
]
},
{
"name": "Linux",
"includePath": [
"/usr/include",
"/usr/local/include",
"$\{workspaceFolder\}"
],
"defines": [],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"$\{workspaceFolder\}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
},
{
"name": "Win32",
"includePath": [
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include",
"$\{workspaceFolder\}"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"intelliSenseMode": "msvc-x64",
"browse": {
"path": [
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*",
"$\{workspaceFolder\}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
],
"version": ${configVersion}
// 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: {} };
} else if (process.platform === 'win32') {
return { name: "Win32", browse: {} };
} else {
return { name: "Linux", browse: {} };
}
}
`;
export interface Browse {
path?: string[];
limitSymbolsToIncludedHeaders?: boolean;
databaseFilename?: string;
function getDefaultCppProperties(): ConfigurationJson {
return {
configurations: [getDefaultConfig()],
version: configVersion
};
}
interface ConfigurationJson {
configurations: Configuration[];
env?: {[key: string]: string | string[]};
version: number;
}
export interface Configuration {
@@ -101,20 +53,23 @@ export interface Configuration {
browse?: Browse;
}
export interface Browse {
path?: string[];
limitSymbolsToIncludedHeaders?: boolean | string;
databaseFilename?: string;
}
export interface CompilerDefaults {
compilerPath: string;
cStandard: string;
cppStandard: string;
includes: string[];
frameworks: string[];
}
interface ConfigurationJson {
configurations: Configuration[];
version: number;
intelliSenseMode: string;
}
export class CppProperties {
private rootUri: vscode.Uri;
private propertiesFile: vscode.Uri = null;
private readonly configFolder: string;
private configurationJson: ConfigurationJson = null;
@@ -127,25 +82,33 @@ export class CppProperties {
private defaultCppStandard: string = null;
private defaultIncludes: string[] = null;
private defaultFrameworks: string[] = null;
private vcpkgIncludes: string[] = [];
private vcpkgPathReady: boolean = false;
private defaultIntelliSenseMode: string = null;
private readonly configurationGlobPattern: string = "**/c_cpp_properties.json"; // TODO: probably should be a single file, not all files...
private disposables: vscode.Disposable[] = [];
private configurationsChanged = new vscode.EventEmitter<Configuration[]>();
private selectionChanged = new vscode.EventEmitter<number>();
private compileCommandsChanged = new vscode.EventEmitter<string>();
// Any time the `defaultSettings` are parsed and assigned to `this.configurationJson`,
// Any time the default settings are parsed and assigned to `this.configurationJson`,
// we want to track when the default includes have been added to it.
private configurationIncomplete: boolean = true;
constructor(rootPath: string) {
console.assert(rootPath !== undefined);
constructor(rootUri: vscode.Uri) {
console.assert(rootUri !== undefined);
this.rootUri = rootUri;
let rootPath: string = rootUri ? rootUri.fsPath : "";
this.currentConfigurationIndex = new PersistentFolderState<number>("CppProperties.currentConfigurationIndex", -1, rootPath);
this.configFolder = path.join(rootPath, ".vscode");
this.resetToDefaultSettings(this.currentConfigurationIndex.Value === -1);
let configFilePath: string = path.join(this.configFolder, "c_cpp_properties.json");
if (fs.existsSync(configFilePath)) {
this.propertiesFile = vscode.Uri.file(configFilePath);
this.parsePropertiesFile();
}
if (!this.configurationJson) {
this.resetToDefaultSettings(this.CurrentConfiguration === -1);
}
this.configFileWatcher = vscode.workspace.createFileSystemWatcher(path.join(this.configFolder, this.configurationGlobPattern));
@@ -165,6 +128,8 @@ export class CppProperties {
this.handleConfigurationChange();
});
this.buildVcpkgIncludePath();
this.disposables.push(vscode.Disposable.from(this.configurationsChanged, this.selectionChanged, this.compileCommandsChanged));
}
@@ -186,12 +151,17 @@ export class CppProperties {
this.defaultCppStandard = compilerDefaults.cppStandard;
this.defaultIncludes = compilerDefaults.includes;
this.defaultFrameworks = compilerDefaults.frameworks;
this.defaultIntelliSenseMode = compilerDefaults.intelliSenseMode;
// defaultPaths is only used when there isn't a c_cpp_properties.json, but we don't send the configuration changed event
// to the language server until the default include paths and frameworks have been sent.
this.handleConfigurationChange();
}
public get VcpkgInstalled(): boolean {
return this.vcpkgIncludes.length > 0;
}
private onConfigurationsChanged(): void {
this.configurationsChanged.fire(this.Configurations);
}
@@ -204,8 +174,19 @@ export class CppProperties {
this.compileCommandsChanged.fire(path);
}
public onDidChangeSettings(): void {
// Default settings may have changed in a way that affects the configuration.
// Just send another message since the language server will sort out whether anything important changed or not.
if (!this.propertiesFile) {
this.resetToDefaultSettings(true);
this.handleConfigurationChange();
} else if (!this.configurationIncomplete) {
this.handleConfigurationChange();
}
}
private resetToDefaultSettings(resetIndex: boolean): void {
this.configurationJson = JSON.parse(defaultSettings);
this.configurationJson = getDefaultCppProperties();
if (resetIndex || this.CurrentConfiguration < 0 ||
this.CurrentConfiguration >= this.configurationJson.configurations.length) {
this.currentConfigurationIndex.Value = this.getConfigIndexForPlatform(this.configurationJson);
@@ -213,38 +194,86 @@ export class CppProperties {
this.configurationIncomplete = true;
}
private applyDefaultIncludePathsAndFrameworks(): void {
if (this.configurationIncomplete && this.defaultIncludes && this.defaultFrameworks) {
this.configurationJson.configurations[this.CurrentConfiguration].includePath = this.defaultIncludes;
this.configurationJson.configurations[this.CurrentConfiguration].browse.path = this.defaultIncludes;
if (process.platform === 'darwin') {
this.configurationJson.configurations[this.CurrentConfiguration].macFrameworkPath = this.defaultFrameworks;
private applyDefaultIncludePathsAndFrameworks(): void {
if (this.configurationIncomplete && this.defaultIncludes && this.defaultFrameworks && this.vcpkgPathReady) {
let configuration: Configuration = this.configurationJson.configurations[this.CurrentConfiguration];
let settings: CppSettings = new CppSettings(this.rootUri);
// Anything that has a vscode setting for it will be resolved in updateServerOnFolderSettingsChange.
// So if a property is currently unset, but has a vscode setting, don't set it yet, otherwise the linkage
// to the setting will be lost if this configuration is saved into a c_cpp_properties.json file.
// Only add settings from the default compiler if user hasn't explicitly set the corresponding VS Code setting.
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 (this.defaultCompilerPath) {
this.configurationJson.configurations[this.CurrentConfiguration].compilerPath = this.defaultCompilerPath;
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);
}
if (this.defaultCStandard) {
this.configurationJson.configurations[this.CurrentConfiguration].cStandard = this.defaultCStandard;
if (!settings.defaultDefines) {
configuration.defines = (process.platform === 'win32') ? ["_DEBUG", "UNICODE", "_UNICODE"] : [];
}
if (this.defaultCppStandard) {
this.configurationJson.configurations[this.CurrentConfiguration].cppStandard = this.defaultCppStandard;
if (!settings.defaultMacFrameworkPath && process.platform === 'darwin') {
configuration.macFrameworkPath = this.defaultFrameworks;
}
if (!settings.defaultCompilerPath && this.defaultCompilerPath) {
configuration.compilerPath = this.defaultCompilerPath;
}
if (!settings.defaultCStandard && this.defaultCStandard) {
configuration.cStandard = this.defaultCStandard;
}
if (!settings.defaultCppStandard && this.defaultCppStandard) {
configuration.cppStandard = this.defaultCppStandard;
}
if (!settings.defaultIntelliSenseMode) {
configuration.intelliSenseMode = this.defaultIntelliSenseMode;
}
this.configurationIncomplete = false;
}
}
private getConfigIndexForPlatform(config: any): number {
if (this.configurationJson.configurations.length > 3) {
return this.configurationJson.configurations.length - 1; // Default to the last custom configuration.
private async buildVcpkgIncludePath(): Promise<void> {
try {
// Check for vcpkg instance and include relevent paths if found.
if (await util.checkFileExists(util.getVcpkgPathDescriptorFile())) {
let vcpkgRoot: string = await util.readFileText(util.getVcpkgPathDescriptorFile());
vcpkgRoot = vcpkgRoot.trim();
if (await util.checkDirectoryExists(vcpkgRoot)) {
let vcpkgInstalledPath: string = path.join(vcpkgRoot, "/installed");
let list: string[] = await util.readDir(vcpkgInstalledPath);
if (list !== undefined) {
// For every *directory* in the list (non-recursive). Each directory is basically a platform.
list.forEach((entry) => {
if (entry !== "vcpkg") {
let pathToCheck: string = path.join(vcpkgInstalledPath, entry);
if (fs.existsSync(pathToCheck)) {
let p: string = path.join(pathToCheck, "include");
if (fs.existsSync(p)) {
this.vcpkgIncludes.push(p);
}
}
}
});
}
}
}
} catch (error) {} finally {
this.vcpkgPathReady = true;
this.handleConfigurationChange();
}
let nodePlatform: NodeJS.Platform = process.platform;
}
private getConfigIndexForPlatform(config: any): number {
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) {
@@ -260,14 +289,12 @@ 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 {
@@ -281,7 +308,12 @@ export class CppProperties {
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) {
config.includePath = ["${default}"];
}
config.includePath.splice(config.includePath.length, 0, path);
fs.writeFileSync(this.propertiesFile.fsPath, JSON.stringify(this.configurationJson, null, 4));
this.updateServerOnFolderSettingsChange();
@@ -297,38 +329,83 @@ export class CppProperties {
this.onSelectionChanged();
}
private resolveAndSplit(paths: string[] | undefined): string[] {
private resolveDefaults(entries: string[], defaultValue: string[]): string[] {
let result: string[] = [];
entries.forEach(entry => {
if (entry === "${default}") {
// 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);
}
});
return result;
}
private resolveAndSplit(paths: string[] | undefined, defaultValue: string[]): string[] {
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);
});
}
return result;
}
private resolveVariables(input: string | boolean, defaultValue: string | boolean): string | boolean {
if (input === undefined || input === "${default}") {
input = defaultValue;
}
if (typeof input === "boolean") {
return input;
}
return util.resolveVariables(input, this.configurationJson.env);
}
private updateConfiguration(property: string[], defaultValue: string[]): string[];
private updateConfiguration(property: string, defaultValue: string): string;
private updateConfiguration(property: string | boolean, defaultValue: boolean): boolean;
private updateConfiguration(property, defaultValue): any {
if (typeof property === "string" || typeof defaultValue === "string") {
return this.resolveVariables(property, defaultValue);
} else if (typeof property === "boolean" || typeof defaultValue === "boolean") {
return this.resolveVariables(property, defaultValue);
} else if (property instanceof Array || defaultValue instanceof Array) {
if (property) {
return this.resolveAndSplit(property, defaultValue);
} else if (property === undefined && defaultValue) {
return this.resolveAndSplit(defaultValue, []);
}
}
return property;
}
private updateServerOnFolderSettingsChange(): void {
let settings: CppSettings = new CppSettings(this.rootUri);
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let configuration: Configuration = this.configurationJson.configurations[i];
if (configuration.includePath) {
configuration.includePath = this.resolveAndSplit(configuration.includePath);
}
if (configuration.browse && configuration.browse.path) {
configuration.browse.path = this.resolveAndSplit(configuration.browse.path);
}
if (configuration.macFrameworkPath) {
configuration.macFrameworkPath = this.resolveAndSplit(configuration.macFrameworkPath);
}
if (configuration.forcedInclude) {
configuration.forcedInclude = this.resolveAndSplit(configuration.forcedInclude);
}
if (configuration.compileCommands) {
configuration.compileCommands = util.resolveVariables(configuration.compileCommands);
}
if (configuration.compilerPath) {
configuration.compilerPath = util.resolveVariables(configuration.compilerPath);
configuration.includePath = this.updateConfiguration(configuration.includePath, settings.defaultIncludePath);
configuration.defines = this.updateConfiguration(configuration.defines, settings.defaultDefines);
configuration.macFrameworkPath = this.updateConfiguration(configuration.macFrameworkPath, settings.defaultMacFrameworkPath);
configuration.forcedInclude = this.updateConfiguration(configuration.forcedInclude, settings.defaultForcedInclude);
configuration.compileCommands = this.updateConfiguration(configuration.compileCommands, settings.defaultCompileCommands);
configuration.compilerPath = this.updateConfiguration(configuration.compilerPath, settings.defaultCompilerPath);
configuration.cStandard = this.updateConfiguration(configuration.cStandard, settings.defaultCStandard);
configuration.cppStandard = this.updateConfiguration(configuration.cppStandard, settings.defaultCppStandard);
configuration.intelliSenseMode = this.updateConfiguration(configuration.intelliSenseMode, settings.defaultIntelliSenseMode);
if (!configuration.browse) {
configuration.browse = {};
}
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);
}
this.updateCompileCommandsFileWatchers();
@@ -435,7 +512,7 @@ export class CppProperties {
throw { message: "Invalid configuration file. There must be at least one configuration present in the array." };
}
if (!this.configurationIncomplete && this.configurationJson && this.configurationJson.configurations &&
this.CurrentConfiguration < this.configurationJson.configurations.length) {
this.CurrentConfiguration >= 0 && this.CurrentConfiguration < this.configurationJson.configurations.length) {
for (let i: number = 0; i < newJson.configurations.length; i++) {
if (newJson.configurations[i].name === this.configurationJson.configurations[this.CurrentConfiguration].name) {
this.currentConfigurationIndex.Value = i;
@@ -444,23 +521,22 @@ export class CppProperties {
}
}
this.configurationJson = newJson;
if (this.CurrentConfiguration >= newJson.configurations.length) {
if (this.CurrentConfiguration < 0 || this.CurrentConfiguration >= newJson.configurations.length) {
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;
let dirty: boolean = false;
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let config: Configuration = this.configurationJson.configurations[i];
if (config.intelliSenseMode === undefined) {
dirty = true;
config.intelliSenseMode = this.getIntelliSenseModeForPlatform(config.name);
}
}
if (this.configurationJson.version !== configVersion) {
dirty = true;
if (this.configurationJson.version === undefined) {
@@ -469,30 +545,23 @@ 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.');
}
}
// Update the compilerPath, cStandard, and cppStandard with the default if they're missing.
let config: Configuration = this.configurationJson.configurations[this.CurrentConfiguration];
// 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) {
config.compilerPath = this.defaultCompilerPath;
dirty = true;
}
if (!config.cStandard && this.defaultCStandard) {
config.cStandard = this.defaultCStandard;
dirty = true;
}
if (!config.cppStandard && this.defaultCppStandard) {
config.cppStandard = this.defaultCppStandard;
dirty = true;
}
if (dirty) {
fs.writeFileSync(this.propertiesFile.fsPath, JSON.stringify(this.configurationJson, null, 4));
try {
fs.writeFileSync(this.propertiesFile.fsPath, JSON.stringify(this.configurationJson, null, 4));
} catch {
// Ignore write errors, the file may be under source control. Updated settings will only be modified in memory.
vscode.window.showWarningMessage('Attempt to update "' + this.propertiesFile.fsPath + '" failed (do you have write access?)');
}
}
} catch (err) {
vscode.window.showErrorMessage('Failed to parse "' + this.propertiesFile.fsPath + '": ' + err.message);
@@ -520,7 +589,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",
@@ -531,6 +600,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");
+59 -3
View File
@@ -47,14 +47,28 @@ export function activate(activationEventOccurred: boolean): void {
// Check if an activation event has already occurred.
if (activationEventOccurred) {
return onActivationEvent();
onActivationEvent();
return;
}
// handle "workspaceContains:/.vscode/c_cpp_properties.json" activation event.
if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) {
for (let i: number = 0; i < vscode.workspace.workspaceFolders.length; ++i) {
let config: string = path.join(vscode.workspace.workspaceFolders[i].uri.fsPath, ".vscode/c_cpp_properties.json");
if (fs.existsSync(config)) {
onActivationEvent();
return;
}
}
}
// handle "onLanguage:cpp" and "onLanguage:c" activation events.
if (vscode.workspace.textDocuments !== undefined && vscode.workspace.textDocuments.length > 0) {
for (let i: number = 0; i < vscode.workspace.textDocuments.length; ++i) {
let document: vscode.TextDocument = vscode.workspace.textDocuments[i];
if (document.languageId === "cpp" || document.languageId === "c") {
return onActivationEvent();
onActivationEvent();
return;
}
}
}
@@ -192,6 +206,7 @@ function registerCommands(): void {
disposables.push(vscode.commands.registerCommand('C_Cpp.ConfigurationEdit', onEditConfiguration));
disposables.push(vscode.commands.registerCommand('C_Cpp.AddToIncludePath', onAddToIncludePath));
disposables.push(vscode.commands.registerCommand('C_Cpp.ToggleErrorSquiggles', onToggleSquiggles));
disposables.push(vscode.commands.registerCommand('C_Cpp.ToggleSnippets', onToggleSnippets));
disposables.push(vscode.commands.registerCommand('C_Cpp.ToggleIncludeFallback', onToggleIncludeFallback));
disposables.push(vscode.commands.registerCommand('C_Cpp.ToggleDimInactiveRegions', onToggleDimInactiveRegions));
disposables.push(vscode.commands.registerCommand('C_Cpp.ShowReleaseNotes', onShowReleaseNotes));
@@ -329,6 +344,47 @@ function onToggleSquiggles(): void {
settings.toggleSetting("errorSquiggles", "Enabled", "Disabled");
}
function onToggleSnippets(): void {
onActivationEvent();
// This will apply to all clients as it's a global toggle. It will require a reload.
const snippetsCatName: string = "Snippets";
let newPackageJson: any = util.getRawPackageJson();
if (newPackageJson.categories.findIndex(cat => cat === snippetsCatName) === -1) {
// Add the Snippet category and snippets node.
newPackageJson.categories.push(snippetsCatName);
newPackageJson.contributes.snippets = [{"language": "cpp", "path": "./cpp_snippets.json"}, {"language": "c", "path": "./cpp_snippets.json"}];
fs.writeFile(util.getPackageJsonPath(), util.stringifyPackageJson(newPackageJson), () => {
showReloadPrompt("Reload Window to finish enabling C++ snippets");
});
} else {
// Remove the category and snippets node.
let ndxCat: number = newPackageJson.categories.indexOf(snippetsCatName);
if (ndxCat !== -1) {
newPackageJson.categories.splice(ndxCat, 1);
}
delete newPackageJson.contributes.snippets;
fs.writeFile(util.getPackageJsonPath(), util.stringifyPackageJson(newPackageJson), () => {
showReloadPrompt("Reload Window to finish disabling C++ snippets");
});
}
}
function showReloadPrompt(msg: string): void {
let reload: string = "Reload";
vscode.window.showInformationMessage(msg, reload).then(value => {
if (value === reload) {
vscode.commands.executeCommand("workbench.action.reloadWindow");
}
});
}
function onToggleIncludeFallback(): void {
onActivationEvent();
// This only applies to the active client.
+14
View File
@@ -47,6 +47,20 @@ export class CppSettings extends Settings {
public get workspaceParsingPriority(): boolean { return super.Section.get<boolean>("workspaceParsingPriority"); }
public get exclusionPolicy(): boolean { return super.Section.get<boolean>("exclusionPolicy"); }
public get commentContinuationPatterns(): (string | CommentPattern)[] { return super.Section.get<(string | CommentPattern)[]>("commentContinuationPatterns"); }
public get preferredPathSeparator(): string { return super.Section.get<string>("preferredPathSeparator"); }
public get defaultIncludePath(): string[] { return super.Section.get<string[]>("default.includePath"); }
public get defaultDefines(): string[] { return super.Section.get<string[]>("default.defines"); }
public get defaultMacFrameworkPath(): string[] { return super.Section.get<string[]>("default.macFrameworkPath"); }
public get defaultCompileCommands(): string { return super.Section.get<string>("default.compileCommands"); }
public get defaultForcedInclude(): string[] { return super.Section.get<string[]>("default.forcedInclude"); }
public get defaultIntelliSenseMode(): string { return super.Section.get<string>("default.intelliSenseMode"); }
public get defaultCompilerPath(): string { return super.Section.get<string>("default.compilerPath"); }
public get defaultCStandard(): string { return super.Section.get<string>("default.cStandard"); }
public get defaultCppStandard(): string { return super.Section.get<string>("default.cppStandard"); }
public get defaultBrowsePath(): string[] { return super.Section.get<string[]>("default.browse.path"); }
public get defaultDatabaseFilename(): string { return super.Section.get<string>("default.browse.databaseFilename"); }
public get defaultLimitSymbolsToIncludedHeaders(): boolean { return super.Section.get<boolean>("default.browse.limitSymbolsToIncludedHeaders"); }
public get defaultSystemIncludePath(): string[] { return super.Section.get<string[]>("default.systemIncludePath"); }
public toggleSetting(name: string, value1: string, value2: string): void {
let value: string = super.Section.get<string>(name);
@@ -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;
}
+8 -5
View File
@@ -110,12 +110,15 @@ export class UI {
public activeDocumentChanged(): void {
let activeEditor: vscode.TextEditor = vscode.window.activeTextEditor;
let show: boolean = (activeEditor && (activeEditor.document.languageId === "cpp" || activeEditor.document.languageId === "c"));
let isCpp: boolean = (activeEditor && (activeEditor.document.languageId === "cpp" || activeEditor.document.languageId === "c"));
this.ShowConfiguration = show;
this.ShowDBIcon = show;
this.ShowFlameIcon = show;
this.ShowNavigation = show;
// It's sometimes desirable to see the config and icons when making settings changes.
let isSettingsJson: boolean = (activeEditor && (activeEditor.document.fileName.endsWith("c_cpp_properties.json") || activeEditor.document.fileName.endsWith("settings.json")));
this.ShowConfiguration = isCpp || isSettingsJson;
this.ShowDBIcon = isCpp || isSettingsJson;
this.ShowFlameIcon = isCpp || isSettingsJson;
this.ShowNavigation = isCpp;
}
public bind(client: Client): void {
+8 -7
View File
@@ -35,7 +35,7 @@ function downloadCpptoolsJson(urlString): Promise<void> {
let request: ClientRequest = https.request({
host: parsedUrl.host,
path: parsedUrl.path,
agent: util.GetHttpsProxyAgent(),
agent: util.getHttpsProxyAgent(),
rejectUnauthorized: vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true)
}, (response) => {
if (response.statusCode === 301 || response.statusCode === 302) {
@@ -80,16 +80,17 @@ export function downloadCpptoolsJsonPkg(): Promise<void> {
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 (!util.packageJson.extensionFolderPath.includes(".vscode-insiders")) {
let prevIntelliSenseEngineDefault: any = util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default;
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) {
util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Default";
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Default";
} else {
util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Tag Parser";
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Tag Parser";
}
if (prevIntelliSenseEngineDefault !== util.packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default) {
return util.writeFileText(util.getPackageJsonPath(), util.getPackageJsonString());
if (prevIntelliSenseEngineDefault !== packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default) {
return util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson));
}
}
}
+1
View File
@@ -22,6 +22,7 @@ class TemporaryCommandRegistrar {
"C_Cpp.ToggleErrorSquiggles",
"C_Cpp.ToggleIncludeFallback",
"C_Cpp.ToggleDimInactiveRegions",
"C_Cpp.ToggleSnippets",
"C_Cpp.ShowReleaseNotes",
"C_Cpp.ResetDatabase",
"C_Cpp.PauseParsing",
+80 -8
View File
@@ -20,17 +20,41 @@ export function setExtensionContext(context: vscode.ExtensionContext): void {
extensionContext = context;
}
export let packageJson: any = vscode.extensions.getExtension("ms-vscode.cpptools").packageJSON;
// Use this package.json to read values
export const packageJson: any = vscode.extensions.getExtension("ms-vscode.cpptools").packageJSON;
// Use getRawPackageJson to read and write back to package.json
// This prevents obtaining any of VSCode's expanded variables.
let rawPackageJson: any = null;
export function getRawPackageJson(): any {
if (rawPackageJson === null) {
const fileContents: Buffer = fs.readFileSync(getPackageJsonPath());
rawPackageJson = JSON.parse(fileContents.toString());
}
return rawPackageJson;
}
// This function is used to stringify the rawPackageJson.
// Do not use with util.packageJson or else the expanded
// package.json will be written back.
export function stringifyPackageJson(packageJson: string): string {
return JSON.stringify(packageJson, null, 2);
}
export function getExtensionFilePath(extensionfile: string): string {
return path.resolve(extensionContext.extensionPath, extensionfile);
}
export function getPackageJsonPath(): string {
return getExtensionFilePath("package.json");
}
export function getPackageJsonString(): string {
packageJson.main = "./out/src/main"; // Needs to be reset, because the relative path is removed by VS Code.
return JSON.stringify(packageJson, null, 2);
export function getVcpkgPathDescriptorFile(): string {
if (process.platform === 'win32') {
return path.join(process.env.LOCALAPPDATA, "vcpkg/vcpkg.path.txt");
} else {
return path.join(process.env.HOME, ".vcpkg/vcpkg.path.txt");
}
}
// Extension is ready if install.lock exists and debugAdapters folder exist.
@@ -119,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
@@ -134,7 +161,18 @@ 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('.');
@@ -142,6 +180,18 @@ export function resolveVariables(input: string): string {
newValue = (config) ? config.toString() : undefined;
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"); }
}
return (newValue) ? newValue : match;
@@ -182,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;
@@ -250,6 +300,28 @@ export function checkFileExists(filePath: string): Promise<boolean> {
});
}
/** Test whether a directory exists */
export function checkDirectoryExists(dirPath: string): Promise<boolean> {
return new Promise((resolve, reject) => {
fs.stat(dirPath, (err, stats) => {
if (stats && stats.isDirectory()) {
resolve(true);
} else {
resolve(false);
}
});
});
}
/** Read the files in a directory */
export function readDir(dirPath: string): Promise<string[]> {
return new Promise((resolve) => {
fs.readdir(dirPath, (err, list) => {
resolve(list);
});
});
}
/** Test whether the lock file exists.*/
export function checkInstallLockFile(): Promise<boolean> {
return checkFileExists(getInstallLockPath());
+20 -12
View File
@@ -114,18 +114,22 @@ async function downloadAndInstallPackages(info: PlatformInformation): Promise<vo
let outputChannelLogger: Logger = getOutputChannelLogger();
outputChannelLogger.appendLine("Updating C/C++ dependencies...");
let statusItem: vscode.StatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
let packageManager: PackageManager = new PackageManager(info, outputChannelLogger, statusItem);
let packageManager: PackageManager = new PackageManager(info, outputChannelLogger);
outputChannelLogger.appendLine('');
setInstallationStage('downloadPackages');
await packageManager.DownloadPackages();
return vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: "C/C++ Extension",
cancellable: false
}, async (progress, token) => {
outputChannelLogger.appendLine('');
setInstallationStage('installPackages');
await packageManager.InstallPackages();
outputChannelLogger.appendLine('');
setInstallationStage('downloadPackages');
await packageManager.DownloadPackages(progress);
statusItem.dispose();
outputChannelLogger.appendLine('');
setInstallationStage('installPackages');
await packageManager.InstallPackages(progress);
});
}
function makeBinariesExecutable(): Promise<void> {
@@ -287,7 +291,9 @@ async function finalizeExtensionActivation(): Promise<void> {
function rewriteManifest(): Promise<void> {
// Replace activationEvents with the events that the extension should be activated for subsequent sessions.
util.packageJson.activationEvents = [
let packageJson: any = util.getRawPackageJson();
packageJson.activationEvents = [
"onLanguage:cpp",
"onLanguage:c",
"onCommand:extension.pickNativeProcess",
@@ -301,14 +307,16 @@ function rewriteManifest(): Promise<void> {
"onCommand:C_Cpp.ToggleErrorSquiggles",
"onCommand:C_Cpp.ToggleIncludeFallback",
"onCommand:C_Cpp.ToggleDimInactiveRegions",
"onCommand:C_Cpp.ToggleSnippets",
"onCommand:C_Cpp.ShowReleaseNotes",
"onCommand:C_Cpp.ResetDatabase",
"onCommand:C_Cpp.PauseParsing",
"onCommand:C_Cpp.ResumeParsing",
"onCommand:C_Cpp.ShowParsingCommands",
"onCommand:C_Cpp.TakeSurvey",
"onDebug"
"onDebug",
"workspaceContains:/.vscode/c_cpp_properties.json"
];
return util.writeFileText(util.getPackageJsonPath(), util.getPackageJsonString());
return util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson));
}
+26 -43
View File
@@ -67,24 +67,33 @@ export class PackageManager {
public constructor(
private platformInfo: PlatformInformation,
private outputChannel?: Logger,
private statusItem?: vscode.StatusBarItem) {
private outputChannel?: Logger) {
// Ensure our temp files get cleaned up in case of error
tmp.setGracefulCleanup();
}
public DownloadPackages(): Promise<void> {
public DownloadPackages(progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
return this.GetPackages()
.then((packages) => {
return this.BuildPromiseChain(packages, (pkg) => this.DownloadPackage(pkg));
let count: number = 1;
return this.BuildPromiseChain(packages, (pkg): Promise<void> => {
const p: Promise<void> = this.DownloadPackage(pkg, `${count}/${packages.length}`, progress);
count += 1;
return p;
});
});
}
public InstallPackages(): Promise<void> {
public InstallPackages(progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
return this.GetPackages()
.then((packages) => {
return this.BuildPromiseChain(packages, (pkg) => this.InstallPackage(pkg));
.then((packages) => {
let count: number = 1;
return this.BuildPromiseChain(packages, (pkg): Promise<void> => {
const p: Promise<void> = this.InstallPackage(pkg, `${count}/${packages.length}`, progress);
count += 1;
return p;
});
});
}
/** Builds a chain of promises by calling the promiseBuilder function once per item in the list.
@@ -137,14 +146,13 @@ export class PackageManager {
});
}
private async DownloadPackage(pkg: IPackage): Promise<void> {
private async DownloadPackage(pkg: IPackage, progressCount: string, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
this.AppendChannel(`Downloading package '${pkg.description}' `);
this.SetStatusText("$(cloud-download) Downloading packages...");
this.SetStatusTooltip(`Downloading package '${pkg.description}'...`);
progress.report({message: `Downloading ${progressCount}: ${pkg.description}`});
const tmpResult: tmp.SyncResult = await this.CreateTempFile(pkg);
await this.DownloadPackageWithRetries(pkg, tmpResult);
await this.DownloadPackageWithRetries(pkg, tmpResult, progress);
}
private async CreateTempFile(pkg: IPackage): Promise<tmp.SyncResult> {
@@ -159,7 +167,7 @@ export class PackageManager {
});
}
private async DownloadPackageWithRetries(pkg: IPackage, tmpResult: tmp.SyncResult): Promise<void> {
private async DownloadPackageWithRetries(pkg: IPackage, tmpResult: tmp.SyncResult, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
pkg.tmpFile = tmpResult;
let success: boolean = false;
@@ -170,7 +178,7 @@ export class PackageManager {
// Retry the download at most MAX_RETRIES times with 2-32 seconds delay.
do {
try {
await this.DownloadFile(pkg.url, pkg, retryCount);
await this.DownloadFile(pkg.url, pkg, retryCount, progress);
success = true;
} catch (error) {
retryCount += 1;
@@ -208,14 +216,14 @@ export class PackageManager {
}
// reloadCpptoolsJson in main.ts uses ~25% of this function.
private DownloadFile(urlString: any, pkg: IPackage, delay: number): Promise<void> {
private DownloadFile(urlString: any, pkg: IPackage, delay: number, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
let parsedUrl: url.Url = url.parse(urlString);
let proxyStrictSSL: any = vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true);
let options: https.RequestOptions = {
host: parsedUrl.host,
path: parsedUrl.path,
agent: util.GetHttpsProxyAgent(),
agent: util.getHttpsProxyAgent(),
rejectUnauthorized: proxyStrictSSL
};
@@ -241,7 +249,7 @@ export class PackageManager {
} else {
redirectUrl = response.headers.location[0];
}
return resolve(this.DownloadFile(redirectUrl, pkg, 0));
return resolve(this.DownloadFile(redirectUrl, pkg, 0, progress));
} else if (response.statusCode !== 200) {
// Download failed - print error message
let errorMessage: string = `failed (error code '${response.statusCode}')`;
@@ -255,7 +263,6 @@ export class PackageManager {
contentLength = response.headers['content-length'][0];
}
let packageSize: number = parseInt(contentLength, 10);
let downloadedBytes: number = 0;
let downloadPercentage: number = 0;
let dots: number = 0;
let tmpFile: fs.WriteStream = fs.createWriteStream(null, { fd: pkg.tmpFile.fd });
@@ -263,15 +270,6 @@ export class PackageManager {
this.AppendChannel(`(${Math.ceil(packageSize / 1024)} KB) `);
response.on('data', (data) => {
downloadedBytes += data.length;
// Update status bar item with percentage
let newPercentage: number = Math.ceil(100 * (downloadedBytes / packageSize));
if (newPercentage !== downloadPercentage) {
this.SetStatusTooltip(`Downloading package '${pkg.description}'... ${downloadPercentage}%`);
downloadPercentage = newPercentage;
}
// Update dots after package name in output console
let newDots: number = Math.ceil(downloadPercentage / 5);
if (newDots > dots) {
@@ -305,11 +303,10 @@ export class PackageManager {
});
}
private InstallPackage(pkg: IPackage): Promise<void> {
private InstallPackage(pkg: IPackage, progressCount: string, progress: vscode.Progress<{message?: string; increment?: number}>): Promise<void> {
this.AppendLineChannel(`Installing package '${pkg.description}'`);
this.SetStatusText("$(desktop-download) Installing packages...");
this.SetStatusTooltip(`Installing package '${pkg.description}'`);
progress.report({message: `Installing ${progressCount}: ${pkg.description}`});
return new Promise<void>((resolve, reject) => {
if (!pkg.tmpFile || pkg.tmpFile.fd === 0) {
@@ -424,18 +421,4 @@ export class PackageManager {
this.outputChannel.appendLine(text);
}
}
private SetStatusText(text: string): void {
if (this.statusItem) {
this.statusItem.text = text;
this.statusItem.show();
}
}
private SetStatusTooltip(text: string): void {
if (this.statusItem) {
this.statusItem.tooltip = text;
this.statusItem.show();
}
}
}
@@ -20,8 +20,12 @@ suite(`Debug Integration Test: `, function() {
let debugSessionTerminated = new Promise(resolve => {
vscode.debug.onDidTerminateDebugSession((e) => resolve());
});
assert.equal(vscode.debug.activeDebugSession.type, "cppdbg");
try {
assert.equal(vscode.debug.activeDebugSession.type, "cppdbg");
} catch (e) {
assert.fail("Debugger failed to launch. Did the extension activate correctly?")
}
await debugSessionTerminated;
});
@@ -6,6 +6,8 @@
import * as vscode from 'vscode';
import * as assert from 'assert';
import { getLanguageConfigFromPatterns } from '../../src/LanguageServer/languageConfig';
import * as config from '../../src/LanguageServer/configurations';
import { CppSettings } from '../../src/LanguageServer/settings';
suite("multiline comment setting tests", function() {
suiteSetup(async function() {
@@ -74,4 +76,56 @@ suite("multiline comment setting tests", function() {
assert.deepEqual(rules, defaultSLRules);
});
});
});
/*
suite("configuration tests", function() {
suiteSetup(async function() {
let extension: vscode.Extension<any> = vscode.extensions.getExtension("ms-vscode.cpptools");
if (!extension.isActive) {
await extension.activate();
}
// Open a c++ file to start the language server.
await vscode.workspace.openTextDocument({ language: "cpp", content: "int main() { return 0; }"});
});
suiteTeardown(async function() {
// Delete c_cpp_properties.json
});
test("Check default configuration", () => {
let rootUri: vscode.Uri;
if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) {
rootUri = vscode.workspace.workspaceFolders[0].uri;
}
assert.notEqual(rootUri, undefined, "Root Uri is not defined");
if (rootUri) {
let cppProperties: config.CppProperties = new config.CppProperties(rootUri);
let configurations: config.Configuration[] = cppProperties.Configurations;
let defaultConfig: config.Configuration = config.getDefaultConfig();
assert.deepEqual(configurations[0], defaultConfig);
console.log(JSON.stringify(configurations, null, 2));
// Need to set the CompilerDefaults before the CppProperties can be successfully modified.
cppProperties.CompilerDefaults = {
compilerPath: "/path/to/compiler",
cStandard: "c99",
cppStandard: "c++14",
frameworks: ["/path/to/framework"],
includes: ["/path/to/includes"]
};
configurations[0].cppStandard = "${default}";
let s: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp.default", rootUri);
let d: any = s.inspect("cppStandard");
s.update("cppStandard", "c++11", vscode.ConfigurationTarget.WorkspaceFolder);
d = s.inspect("cppStandard");
cppProperties.onDidChangeSettings();
}
});
});
*/
+123
View File
@@ -0,0 +1,123 @@
/*---------------------------------------------------------------------------------------------
* 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);
}
+546
View File
@@ -0,0 +1,546 @@
{
"_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",
"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",
"properties": {
"name": "string",
"value": "string"
}
},
"CppdbgLaunchOptions": {
"type": "object",
"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"
},
"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",
"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",
"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",
"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"
]
}
+7
View File
@@ -1,4 +1,10 @@
<!--
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
@@ -9,6 +15,7 @@
* 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
+21 -5
View File
@@ -1,15 +1,31 @@
# vscode-cpptools
This is the official repository for filing issues against and getting support for the [Microsoft C/C++ extension for VS Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools).
This is the official repository for the [Microsoft C/C++ extension for VS Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools).
The `vscode-cpptools` repository is where we do development and there are many ways you can support the extension, for example:
* [Report issues or request features](https://github.com/Microsoft/vscode-cpptools/issues)
- If someone has filed a similar issue, please provide any additional information that can help us resolve it on the issue
- If someone has filed a similar feature request, please leave a thumbs up reaction on the issue
- [List of popular feature requests](https://github.com/Microsoft/vscode-cpptools/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3A%22Feature+Request%22)
* [Contribute to the extension](Extension)
## Getting Started
You can learn how to use the extension at [VS Code for C/C++](https://code.visualstudio.com/docs/languages/cpp).
If you clone this repository, you can also try out our [Code Samples](Code%20Samples).
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
Contributions are always welcome. Please see our [contributing guide](CONTRIBUTING.md) for more details.
### Microsoft Open Source Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact opencode@microsoft.com with any additional questions or comments.
### Documentation
The documentation has been moved to the [**Documentation**](Documentation) folder. If you would like to contribute, please create a Markdown file and submit a pull request.
### Data/Telemetry
This project collects usage data and sends it to Microsoft to help improve our products and services. Read our [privacy statement](https://privacy.microsoft.com/en-us/privacystatement) to learn more.
+1 -1
View File
@@ -70,7 +70,7 @@ Set or change the following options to control VS Code's behavior during debuggi
The following options enable you to modify the state of the target application when it is launched:
* #### `args`
JSON array of command line arguments to pass to the program when it is launched. Example `["arg1", "arg2]`.
JSON array of command line arguments to pass to the program when it is launched. Example `["arg1", "arg2"]`. If you are escaping characters you will need to double escape them. For example `["{\\\"arg\\\": true}]` will send `{"arg1": true}` to your application.
* #### `cwd`
Sets the the working directory of the application launched by the debugger.