Compare commits

...
259 Commits
Author SHA1 Message Date
Sean McManus da277c8593 Seanmcm/0 21 0 release2 (#3070)
* Update yauzl version and changelog date. (#3069)
2019-01-22 19:17:42 -08:00
Bob Brown b3cce807bb Merge pull request #3068 from Microsoft/seanmcm/0_21_0_release 2019-01-22 14:43:34 -08:00
Sean McManus a533eb9a43 Merge branch 'release' into seanmcm/0_21_0_release 2019-01-22 14:32:57 -08:00
Sean McManus 9702eae953 Update package.json. 2019-01-22 14:32:04 -08:00
Sean McManus a4b51997ff Update version. 2019-01-22 14:30:32 -08:00
Sean McManus ec9270f5a9 Update ReleaseNotes. (#3067) 2019-01-22 14:25:09 -08:00
Griffin Downs 75f35a1fd7 Fix CLI mismatch for downgrading (#3065) 2019-01-22 13:24:00 -08:00
Sean McManus dcc0174133 Update changelog. (#3050) 2019-01-18 11:23:33 -08:00
jogo- 3b8c3143e4 Fix typos in launch.md (#3027)
* Fix typos in launch.md
2019-01-16 16:24:56 -08:00
jogo- 33e7d70324 Fix typo in How To Debug MIEngine.md (#3028) 2019-01-14 16:47:54 -08:00
jogo- 703e23a62b Update FAQs.md (#3029)
Missing whitespace
2019-01-14 13:15:28 -08:00
Jmnote 39ba7fc6ba extenion → extension (#3002)
extenion → extension
2019-01-08 16:00:02 -08:00
Sean McManus 6488a11dc3 Update changelog (#2997) 2019-01-03 14:31:12 -08:00
Sean McManus 5ca48e24cf Update changelog for 0.21.0-insiders3. (#2958)
* Update changelog for 0.21.0-insiders3.
2019-01-03 13:20:33 -08:00
Sean McManus de9cc715fc Give a better message if the binary is missing. (#2975)
* Give a better message if the binary is missing.
2019-01-02 18:15:05 -08:00
Sean McManus c727ceca1b Remove json-based snippets, handled by the server now. (#2945)
* Remove json-based snippets, handled by the server now.
2018-12-27 18:36:27 -08:00
Sean McManus f58af4fb2e Disable wordBasedSuggestions by default. (#2944) 2018-12-20 14:39:41 -08:00
Andrew Wang 7935b97329 Update How To Debug MIEngine.md (#2935)
* Update How To Debug MIEngine.md

Added information on how to debug with VS Code

* Update How To Debug MIEngine.md

* .dll -> .pdb

Mistake on symbol list
2018-12-17 14:33:09 -08:00
Sean McManus bd6f8f0df3 Update date in changelog. (#2926)
* Update changelog.
2018-12-17 14:11:40 -08:00
Sean McManus 4b22333f5c Attempt to fix download failure. (#2931)
* Retry vsix download with http.proxySupport "off".
2018-12-17 13:58:43 -08:00
Sean McManus 968e0d2aae Fix bug with Insiders updating. 2018-12-14 18:39:36 -08:00
Sean McManus 8dc8b3bc37 Update changelog for 0.21.0-insiders2. (#2911)
* Update changelog for 0.21.0-insiders2.
* Update README.md.
* Update to 5.1.1 of the vscode-languageclient.
2018-12-13 18:02:35 -08:00
Matt Bise bb962b91e8 Add refresh button to process picker (#2895)
* Add attach QuickView with refresh

* vscode engine 1.23 -> 1.26

* Clean up disposables

* Add entry to CHANGELOG

* Provide refresh image for dark and light themes

* Add title to QuickPick
2018-12-10 15:50:53 -08:00
Sean McManus 8c53c027ca Protect against no activeDocument. (#2875) 2018-11-28 16:05:27 -08:00
Sean McManus b864126494 Fix missed package.json issue from my last checkin. (#2873) 2018-11-28 11:33:16 -08:00
Bob Brown b78e85619a bump up the timeout (#2872) 2018-11-28 09:17:16 -08:00
Sean McManus f474ba8539 Seanmcm/fix insiders debugging (#2871)
* Fix debugging with VS Code Insiders and other Linter fixes.
2018-11-27 16:34:31 -08:00
Sean McManus 0f1071a5c9 Seanmcm/exploration build (#2829)
* Treat the Exploration build like Insiders.
* Update changelog.
2018-11-16 15:11:05 -08:00
Sean McManus f69e6e191b Update telemetry API. (#2828) 2018-11-14 19:38:49 -08:00
Sean McManus 230895d6ba Remove <numbers><spaces> from the start of call stack lines. (#2827)
* Remove <numbers><spaces> from the start of call stack lines.
* Remove __1::.
2018-11-14 19:06:08 -08:00
Sean McManus fa8173076d Update MinGW.md (#2813)
* Update MinGW.md
2018-11-14 17:51:23 -08:00
Bob Brown 3079fb58ae ignore update failures caused by no network present (#2808) 2018-11-13 15:37:35 -08:00
Julien Russo 9f1b482de4 Translation improvements (#2663)
Moved command english translation to package.nls.json, added command translation for italian and modified package.json to use localization files.
2018-11-12 16:54:22 -08:00
Sean McManus 8f6714254a Seanmcm/0 21 0 changelog3 (#2796)
* Change "Fix for" to "Fix" in changelog.
2018-11-08 17:34:34 -08:00
Sean McManus 5246cdc527 Update changelog. (#2795) 2018-11-08 17:21:36 -08:00
Sean McManus 4938f5b2f4 Update changelog for 0.21.0-insiders. (#2794) 2018-11-08 16:14:52 -08:00
Bob Brown 21fef3b067 use WebviewPanel (#2781) (#2783) 2018-11-07 14:47:57 -08:00
Pierson Lee 71582d1883 Add avoidWindowsConsoleRedirection and fix externalConsole comment (#2772)
* Add avoidWindowsConsoleRedirection and fix externalConsole comment

* Update OptionsSchema.json

* Making Andrew happy by updating npm@latest
2018-11-06 13:33:04 -08:00
Pierson Lee 23fc338f71 Update launch.md 2018-11-05 10:31:37 -08:00
Sean McManus 4a8b143ce0 Add more crash telemetry filtering. (#2759) 2018-11-01 15:55:47 -07:00
Sean McManus b1274d3c76 Merge pull request #2749 from Microsoft/seanmcm/0_20_1_release
Seanmcm/0 20 1 release
2018-10-31 17:24:43 -07:00
Sean McManus 8f8565dbfd Merge branch 'seanmcm/0_20_1_release' of https://github.com/Microsoft/vscode-cpptools into seanmcm/0_20_1_release 2018-10-31 17:16:30 -07:00
Sean McManus 7f4614c31c Merge again. 2018-10-31 17:15:52 -07:00
Sean McManus eccee49017 Fix punctuation/spacing inconsistencies. (#2750) 2018-10-31 17:12:30 -07:00
Sean McManus e231453778 Merge branch 'release' into seanmcm/0_20_1_release 2018-10-31 16:29:33 -07:00
Sean McManus 8729804dc2 Update version. 2018-10-31 16:27:42 -07:00
Anandlal c607604b6b "taskName" changed to "label" as per version 2.0.0 (#2741)
https://code.visualstudio.com/docs/editor/tasks#_migrating-to-tasks-200
2018-10-31 16:24:50 -07:00
Sean McManus 460b95920f Update changelog, fwlinks, and update telemetry API (#2748)
Update changelog, fwlinks, and update telemetry API
2018-10-31 16:06:34 -07:00
Pierson Lee 1c38b55b9f Update external Console notes
Updated external console option to show changes to support for integratedTerminal.
2018-10-31 12:08:00 -07:00
Sean McManus 0cf237c839 Merge pull request #2725 from Microsoft/master
2nd merge for 0.20.0
2018-10-25 16:46:17 -07:00
Sean McManus e12bad5172 Fix 2 typos in the changelog. (#2723) 2018-10-25 16:42:57 -07:00
Bob Brown 04bb260577 update release notes (#2722) 2018-10-25 16:42:15 -07:00
Bob Brown ddc1f901c2 Merge pull request #2721 from Microsoft/seanmcm/0_20_0_release
Seanmcm/0 20 0 release
2018-10-25 16:21:08 -07:00
Sean McManus 9ca27af2df Merge. 2018-10-25 15:58:34 -07:00
Sean McManus b964d4ebc4 Fix comment for intelliSenseEngine setting. (#2720) 2018-10-25 15:57:20 -07:00
Sean McManus 082435ec8b Fix comment for intelliSenseEngine setting. 2018-10-25 15:48:28 -07:00
Sean McManus 324c5f59f4 Update changelog for 0.20.0 release. 2018-10-25 15:38:26 -07:00
Sean McManus 72581c23b7 Update changelog for 0.20.0. (#2718)
* Update changelog for 0.20.0.

* Revise changelog for 0.20.0.
2018-10-25 15:29:44 -07:00
Sean McManus 807ff80f56 Update vscode telemetry api used. (#2707) 2018-10-23 20:23:12 -07:00
Griffin Downs b0e17a1fd9 Don't update pre-releases (#2693) 2018-10-19 16:00:55 -07:00
Griffin Downs bc64d25a1d Ensure that package version suffix + version suffix version are set (#2686) 2018-10-19 15:29:38 -07:00
Sean McManus ed5d8c8fac Get rid of the MacCrash memory addresses. (#2695) 2018-10-18 19:17:36 -07:00
Sean McManus 3a9f4c404d Update changelog for 0.19.1-insiders3. (#2694) 2018-10-18 17:19:28 -07:00
Bob Brown 4330679e23 Don't allow configuration providers to activate the extension when IntelliSense is disabled (#2692) 2018-10-18 12:29:06 -07:00
Andrew Wang 88e9724892 Attempt to fix security and gulp 4.0 (#2689) 2018-10-17 14:34:21 -07:00
Sean McManus acf7b464eb Update changelog.md. (#2676)
* Update changelog.md.
2018-10-16 13:38:58 -07:00
Sean McManus 78f5a38110 Update changelog for 0.19.1-insiders2 (#2649)
* Update changelog for 0.19.1-insiders2
2018-10-11 15:59:02 -07:00
Pierson Lee 31eed4cee2 Add missing interop 15 file to dev workflow (#2643) 2018-10-11 12:28:32 -07:00
Pierson Lee ea8ab1358f Update CHANGELOG.md and copyDebuggerDependencies (#2641)
Update for VSCodeDebugProtocol dll and for the Integratedterminal Work.
2018-10-10 17:53:20 -07:00
Pierson Lee 55558a53e3 Update links for mono framework and runtime (#2640)
Updating to 5.14.0.177 of mono. Update TPN header per CELA
2018-10-10 16:37:23 -07:00
Griffin Downs 536685c8a0 Grdowns/update channel fix (#2637)
* Use shell optional arg

* Add try/catch around spawn to override any possible exceptions

* Default vsixname to cpptools-linux32.vsix

* Move logFailure inline

* Remove potential PII from error message to be on the safe side

* Fix linter errors

* Remove spawn optional arg; instead remove quotes surrounding command

* Remove rethrowing of error at the top level checkAndApplyUpdate

* Commenting

* Remove default case in switch statement for vsixName; Add x86, i383, i686 cases
2018-10-10 15:51:29 -07:00
Sean McManus b6f184744c Update changelog. (#2625) 2018-10-08 15:04:16 -07:00
Sean McManus 539ecc536f Update the changlog for 0.19.1-insiders. (#2615)
* Update the changlog for 0.19.1-insiders.
2018-10-08 11:42:59 -07:00
Sean McManus e819f36e91 Fix error when rootRui is null. (#2614) 2018-10-05 15:34:44 -07:00
Bob Brown 140670c371 Update c_cpp_properties.json.md 2018-10-04 08:48:54 -07:00
Pierson Lee 102ffc1616 Fixing quoting around ssh's command (#2604)
This fixes #2585
2018-10-03 17:35:02 -07:00
Bob Brown 28981f3ce6 remove telemetry that is already being blocked (#2603) 2018-10-03 16:45:53 -07:00
shankaryoga21 775aba8650 don't use falsy comparisons when resolving default settings. (#2592) 2018-10-02 13:18:16 -07:00
Bob Brown b3fb2558fd update telemetry version (#2593) 2018-10-02 12:46:35 -07:00
Griffin Downs 80716ae228 Grdowns/update channel4 (#2576)
* Remove redundant error telemetry
* Check rate limit before attempting to download release JSON
2018-10-02 10:13:10 -07:00
Bob Brown 6d71c6dd4f Merge pull request #2575 from Microsoft/bobbrow/releaseToMaster
Merge release to master
2018-09-28 09:54:40 -07:00
Bob Brown (DEVDIV) da68908e3e update version and fwlinks for October release 2018-09-28 09:35:26 -07:00
Sean McManus 963ee02117 Merge pull request #2572 from Microsoft/master
Merge latest changes
2018-09-27 15:05:13 -07:00
Sean McManus 45a1804da4 Update changelog. (#2571) 2018-09-27 14:57:45 -07:00
Pierson Lee f66eb138f4 Return null config to VS Code (#2570)
return null to trigger VS Code to open a configuration file
https://github.com/Microsoft/vscode/issues/54213
2018-09-27 14:32:35 -07:00
Bob Brown da862646c3 Merge pull request #2566 from Microsoft/bobbrow/release-19.0
Bobbrow/release 19.0
2018-09-26 16:32:14 -07:00
Bob Brown (DEVDIV) 1bcaa540b6 update version number and fwlink for abtesting json 2018-09-26 16:30:07 -07:00
Bob Brown 96e3386288 september release notes/string changes (#2563) 2018-09-26 13:38:54 -07:00
Sean McManus 862a10f3f8 Merge branch 'master' of https://github.com/Microsoft/vscode-cpptools 2018-09-26 13:16:13 -07:00
Sean McManus 2e62382b24 Update changelog for 0.19.0. 2018-09-26 13:15:40 -07:00
Sean McManus 5f9ef54c54 Add ab testing for Go to Def (fix some ab testing bugs) (#2559)
* Add goto_def_intellisense abTesting.
2018-09-26 09:39:31 -07:00
Bob Brown 4575e2840e incorrect warning messages (#2560) 2018-09-25 17:13:10 -07:00
Bob Brown a9a09dcd11 Only serialize tasks that require it (#2553)
* Remove serialization in the queuing except for cases that actually need it
2018-09-25 13:28:14 -07:00
Bob Brown e0e7944f3a Don't add workspaceFolderBasename to new config files (#2552) 2018-09-25 12:48:14 -07:00
Griffin Downs 63e18afcf1 Update Channel pt 3 (#2543)
* Instead of uninstalling then installing, install and override when prompted
2018-09-24 16:32:06 -07:00
Bob Brown fcdcd80157 Fixing queuing logic that stalls LS on Mac (#2540) 2018-09-24 15:01:06 -07:00
Griffin Downs 126cf7cef6 Update channel feature pt 2 (#2541)
* Find Mac code script; Commenting; Move code into try catches correctly filter errors; Add notification on installation

* Merge files from correct commit

* Revert changes made from not having master branch code
2018-09-21 16:25:27 -07:00
Bob Brown ad451bb438 Resolve empty array environment variables #2532 (#2534) 2018-09-20 16:15:32 -07:00
Griffin Downs 83be111769 Add updateChannel setting (#2465)
* Read json from harded-coded file location

* Expose settings tracker

* Get linux download url

* Remove unused imports

* Correctly get changed setting

* Add update timer

* Minimum end to end

* Refactoring; Commenting; Renaming

* Commenting

* Add optional param to download fn; Refactoring; Renaming

* Commenting; Then parse fn

* Mark vars const; Add todos; Refactoring

* Commenting; Refactoring

* url from any to string; Index into parsed json as separate step

* Use temp files to prevent clutter

* Correct windows platform name check; Replace quotes

* Resolve vsixName for mac + win

* Factor version comparisons into ParsedVersion class while correcting version comparison

* Use which utility to find code script

* Update timer to once per hour

* Move downloadFileToDestination to common; Replace downloadCpptoolsJsonAsync

* Return changed settings on onDidChangeSettings

* Get changed settings without stealing them

* Remove tracker from client interface

* Add basic isReleaseJson fn; Add telemetry; Add catch functions

* Write type predicates for release json

* Refactoring; Rewrite version check; Rewrite build selection

* Factor target build search into helper fn

* Reorder fn defs

* Uninstall version before installing if downgrading

* Add undefined checks; Update version comparison

* Reorder fn

* Telemetry rename; Parse versions more safely

* Turn ParsedVersion into interface; Rename release to build

* Fix fn return types

* Commenting

* Remove unneeded validity check

* Rename telemetry event; Correct fn return type

* Update setting description

* Remove promise rejection

* Remove unwanted changes

* Rename var

* Remove imports; Move call to updateSettingsAsync to .then in abTesting

* Remove import; Remove unneeded uses of await

* Remove comment

* Reformat else ifs

* Remove '| undefined' instances

* Use find fn more idiomatically

* Add type specification for predicates + rename them

* Add url var to shorten call to downloadFileToDestination

* Move parsedVersion to separate file

* Move parsedVersion into PackageVersion class

* Move helper fn's to separate file

* Get script name for both insiders and release VSCode (untested)

* Move packageVersion + ghAPI from LanguageServe to src

* Update imports to reflect mv; Check isValid on PackageVersion

* Add todo's

* Correctly get download URL; Correctly verify releaseJson by only checking recent 5 builds

* Check version numbers against undefined instead of 0

* Await install command before removing install file; Change var name

* Re-merge package.json

* Rename ghAPI.ts to githubAPI.ts

* Rename vars; Remove TODO

* Modify version comparison (untested)

* Remove todo

* Create file async

* Download and install file async

* Rework promises

* Make functions async where possible

* Commenting

* Grandfather in insiders users

* Change syntax via await keyword

* Re-enable interval timer

* Add updateChannel settings get

* Immediately check for update on extension activation if on insiders

* Surround windows code script path in quotes

* Rename versionStr to version

* Change telemetry event

* Update telemetry/exception handling

* Update telemetry strings; Reformat is functions

* Another pass at promises + telemetry

* Commenting

* Remove undefined from fn return

* Fix headers not being forwarded to recursive call

* Another pass at promises

* Correctly return promise in checkAndApplyUpdate

* Remove debug vars

* Rename fns

* Fix version parsing

* Tidy version comparison

* Remove commented out code

* Variable rename; Add newline at EOF

* Add newline at EOF

* Commenting; Unbind functions and use function syntax for .thens

* Error message; add rejection

* Correct exceptions being handled one promise too late

* PR feedback

* Rewrite promise chain to await to allow premature cancellation of promise chain

* Mark vars const; Comment; Rename var
2018-09-19 10:44:24 -07:00
Bob Brown 2f931d930d Implement provider API v2 (#2531)
* Implement provider API v2
2018-09-18 16:33:08 -07:00
Sean McManus bc6cb3e55f Add the active selection end. (#2511)
* Add the active selection end.
2018-09-17 14:11:13 -07:00
Gabriel Arjones f44e9068ca Allow workspaceFolderBasename in default settings (#2503) 2018-09-10 12:33:30 -07:00
Gabriel Arjones c206a4b88c Add support for 'workspaceFolderBasename' expansion (#2491) (#2495) 2018-09-07 15:06:08 -07:00
Bob Brown 9e95e412a8 The user settings were not considered when querying the active configuration provider (#2485) 2018-09-05 12:40:28 -07:00
Bob Brown 86ce6c6115 Update c_cpp_properties.json.md 2018-09-04 09:17:44 -07:00
Pierson Lee ecd3eb24f4 Fix sh command (#2475)
When the change from bash to sh happened, the comparison operator was
not updated.

Fixes #2444
2018-08-31 15:30:33 -07:00
Bob Brown 25e29a01c2 Fix bug in default CL macros (#2468)
* incorrect cl macros being defined
2018-08-30 17:00:56 -07:00
Bob Brown e9b8ad66a1 fix bad line endings (#2469) 2018-08-30 16:48:44 -07:00
Bob Brown 3e5a6aae80 Update c_cpp_properties.json.md 2018-08-28 10:47:22 -07:00
Bob Brown 49fea0249d Update MinGW.md 2018-08-28 10:45:36 -07:00
Bob Brown 7de9956a92 Update Windows Subsystem for Linux.md
a few people seem to be getting confused about the example usage
2018-08-28 08:38:29 -07:00
Bob Brown 9abf44b7ac Update language-service.md (#2454) 2018-08-27 12:52:35 -07:00
Bob Brown daaf169c8a Update Enabling logging.md 2018-08-24 11:27:23 -07:00
Bob Brown 23d94452bb Update MinGW.md 2018-08-20 08:29:41 -07:00
Bob Brown 705122a168 update master branch version (#2428) 2018-08-17 13:53:15 -07:00
Sean McManus 757f1f94be Merge pull request #2427 from Microsoft/master
Update changelog and version for 0.18.1. fwlinks don't need to change…
2018-08-17 11:08:28 -07:00
Sean McManus 7fe2db1202 Update changelog and version for 0.18.1. fwlinks don't need to change. (#2426) 2018-08-17 10:53:49 -07:00
Sean McManus d8738c3e0c Merge pull request #2421 from Microsoft/master
Update changelog. (#2420)
2018-08-17 06:07:19 -07:00
Sean McManus b1bd33b8f4 Update changelog. (#2420) 2018-08-17 06:05:16 -07:00
Sean McManus 436c483d35 Merge pull request #2418 from Microsoft/master
Register the config provider for new clients. (#2416)
2018-08-17 05:05:56 -07:00
Sean McManus 99bd382707 Register the config provider for new clients. (#2416) 2018-08-16 15:50:36 -07:00
Bob Brown 356bb903d0 Merge pull request #2414 from Microsoft/master
Merge for 0.18.0
2018-08-16 10:34:19 -07:00
Sean McManus b0fc9427cf Merge branch 'release' into master 2018-08-16 10:01:07 -07:00
Sean McManus 60b20dce8d Update package-lock and fix new linter errors. (#2412)
Update package-lock and fix new linter errors.
2018-08-16 09:59:18 -07:00
Sean McManus 906fd2d8f0 Seanmcm/auto open cpp properties (#2410)
* Invoke `Edit Configurations...` when the `Configuration Help` button is clicked.
2018-08-16 09:34:20 -07:00
Bob Brown 4afadad93b update changelog (#2411) 2018-08-16 09:22:46 -07:00
Sean McManus 3790fa95e7 Add intelliSenseEngine "Disabled". (#2392)
* Add intelliSenseEngine "Disabled".
2018-08-16 09:12:32 -07:00
Griffin Downs a0882446d9 Update changelog to reflect compile commands parsing fix (#2409)
* Update changelog to reflect compile commands parsing fix
2018-08-16 06:35:39 -07:00
Sean McManus ce59810a6d Update changelog for 0.18.0. (#2384)
* Update changelog for 0.18.0.
2018-08-15 13:45:38 -07:00
Sean McManus 770013d77e Enable environment variables with clang_format_path. (#2380)
* Enable environment variables with clang_format_path.
2018-08-15 09:39:45 -07:00
Pierson Lee 2388fa97f4 Update FAQs.md (#2343) 2018-08-08 11:26:53 -07:00
Sean McManus 3381cde61c Update changelog for 0.17.8-insiders. (#2353)
* Update changelog for 0.17.8-insiders.
2018-08-03 17:36:17 -07:00
Sean McManus 3a46f10d97 Add gcc-x64 intelliSenseMode. (#2315)
* Add gcc-x64 intelliSenseMode.
2018-08-02 13:53:19 -07:00
Bob Brown 2b4b5d397d add a setting to modify the behavior of go to symbol in workspace (#2349)
* add a setting to modify the behavior of go to symbol in workspace
2018-08-02 13:37:47 -07:00
Andy Neff c36eb8e7b1 Using sh instead of bash (#2340)
Fixes #569
2018-07-30 15:37:55 -07:00
Bob Brown ad46d3887a Only allow one configuration popup at a time (#2337) 2018-07-30 14:28:19 -07:00
Bob Brown 8b704f5972 allow users to use ~ for ${userprofile} on Windows (#2333) 2018-07-27 12:50:56 -07:00
Bob Brown 1009b76b22 minor tweaks to config provider experience (#2302) 2018-07-27 09:27:14 -07:00
John Patterson 84ff661e15 adds CHANGELOG entry for PR 2322 (#2325)
Realized I had left out the CHANGELOG update. For [PR
2322](https://github.com/Microsoft/vscode-cpptools/pull/2322).
2018-07-27 09:24:11 -07:00
Xeonacid 2292e7d762 Improve description in Extension/README.md (#2336)
`MinGW` is the proper spelling

`OS X` is now called `macOS`
2018-07-27 09:23:40 -07:00
Andrew Wang c8e30c70b1 Allow telemetry to detect failed downloads (#2332) 2018-07-26 13:35:34 -07:00
John Patterson 7947dd80d6 Add multi-pass environment variable resolution (#2322)
* Dependent variable definition
```
"env": {
    "envRoot": "apps/tool/builldenv",
    "arm6.include": "${envRoot}/arm6/include"
},
...
"some_config": "${arm6.include}
```

* Additionally, this fixes an open bug that was not reported. If a variable contained "env", "config", or "workspaceFolder" it would not be parsed correctly. If you used a variable ${envRoot} it would match "envR" as the type and "oot" as the variable. This has been resolved.

* Also fixes travis-ci to run the unit tests as part of checkin validation
2018-07-24 14:40:58 -07:00
John Patterson 913f740cc2 adds settings for inactive region font & bg color (#2308)
* adds settings for inactive region font & bg color

This adds the inactiveRegionForegroundColor and inactiveRegionBackgroundColor
settings. If a preprocessor block is found to be inactive, it will be
colored by these fields if they are set. They accept hexadecimal font
strings or valid theme colors as their values.These fields also
interactive with the dimInactiveRegions setting.

This was requested in issue
https://github.com/Microsoft/vscode-cpptools/issues/2212.
2018-07-23 15:52:41 -07:00
Sean McManus 2cbc90d98b Fix empty windowsSDKVersion. (#2301) 2018-07-20 17:07:14 -07:00
Bob Brown 25a29d0bc3 update fwlinks 2018-07-20 10:45:55 -07:00
Bob Brown 052f4e7b39 update version 2018-07-20 10:34:59 -07:00
Bob Brown 2b245202b5 Merge pull request #2295 from Microsoft/bobbrow/merge_release
0.17.7
2018-07-19 12:27:41 -07:00
Bob Brown 15c6c0a50e update version number 2018-07-19 12:23:32 -07:00
Bob Brown a0e0254c73 Add a setting to silence configuration provider warnings (#2293)
* Add a setting to silence configuration provider warnings
2018-07-19 12:14:05 -07:00
Sean McManus 528905326f Update changelog. (#2289) 2018-07-19 12:03:37 -07:00
Sean McManus 458b2be489 Update changelog for 0.17.7. (#2288)
* Update changelog for 0.17.7.
* Fix main snippet.
2018-07-18 16:10:00 -07:00
Pierson Lee 95d4724dc8 Update launch.md with miDebuggerArgs (#2270) 2018-07-13 15:56:49 -07:00
Sean McManus a178faab9b Update cpp.hint to use the injected defaults. (#2261) 2018-07-12 15:22:47 -07:00
Sean McManus 25aa8206a0 Update changelog. (#2257)
* Update changelog.
2018-07-12 14:54:21 -07:00
Sean McManus 879d880c82 Seanmcm/windows sdk version (#2241)
* Add windowsSDKVersion.
2018-07-10 15:57:03 -07:00
Bob Brown 16c4defcd0 Add a command to change the active custom config provider (#2247) 2018-07-09 16:03:35 -07:00
Bob Brown 725828c1c5 disable the config provider message for headers outside the workspace & while debugging (#2239)
* disable the config provider message for headers & while debugging

* leave the message on for headers inside the workspace folder
2018-07-07 15:11:46 -07:00
Bob Brown 8b188541ba fix spelling 2018-07-06 14:09:42 -07:00
Sean McManus 28f1bc991e Add ${VcpkgRoot} variable 2018-07-06 14:08:37 -07:00
Sean McManus aa424f1946 Fix bug c_cpp_properties.json creation after being deleted. (#2235)
Fix bug c_cpp_properties.json creation after being deleted: https://github.com/Microsoft/vscode-cpptools/issues/2214
2018-07-06 13:12:08 -07:00
Bob Brown 130711f4c5 Update Building the Extension.md 2018-07-03 10:25:12 -07:00
Bob Brown 863d26451c Merge pull request #2218 from Microsoft/master
merge master -> release
2018-07-02 11:38:35 -07:00
Bob Brown 0a85b6c115 Merge branch 'release' into master 2018-07-02 11:38:11 -07:00
Sean McManus f2b3bd5a18 Update changelog. (#2213)
* Update changelog.
2018-07-02 11:33:07 -07:00
Bob Brown ab3e498c17 update version for insiders branch (#2211) 2018-06-29 14:08:08 -07:00
Bob Brown bfad3045bd Merge branch 'insiders' into master 2018-06-29 14:00:30 -07:00
Andrew Wang 842e685a6a Removing dashes for ps command (#2185) 2018-06-29 13:59:14 -07:00
Bob Brown 3b36a23956 Merge pull request #2203 from Microsoft/master
merge master (one more change for 0.17.6)
2018-06-28 16:11:04 -07:00
Bob Brown bf7287e70b Merge branch 'master' of https://github.com/Microsoft/vscode-cpptools 2018-06-28 16:09:01 -07:00
Bob Brown 63ce03573c vscode-cpptools is in the wrong dependency list 2018-06-28 16:08:48 -07:00
Bob Brown 9ddf1098f7 update version for release (#2201)
* Update package.json

* Update package-lock.json
2018-06-28 12:58:02 -07:00
Bob Brown 56f4be1f65 Merge pull request #2200 from Microsoft/master
merge master to release for 0.17.6
2018-06-28 12:56:01 -07:00
Bob Brown 3b6dc61562 sanitize inputs (#2199) 2018-06-28 12:47:06 -07:00
Sean McManus b8a15ddfe6 Updated changelog and fwlinks. (#2195)
* Updated changelog and fwlinks.
2018-06-27 20:23:31 -07:00
Bob Brown f3e188c0ce fix version number (#2194)
* Update package.json

* Update package-lock.json
2018-06-27 13:20:12 -07:00
Bob Brown d403c8f984 Polishing the custom configuration provider experience (#2188) 2018-06-26 13:10:49 -07:00
Bob Brown 35288aad17 start sending installation failure telemetry again (#2189) 2018-06-26 12:35:58 -07:00
Bob Brown 9604256fb8 Merge pull request #2168 from Microsoft/master
Fix ${config:a.b} https://github.com/Microsoft/vscode-cpptools/issues…
2018-06-21 18:42:58 -07:00
Bob Brown d3f701823d Merge branch 'release' into master 2018-06-21 18:42:44 -07:00
Sean McManus 987347c4b6 Update CHANGELOG.md (#2161)
* Update CHANGELOG.md
2018-06-21 18:04:33 -07:00
Sean McManus 7e7a522603 Fix ${config:a.b} https://github.com/Microsoft/vscode-cpptools/issues… (#2166)
* Fix ${config:a.b} https://github.com/Microsoft/vscode-cpptools/issues/2165 .
2018-06-21 18:04:05 -07:00
Bob Brown 14bc488e5b Merge pull request #2154 from Microsoft/master
merge 0.17.5 release notes
2018-06-19 14:57:20 -07:00
Bob Brown 352745754b update (#2153) 2018-06-19 14:52:37 -07:00
Bob Brown dde3b515db update version numbers (#2152)
* Update package.json

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

* fix initialization dependency bug

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

* Forgot extensions
2018-06-07 18:18:31 -07:00
Sean McManus 4b90e4c151 Merge pull request #2100 from Microsoft/0_17_5_insiders
0 17 5 insiders
2018-06-07 16:26:44 -07:00
Sean McManus cc85f3d7c3 Merge, Also updated changelog and versions. 2018-06-07 16:15:56 -07:00
Sean McManus 73c025dcee Update dependencies due to vulnerabilities from npm audit. (#2095)
* Update dependencies due to vulnerabilities from npm audit.
2018-06-07 14:24:12 -07:00
Bob Brown 90b1ebd74c update version (#2097)
* Update package.json
* Update package-lock.json
2018-06-07 09:16:50 -07:00
Griffin Downs 3027e18968 Grdowns/inactive region opacity (#2061) 2018-06-06 12:14:19 -07:00
Pierson Lee 7729d0a700 Update issue templates (#2087)
* Update issue templates

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

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

* updates to logging docs

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

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

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

* support for string[] variables

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

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

* Move tslint to be after compile

* Address PR issues
2018-05-04 16:19:53 -07:00
Sean McManus d6aa178cac Fix issues introduced with VS Code 1.23.0. (#1925) 2018-05-03 16:57:38 -07:00
Bob Brown 264ed5eb23 trim the path before checking if it exists (#1924) 2018-05-03 16:21:52 -07:00
Griffin Downs ded26d66b0 Move settings update into updateToVersion4 function (#1916) 2018-05-03 12:47:45 -07:00
Sean McManus 88a0494ce5 Merge pull request #1766 from Microsoft/master
Merge for 0.16.1 release
2018-03-30 17:08:02 -07:00
Bob Brown 3bbfed643f Merge pull request #1746 from Microsoft/master
Merge to release 0.16.0
2018-03-27 20:36:40 -07:00
Bob Brown d079892710 Merge pull request #1726 from Microsoft/master
Merge to release for 0.16.0
2018-03-22 12:23:03 -07:00
Sean McManus e5976d2656 Merge pull request #1557 from Microsoft/master
Merge for release.
2018-02-14 16:55:56 -08:00
Pierson Lee (PIE) cdab065ded Merge remote-tracking branch 'origin/master' into release 2018-01-17 13:09:00 -08:00
Sean McManus 3f62c3d244 Merge pull request #1458 from Microsoft/master
0.14.6 release
2018-01-16 15:51:11 -08:00
86 changed files with 9284 additions and 5871 deletions
+30
View File
@@ -0,0 +1,30 @@
---
name: Debugger
about: Issues pertaining to debugging such as call stack, breakpoints, watch window,
launching or attaching to a debuggee.
---
Type: Debugger
**Input information below**
**Please review existing issues and our documentation at https://github.com/Microsoft/vscode-cpptools/tree/master/Documentation prior to filing an issue.**
**Describe the bug**
- OS and Version:
- VS Code Version:
- C/C++ Extension Version:
- Other extensions you installed (and if the issue persists after disabling them):
- A clear and concise description of what the bug is.
**To Reproduce**
*Please include a code sample and `launch.json` configuration.*
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Additional context**
*If applicable, please include logging by adding "logging": { "engineLogging": true, "trace": true, "traceResponse": true } in your `launch.json`*
Add any other context about the problem here including log or error messages in your Debug Console or Output windows.
@@ -0,0 +1,34 @@
---
name: General Extension
about: Issues pertaining to downloading, installing, or building the extension.
---
Type: General
**Input information below**
**Please review existing issues and our documentation at https://github.com/Microsoft/vscode-cpptools/tree/master/Documentation prior to filing an issue.**
**Describe the bug**
- OS and Version:
- VS Code Version:
- C/C++ Extension Version:
- Other extensions you installed (and if the issue persists after disabling them):
- A clear and concise description of what the bug is.
**To Reproduce**
*Please include code sample and `task.json` files.*
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here including log messages from the Output window.
@@ -0,0 +1,39 @@
---
name: Language Service
about: 'Issues pertaining to IntelliSense, autocomplete, code editing, etc. '
---
**Type: LanguageService**
<!----- Input information below ----->
<!--
**Please review existing issues and our documentation at https://github.com/Microsoft/vscode-cpptools/tree/master/Documentation prior to filing an issue.**
-->
**Describe the bug**
- OS and Version:
- VS Code Version:
- C/C++ Extension Version:
- Other extensions you installed (and if the issue persists after disabling them):
- A clear and concise description of what the bug is.
**To Reproduce**
<!-- Steps to reproduce the behavior: -->
<!-- *The most actionable issue reports include a code sample including configuration files such as c_cpp_properties.json* -->
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
**Screenshots**
<!-- If applicable, add screenshots to help explain your problem. -->
**Additional context**
<!--
*Call Stacks: For bugs like crashes, deadlocks, infinite loops, etc. that we are not able to repro and for which the call stack may be useful, please attach a debugger and/or create a dmp and provide the call stacks. Starting with 0.17.3, Windows binaries have symbols available in VS Code by setting your "symbolSearchPath" to "http://msdl.microsoft.com/download/symbols".*
Add any other context about the problem here including log messages in your Output window ("C_Cpp.loggingLevel": "Debug" in settings.json).
-->
+4 -2
View File
@@ -31,11 +31,13 @@ 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
- npm run unitTests
# TODO: Merge tests into one group due to Gulp 4.0
- npm run integrationTests
# Dump integrationTest.log output
- find ~ -name "integrationTests.log" -type f -exec cat {} \;
+2 -2
View File
@@ -4,7 +4,7 @@
"version": "2.0.0",
"tasks": [
{
"taskName": "build",
"label": "build",
"type": "shell",
"group": {
"kind": "build",
@@ -47,4 +47,4 @@
}
}
]
}
}
+13 -14
View File
@@ -1,14 +1,13 @@
## How to build and debug the Microsoft CppTools Extension
These steps will allow you to debug the TypeScript code that is part of the Microsoft CppTools extension for Visual Studio Code.
Prerequisite steps:
* Clone [this](https://github.com/Microsoft/vscode-cpptools) repository.
* Install [npm](https://nodejs.org).
* From a command line, run the following commands from the **Extension** folder in the root of the repository:
* `npm install -g vsce` will install `vsce` globally to create the vsix package.
* `npm install` will install the dependencies needed to build the extension.
* Set an environment variable `CPPTOOLS_DEV=1`.
* This enables the local developer workflow, copying dependencies from the **node_modules** folder.
* Open the **Extension** folder in Visual Studio Code and F5.
* Read the [contributing guidelines](https://github.com/Microsoft/vscode-cpptools/blob/master/CONTRIBUTING.md).
## How to build and debug the Microsoft CppTools Extension
These steps will allow you to debug the TypeScript code that is part of the Microsoft CppTools extension for Visual Studio Code.
Prerequisite steps:
* Clone [this](https://github.com/Microsoft/vscode-cpptools) repository.
* Install [npm](https://nodejs.org).
* From a command line, run the following commands from the **Extension** folder in the root of the repository:
* `npm install` will install the dependencies needed to build the extension.
* **(optional)** `npm install -g vsce` will install `vsce` globally to create a VSIX package that you can install.
* **(optional)** Set an environment variable `CPPTOOLS_DEV=1`.
* This enables the local developer workflow when testing the debugger, copying dependencies from the **node_modules** folder. Testing the language server does not require this step.
* Open the **Extension** folder in Visual Studio Code and press F5. This will launch a VS Code Extension Host window and activate the TypeScript debugger. You can set breakpoints on the extension source code and debug your scenario.
+68 -23
View File
@@ -1,6 +1,4 @@
# How To Debug MIEngine (Work in Progress)
*This is a work in progress. Please create a pull request with updates if there is anything wrong with it.*
# How To Debug MIEngine
MIEngine is one of the components used to enable the C/C++ debugging scenario with the Microsoft C/C++ extension with VS Code. This document is to help enable users who want to debug and contribute to MIEngine to fix issues or extend functionality. MIEngine is used to communicate with `gdb`/`lldb` using the MI protocol.
@@ -15,39 +13,52 @@ You can open the solution file **MIDebugEngine.sln** located under **src** and c
* Microsoft.MICore.dll
* Microsoft.MICore.XmlSerializers.dll
* Microsoft.MIDebugEngine.dll
* vscode\OpenDebugAD7.exe
* vscode\Microsoft.DebugEngineHost.dll
* vscode\Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.dll
The symbol files are as follows:
**On Windows**
* Microsoft.MICore.pdb
* Microsoft.MIDebugEngine.dll
* Microsoft.MIDebugEngine.pdb
* vscode\OpenDebugAD7.pdb
* vscode\Microsoft.DebugEngineHost.pdb
**On Linux/Mac**
* Microsoft.MICore.dll.mdb
* Microsoft.MIDebugEngine.dll.mdb
* vscode\OpenDebugAD7.exe.mdb
* vscode\Microsoft.DebugEngineHost.dll.mdb
### Debugging On Windows
On Windows, the easiest way to debug is to use Visual Studio. Locate the **package.json** file in the **Extension** folder and open it in an editor.
On Windows, the easiest way to debug is to use Visual Studio. Locate the **src\Debugger\extension.ts** file in the **Extension** folder and open it in an editor.
Locate the following line:
If you are not building the extension, Locate the **out\src\Debugger\extension.ts** file in the **.vscode\extensions\ms-vscode.cpptools** folder and open it in an editor.
Locate the following lines:
```json
"program": "./debugAdapters/OpenDebugAD7",
return {
command: command
};
```
and add the following line below it:
and add the following line to the object:
```json
"args": ["--pauseForDebugger"],
args: ["--pauseForDebugger"]
```
This will cause the debugger to look like it has hung once you start debugging, but in reality it is waiting for a debugger to attach. Set your breakpoints and attach your debugger to the `OpenDebugAD7.exe` process. Once the debugger is attached, VS Code should start debugging and you can reproduce your scenario.
### Debugging MIEngine running on Linux or Mac OS X
#### With MonoDevelop
On Linux and Mac OS X, we use `mono` as our framework. You can download Xamarin Studio v5.10.1.6 and remotely attach to your Mac or Linux box to debug there.
#### Install Prerequisites
1. Install [GTK](http://www.mono-project.com/download/)
2. Install [Xamarin Studio v5.10.1.6](http://download.xamarin.com/studio/Windows/XamarinStudio-5.10.1.6-0.msi)
##### Install Prerequisites
1. Install [GTK](http://www.mono-project.com/download/).
2. Install [Xamarin Studio v5.10.1.6](http://download.xamarin.com/studio/Windows/XamarinStudio-5.10.1.6-0.msi).
Remote attach functionality behind a flag. You can run it like this:
```PowerShell
@@ -56,26 +67,60 @@ set MONODEVELOP_SDB_TEST=1
MonoDevelop.exe
```
#### Create an empty project for attaching (one-time setup)
##### Create an empty project for attaching (one-time setup)
1. Launch MonoDevelop
2. File -> New Solution
3. Misc/Generic Project
4. Name project and hit "Create"
5. Right-click the project node (blue square) and do "Options"
1. Launch MonoDevelop.
2. File -> New Solution.
3. Misc/Generic Project.
4. Name project and hit "Create".
5. Right-click the project node (blue square) and do "Options".
6. Under Run -> Custom Commands, select "Execute" in the lower dropdown and choose a command (I use `c:\windows\notepad.exe` - it doesn't matter what the command is, but MonoDevelop requires it to exist before it'll light up the Run menu).
#### Configure the extension to enable remote debugging
##### Configure the extension to enable remote debugging
Open the **~/.vscode/extensions/ms-vscode.cpptools-\<version\>/debugAdapters/OpenDebugAD7** file with a text editor and locate and uncomment the line at the bottom. When you start debugging, it will now hang until the remote debugger is attached from Xamarin Studio.
#### Attach the remote debugger
##### Attach the remote debugger
In MonoDevelop: Run -> Run With -> Custom Command Mono Soft Debugger
Fill in the IP and port of the Linux/Mac OS X machine and hit "Connect" to start debugging
In MonoDevelop: Run -> Run With -> Custom Command Mono Soft Debugger.
Fill in the IP and port of the Linux/Mac OS X machine and hit "Connect" to start debugging.
After you've done this once, you can hit the MonoDevelop "Play" button or <kbd>F5</kbd> to bring up the connect dialog again.
Note: If you are debugging to CentOS, you will need to make an exception in the firewall
#### With VS Code + Mono Debug
##### Install Prerequisites
1. Install [VS Code](https://code.visualstudio.com/Download).
2. Install Mono Debug extension for VS Code.
##### Create an empty project (one-time setup)
1. Open to a new folder and create `.vscode/launch.json`.
2. Create the following configuration in launch.json.
```
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Mono",
"request": "attach",
"type": "mono",
"address": "<INSERT_MACHINE_IP_ADDRESS_HERE>",
"port": 1234
}
]
}
```
##### Configure the extension to enable remote debugging
Open the **~/.vscode/extensions/ms-vscode.cpptools-\<version\>/debugAdapters/OpenDebugAD7** file with a text editor and locate and uncomment the line at the bottom. When you start debugging, it will now hang until the remote debugger is attached from VS Code.
##### Attach the remote debugger
Select the `Attach to Mono` configuration and hit F5.
#### Additional Notes
Note: If you are debugging to CentOS, you will need to make an exception in the firewall.
* `sudo firewall-cmd --zone=public --add-port=1234/tcp --permanent`
* `sudo firewall-cmd --reload`
+39 -2
View File
@@ -3,7 +3,8 @@
## Table of Contents
* Setup: [Debugging Setup](#debugging-setup)
* Debugger: [Why is debugging not working?](#why-is-debugging-not-working)
* Build: [How to enable debug symbols?](#how-to-enable-debug-symbols)
* Build: [How to enable debug symbols](#how-to-enable-debug-symbols)
* Logging: [How to enable logging](#how-to-enable-logging)
## Debugging Setup
The debugger needs to be configured to know which executable and debugger to use:
@@ -22,7 +23,7 @@ When you start debugging, if it is showing that your breakpoints aren't bound (s
### Debugging starts but all the lines in my stack trace are grey
If your debugger is showing a grey stacktrace or won't stop at a breakpoint,or the symbols in the call stack are grey then your executable was compiled without [debug symbols](#how-to-enable-debug-symbols).
If your debugger is showing a grey stacktrace or won't stop at a breakpoint, or the symbols in the call stack are grey then your executable was compiled without [debug symbols](#how-to-enable-debug-symbols).
## How to enable debug symbols?
@@ -43,3 +44,39 @@ When in doubt, please check your compiler's documentation for the options necess
* #### cl.exe
Symbols are located in the `*.pdb` file.
## How to enable logging
Enabling logging will show communication information between VS Code and our extension and between our extension and the debugger.
### Logging for `MI` debuggers
The logging block with its defaults is as follows:
```
"logging": {
"trace": false,
"traceResponse": false,
"engineLogging": false
}
```
#### VS Code and the CppTools extension
The logging here is called `trace` logging and can be enabled by setting `trace` and `traceResponse` to `true` in the logging block inside `launch.json`. This will help diagnose issues related to VS Code's communication to our extension and our responses.
#### CppTools extension and the debugger
The logging between CppTools and the debugger is called `engineLogging`. When using an `MI` debugger such as `gdb` or `lldb`, this will show the request, response and events using the `mi` interpreter. This logging will help us determine whether the debugger is receiving the right commands and generating the correct responses.
### Logging for `Visual C++` debugger
The logging block with its defaults is as follows:
```
"logging": {
"engineLogging": false
}
```
The `Visual C++` debugger logging will show only the communication to and from VS Code as all communication to the debugger is done internally to the process and is not visible through logging.
@@ -0,0 +1,16 @@
#### Old information (it still works, but is no longer recommended):
Logging is controlled by environment variables and is disabled by default. To enable logging, launch VS Code from an environment that contains the following variables:
```
VSCODE_CPP_LOGDIR=c:\path\to\logfolder
VSCODE_CPP_LOGFILE_LEVEL=5
```
When you open your folder in VS Code, we will create a **vscode.cpp.log.\<pid\>.txt** file for each extension process launched (\<pid\> = process id).
The log file level is a number that determines how much detail we'll log. Level 5 is generally detailed enough to give us information about what is going on in your session. We don't recommend you set this higher than 7 since the log quickly becomes cluttered with information that doesn't really help us diagnose your issues and actually makes it harder for us to spot problems. It may also slow down the extension considerably and make it harder for you to reproduce your problem.
**Note:** You will likely need to reload the window or close VS Code to flush the contents of the log file since we do not flush the log after every call. If your log file seems to be empty, try reloading the window after you have followed the steps to reproduce your issue.
**Don't forget to remove the environment variables when you are finished providing us with the logs.** You wouldn't want the extension to needlessly spend CPU time and disk space writing data you don't need into log files.
@@ -0,0 +1,76 @@
## Extension version 0.16.1 and earlier:
For developers using MinGW on Windows, we recommend you start with the following **c_cpp_properties.json** template. Select "C/Cpp: Edit Configurations" from the command palette to create this file if you haven't already.
In earlier versions of the extension, the `includePath` and a some system defines need to be set in order for IntelliSense to work properly. Note that you may have to change the MinGW version number to match what you have installed. Eg. `C:/MinGW/lib/gcc/mingw32/5.3.0/` instead of `C:/MinGW/lib/gcc/mingw32/6.3.0/`.
```json
{
"configurations": [
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/mingw32",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/backward",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed"
],
"defines": [
"_DEBUG",
"__GNUC__=6",
"__cdecl=__attribute__((__cdecl__))"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
The `includePath` above includes the system header paths that gcc uses in version 6.3.0 for C++ projects and matches the output of `"gcc -v -E -x c++ nul"`. The `intelliSenseMode` should be set to **"clang-x64"** to get MinGW projects to work properly with IntelliSense. The `__GNUC__=#` define should match the major version of the toolchain in your installation (6 in this example).
For C projects, simply remove the C++ lines:
```json
{
"configurations": [
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed"
],
"defines": [
"_DEBUG",
"__GNUC__=6",
"__cdecl=__attribute__((__cdecl__))"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
@@ -0,0 +1,139 @@
# Windows Subsystem for Linux
To use the Windows Subsystem for Linux with this extension you need to add a configuration to your **c_cpp_properties.json** file which adds the necessary header paths from within the WSL filesystem to the `includePath`.
Select "C/Cpp: Edit Configurations" from the command palette to create the **c_cpp_properties.json** file if you haven't already.
## Release
For developers using Ubuntu with the current version of WSL released with the Fall Creators Update, you can add the following configuration template to your **c_cpp_properties.json** file.
```json
{
"name": "WSL",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5/backward",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
Note that `${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/` is the path to the root of the Ubuntu filesystem. This will be different if you are using a different distro. You can discover the paths to your distro's filesystem by using this handy PowerShell command:
```Powershell
PS R:\> ($(get-appxpackage).PackageFamilyName | findstr /i 'SUSE Ubuntu') -replace '^', "$`{localappdata`}/Packages/"
${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc
${localappdata}/Packages/46932SUSE.openSUSELeap42.2_022rs5jcyhyac
${localappdata}/Packages/46932SUSE.SUSELinuxEnterpriseServer12SP2_022rs5jcyhyac
```
For C projects, simply remove the C++ lines:
```json
{
"name": "WSL",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
### Beta
For developers using Bash on Ubuntu on Windows with the beta version of WSL from before the Fall Creators Update, you can add the following configuration template to your **c_cpp_properties.json** file.
```json
{
"name": "WSL (Beta)",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/include/c++/5/backward",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
Note that `${localappdata}/lxss/rootfs/` is the path to the root of the filesystem for Bash on Ubuntu on Windows.
For C projects, simply remove the C++ lines as in the previous example.
---
With these configurations, you should be all set up to use the new IntelliSense engine for linting, memberlist autocomplete, and quick info (tooltips). Add `"C_Cpp.intelliSenseEngine": "Default"` to your **settings.json** file to try out the new IntelliSense engine.
And remember to [heed the warnings of the Windows team about not creating or editing Linux files from a Windows app](https://blogs.msdn.microsoft.com/commandline/2016/11/17/do-not-change-linux-files-using-windows-apps-and-tools/)!
@@ -0,0 +1,99 @@
# Customizing Default Settings
In version 0.17.0 we introduced new settings that allow you to override the extension's default values for properties set in **c_cpp_properties.json**.
## New VS Code settings
The following `C_Cpp.default.*` settings map to each of the properties in a configuration block of **c_cpp_properties.json**. Namely:
```
C_Cpp.default.includePath : string[]
C_Cpp.default.defines : string[]
C_Cpp.default.compileCommands : string
C_Cpp.default.macFrameworkPath : string[]
C_Cpp.default.forcedIncludes : string[]
C_Cpp.default.intelliSenseMode : string
C_Cpp.default.compilerPath : string
C_Cpp.default.cStandard : c89 | c99 | c11
C_Cpp.default.cppStandard : c++98 | c++03 | c++11 | c++14 | c++17
C_Cpp.default.browse.path : string[]
C_Cpp.default.browse.databaseFilename : string
C_Cpp.default.browse.limitSymbolsToIncludedHeaders : boolean
```
These settings have all of the benefits of VS Code settings, meaning that they can have default, "User", "Workspace", and "Folder" values. So you can set a global value for `C_Cpp.default.cppStandard` in your "User" settings and have it apply to all of the folders you open. If any one folder needs a different value, you can override the value by adding a "Folder" or "Workspace" value.
This property of VS Code settings allows you to configure each of your workspaces independently - making the **c_cpp_properties.json** file optional.
## Updated **c_cpp_properties.json** syntax
A special variable has been added to the accepted syntax of **c_cpp_properties.json** that will instruct the extension to insert the value from the VS Code settings mentioned above. If you set the value of any setting in **c_cpp_properties.json** to "${default}" it will instruct the extension to read the VS Code default setting for that property and insert it. For example:
```
"configurations": [
{
"name": "Win32",
"includePath": [
"additional/paths",
"${default}"
],
"defines": [
"${default}",
],
"macFrameworkPath": [
"${default}",
"additional/paths"
],
"forceInclude": [
"${default}",
"additional/paths"
],
"compileCommands": "${default}",
"browse": {
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": "${default}",
"path": [
"${default}",
"additional/paths"
]
},
"intelliSenseMode": "${default}",
"cStandard": "${default}",
"cppStandard": "${default}",
"compilerPath": "${default}"
}
],
```
Take note that for the properties that accept string[], the syntax proposed above allows you to augment the VS Code setting with additional values, thus allowing you to have common paths listed in the VS Code settings and configuration-specific settings in **c_cpp_properties.json**.
If a property is missing from **c_cpp_properties.json**, the extension will use the value in the VS Code setting. If a developer assigns values to all of the settings that apply for a given folder, then **c_cpp_properties.json** could be removed from the .vscode folder as it will no longer be needed.
### System includes
A new setting will be added that allows you specify the system include path separate from the folder's include path. If this setting has a value, then the system include path the extension gets from the compiler specified in the `compilerPath` setting will not be added to the path array that the extension uses for IntelliSense. We may want to provide a VS Code command to populate this value from the compiler's default for users who are interested in using it in case they want to make some modifications to the defaults.
```
C_Cpp.default.systemIncludePath : string[]
```
### System Include Path/Defines Resolution Strategies
The extension determines the system includePath and defines to send to the IntelliSense engine in the following manner:
1. If `compileCommands` has a valid value and the file open in the editor is in the database, use the compile command in the database entry to determine the include path and defines.
* The system include path and defines are determined using the following logic (in order):
1. If `systemIncludePath` has a value, use it (continue to the next step to search for system defines).
2. If `compilerPath` is valid, query it.
3. Interpret the first argument in the command as the compiler and attempt to query it.
4. If `compilerPath` is `""`, use an empty array for system include path and defines.
5. If `compilerPath` is undefined, look for a compiler on the system and query it.
2. If `compileCommands` is invalid or the current file is not listed in the database, use the `includePath` and `defines` properties in the configuration for IntelliSense.
* The system include path and defines are determined using the following logic (in order):
1. If `systemIncludePath` has a value, use it (continue to the next step to search for system defines).
2. If `compilerPath` is valid, query it.
3. If `compilerPath` is `""`, use an empty array for system include path and defines (they are assumed to be in the `includePath` and `defines` for the current config already).
4. If `compilerPath` is undefined, look for a compiler on the system and query it.
System includes should no longer be added to the `"includePath"` or `"browse.path"` variables. If the extension detects any system include paths in the `"includePath"` property it will silently remove them so that it can ensure system include paths are added last and in the correct order (this is especially important for GCC/Clang). In a future update we may add a notification message to the extension to remind developers to remove system include paths from their `"includePath"` and `'browse.path"` as they will be ignored.
@@ -2,23 +2,11 @@
If you are experiencing a problem that we are unable to diagnose based on information in your issue report, we might ask you to enable logging and send us your logs.
As of version 0.14.0 of the extension, logging information is now delivered directly to the Output window in VSCode. To turn on full logging for an issue report, add `"C_Cpp.loggingLevel": "Information"` to your **settings.json**.
As of version 0.14.0 of the extension, logging information is now delivered directly to the Output window in VSCode. To turn on full logging for an issue report, add `"C_Cpp.loggingLevel": "Information"` or `"C_Cpp.loggingLevel": "Debug"` to your **settings.json**.
![image](https://user-images.githubusercontent.com/12818240/31898313-b32ff284-b7cd-11e7-97f5-89df93b5d9de.png)
![image](https://user-images.githubusercontent.com/12818240/44601186-8a2af380-a790-11e8-9094-7064d1ba3cfb.png)
#### Old information (it still works, but is no longer recommended):
VS Code organizes the logging from different extensions to improve readability so you must select the "C/C++" option in the log filter selector to see logging from the C/C++ extension:
<del>
Logging is controlled by environment variables and is disabled by default. To enable logging, launch VS Code from an environment that contains the following variables:
![image](https://user-images.githubusercontent.com/12818240/39769357-d6673bea-52a0-11e8-86c6-3be91618e8fc.png)
```
VSCODE_CPP_LOGDIR=c:\path\to\logfolder
VSCODE_CPP_LOGFILE_LEVEL=5
```
When you open your folder in VS Code, we will create a **vscode.cpp.log.\<pid\>.txt** file for each extension process launched (\<pid\> = process id).
The log file level is a number that determines how much detail we'll log. Level 5 is generally detailed enough to give us information about what is going on in your session. We don't recommend you set this higher than 7 since the log quickly becomes cluttered with information that doesn't really help us diagnose your issues and actually makes it harder for us to spot problems. It may also slow down the extension considerably and make it harder for you to reproduce your problem.
**Don't forget to remove the environment variables when you are finished providing us with the logs.** You wouldn't want the extension to needlessly spend CPU time and disk space writing data you don't need into log files.
</del>
+14 -2
View File
@@ -3,6 +3,7 @@
* [How do I get IntelliSense to work correctly?](#how-do-i-get-intellisense-to-work-correctly)
* [Why do I see red squiggles under Standard Library types?](#why-do-i-see-red-squiggles-under-standard-library-types)
* [How do I get the new IntelliSense to work with MinGW on Windows?](#how-do-i-get-the-new-intellisense-to-work-with-mingw-on-windows)
* [How do I get the new IntelliSense to work with the Windows Subsystem for Linux?](#how-do-i-get-the-new-intellisense-to-work-with-the-windows-subsystem-for-linux)
* [What is the difference between `"includePath"` and `"browse.path"` in **c_cpp_properties.json**?](#what-is-the-difference-between-includepath-and-browsepath-in-c_cpp_propertiesjson)
* [How do I re-create the IntelliSense database?](#how-do-i-re-create-the-intellisense-database)
@@ -27,11 +28,22 @@ If you want IntelliSense to operate on your files even when all #include directi
## Why do I see red squiggles under Standard Library types?
The most common reason for this is missing or sorted include paths. If you are using a compiler in the GCC family, the system includes that you add to your `"includePath"` in **c_cpp_properties.json** should match the output of the following command: `gcc -Wp,-v -E -xc -x c++ /dev/null` (replace 'gcc' with whichever compiler you are using). GCC and its relatives require the paths to be in a specific order too, so sorting the paths for aesthetics will likely result in incorrect IntelliSense results.
The most common reason for this is missing include paths and defines. The easiest way to fix this on each platform is as follows:
**Linux/Mac**
* Set `"intelliSenseMode": "clang-x64"` and `"compilerPath"` in **c_cpp_properties.json** to the path to your compiler.
**Windows**
* If you are using a Microsoft compiler from Visual Studio, set `"intelliSenseMode": "msvc-x64"`, but don't add the `"compilerPath"` property to **c_cpp_properties.json**.
* If you are using Clang for Windows, set `"intelliSenseMode": "msvc-x64"`, and `"compilerPath"` in **c_cpp_properties.json** to the path to your compiler.
## How do I get the new IntelliSense to work with MinGW on Windows?
Since MinGW is a relative of GCC, Microsoft mode compilation (which is the default on Windows) doesn't work very well with it. To use GCC/CLang mode, set the `"intelliSenseMode"` property in your **c_cpp_properties.json** file to `"clang-x64"`. An example **c_cpp_properties.json** [is shared here for your convenience](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/MinGW.md).
The page discussing configuration with MinGW is [here](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/MinGW.md).
## How do I get the new IntelliSense to work with the Windows Subsystem for Linux?
The page discussing configuration with WSL is [here](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/Windows%20Subsystem%20for%20Linux.md).
## What is the difference between `"includePath"` and `"browse.path"` in **c_cpp_properties.json**?
@@ -39,6 +39,6 @@ We recommend using the "Default" engine for the best IntelliSense experience. Ho
### See Also
[Configuring includePath for better IntelliSense results](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/Getting%20started.md)
[Configuring includePath for better IntelliSense results](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/Getting%20started%20with%20IntelliSense%20configuration.md)
[**c_cpp_properties.json** reference guide](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/LanguageServer/c_cpp_properties.json.md)
+18 -100
View File
@@ -1,113 +1,31 @@
For developers using MinGW on Windows, we recommend you start with the following **c_cpp_properties.json** template. Select "C/Cpp: Edit Configurations" from the command palette to create this file if you haven't already.
# MinGW
## With extension version 0.16.1 and higher:
To use MinGW on Windows, we recommend you add the following configuration to your **c_cpp_properties.json** file. Select "C/Cpp: Edit Configurations" from the command palette to create this file if you haven't already.
Starting with version 0.16.1, if you set the `compilerPath` property and change `intelliSenseMode` to `clang-x64`, you no longer need to copy the system include path or defines to `includePath` and `defines` to enable IntelliSense to work properly. However, `browse.path` still needs to be updated manually to add the system include paths to enable code browsing for system headers. For example:
## Extension version 0.17.0 and higher:
When you set the `compilerPath` property and change `intelliSenseMode` to `clang-x64` (or `gcc-x64` in version 0.18.0 and higher), you no longer need to copy the system include path or defines to `includePath`, `browse.path`, or `defines` to enable IntelliSense to work properly. For example:
```json
{
"configurations": [
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"compilerPath": "C:/MinGW/bin/gcc.exe",
"includePath": [
"${workspaceFolder}"
],
"defines": [
"_DEBUG"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*",
"${workspaceFolder}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"cStandard": "c11",
"cppStandard": "c++17"
}
"name": "MinGW",
"intelliSenseMode": "gcc-x64",
"compilerPath": "C:/mingw64/bin/gcc.exe",
"includePath": [
"${workspaceFolder}"
],
"version": 3
"defines": [],
"cStandard": "c11",
"cppStandard": "c++17"
}
```
Note that the `browse.path` setting is not automatically updated at this time and you may have to change the MinGW version number to match what you have installed. If you are using a different MinGW distribution, the values for `compilerPath` and `browse.path` will likely be different than what is written here.
Replace "gcc.exe" with whatever compiler you're using, e.g. "g++.exe", "clang-5.0.exe", etc. -- just make sure the file is a valid Windows executable (not a 0 size symlink).
## With extension version 0.16.0 and earlier:
For Cygwin, set the `compilerPath` to the appropriate Cygwin path, e.g. "C:/cygwin64/bin/g++.exe".
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/`.
If it seems like the `compilerPath` is not getting used, you can debug the issue via [enabling logging](Enabling%20logging.md).
```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": ""
}
}
]
}
```
## Extension version 0.16.1 and earlier:
The `includePath` above includes the system header paths that gcc uses in version 6.3.0 for C++ projects and matches the output of `"gcc -v -E -x c++ nul"`. The `intelliSenseMode` should be set to **"clang-x64"** to get MinGW projects to work properly with IntelliSense. The `__GNUC__=#` define should match the major version of the toolchain in your installation (6 in this example).
For C projects, simply remove the C++ lines:
```json
{
"configurations": [
{
"name": "MinGW",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed"
],
"defines": [
"_DEBUG",
"__GNUC__=6",
"__cdecl=__attribute__((__cdecl__))"
],
"browse": {
"path": [
"C:/MinGW/lib/gcc/mingw32/6.3.0/include",
"C:/MinGW/lib/gcc/mingw32/6.3.0/include-fixed",
"C:/MinGW/include/*",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
]
}
```
If you have an older version of the C/C++ extension installed, use [these instructions](Archive/MinGW.md) instead.
@@ -1,139 +1,33 @@
# Windows Subsystem for Linux
> **Note:** If you are on **build 17110 of Windows or higher**, you must use extension 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",
"intelliSenseMode": "gcc-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"
"${workspaceFolder}/**"
],
"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": ""
}
"defines": [],
"cStandard": "c11",
"cppStandard": "c++17"
}
```
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
## Earlier versions of the extension:
Note that `${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/` is the path to the root of the Ubuntu filesystem. This will be different if you are using a different distro. You can discover the paths to your distro's filesystem by using this handy PowerShell command:
```Powershell
PS R:\> ($(get-appxpackage).PackageFamilyName | findstr /i 'SUSE Ubuntu') -replace '^', "$`{localappdata`}/Packages/"
${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc
${localappdata}/Packages/46932SUSE.openSUSELeap42.2_022rs5jcyhyac
${localappdata}/Packages/46932SUSE.SUSELinuxEnterpriseServer12SP2_022rs5jcyhyac
```
For C projects, simply remove the C++ lines:
```json
{
"name": "WSL",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
## Beta
For developers using Bash on Ubuntu on Windows with the beta version of WSL from before the Fall Creators Update, you can add the following configuration template to your **c_cpp_properties.json** file.
```json
{
"name": "WSL (Beta)",
"intelliSenseMode": "clang-x64",
"includePath": [
"${workspaceRoot}",
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/include/c++/5/backward",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include"
],
"defines": [
"__linux__",
"__x86_64__"
],
"browse": {
"path": [
"${localappdata}/lxss/rootfs/usr/include/c++/5",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu/c++/5",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
"${localappdata}/lxss/rootfs/usr/local/include",
"${localappdata}/lxss/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"${localappdata}/lxss/rootfs/usr/include/x86_64-linux-gnu",
"${localappdata}/lxss/rootfs/usr/include/*"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
```
The `includePath` above includes the system header paths that gcc uses for C++ projects and matches the output of `gcc -v -E -x c++ - < /dev/null`. The intelliSenseMode should be set to **"clang-x64"** to get WSL projects to work properly with IntelliSense.
Note that `${localappdata}/lxss/rootfs/` is the path to the root of the filesystem for Bash on Ubuntu on Windows.
For C projects, simply remove the C++ lines as in the previous example.
If you are on a build of Windows prior to 17110 and you have an older version of the C/C++ extension installed, use [these instructions](Archive/Windows%20Subsystem%20for%20Linux.md) instead.
---
With these configurations, you should be all set up to use the new IntelliSense engine for linting, memberlist autocomplete, and quick info (tooltips). Add `"C_Cpp.intelliSenseEngine": "Default"` to your **settings.json** file to try out the new IntelliSense engine.
And remember to [heed the warnings of the Windows team about not creating or editing Linux files from a Windows app](https://blogs.msdn.microsoft.com/commandline/2016/11/17/do-not-change-linux-files-using-windows-apps-and-tools/)!
Remember to [heed the warnings of the Windows team about not creating or editing Linux files from a Windows app](https://blogs.msdn.microsoft.com/commandline/2016/11/17/do-not-change-linux-files-using-windows-apps-and-tools/)!
@@ -1,14 +1,23 @@
# `c_cpp_properties.json` Reference Guide
> See also: [Customizing Default Settings](Customizing%20Default%20Settings.md)
### Example
```json
{
"env" : {
"myDefaultIncludePath": [
"${workspaceFolder}",
"${workspaceFolder}/include"
],
"myCompilerPath": "/usr/local/bin/gcc-7"
},
"configurations": [
{
"name": "Win32",
"intelliSenseMode": "msvc-x64",
"includePath": [ "${workspaceFolder}" ],
"name": "Mac",
"intelliSenseMode": "clang-x64",
"includePath": [ "${myDefaultIncludePath}", "/another/path" ],
"macFrameworkPath": [ "/System/Library/Frameworks" ],
"defines": [ "FOO", "BAR=100" ],
"forcedInclude": [ "${workspaceFolder}/include/config.h" ],
@@ -23,14 +32,17 @@
}
}
],
"version": 3
"version": 4
}
```
## Top-level properties
* #### `env`
An array of user-defined variables that will be available for substitution in the configurations via the standard environment variable syntax: `${<var>}` or `${env:<var>}`. Strings and arrays of strings are accepted.
* #### `configurations`
An array of configuration objects that provide the IntelliSense engine with information about your project and your preferences. By default, the extension creates 3 configurations for you, one each for Linux, Mac, and Windows, but it is not required to keep them all. You may also add additional configurations if necessary.
An array of configuration objects that provide the IntelliSense engine with information about your project and your preferences. By default, the extension creates a configuration for you based on your operating system. You may also add additional configurations.
* #### `version`
We recommend you don't edit this field. It tracks the current version of the **c_cpp_properties.json** file so that the extension knows what properties and settings should be present and how to upgrade this file to the latest version.
@@ -41,22 +53,26 @@
A friendly name for the configuration. "Linux", "Mac", and "Win32" are special names that instruct the extension to load that configuration by default on the associated operating system unless additional configurations have been created. The status bar in VS Code will show you which configuration is active. You can also click on the label in the status bar to change the active configuration.
* #### `intelliSenseMode`
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this property determines which mode the IntelliSense engine will run in. `"msvc-x64"` maps to Visual Studio mode with 64-bit pointer sizes. `"clang-x64"` maps to GCC/CLang mode with 64-bit pointer sizes. Windows uses `"msvc-x64"` by default and Linux/Mac use `"clang-x64"` by default.
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this property determines which mode the IntelliSense engine will run in. `"msvc-x64"` maps to Visual Studio mode with 64-bit pointer sizes. `"clang-x64"` maps to CLang mode with 64-bit pointer sizes. `"gcc-x64"` maps to GCC mode with 64-bit pointer sizes. Windows uses `"msvc-x64"` by default, macOS uses `"clang-x64"` by default, and Linux uses `"gcc-x64"` by default.
* #### `includePath`
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of paths will be used by IntelliSense to search for headers included by your source files. This is basically the same as the list of paths you pass to your compiler with the `-I` switch; the IntelliSense engine will not do a recursive search in these paths for includes. If a GCC/CLang compiler is specified in the `compilerPath` setting, it is not necessary to list the system include paths in this list.
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of paths will be used by IntelliSense to search for headers included by your source files. This is basically the same as the list of paths you pass to your compiler with the `-I` switch. If a path ends with `/**` the IntelliSense engine will do a recursive search for includes starting from that directory. If on Windows with Visual Studio installed, or if a compiler is specified in the `compilerPath` setting, it is not necessary to list the system include paths in this list.
* #### `macFrameworkPath`
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of paths will be used by IntelliSense to search for framework headers included by your source files. This is basically the same as the list of paths you pass to your compiler with the `-F` switch; the IntelliSense engine will not do a recursive search in these paths for includes.
* #### `defines`
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of preprocessor symbols will be used by IntelliSense during the compilation of your source files. This is basically the same as the list of symbols you pass to your compiler with the `-D` switch.
If `"C_Cpp.intelliSenseEngine"` is set to "Default" in your settings file, this list of preprocessor symbols will be used by IntelliSense during the compilation of your source files. This is basically the same as the list of symbols you pass to your compiler with the `-D` switch. If on Windows with Visual Studio installed, or if a compiler is specified in the `compilerPath` setting, it is not necessary to list the system include paths in this list.
* #### `forcedInclude` (optional)
A list of files that should be included before any other characters in the source file are processed. Files are included in the order listed.
* #### `compilerPath` (optional)
The absolute path to the compiler you use to build your project. The extension will query the compiler to determine the system include paths and default defines to use for IntelliSense. Args can be added to modify the includes/defines used, e.g. `-nostdinc++`, `-m32`, etc., but paths with spaces must be surrounded by double quotes (`"`) if args are used.
The absolute path to the compiler you use to build your project. The extension will query the compiler to determine the system include paths and default defines to use for IntelliSense.
Args can be added to modify the includes/defines used, e.g. `-nostdinc++`, `-m32`, `-fno-ms-extensions`, etc., but paths with spaces must be surrounded by double quotes (`"`) if args are used.
If you want to disable automatic querying of system include paths and defines, set this value to the emptry string `""`. This is generally not recommended, but there are some cases where automatic querying of system includes and defines is undesirable.
* #### `cStandard`
The C standard revision to use for IntelliSense in your project.
@@ -67,7 +83,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.
@@ -75,7 +91,7 @@
### Browse properties
* #### `path`
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`.
This list of paths will be used by the Tag Parser to search for headers included by your source files. If omitted, `includePath` will be used as the `path`. 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 `${workspaceFolder}`. When false, the Tag Parser will parse all code files found in the paths specified in the **path** list.
+2 -1
View File
@@ -17,4 +17,5 @@ install.lock
*.vsix
# ignore vscode test
.vscode-test/
.vscode-test/
browse*db*
+3 -3
View File
@@ -15,7 +15,7 @@
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "npm"
"preLaunchTask": "TypeScript Compile",
},
{
"name": "Launch Tests",
@@ -24,14 +24,14 @@
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test"
"--extensionTestsPath=${workspaceFolder}/out/test/unitTests"
],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/test/**/*.js"
],
"preLaunchTask": "npm"
"preLaunchTask": "TypeScript Compile"
},
{
"name": "Node Attach",
+56 -28
View File
@@ -1,30 +1,58 @@
// 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",
"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",
"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": [
"TypeScript Compile"
]
}
]
}
+1
View File
@@ -11,4 +11,5 @@ CMakeLists.txt
debugAdapters/install.lock*
out/src/Debugger/copyScript.js
tools/**
out/tools/**
notices/**
+240 -15
View File
@@ -1,14 +1,239 @@
# C/C++ for Visual Studio Code Change Log
## Version 0.21.0 January 23, 2019
### New Features
* Add documentation comments for hover, completion, and signature help. [#399](https://github.com/Microsoft/vscode-cpptools/issues/399)
* Add completion committing for methods after `(`. [#1184](https://github.com/Microsoft/vscode-cpptools/issues/1184)
* Add macro expansions to hover. [#1734](https://github.com/Microsoft/vscode-cpptools/issues/1734)
* Add support for `__int128_t` and `__uint128_t` types. [#1815](https://github.com/Microsoft/vscode-cpptools/issues/1815)
* Add Italian translations for command titles.
* Julien Russo (@Dotpys) [PR #2663](https://github.com/Microsoft/vscode-cpptools/pull/2663)
* Add icons for operators, structs/unions, enum values, template arguments, and macros. [#2849](https://github.com/Microsoft/vscode-cpptools/issues/2849)
* Change `#include` completion to show individual folders instead of the entire paths, fixing previous performance problems. [#2836](https://github.com/Microsoft/vscode-cpptools/issues/2836)
* Add text `(declaration)`, `(typedef)`, `(type alias)`, and `(union)` to symbols. [#2851](https://github.com/Microsoft/vscode-cpptools/issues/2851)
* Add a refresh button to the `Attach to Process` picker. [#2885](https://github.com/Microsoft/vscode-cpptools/issues/2885)
* Matt Bise (@mbise1993) [PR #2895](https://github.com/Microsoft/vscode-cpptools/pull/2895)
* Add completion committing for templates after `<`. [#2953](https://github.com/Microsoft/vscode-cpptools/issues/2953)
### Bug Fixes
* Add the Microsoft digital signature to Windows binaries to avoid getting incorrectly flagged by virus scanners. [#1103](https://github.com/Microsoft/vscode-cpptools/issues/1103), [#2970](https://github.com/Microsoft/vscode-cpptools/issues/2970)
* Fix bugs when UTF-8 characters > 1 byte are used. [#1504](https://github.com/Microsoft/vscode-cpptools/issues/1504), [#1525](https://github.com/Microsoft/vscode-cpptools/issues/1525), [#2034](https://github.com/Microsoft/vscode-cpptools/issues/2034), [#2082](https://github.com/Microsoft/vscode-cpptools/issues/2082), [#2883](https://github.com/Microsoft/vscode-cpptools/issues/2883)
* Fix some IntelliSense process crashes. [#1785](https://github.com/Microsoft/vscode-cpptools/issues/1785), [#2913](https://github.com/Microsoft/vscode-cpptools/issues/2913)
* Fix several incorrect IntelliSense error squiggles. [#1942](https://github.com/Microsoft/vscode-cpptools/issues/1942), [#2422](https://github.com/Microsoft/vscode-cpptools/issues/2422), [#2474](https://github.com/Microsoft/vscode-cpptools/issues/2474), [#2478](https://github.com/Microsoft/vscode-cpptools/issues/2478), [#2597](https://github.com/Microsoft/vscode-cpptools/issues/2597), [#2763](https://github.com/Microsoft/vscode-cpptools/issues/2763)
* Fix some main process crashes. [#2505](https://github.com/Microsoft/vscode-cpptools/issues/2505), [#2768](https://github.com/Microsoft/vscode-cpptools/issues/2768)
* Fix incorrect IntelliSense error with Mac clang 10.0 libraries. [#2608](https://github.com/Microsoft/vscode-cpptools/issues/2608)
* Fix completion not working in template specializations. [#2620](https://github.com/Microsoft/vscode-cpptools/issues/2620)
* Fix incorrect completions after Enter is used after struct, class, etc. [#2734](https://github.com/Microsoft/vscode-cpptools/issues/2734)
* Fix memory "leak" when parsing a large workspace. [#2737](https://github.com/Microsoft/vscode-cpptools/issues/2737)
* Fix IntelliSense-based `Go to Definition` with overloads that return a template with a default param (e.g. vector) [#2736](https://github.com/Microsoft/vscode-cpptools/issues/2736)
* Fix `Go to Definition` when `__catch()`, `_NO_EXCEPT_DEBUG`, or `_LIBCPP_BEGIN_NAMESPACE_STD` is used. [#2761](https://github.com/Microsoft/vscode-cpptools/issues/2761), [#2766](https://github.com/Microsoft/vscode-cpptools/issues/2766)
* Fix `Go to Definition` when `method(void)` is used. [#2802](https://github.com/Microsoft/vscode-cpptools/issues/2802)
* Fix error `"TypeError: Cannot read property 'map' of undefined at asCompletionResult"`. [#2807](https://github.com/Microsoft/vscode-cpptools/issues/2807)
* Fix quotes around defines not supported for custom configuration providers. [#2820](https://github.com/Microsoft/vscode-cpptools/issues/2820)
* Fix PowerShell bug on Win7. [#2822](https://github.com/Microsoft/vscode-cpptools/issues/2822)
* Fix Tag Parser completion details missing keywords (i.e. `using`, `class`, `#define`, etc.). [#2850](https://github.com/Microsoft/vscode-cpptools/issues/2850)
* Fix problem with empty recursive include paths. [#2855](https://github.com/Microsoft/vscode-cpptools/issues/2855)
* Fix `NullReferenceException` on debugger launch with VS Code Insiders. [#2858](https://github.com/Microsoft/vscode-cpptools/issues/2858), [PR Microsoft/MIEngine#810](https://github.com/Microsoft/MIEngine/pull/810)
* Fix IntelliSense errors with template argument deduction. [#2907](https://github.com/Microsoft/vscode-cpptools/issues/2907), [#2912](https://github.com/Microsoft/vscode-cpptools/issues/2912)
* Retry Insider VSIX downloading with `http.proxySupport` `"off"`. [#2927](https://github.com/Microsoft/vscode-cpptools/issues/2927)
* Fix snippet completions being offered when they shouldn't be. [#2942](https://github.com/Microsoft/vscode-cpptools/issues/2942)
* Set the `editor.wordBasedSuggestions` to `false` by default to prevent incorrect completions. [#2943](https://github.com/Microsoft/vscode-cpptools/issues/2943)
* Fix IntelliSense-based `Go to Definition` for functions with function pointer parameters. [#2981](https://github.com/Microsoft/vscode-cpptools/issues/2981)
* Fix `<` incorrectly triggering completions. [#2985](https://github.com/Microsoft/vscode-cpptools/issues/2985)
* Fix recursive includes not adding paths used by `forcedInclude` files. [#2986](https://github.com/Microsoft/vscode-cpptools/issues/2986)
* Fix crash when `//` is used in a recursive `includePath`. [#2987](https://github.com/Microsoft/vscode-cpptools/issues/2987)
* Fix compiler in `compile_commands.json` not taking precedence over the `Cpp.default.compilerPath`. [#2793](https://github.com/Microsoft/vscode-cpptools/issues/2793)
* Fix `#include` completion not working for symlinks. [#2843](https://github.com/Microsoft/vscode-cpptools/issues/2843)
* Fix IntelliSense-based `Go to Definition` for `const` methods. [#3014](https://github.com/Microsoft/vscode-cpptools/issues/3014)
* Support `C_Cpp.updateChannel` for VS Code Exploration builds.
## Version 0.20.1: October 31, 2018
* Fix IntelliSense-based `Go to Declaration` when there's only a definition in a TU. [#2743](https://github.com/Microsoft/vscode-cpptools/issues/2743)
* Fix `#include` completion for standalone header files. [#2744](https://github.com/Microsoft/vscode-cpptools/issues/2744)
* Fix the highest hitting main process crash.
* Fix IntelliSense process crash with completion.
## Version 0.20.0: October 30, 2018
* Add IntegratedTerminal support for Linux and Windows. [#35](https://github.com/microsoft/vscode-cpptools/issues/35)
* Unify Visual Studio Code debug protocol parsing by using a shared library with Visual Studio.
* Fix IntelliSense-based `Go to Definition` on overloads (in the same TU). [#1071](https://github.com/Microsoft/vscode-cpptools/issues/1071)
* Fix inactive regions not being disabled when falling back to the Tag Parser. [#2181](https://github.com/Microsoft/vscode-cpptools/issues/2181)
* Fix `#include` completion not working with `compile_commands.json` or custom configuration providers. [#2242](https://github.com/Microsoft/vscode-cpptools/issues/2242)
* Fix IntelliSense failing if recursive includes removes all paths. [#2442](https://github.com/Microsoft/vscode-cpptools/issues/2442)
* Fix incorrect IntelliSense errors with MinGW (stop using `-fms-extensions` by default). [#2443](https://github.com/Microsoft/vscode-cpptools/issues/2443), [#2623](https://github.com/Microsoft/vscode-cpptools/issues/2623)
* Fix error squiggles sometimes not updating after typing. [#2448](https://github.com/Microsoft/vscode-cpptools/issues/2448)
* Add support for Mac framework paths in `compile_commands.json`. [#2508](https://github.com/Microsoft/vscode-cpptools/issues/2508)
* Fix IntelliSense-based `Go to Definition` falling back to the Tag Parser for definitions not in the TU. [#2536](https://github.com/Microsoft/vscode-cpptools/issues/2536), [#2677](https://github.com/Microsoft/vscode-cpptools/issues/2677)
* Fix IntelliSense-based `Go to Definition` on the identifier of a definition with no declaration. [#2573](https://github.com/Microsoft/vscode-cpptools/issues/2573)
* Fix IntelliSense-based `Go to Definition` not falling back to the declaration (in certain cases). [#2574](https://github.com/Microsoft/vscode-cpptools/issues/2574)
* Fix IntelliSense-based `Go to Definition` going to the wrong location after edits are made. [#2579](https://github.com/Microsoft/vscode-cpptools/issues/2579)
* Fix `Go to Definition` when the `intelliSenseEngineFallback` is `Disabled` and `#include`s are missing. [#2583](https://github.com/Microsoft/vscode-cpptools/issues/2583)
* Fix empty `C_Cpp.default.*` settings not being used. [#2584](https://github.com/Microsoft/vscode-cpptools/issues/2584)
* Fix quoting around `ssh`'s command (for the debugger). [#2585](https://github.com/Microsoft/vscode-cpptools/issues/2585)
* Fix crash on hover (and `Go to Definition`) when using the `Tag Parser`. [#2586](https://github.com/Microsoft/vscode-cpptools/issues/2586)
* Fix errors when a workspace folder isn't open. [#2613](https://github.com/Microsoft/vscode-cpptools/issues/2613), [#2691](https://github.com/Microsoft/vscode-cpptools/issues/2691)
* Fix `-isystem` without a space after getting ignored in `compile_comamands.json`. [#2629](https://github.com/Microsoft/vscode-cpptools/issues/2629)
* Fix Insiders update channel installation bugs. [#2636](https://github.com/Microsoft/vscode-cpptools/issues/2636), [#2685](https://github.com/Microsoft/vscode-cpptools/issues/2685)
* Fix IntelliSense-based `Go to Declaration` falling back to the Tag Parser if the definition is also in the TU. [#2642](https://github.com/Microsoft/vscode-cpptools/issues/2642)
* Fix the `Disabled` `intelliSenseEngine` setting not working with custom configuration providers. [#2656](https://github.com/Microsoft/vscode-cpptools/issues/2656)
## Version 0.19.0: September 27, 2018
* Change the symbol database to update without needing to save. [#202](https://github.com/Microsoft/vscode-cpptools/issues/202)
* Enable IntelliSense-based `Go to Definition` for the current translation unit, including local variables and overloaded operators. [#255](https://github.com/Microsoft/vscode-cpptools/issues/255), [#979](https://github.com/Microsoft/vscode-cpptools/issues/979)
* Improved the `Go to Definition` performance with large workspaces and files with lots of `#include`s. [#273](https://github.com/Microsoft/vscode-cpptools/issues/273)
* Disable `Go to Definition` for invalid tokens, e.g. comments, strings, keywords, etc. [#559](https://github.com/Microsoft/vscode-cpptools/issues/559)
* Add `C_Cpp.updateChannel` setting for easier access to Insider builds of the extension. [#1526](https://github.com/Microsoft/vscode-cpptools/issues/1526)
* Add support for v2 of the configuration provider API. [#2237](https://github.com/Microsoft/vscode-cpptools/issues/2237)
* Fix bug with parsing definitions in `compile_commands.json`. [#2305](https://github.com/Microsoft/vscode-cpptools/issues/2305)
* Fix `sh` failure when attaching to a remote Linux process. [#2444](https://github.com/Microsoft/vscode-cpptools/issues/2444)
* Fix incorrect default `cl.exe` macro. [PR #2468](https://github.com/Microsoft/vscode-cpptools/issues/2468)
* Fix multiple bugs with the symbols in the Outline view not updating correctly. [#2477](https://github.com/Microsoft/vscode-cpptools/issues/2477), [#2500](https://github.com/Microsoft/vscode-cpptools/issues/2500), [#2504](https://github.com/Microsoft/vscode-cpptools/issues/2504)
* Add support for `workspaceFolderBasename` expansion. [#2491](https://github.com/Microsoft/vscode-cpptools/issues/2491)
* Gabriel Arjones (@g-arjones) [PR #2495](https://github.com/Microsoft/vscode-cpptools/pull/2495), [PR #2503](https://github.com/Microsoft/vscode-cpptools/pull/2503)
* Fix bug with variable resolution. [#2532](https://github.com/Microsoft/vscode-cpptools/issues/2532)
* Fix off-by-one bug with hover and `Go to Definition`. [#2535](https://github.com/Microsoft/vscode-cpptools/issues/2535)
* Fix [Microsoft/vscode#54213](https://github.com/Microsoft/vscode/issues/54213)
## Version 0.18.1: August 17, 2018
* Fix 0.18.0 regression causing non-MinGW compilers to use `-fms-extensions` on Windows. [#2424](https://github.com/Microsoft/vscode-cpptools/issues/2424), [#2425](https://github.com/Microsoft/vscode-cpptools/issues/2425)
## Version 0.18.0: August 17, 2018
### New Features
* Add the `C_Cpp.intelliSenseEngine` setting value of `Disabled` (for users who only use the debugger). [#785](https://github.com/Microsoft/vscode-cpptools/issues/785)
* Add `C_Cpp.workspaceSymbols` setting with default `Just My Code` to filter out system header symbols. [#1119](https://github.com/Microsoft/vscode-cpptools/issues/1119), [#2320](https://github.com/Microsoft/vscode-cpptools/issues/2320)
* Add `C_Cpp.inactiveRegionForegroundColor` and `C_Cpp.inactiveRegionBackgroundColor` settings. [#1620](https://github.com/Microsoft/vscode-cpptools/issues/1620), [#2212](https://github.com/Microsoft/vscode-cpptools/issues/2212)
* John Patterson (@john-patterson) [PR #2308](https://github.com/Microsoft/vscode-cpptools/pull/2308)
* Add `gcc-x64` `intelliSenseMode` and send the correct clang or gcc version to our parser, fixing various IntelliSense errors. [#2112](https://github.com/Microsoft/vscode-cpptools/issues/2112), [#2175](https://github.com/Microsoft/vscode-cpptools/issues/2175), [#2260](https://github.com/Microsoft/vscode-cpptools/issues/2260), [#2299](https://github.com/Microsoft/vscode-cpptools/issues/2299), [#2317](https://github.com/Microsoft/vscode-cpptools/issues/2317)
* Make `Go to Definition` on the definition go to the declaration instead. [#2298](https://github.com/Microsoft/vscode-cpptools/issues/2298)
* Add multi-pass environment variable resolution allowing variables defined in terms of other variables. [#2057](https://github.com/Microsoft/vscode-cpptools/issues/2057)
* John Patterson (@john-patterson) [PR #2322](https://github.com/Microsoft/vscode-cpptools/pull/2322)
* Allow users to use `~` for `${userProfile}` on Windows. [PR #2333](https://github.com/Microsoft/vscode-cpptools/pull/2333)
* Add support for compiler flags `-fms-extensions` and `-fno-ms-extensions` on Windows (the default for MinGW-based compilers). [#2363](https://github.com/Microsoft/vscode-cpptools/issues/2363)
* Make completion "show more results" (i.e. inaccessible members) when invoked a 2nd time. [#2386](https://github.com/Microsoft/vscode-cpptools/issues/2386)
### Bug Fixes
* Fix attach to process for systems without `bash` by using `sh` instead. [#569](https://github.com/Microsoft/vscode-cpptools/issues/569)
* Andy Neff (@andyneff) [PR #2340](https://github.com/Microsoft/vscode-cpptools/pull/2340)
* Fix IntelliSense crash after hover or completion with `_Complex` types. [#689](https://github.com/Microsoft/vscode-cpptools/issues/689), [#1112](https://github.com/Microsoft/vscode-cpptools/issues/1112)
* Fix `files.exclude` not working to exclude non-workspace folders from symbol parsing. [#1066](https://github.com/Microsoft/vscode-cpptools/issues/1066)
* Fix `Switch Header/Source` to give results that match the parent folder name before using just the file name. [#1085](https://github.com/Microsoft/vscode-cpptools/issues/1085)
* Fix incorrect IntelliSense errors caused by namespace lookup failure when instantiation template arguments in clang mode. [#1395](https://github.com/Microsoft/vscode-cpptools/issues/1395), [#1559](https://github.com/Microsoft/vscode-cpptools/issues/1559), [#1753](https://github.com/Microsoft/vscode-cpptools/issues/1753), [#2272](https://github.com/Microsoft/vscode-cpptools/issues/2272)
* Fix missing parameter help when using { for constructors. [#1667](https://github.com/Microsoft/vscode-cpptools/issues/1667)
* Fix Mac framework dependencies not being discovered. [#1913](https://github.com/Microsoft/vscode-cpptools/issues/1913)
* Fix `compilerPath` not working with `${workspaceFolder}`. [#1982](https://github.com/Microsoft/vscode-cpptools/issues/1982)
* Fix red flame getting stuck after modifying `c_cpp_properties.json`. [#2077](https://github.com/Microsoft/vscode-cpptools/issues/2077)
* Don't add empty `windowsSDKVersion` if none exists. [#2300](https://github.com/Microsoft/vscode-cpptools/issues/2300)
* Fix IntelliSense crash when the gcc-8 type_traits header is used. [#2323](https://github.com/Microsoft/vscode-cpptools/issues/2323), [#2328](https://github.com/Microsoft/vscode-cpptools/issues/2328)
* Limit configuration popups to one at a time. [#2324](https://github.com/Microsoft/vscode-cpptools/issues/2324)
* Don't show `includePath` code actions if compile commands or custom configuration providers are used. [#2334](https://github.com/Microsoft/vscode-cpptools/issues/2334)
* Fix `C_Cpp.clang_format_path` not accepting environment variables. [#2344](https://github.com/Microsoft/vscode-cpptools/issues/2344)
* Fix IntelliSense not working with non-ASCII characters in the WSL install path. [#2351](https://github.com/Microsoft/vscode-cpptools/issues/2351)
* Filter out buggy IntelliSense error `"= delete" can only appear on the first declaration of a function`. [#2352](https://github.com/Microsoft/vscode-cpptools/issues/2352)
* Fix IntelliSense failing with WSL if gcc is installed bug g++ isn't. [#2360](https://github.com/Microsoft/vscode-cpptools/issues/2360)
* Fix WSL paths starting with `/mnt/` failing to get symbols parsed. [#2361](https://github.com/Microsoft/vscode-cpptools/issues/2361)
* Fix IntelliSense process crash when hovering over a designated initializer list with an anonymous struct. [#2370](https://github.com/Microsoft/vscode-cpptools/issues/2370)
* Stop showing "File: " in completion details for internal compiler defines. [#2387](https://github.com/Microsoft/vscode-cpptools/issues/2387)
* Invoke `Edit Configurations...` when the `Configuration Help` button is clicked. [#2408](https://github.com/Microsoft/vscode-cpptools/issues/2408)
* Fix provider configuration prompt not showing for newly added workspace folders. [#2415](https://github.com/Microsoft/vscode-cpptools/issues/2415)
* Fix to allow SIGINT to be sent using the kill -2 command when using pipeTransport.
## Version 0.17.7: July 22, 2018
* Fix `Go to Definition` for code scoped with an aliased namespace. [#387](https://github.com/Microsoft/vscode-cpptools/issues/387)
* Fix incorrect IntelliSense errors with template template-arguments. [#1014](https://github.com/Microsoft/vscode-cpptools/issues/1014)
* Fix crash when using designated initializer lists. [#1440](https://github.com/Microsoft/vscode-cpptools/issues/1440)
* Add `windowsSdkVersion` to `c_cpp_properties.json`. [#1585](https://github.com/Microsoft/vscode-cpptools/issues/1585)
* Add `${vcpkgRoot}` variable. [#1817](https://github.com/Microsoft/vscode-cpptools/issues/1817)
* Fix dangling IntelliSense processes. [#2075](https://github.com/Microsoft/vscode-cpptools/issues/2075), [#2169](https://github.com/Microsoft/vscode-cpptools/issues/2169)
* Fix incorrect IntelliSense errors when class template argument deduction is used. [#2101](https://github.com/Microsoft/vscode-cpptools/issues/2101)
* Skip automatic parsing of source files in Mac system framework paths. [#2156](https://github.com/Microsoft/vscode-cpptools/issues/2156)
* Fix `Edit Configurations...` not working after `c_cpp_properties.json` is deleted. [#2214](https://github.com/Microsoft/vscode-cpptools/issues/2214)
* Fix indexing of the entire root drive on Windows when no is folder open. [#2216](https://github.com/Microsoft/vscode-cpptools/issues/2216)
* Disable the config provider message for headers outside the workspace and when debugging. [#2221](https://github.com/Microsoft/vscode-cpptools/issues/2221)
* Add `Change Configuration Provider...` command. [#2224](https://github.com/Microsoft/vscode-cpptools/issues/2224)
* Fix out-of-memory crash with `#include` code actions when no folder is open. [#2225](https://github.com/Microsoft/vscode-cpptools/issues/2225)
* Fix `intelliSenseMode` with custom config providers on Windows. [#2228](https://github.com/Microsoft/vscode-cpptools/issues/2228)
* Fix formatting not working on Windows if the VC++ 2015 redist isn't installed. [#2232](https://github.com/Microsoft/vscode-cpptools/issues/2232)
* Fix variables not resolving in `macFrameworkPath`. [#2234](https://github.com/Microsoft/vscode-cpptools/issues/2234)
* Fix `Go to Definition` not working for macros followed by `.` or `->`. [#2245](https://github.com/Microsoft/vscode-cpptools/issues/2245)
* Fix `#include` autocomplete with Mac framework headers. [#2251](https://github.com/Microsoft/vscode-cpptools/issues/2251)
* Fix debugging to support empty arguments for debuggee. [#2258](https://github.com/Microsoft/vscode-cpptools/issues/2258)
* Fix `Go to Definition` bug (missing symbols outside the workspace). [#2281](https://github.com/Microsoft/vscode-cpptools/issues/2281)
* Fix incorrect hover in enum definitions. [#2286](https://github.com/Microsoft/vscode-cpptools/issues/2286)
* Add a setting to silence configuration provider warnings. [#2292](https://github.com/Microsoft/vscode-cpptools/issues/2292)
* Fix debugging async Visual C++ causing debugger to hang.
* Fix `main` snippet.
## Version 0.17.6: July 2, 2018
* Fix the database icon getting stuck with recursive includes. [#2104](https://github.com/Microsoft/vscode-cpptools/issues/2104)
* Fix the red flame appearing late with recursive includes. [#2105](https://github.com/Microsoft/vscode-cpptools/issues/2105)
* Fix source files being parsed in system directories. [#2156](https://github.com/Microsoft/vscode-cpptools/issues/2156)
* Fix internal document corruption (visible after formatting) when edits are made too soon after activation. [#2162](https://github.com/Microsoft/vscode-cpptools/issues/2162)
* Fix a crash when saving with recursive includes. [#2173](https://github.com/Microsoft/vscode-cpptools/issues/2173)
* Fix a crash when the `includePath` or `browse.path` is `"**"`. [#2174](https://github.com/Microsoft/vscode-cpptools/issues/2174)
* Fix IntelliSense for WSL without g++ installed. [#2178](https://github.com/Microsoft/vscode-cpptools/issues/2178)
* Fix random IntelliSense (completion) failures due to edits being delayed. [#2184](https://github.com/Microsoft/vscode-cpptools/issues/2184)
* Fix database deletion failure with non-ASCII file paths on Windows. [#2205](https://github.com/Microsoft/vscode-cpptools/issues/2205)
* Fix `Go to Definition` results with `var::` and `var->`, and filter out invalid constructor results. [#2207](https://github.com/Microsoft/vscode-cpptools/issues/2207)
* Fix a performance bug with recursive includes.
* Fixed a CPU usage problem on Mac related to system frameworks parsing.
* Keep the IntelliSense process around for 10 seconds after a file is closed in case it's needed again.
* Added an API so build system extensions can provide IntelliSense configurations for source files. More details at [npmjs.com](https://www.npmjs.com/package/vscode-cpptools).
* Fix automatic argument quoting when debugging with gdb/lldb to include when the argument has a '(' or ')' in it. Also escape existing '"' symbols.
* Removed `-` in `ps` call for ProcessPicker and RemoteProcessPicker. [#2183](https://github.com/Microsoft/vscode-cpptools/issues/2183)
## Version 0.17.5: June 21, 2018
* Detect `compile_commands.json` and show prompt to use it. [#1297](https://github.com/Microsoft/vscode-cpptools/issues/1297)
* Change inactive regions from gray to translucent. [#1907](https://github.com/Microsoft/vscode-cpptools/issues/1907)
* Improve performance of recursive includes paths. [#2068](https://github.com/Microsoft/vscode-cpptools/issues/2068)
* Fix IntelliSense client failure due to `No args provider`. [#1908](https://github.com/Microsoft/vscode-cpptools/issues/1908)
* Fix `#include` completion with headers in the same directory. [#2031](https://github.com/Microsoft/vscode-cpptools/issues/2031)
* Fix non-header files outside the workspace folder not being parsed (i.e. so `Go to Definition` works). [#2053](https://github.com/Microsoft/vscode-cpptools/issues/2053)
* Fix some crashes. [#2080](https://github.com/Microsoft/vscode-cpptools/issues/2080)
* Support asm clobber registers on Windows. [#2090](https://github.com/Microsoft/vscode-cpptools/issues/2090)
* Fix usage of `${config:section.setting}`. [#2165](https://github.com/Microsoft/vscode-cpptools/issues/2165)
* `browse.path` now inherits `includePath` if not set in `c_cpp_properties.json`.
* On Windows, `compilerPath` now populates with the guessed `cl.exe` path, and the `MSVC` include path is based on the `cl.exe` path.
* Fix files under a non-recursive `browse.path` being removed from the database.
* Fix `*` not working in `browse.path` with WSL.
* Fix -break-insert main returning multiple bind points. [PR Microsoft/MIEngine#729](https://github.com/Microsoft/MIEngine/pull/729)
* Use -- instead of -x for gnome-terminal. [PR Microsoft/MIEngine#733](https://github.com/Microsoft/MIEngine/pull/733)
* Added `miDebuggerArgs` in order to pass arguments to the program in `miDebuggerPath`. [PR Microsoft/MIEngine#720](https://github.com/Microsoft/MIEngine/pull/720)
## Version 0.17.4: May 31, 2018
* Fix infinite loop (caused by deadlock) when using recursive includes. [#2043](https://github.com/Microsoft/vscode-cpptools/issues/2043)
* Stop using recursive includes in the default configuration.
* @Hyzeta [PR #2059](https://github.com/Microsoft/vscode-cpptools/pull/2059)
* Fix various other potential deadlocks and crashes.
* Fix `Go to Definition` on `#include` not filtering out results based on the path. [#1253](https://github.com/Microsoft/vscode-cpptools/issues/1253), [#2033](https://github.com/Microsoft/vscode-cpptools/issues/2033)
* Fix database icon getting stuck. [#1917](https://github.com/Microsoft/vscode-cpptools/issues/1917)
## Version 0.17.3: May 22, 2018
* Add support for `${workspaceFolder:folderName}`. [#1774](https://github.com/Microsoft/vscode-cpptools/issues/1774)
* Fix infinite loop during initialization on Windows. [#1960](https://github.com/Microsoft/vscode-cpptools/issues/1960)
* Fix main process IntelliSense-related crashes. [#2006](https://github.com/Microsoft/vscode-cpptools/issues/2006)
* Fix deadlock after formatting large files. [#2007](https://github.com/Microsoft/vscode-cpptools/issues/2007)
* Fix recursive includes failing to find some system includes. [#2019](https://github.com/Microsoft/vscode-cpptools/issues/2019)
## Version 0.17.1: May 17, 2018
* Fix IntelliSense update slowness when using recursive includes. [#1949](https://github.com/Microsoft/vscode-cpptools/issues/1949)
* Fix code navigation failure after switching between WSL and non-WSL configs. [#1958](https://github.com/Microsoft/vscode-cpptools/issues/1958)
* Fix extension crash when the `includePath` is a file or the root drive. [#1979](https://github.com/Microsoft/vscode-cpptools/issues/1979), [#1965](https://github.com/Microsoft/vscode-cpptools/issues/1965)
* Fix IntelliSense crash in `have_member_access_from_class_scope`. [#1763](https://github.com/Microsoft/vscode-cpptools/issues/1763)
* Fix `#include` completion bugs. [#1959](https://github.com/Microsoft/vscode-cpptools/issues/1959), [#1970](https://github.com/Microsoft/vscode-cpptools/issues/1970)
* Add `Debug` value for `loggingLevel` (previously the hidden value `"6"`).
* Fix C++17 features not being fully enabled with msvc-x64 mode. [#1990](https://github.com/Microsoft/vscode-cpptools/issues/1990)
* Fix IntelliSense interprocess deadlocks. [#1407](https://github.com/Microsoft/vscode-cpptools/issues/1407), [#1777](https://github.com/Microsoft/vscode-cpptools/issues/1777)
## Version 0.17.0: May 7, 2018
* Auto-complete for headers after typing `#include`. [#802](https://github.com/Microsoft/vscode-cpptools/issues/802)
* Add support for recursive `includePath`, e.g. `${workspaceFolder}/**`. [#897](https://github.com/Microsoft/vscode-cpptools/issues/897)
* Configuration improvements. [#1338](https://github.com/Microsoft/vscode-cpptools/issues/1338)
* Potentially addresses: [#368](https://github.com/Microsoft/vscode-cpptools/issues/368), [#410](https://github.com/Microsoft/vscode-cpptools/issues/410), [#1229](https://github.com/Microsoft/vscode-cpptools/issues/1229), [#1270](https://github.com/Microsoft/vscode-cpptools/issues/), [#1404](https://github.com/Microsoft/vscode-cpptools/issues/1404)
* Potentially addresses: [#368](https://github.com/Microsoft/vscode-cpptools/issues/368), [#410](https://github.com/Microsoft/vscode-cpptools/issues/410), [#1229](https://github.com/Microsoft/vscode-cpptools/issues/1229), [#1270](https://github.com/Microsoft/vscode-cpptools/issues/1270), [#1404](https://github.com/Microsoft/vscode-cpptools/issues/1404)
* Add support for querying system includes/defines from WSL and Cygwin compilers. [#1845](https://github.com/Microsoft/vscode-cpptools/issues/1845), [#1736](https://github.com/Microsoft/vscode-cpptools/issues/1736)
* Fix IntelliSense for WSL projects in Windows builds 17110 and greater. [#1694](https://github.com/Microsoft/vscode-cpptools/issues/1694)
* Add snippets. [PR #1823](https://github.com/Microsoft/vscode-cpptools/pull/1823)
* Add support for vcpkg. [PR #1886](https://github.com/Microsoft/vscode-cpptools/pull/1886)
* Add support for custom variables in `c_cpp_properties.json` via `env`. [#1857](https://github.com/Microsoft/vscode-cpptools/issues/1857), [#368](https://github.com/Microsoft/vscode-cpptools/issues/368)
* Stop automatically adding `/usr/include` to the `includePath`. [#1819](https://github.com/Microsoft/vscode-cpptools/issues/1819)
* Fix wrong configuration being used if there are four or more. [#1599](https://github.com/Microsoft/vscode-cpptools/issues/1599)
* Fix `c_cpp_properties.json` requiring write access. [#1790](https://github.com/Microsoft/vscode-cpptools/issues/1790)
@@ -77,9 +302,9 @@
* Add `C_Cpp.exclusionPolicy` default to `checkFolders` to avoid expensive `files.exclude` checking on every file.
## Version 0.14.5: December 18, 2017
* Fix for stackwalk `NullReferenceException`. [#1339](https://github.com/Microsoft/vscode-cpptools/issues/1339)
* Fix for `-isystem` (or `-I`) not being used in `compile_commands.json` if there's a space after it. [#1343](https://github.com/Microsoft/vscode-cpptools/issues/1343)
* Fix for header switching from `.cc` to `.hpp` files (and other cases). [#1341](https://github.com/Microsoft/vscode-cpptools/issues/1341)
* Fix stackwalk `NullReferenceException`. [#1339](https://github.com/Microsoft/vscode-cpptools/issues/1339)
* Fix `-isystem` (or `-I`) not being used in `compile_commands.json` if there's a space after it. [#1343](https://github.com/Microsoft/vscode-cpptools/issues/1343)
* Fix header switching from `.cc` to `.hpp` files (and other cases). [#1341](https://github.com/Microsoft/vscode-cpptools/issues/1341)
* Fix reload prompts not appearing in debugging scenarios (after the initial installation). [#1344](https://github.com/Microsoft/vscode-cpptools/issues/1344)
* Add a "wait" message when commands are invoked during download/installation. [#1344](https://github.com/Microsoft/vscode-cpptools/issues/1344)
* Prevent blank "C/C++ Configuration" from appearing when debugging is started but the language service is not. [#1353](https://github.com/Microsoft/vscode-cpptools/issues/1353)
@@ -98,9 +323,9 @@
* Improve performance for fetching call stacks with large arguments. [#363](https://github.com/Microsoft/vscode-cpptools/issues/363)
## Version 0.14.3: November 27, 2017
* Fix for disappearing parameter hints tooltip. [#1165](https://github.com/Microsoft/vscode-cpptools/issues/1165)
* Fix for parameter hints only showing up after the opening parenthesis. [#902](https://github.com/Microsoft/vscode-cpptools/issues/902), [#819](https://github.com/Microsoft/vscode-cpptools/issues/819)
* Fix for customer reported crashes in the TypeScript extension code. [#1240](https://github.com/Microsoft/vscode-cpptools/issues/1240), [#1245](https://github.com/Microsoft/vscode-cpptools/issues/1245)
* Fix disappearing parameter hints tooltip. [#1165](https://github.com/Microsoft/vscode-cpptools/issues/1165)
* Fix parameter hints only showing up after the opening parenthesis. [#902](https://github.com/Microsoft/vscode-cpptools/issues/902), [#819](https://github.com/Microsoft/vscode-cpptools/issues/819)
* Fix customer reported crashes in the TypeScript extension code. [#1240](https://github.com/Microsoft/vscode-cpptools/issues/1240), [#1245](https://github.com/Microsoft/vscode-cpptools/issues/1245)
* Fix .browse.VC-#.db files being unnecessarily created when an shm file exists. [#1234](https://github.com/Microsoft/vscode-cpptools/issues/1234)
* Fix language service to only activate after a C/C++ file is opened or a C/Cpp command is used (not onDebug).
* Fix database resetting if shutdown got blocked by an IntelliSense operation. [#1260](https://github.com/Microsoft/vscode-cpptools/issues/1260)
@@ -154,10 +379,10 @@
## Version 0.13.0: September 25, 2017
* Reference highlighting is now provided by the extension for both IntelliSense engines.
* Parameter help is now provided by both IntelliSense engines.
* Light bulbs (code actions) for #include errors now suggest potential paths to add to the `includePath` based on a recursive search of the `browse.path`. [#846](https://github.com/Microsoft/vscode-cpptools/issues/846)
* Light bulbs (code actions) for `#include` errors now suggest potential paths to add to the `includePath` based on a recursive search of the `browse.path`. [#846](https://github.com/Microsoft/vscode-cpptools/issues/846)
* Browse database now removes old symbols when `browse.path` changes. [#262](https://github.com/Microsoft/vscode-cpptools/issues/262)
* Add `*` on new lines after a multiline comment with `/**` is started. [#579](https://github.com/Microsoft/vscode-cpptools/issues/579)
* Fix Go to Definition, completion, and parameter hints for partially scoped members. [#635](https://github.com/Microsoft/vscode-cpptools/issues/635)
* Fix `Go to Definition`, completion, and parameter hints for partially scoped members. [#635](https://github.com/Microsoft/vscode-cpptools/issues/635)
* Fix bug in `macFrameworkPath` not resolving variables.
## Version 0.12.4: September 12, 2017
@@ -168,7 +393,7 @@
* Support `${env:VAR}` syntax for environment variables in `c_cpp_properties.json`. [#1000](https://github.com/Microsoft/vscode-cpptools/issues/1000)
* Support semicolon delimiters for include paths in `c_cpp_properties.json` to better support environment variables. [#1001](https://github.com/Microsoft/vscode-cpptools/issues/1001)
* Add `__LITTLE_ENDIAN__=1` to default defines so that "endian.h" is not needed on Mac projects. [#1005](https://github.com/Microsoft/vscode-cpptools/issues/1005)
* Fix for source code files on Windows with incorrect casing. [#984](https://github.com/Microsoft/vscode-cpptools/issues/984)
* Fix source code files on Windows with incorrect casing. [#984](https://github.com/Microsoft/vscode-cpptools/issues/984)
## Version 0.12.3: August 17, 2017
* Fix regression for paths containing multibyte characters. [#958](https://github.com/Microsoft/vscode-cpptools/issues/958)
@@ -204,7 +429,7 @@
* Update Microsoft Visual C++ debugger to Visual Studio 2017 released components.
* Fix issue with showing wrong thread. [#550](https://github.com/Microsoft/vscode-cpptools/issues/550)
* Fix issue with binaries compiled with /FASTLINK causing debugger to hang. [#484](https://github.com/Microsoft/vscode-cpptools/issues/484)
* Fix issue in MinGW/Cygwin debugging where stop debugging causes VS Code to hang. [Microsoft/MIEngine#636](https://github.com/Microsoft/MIEngine/pull/636)
* Fix issue in MinGW/Cygwin debugging where stop debugging causes VS Code to hang. [PR Microsoft/MIEngine#636](https://github.com/Microsoft/MIEngine/pull/636)
## Version 0.12.0: June 26, 2017
* The default IntelliSense engine now provides semantic-aware autocomplete suggestions for `.`, `->`, and `::` operators. [#13](https://github.com/Microsoft/vscode-cpptools/issues/13)
@@ -221,8 +446,8 @@
* Fix `Go to Definition` not working until all `browse.path` files are re-scanned. [#788](https://github.com/Microsoft/vscode-cpptools/issues/788)
## Version 0.11.4: June 2, 2017
* Fix for `System.Xml.Serialization.XmlSerializationReader threw an exception` when debugging on Linux. [#792](https://github.com/Microsoft/vscode-cpptools/issues/792)
* Fix for escaping for `${workspaceRoot}` in `launch.json`.
* Fix `System.Xml.Serialization.XmlSerializationReader threw an exception` when debugging on Linux. [#792](https://github.com/Microsoft/vscode-cpptools/issues/792)
* Fix escaping for `${workspaceRoot}` in `launch.json`.
## Version 0.11.3: May 31, 2017
* Fix `x86_64-pc-linux-gnu` and `x86_64-linux-gnu` paths missing from the default `includePath`.
@@ -270,7 +495,7 @@
## Version 0.10.5: March 21, 2017
* Fix a crash that randomly occurred when the size of a document increased. [#430](https://github.com/Microsoft/vscode-cpptools/issues/430)
* Fix for browsing not working for Linux/Mac stdlib.h functions. [#578](https://github.com/Microsoft/vscode-cpptools/issues/578)
* Fix browsing not working for Linux/Mac stdlib.h functions. [#578](https://github.com/Microsoft/vscode-cpptools/issues/578)
* Additional fixes for switch header/source not respecting `files.exclude`. [#485](https://github.com/Microsoft/vscode-cpptools/issues/485)
* Made `editor.quickSuggestions` dependent on `C_Cpp.autocomplete`. [#572](https://github.com/Microsoft/vscode-cpptools/issues/572)
* We recommend you close and reopen your settings.json file anytime you change the `C_Cpp.autocomplete` setting. [More info here](https://github.com/Microsoft/vscode-cpptools/releases).
@@ -350,7 +575,7 @@
* Switch between header and source.
* Control which files are processed under include path.
## Version 0.6.1: June 03, 2016
## Version 0.6.1: June 3, 2016
* Bug fixes.
## Version 0.6.0: May 24, 2016
+2 -2
View File
@@ -2,7 +2,7 @@
This preview release of the extension adds language support for C/C++ to Visual Studio Code including:
* Language service
* Code Formatting (clang-format)
* Auto-Completion (experimental)
* Auto-Completion
* Symbol Searching
* Go to Definition/Declaration
* Peek Definition/Declaration
@@ -11,7 +11,7 @@ This preview release of the extension adds language support for C/C++ to Visual
* Quick Info (Hover)
* Error Squiggles
* Debugging
* Support for debugging Windows (PDB, Mingw/Cygwin), Linux and OS X applications
* Support for debugging Windows (PDB, MinGW/Cygwin), Linux and macOS applications
* Line by line code stepping
* Breakpoints (including conditional and function breakpoints)
* Variable inspection
+6 -6
View File
@@ -205,9 +205,9 @@
<tr>
<td>
<div>
<h2 class="caption">March 2018 Update</h2>
<div>Thank you for installing the C/C++ extension. In the March update, we finished our implementation of autocomplete for the default IntelliSense engine. We also added additional configuration settings for forced include files, specifying your compiler path and language standard to improve IntelliSense accuracy.<br />
<br />
<h2 class="caption">January 2019 Update</h2>
<div>Thank you for installing the C/C++ extension. In the January update, we added documentation comments for hover, completion, and signature help.<br/>
<br/>
Additional features and bug fixes are detailed in the <a href="https://github.com/Microsoft/vscode-cpptools/releases">full release notes</a>.</div>
</div>
</td>
@@ -231,9 +231,9 @@
<td>
<div>
<h3 class="caption">Blog Posts</h3>
<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/2018/12/05/visual-studio-code-cpp-extension-october-2018-update-and-a-simplified-insiders-program/">October 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/08/23/visual-studio-code-c-c-extension-august-2018-update/">August 2018 Update</a></div>
<div><a href="https://blogs.msdn.microsoft.com/vcblog/2018/07/25/visual-studio-code-cc-extension-july-2018-update-and-intellisense-auto-configuration-for-cmake/">July 2018 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>
+11 -3
View File
@@ -1,8 +1,16 @@
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
THIRD PARTY SOFTWARE NOTICES AND INFORMATION
Do Not Translate or Localize
Microsoft C/C++ Extension for Visual Studio Code incorporates components from the projects listed below. Microsoft licenses these components under the Microsoft C/C++ Extension for Visual Studio Code license terms, except as noted. The original copyright notices and the licenses under which Microsoft received such components are set forth below for informational purposes. Microsoft reserves all rights not expressly granted herein, whether by implication, estoppel or otherwise.
This Microsoft product may utilize material made available by third parties under the following license terms. Any source code that Microsoft is required to make available can be found at http://3rdpartysource.microsoft.com. You may also obtain a copy of any such source code (during the period provided by the license) by sending a check or money order for US $5.00 to:
Source Code Compliance Team
Microsoft Corporation
One Microsoft Way
Redmond, WA 98052 USA
Please write “Source for [OSS PROJECT NAME]” in the memo line of your payment.
1. agent-base (https://github.com/TooTallNate/node-agent-base)
2. ANTLR (http://www.antlr2.org/)
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z" fill="#F6F6F6"/><path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z" fill="#424242"/></svg>

After

Width:  |  Height:  |  Size: 986 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z" fill="#2D2D30"/><path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z" fill="#C5C5C5"/></svg>

After

Width:  |  Height:  |  Size: 986 B

+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"
-1
View File
@@ -1,6 +1,5 @@
{
"defaults": [
"--clang",
"--pack_alignment",
"8"
],
+4 -4
View File
@@ -4,15 +4,15 @@
"--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"
"-D_M_AMD64=100"
],
"defaults_op" : "merge"
}
-1
View File
@@ -1,6 +1,5 @@
{
"defaults": [
"--clang",
"--pack_alignment",
"8"
],
+4 -4
View File
@@ -4,15 +4,15 @@
"--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"
"-D_M_AMD64=100"
],
"defaults_op" : "merge"
}
-1
View File
@@ -1,6 +1,5 @@
{
"defaults": [
"--clang",
"--pack_alignment",
"8"
],
+4 -4
View File
@@ -4,15 +4,15 @@
"--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"
"-D_M_AMD64=100"
],
"defaults_op" : "merge"
}
+35 -2
View File
@@ -58,6 +58,11 @@
"type": "string"
}
},
"windowsSdkVersion": {
"description": "Version of the Windows SDK include path to use on Windows, e.g. '10.0.17134.0'.",
"type": "string",
"pattern": "^\\d{2}\\.\\d{1}\\.\\d{5}\\.\\d{1}$|^8\\.1$"
},
"defines": {
"description": "A list of preprocessor definitions for the IntelliSense engine to use while parsing files. Optionally, use = to set a value, e.g. VERSION=1.",
"type": "array",
@@ -66,10 +71,11 @@
}
},
"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.",
"description": "If set, it overrides the default mode used by the IntelliSense engine. Windows defaults to msvc-x64, Linux defaults to gcc-x64, and Mac default to clang-x64.",
"type": "string",
"enum": [
"msvc-x64",
"gcc-x64",
"clang-x64",
"${default}"
]
@@ -81,6 +87,10 @@
"type": "string"
}
},
"configurationProvider": {
"description": "The id of a VS Code extension that can provide IntelliSense configuration information for source files.",
"type": "string"
},
"browse": {
"type": "object",
"properties": {
@@ -107,6 +117,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$)(?!^workspaceFolderBasename$)(?!^default$)(^.+$)": {
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}
},
"additionalProperties": false
},
"version": {
"type": "integer",
"description": "Version of the configuration file. This property is managed by the extension. Please do not change it."
@@ -116,6 +146,9 @@
"configurations": {
"$ref": "#/definitions/configurations"
},
"env": {
"$ref": "#/definitions/env"
},
"version": {
"$ref": "#/definitions/version"
}
@@ -124,4 +157,4 @@
"configurations",
"version"
]
}
}
+2 -2574
View File
File diff suppressed because it is too large Load Diff
-140
View File
@@ -1,140 +0,0 @@
{
"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"
}
}
+4 -1
View File
@@ -1,3 +1,6 @@
{
"intelliSenseEngine_default_percentage": 100
"intelliSenseEngine_default_percentage": 100,
"defaultIntelliSenseEngine": 100,
"recursiveIncludes": 100,
"gotoDefIntelliSense": 100
}
+39 -30
View File
@@ -10,47 +10,47 @@ 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');
gulp.start('integrationTests');
});
gulp.task('unitTests', (done) => {
env.set({
CODE_TESTS_PATH: "./out/test/unitTests",
});
gulp.task('unitTests', () => {
gulp.src('./out/test/unitTests', {read: false}).pipe(
mocha({
ui: "tdd"
return gulp.src('./test/runVsCodeTestsWithAbsolutePaths.js', {read: false})
.pipe(mocha({ ui: "tdd" }))
.once('error', err => {
done();
process.exit(1);
})
).once('error', err => {
process.exit(1);
})
.once('end', () => {
process.exit();
})
.once('end', () => {
done();
process.exit();
});
});
gulp.task('integrationTests', () => {
gulp.task('integrationTests', (done) => {
env.set({
CODE_TESTS_PATH: "./out/test/integrationTests",
CODE_TESTS_WORKSPACE: "./test/integrationTests/testAssets/SimpleCppProject"
}
);
gulp.src('./test/runVsCodeTestsWithAbsolutePaths.js', {read: false}).pipe(
mocha({
ui: "tdd",
delay: true
});
return gulp.src('./test/runVsCodeTestsWithAbsolutePaths.js', {read: false})
.pipe(mocha({ ui: "tdd" }))
.once('error', err => {
done();
process.exit(1);
})
).once('error', err => {
process.exit(1);
})
.once('end', () => {
process.exit();
})
.once('end', () => {
done();
process.exit();
});
});
/// Misc Tasks
const allTypeScript = [
'src/**/*.ts',
'tools/**/*.ts',
'!**/*.d.ts',
'!**/typings**'
];
@@ -65,7 +65,7 @@ const lintReporter = (output, file, options) => {
};
gulp.task('tslint', () => {
gulp.src(allTypeScript)
return gulp.src(allTypeScript)
.pipe(tslint({
program: require('tslint').Linter.createProgram("./tsconfig.json"),
configuration: "./tslint.json"
@@ -76,10 +76,19 @@ gulp.task('tslint', () => {
}))
});
gulp.task('pr-check', () => {
gulp.task('pr-check', (done) => {
const packageJson = JSON.parse(fs.readFileSync('./package.json').toString());
if (packageJson.activationEvents.length !== 1 && packageJson.activationEvents[0] !== '*') {
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`.');
done();
process.exit(1);
}
done();
});
gulp.task('generateOptionsSchema', (done) => {
optionsSchemaGenerator.generateOptionsSchema();
done();
});
+3948 -1955
View File
File diff suppressed because it is too large Load Diff
+188 -83
View File
@@ -2,7 +2,7 @@
"name": "cpptools",
"displayName": "C/C++",
"description": "C/C++ IntelliSense, debugging, and code browsing.",
"version": "0.17.0-insiders2",
"version": "0.21.0",
"publisher": "ms-vscode",
"preview": true,
"icon": "LanguageCCPP_color_128x.png",
@@ -12,7 +12,7 @@
},
"license": "SEE LICENSE IN LICENSE.txt",
"engines": {
"vscode": "^1.22.0"
"vscode": "^1.26.0"
},
"bugs": {
"url": "https://github.com/Microsoft/vscode-cpptools/issues",
@@ -32,7 +32,7 @@
"multi-root ready"
],
"categories": [
"Languages",
"Programming Languages",
"Debuggers",
"Formatters",
"Linters",
@@ -63,7 +63,7 @@
],
"configuration": {
"type": "object",
"title": "C/C++ Configuration",
"title": "C/C++",
"properties": {
"C_Cpp.clang_format_path": {
"type": [
@@ -104,10 +104,11 @@
"type": "string",
"enum": [
"Default",
"Tag Parser"
"Tag Parser",
"Disabled"
],
"default": "Default",
"description": "Controls the IntelliSense provider. \"Tag Parser\" provides \"fuzzy\" results that are not context-aware. \"Default\" provides context-aware results and is in preview mode - member list, hover tooltips, and error squiggles are currently implemented. Features not yet implemented in the new default engine will use the tag parser engine instead.",
"description": "Controls the IntelliSense provider. \"Tag Parser\" provides \"fuzzy\" results that are not context-aware. \"Default\" provides context-aware results. \"Disabled\" turns off C/C++ language service features.",
"scope": "resource"
},
"C_Cpp.intelliSenseEngineFallback": {
@@ -146,6 +147,32 @@
"description": "Controls whether inactive preprocessor blocks are colored differently than active code. This setting is ignored by the Tag Parser engine.",
"scope": "resource"
},
"C_Cpp.inactiveRegionOpacity": {
"type:": "number",
"default": 0.55,
"Description": "Controls the opacity of inactive preprocessor blocks. Scales between 0.1 and 1.0. This setting only applies when inactive region dimming is enabled.",
"scope": "resource",
"minimum": 0.1,
"maximum": 1
},
"C_Cpp.inactiveRegionForegroundColor": {
"type": [
"string",
"null"
],
"default": null,
"description": "Controls the font coloring of inactive preprocessor blocks. Input is in the form a hexadecimal color code or a valid Theme Color. If not set, this defaults to the syntax coloring scheme of the editor. This setting only applies when inactive region dimming is enabled.",
"scope": "resource"
},
"C_Cpp.inactiveRegionBackgroundColor": {
"type": [
"string",
"null"
],
"default": null,
"description": "Controls the background coloring of inactive preprocessor blocks. Input is in the form a hexadecimal color code or a valid Theme Color. If not set, this defaults to transparent. This setting only applies when inactive region dimming is enabled.",
"scope": "resource"
},
"C_Cpp.formatting": {
"type": "string",
"enum": [
@@ -168,10 +195,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": {
@@ -192,6 +220,16 @@
"description": "Controls whether parsing of the non-active workspace files uses sleeps to avoid using 100% CPU. The values highest/high/medium/low correspond to approximately 100/75/50/25% CPU usage.",
"scope": "resource"
},
"C_Cpp.workspaceSymbols": {
"type": "string",
"enum": [
"All",
"Just My Code"
],
"default": "Just My Code",
"description": "The symbols to include in the query results when 'Go to Symbol in Workspace' is invoked",
"scope": "resource"
},
"C_Cpp.exclusionPolicy": {
"type": "string",
"enum": [
@@ -241,6 +279,16 @@
"description": "Defines the editor behavior for when the Enter key is pressed inside a multiline or single line comment block.",
"scope": "resource"
},
"C_Cpp.configurationWarnings": {
"type": "string",
"enum": [
"Enabled",
"Disabled"
],
"default": "Enabled",
"description": "Determines whether pop up notifications will be shown when a configuration provider extension is unable to provide a configuration for a source file.",
"scope": "resource"
},
"C_Cpp.default.includePath": {
"type": [
"array",
@@ -277,6 +325,16 @@
"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.windowsSdkVersion": {
"type": [
"string",
"null"
],
"default": null,
"description": "Version of the Windows SDK include path to use on Windows, e.g. '10.0.17134.0'.",
"pattern": "^\\d{2}\\.\\d{1}\\.\\d{5}\\.\\d{1}$|^8\\.1$",
"scope": "resource"
},
"C_Cpp.default.compileCommands": {
"type": [
"string",
@@ -305,6 +363,7 @@
],
"enum": [
"msvc-x64",
"gcc-x64",
"clang-x64"
],
"default": null,
@@ -350,6 +409,15 @@
"description": "The value to use in a configuration if \"cppStandard\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.configurationProvider": {
"type": [
"string",
"null"
],
"default": null,
"description": "The value to use in a configuration if \"configurationProvider\" is either not specified or set to \"${default}\".",
"scope": "resource"
},
"C_Cpp.default.browse.path": {
"type": [
"array",
@@ -388,89 +456,99 @@
"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"
},
"C_Cpp.updateChannel": {
"type": "string",
"enum": [
"Default",
"Insiders"
],
"default": "Default",
"description": "Set to \"Insiders\" to automatically download and install the latest Insiders builds of the extension, which include upcoming features and bug fixes.",
"scope": "resource"
}
}
},
"commands": [
{
"command": "C_Cpp.ConfigurationSelect",
"title": "Select a Configuration...",
"category": "C/Cpp"
"title": "%c_cpp.command.configurationSelect.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.ConfigurationProviderSelect",
"title": "%c_cpp.command.configurationProviderSelect.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.ConfigurationEdit",
"title": "Edit Configurations...",
"category": "C/Cpp"
"title": "%c_cpp.command.configurationEdit.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.GoToDeclaration",
"title": "Go to Declaration",
"category": "C/Cpp"
"title": "%c_cpp.command.goToDeclaration.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.PeekDeclaration",
"title": "Peek Declaration",
"category": "C/Cpp"
"title": "%c_cpp.command.peekDeclaration.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.SwitchHeaderSource",
"title": "Switch Header/Source",
"category": "C/Cpp"
"title": "%c_cpp.command.switchHeaderSource.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.Navigate",
"title": "Navigate...",
"category": "C/Cpp"
},
{
"command": "C_Cpp.ToggleSnippets",
"title": "Toggle Snippets",
"category": "C/Cpp"
"title": "%c_cpp.command.navigate.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.ToggleErrorSquiggles",
"title": "Toggle Error Squiggles",
"category": "C/Cpp"
"title": "%c_cpp.command.toggleErrorSquiggles.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.ToggleIncludeFallback",
"title": "Toggle IntelliSense Engine Fallback on Include Errors",
"category": "C/Cpp"
"title": "%c_cpp.command.toggleIncludeFallback.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.ToggleDimInactiveRegions",
"title": "Toggle Inactive Region Colorization",
"category": "C/Cpp"
"title": "%c_cpp.command.toggleDimInactiveRegions.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.ShowReleaseNotes",
"title": "Show Release Notes",
"category": "C/Cpp"
"title": "%c_cpp.command.showReleaseNotes.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.ResetDatabase",
"title": "Reset IntelliSense Database",
"category": "C/Cpp"
"title": "%c_cpp.command.resetDatabase.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.PauseParsing",
"title": "Pause Parsing",
"category": "C/Cpp"
"title": "%c_cpp.command.pauseParsing.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.ResumeParsing",
"title": "Resume Parsing",
"category": "C/Cpp"
"title": "%c_cpp.command.resumeParsing.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.ShowParsingCommands",
"title": "Show Parsing Commands",
"category": "C/Cpp"
"title": "%c_cpp.command.showParsingCommands.title%",
"category": "C/C++"
},
{
"command": "C_Cpp.TakeSurvey",
"title": "Take Survey",
"category": "C/Cpp"
"title": "%c_cpp.command.takeSurvey.title%",
"category": "C/C++"
}
],
"keybindings": [
@@ -533,6 +611,8 @@
},
"configurationAttributes": {
"launch": {
"type": "object",
"default": {},
"required": [
"program"
],
@@ -570,6 +650,7 @@
"description": "One or more GDB/LLDB commands to execute in order to setup the underlying debugger. Example: \"setupCommands\": [ { \"text\": \"-enable-pretty-printing\", \"description\": \"Enable GDB pretty printing\", \"ignoreFailures\": true }].",
"items": {
"type": "object",
"default": {},
"properties": {
"text": {
"type": "string",
@@ -595,6 +676,7 @@
"description": "If provided, this replaces the default commands used to launch a target with some other commands. For example, this can be \"-target-attach\" in order to attach to a target process. An empty command list replaces the launch commands with nothing, which can be useful if the debugger is being provided launch options as command line options. Example: \"customLaunchSetupCommands\": [ { \"text\": \"target-run\", \"description\": \"run target\", \"ignoreFailures\": false }].",
"items": {
"type": "object",
"default": {},
"properties": {
"text": {
"type": "string",
@@ -639,9 +721,14 @@
"description": "Environment variables to add to the environment for the program. Example: [ { \"name\": \"squid\", \"value\": \"clam\" } ].",
"items": {
"type": "object",
"default": {},
"properties": {
"name": "string",
"value": "string"
"name": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"default": []
@@ -661,6 +748,11 @@
"description": "The path to the mi debugger (such as gdb). When unspecified, it will search path first for the debugger.",
"default": "/usr/bin/gdb"
},
"miDebuggerArgs": {
"type": "string",
"description": "Arguments for the mi debugger (such as gdb) to use. When unspecified.",
"default": ""
},
"miDebuggerServerAddress": {
"type": "string",
"description": "Network address of the MI Debugger Server to connect to (example: localhost:1234).",
@@ -708,7 +800,12 @@
},
"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.",
"description": "If true, a console is launched for the debuggee. If false, on Linux and Windows, it will appear in the Integrated Console.",
"default": false
},
"avoidWindowsConsoleRedirection": {
"type": "boolean",
"description": "If true, disables debuggee console redirection that is required for Integrated Terminal support.",
"default": false
},
"sourceFileMap": {
@@ -719,8 +816,8 @@
}
},
"logging": {
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"type": "object",
"default": {},
"properties": {
"exceptions": {
@@ -759,10 +856,10 @@
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).",
"type": "object",
"default": {
"pipeCwd": "${workspaceRoot}",
"pipeCwd": "/usr/bin",
"pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'",
"pipeArgs": [],
"debuggerPath": "enter the path for the debugger on the target machine, for example /usr/bin/gdb"
"debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
},
"properties": {
"pipeCwd": {
@@ -801,6 +898,8 @@
}
},
"attach": {
"type": "object",
"default": {},
"required": [
"program",
"processId"
@@ -883,8 +982,8 @@
}
},
"logging": {
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"type": "object",
"default": {},
"properties": {
"exceptions": {
@@ -923,10 +1022,10 @@
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).",
"type": "object",
"default": {
"pipeCwd": "${workspaceRoot}",
"pipeCwd": "/usr/bin",
"pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'",
"pipeArgs": [],
"debuggerPath": "enter the path for the debugger on the target machine, for example /usr/bin/gdb"
"debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
},
"properties": {
"pipeCwd": {
@@ -967,6 +1066,7 @@
"description": "One or more GDB/LLDB commands to execute in order to setup the underlying debugger. Example: \"setupCommands\": [ { \"text\": \"-enable-pretty-printing\", \"description\": \"Enable GDB pretty printing\", \"ignoreFailures\": true }].",
"items": {
"type": "object",
"default": {},
"properties": {
"text": {
"type": "string",
@@ -1007,6 +1107,8 @@
},
"configurationAttributes": {
"launch": {
"type": "object",
"default": {},
"required": [
"program",
"cwd"
@@ -1040,9 +1142,14 @@
"description": "Environment variables to add to the environment for the program. Example: [ { \"name\": \"squid\", \"value\": \"clam\" } ].",
"items": {
"type": "object",
"default": {},
"properties": {
"name": "string",
"value": "string"
"name": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"default": []
@@ -1109,6 +1216,8 @@
}
},
"attach": {
"type": "object",
"default": {},
"required": [
"processId"
],
@@ -1253,25 +1362,16 @@
},
"configurationDefaults": {
"[cpp]": {
"editor.autoIndent": false
"editor.wordBasedSuggestions": false
},
"[c]": {
"editor.autoIndent": false
"editor.wordBasedSuggestions": 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 ./",
@@ -1285,34 +1385,39 @@
"devDependencies": {
"@types/mocha": "^2.2.43",
"@types/node": "^8.0.46",
"async-child-process": "^1.1.1",
"child-process": "^1.0.2",
"gulp": "^4.0.0",
"gulp-env": "0.4.0",
"gulp-mocha": "5.0.0",
"gulp-tslint": "8.1.2",
"gulp": "3.9.1",
"mocha": "^4.0.1",
"tslint": "5.8.0",
"tslint-microsoft-contrib": "5.0.1",
"tslint-no-unused-expression-chai": "0.0.3",
"tslint": "5.8.0",
"typescript": "^2.5.3",
"vscode": "^1.1.14"
"vrsource-tslint-rules": "^5.8.2",
"vscode": "^1.1.18"
},
"dependencies": {
"http-proxy-agent": "~2.0.0",
"https-proxy-agent": "~2.1.0",
"@types/minimatch": "^3.0.3",
"http-proxy-agent": "~2.1.0",
"https-proxy-agent": "~2.2.0",
"jsonc-parser": "^1.0.0",
"minimatch": "~3.0.4",
"mkdirp": "~0.5.1",
"tmp": "~0.0.33",
"vscode-cpptools": "2.1.1",
"vscode-debugadapter": "~1.24.0",
"vscode-debugprotocol": "~1.24.0",
"vscode-extension-telemetry": "~0.0.11",
"vscode-languageclient": "3.5.1",
"yauzl": "~2.8.0"
"vscode-extension-telemetry": "~0.1.0",
"vscode-languageclient": "5.1.1",
"yauzl": "~2.10.0"
},
"runtimeDependencies": [
{
"description": "C/C++ language components (Linux / x86_64)",
"url": "https://go.microsoft.com/fwlink/?linkid=872599",
"url": "https://go.microsoft.com/fwlink/?linkid=2037608",
"platforms": [
"linux"
],
@@ -1326,7 +1431,7 @@
},
{
"description": "C/C++ language components (Linux / x86)",
"url": "https://go.microsoft.com/fwlink/?linkid=872600",
"url": "https://go.microsoft.com/fwlink/?linkid=2037526",
"platforms": [
"linux"
],
@@ -1342,7 +1447,7 @@
},
{
"description": "C/C++ language components (OS X)",
"url": "https://go.microsoft.com/fwlink/?linkid=872601",
"url": "https://go.microsoft.com/fwlink/?linkid=2037527",
"platforms": [
"darwin"
],
@@ -1353,7 +1458,7 @@
},
{
"description": "C/C++ language components (Windows)",
"url": "https://go.microsoft.com/fwlink/?linkid=872602",
"url": "https://go.microsoft.com/fwlink/?linkid=2037609",
"platforms": [
"win32"
],
@@ -1407,7 +1512,7 @@
},
{
"description": "Mono Framework Assemblies",
"url": "https://go.microsoft.com/fwlink/?LinkId=816539",
"url": "https://go.microsoft.com/fwlink/?LinkId=2027135",
"platforms": [
"linux",
"darwin"
@@ -1416,7 +1521,7 @@
},
{
"description": "Mono Runtime (Linux / x86)",
"url": "https://go.microsoft.com/fwlink/?LinkId=816540",
"url": "https://go.microsoft.com/fwlink/?LinkId=2027410",
"platforms": [
"linux"
],
@@ -1431,7 +1536,7 @@
},
{
"description": "Mono Runtime (Linux / x86_64)",
"url": "https://go.microsoft.com/fwlink/?LinkId=816541",
"url": "https://go.microsoft.com/fwlink/?LinkId=2027416",
"platforms": [
"linux"
],
@@ -1444,7 +1549,7 @@
},
{
"description": "Mono Runtime (OS X)",
"url": "https://go.microsoft.com/fwlink/?LinkId=816542",
"url": "https://go.microsoft.com/fwlink/?LinkId=2027403",
"platforms": [
"darwin"
],
+18
View File
@@ -0,0 +1,18 @@
{
"c_cpp.command.configurationSelect.title": "Scegli una configurazione...",
"c_cpp.command.configurationProviderSelect.title": "Cambia provider configurazioni...",
"c_cpp.command.configurationEdit.title": "Modifica configurazioni...",
"c_cpp.command.goToDeclaration.title": "Vai a dichiarazione",
"c_cpp.command.peekDeclaration.title": "Visualizza dichiarazione",
"c_cpp.command.switchHeaderSource.title": "Visualizza Header/Sorgente",
"c_cpp.command.navigate.title": "Naviga...",
"c_cpp.command.toggleErrorSquiggles.title": "Attiva/Disattiva sottolineamento errori",
"c_cpp.command.toggleIncludeFallback.title": "Attiva/Disattiva motore di fallback IntelliSense negli errori di inclusione",
"c_cpp.command.toggleDimInactiveRegions.title": "Attiva/Disattiva colorazione regioni inattive",
"c_cpp.command.showReleaseNotes.title": "Mostra note di rilascio",
"c_cpp.command.resetDatabase.title": "Reimposta il database di IntelliSense",
"c_cpp.command.pauseParsing.title": "Metti in pausa l'analisi del codice",
"c_cpp.command.resumeParsing.title": "Riprendi l'analisi del codice",
"c_cpp.command.showParsingCommands.title": "Mostra comandi per l'analisi del codice",
"c_cpp.command.takeSurvey.title": "Partecipa al Sondaggio"
}
+18
View File
@@ -0,0 +1,18 @@
{
"c_cpp.command.configurationSelect.title": "Select a configuration...",
"c_cpp.command.configurationProviderSelect.title": "Change configuration provider...",
"c_cpp.command.configurationEdit.title": "Edit configurations...",
"c_cpp.command.goToDeclaration.title": "Go to declaration",
"c_cpp.command.peekDeclaration.title": "Peek declaration",
"c_cpp.command.switchHeaderSource.title": "Switch Header/Source",
"c_cpp.command.navigate.title": "Navigate...",
"c_cpp.command.toggleErrorSquiggles.title": "Toggle error squiggles",
"c_cpp.command.toggleIncludeFallback.title": "Toggle IntelliSense engine fallback on include errors",
"c_cpp.command.toggleDimInactiveRegions.title": "Toggle inactive region colorization",
"c_cpp.command.showReleaseNotes.title": "Show release notes",
"c_cpp.command.resetDatabase.title": "Reset IntelliSense database",
"c_cpp.command.pauseParsing.title": "Pause parsing",
"c_cpp.command.resumeParsing.title": "Resume parsing",
"c_cpp.command.showParsingCommands.title": "Show parsing commands",
"c_cpp.command.takeSurvey.title": "Take survey"
}
+70
View File
@@ -0,0 +1,70 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import * as util from '../common';
import * as vscode from 'vscode';
class RefreshButton implements vscode.QuickInputButton {
get iconPath(): { dark: vscode.Uri; light: vscode.Uri } {
const refreshImagePathDark: string = util.getExtensionFilePath("assets/Refresh_inverse.svg");
const refreshImagePathLight: string = util.getExtensionFilePath("assets/Refresh.svg");
return {
dark: vscode.Uri.file(refreshImagePathDark),
light: vscode.Uri.file(refreshImagePathLight)
};
}
get tooltip(): string {
return "Refresh process list";
}
}
export interface AttachItem extends vscode.QuickPickItem {
id: string;
}
export function showQuickPick(getAttachItems: () => Promise<AttachItem[]>): Promise<string> {
return getAttachItems().then(processEntries => {
return new Promise<string>((resolve, reject) => {
let quickPick: vscode.QuickPick<AttachItem> = vscode.window.createQuickPick<AttachItem>();
quickPick.title = "Attach to process";
quickPick.canSelectMany = false;
quickPick.matchOnDescription = true;
quickPick.matchOnDetail = true;
quickPick.placeholder = "Select the process to attach to";
quickPick.items = processEntries;
quickPick.buttons = [new RefreshButton()];
let disposables: vscode.Disposable[] = [];
quickPick.onDidTriggerButton(button => {
getAttachItems().then(processEntries => quickPick.items = processEntries);
}, undefined, disposables);
quickPick.onDidAccept(() => {
if (quickPick.selectedItems.length !== 1) {
reject(new Error("Process not selected"));
}
let selectedId: string = quickPick.selectedItems[0].id;
disposables.forEach(item => item.dispose());
quickPick.dispose();
resolve(selectedId);
}, undefined, disposables);
quickPick.onDidHide(() => {
disposables.forEach(item => item.dispose());
quickPick.dispose();
reject(new Error("Process not selected."));
}, undefined, disposables);
quickPick.show();
});
});
}
+6 -21
View File
@@ -5,6 +5,7 @@
import { execChildProcess } from '../common';
import { PsProcessParser } from './nativeAttach';
import { AttachItem, showQuickPick } from './attachQuickPick';
import * as debugUtils from './utils';
import * as fs from 'fs';
@@ -13,10 +14,6 @@ import * as path from 'path';
import * as util from '../common';
import * as vscode from 'vscode';
export interface AttachItem extends vscode.QuickPickItem {
id: string;
}
export interface AttachItemsProvider {
getAttachItems(): Promise<AttachItem[]>;
}
@@ -29,19 +26,7 @@ export class AttachPicker {
if (!ready) {
util.displayExtensionNotReadyPrompt();
} else {
return this.attachItemsProvider.getAttachItems()
.then(processEntries => {
let attachPickOptions: vscode.QuickPickOptions = {
matchOnDescription: true,
matchOnDetail: true,
placeHolder: "Select the process to attach to"
};
return vscode.window.showQuickPick(processEntries, attachPickOptions)
.then(chosenProcess => {
return chosenProcess ? chosenProcess.id : Promise.reject<string>(new Error("Process not selected."));
});
});
return showQuickPick(() => this.attachItemsProvider.getAttachItems());
}
});
}
@@ -74,7 +59,7 @@ export class RemoteAttachPicker {
!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);
@@ -84,7 +69,7 @@ export class RemoteAttachPicker {
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);
}
@@ -120,10 +105,10 @@ export class RemoteAttachPicker {
private getRemoteOSAndProcesses(pipeCmd: string): Promise<AttachItem[]> {
// Commands to get OS and processes
const command: string = `bash -c 'uname && if [ $(uname) == "Linux" ] ; then ${PsProcessParser.psLinuxCommand} ; elif [ $(uname) == "Darwin" ] ; ` +
const command: string = `sh -c 'uname && if [ $(uname) = "Linux" ] ; then ${PsProcessParser.psLinuxCommand} ; elif [ $(uname) = "Darwin" ] ; ` +
`then ${PsProcessParser.psDarwinCommand}; fi'`;
return execChildProcess(`${pipeCmd} "${command}"`, null, this._channel).then(output => {
return execChildProcess(`${pipeCmd} '${command}'`, null, this._channel).then(output => {
// OS will be on first line
// Processess will follow if listed
let lines: string[] = output.split(/\r?\n/);
+37 -35
View File
@@ -31,37 +31,39 @@ abstract class CppConfigurationProvider implements vscode.DebugConfigurationProv
* Try to add all missing attributes to the debug configuration being launched.
*/
resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration> {
// Fail if cppvsdbg type is running on non-Windows
if (config.type === 'cppvsdbg' && os.platform() !== 'win32') {
vscode.window.showErrorMessage("Debugger of type: 'cppvsdbg' is only available on Windows. Use type: 'cppdbg' on the current OS platform.");
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 (config) {
// Fail if cppvsdbg type is running on non-Windows
if (config.type === 'cppvsdbg' && os.platform() !== 'win32') {
vscode.window.showErrorMessage("Debugger of type: 'cppvsdbg' is only available on Windows. Use type: 'cppdbg' on the current OS platform.");
return undefined;
}
if (replacedPipeProgram) {
config.pipeTransport.pipeProgram = replacedPipeProgram;
// 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;
}
// if config or type is not specified, return null to trigger VS Code to open a configuration file https://github.com/Microsoft/vscode/issues/54213
return config && config.type ? config : null;
}
}
export class CppVsDbgConfigurationProvider extends CppConfigurationProvider {
@@ -71,7 +73,7 @@ export class CppVsDbgConfigurationProvider extends CppConfigurationProvider {
}
export class CppDbgConfigurationProvider extends CppConfigurationProvider {
public constructor(provider: IConfigurationAssetProvider) {
public constructor(provider: IConfigurationAssetProvider) {
super(provider, DebuggerType.cppdbg);
}
}
@@ -101,12 +103,12 @@ abstract class DefaultConfigurationProvider implements IConfigurationAssetProvid
public getInitialConfigurations(debuggerType: DebuggerType): any {
let configurationSnippet: IConfigurationSnippet[] = [];
// Only launch configurations are initial configurations
this.configurations.forEach(configuration => {
configurationSnippet.push(configuration.GetLaunchConfiguration());
configurationSnippet.push(configuration.GetLaunchConfiguration());
});
let initialConfigurations: any = configurationSnippet.filter(snippet => snippet.debuggerType === debuggerType && snippet.isInitialConfiguration)
.map(snippet => JSON.parse(snippet.bodyText));
@@ -141,7 +143,7 @@ class WindowsConfigurationProvider extends DefaultConfigurationProvider {
constructor() {
super();
this.configurations = [
new MIConfigurations(this.MIMode, this.executable, this.pipeProgram, this.setupCommandsBlock),
new MIConfigurations(this.MIMode, this.executable, this.pipeProgram, this.setupCommandsBlock),
new PipeTransportConfigurations(this.MIMode, this.executable, this.pipeProgram, this.setupCommandsBlock),
new WindowsConfigurations(this.MIMode, this.executable, this.pipeProgram, this.setupCommandsBlock),
new WSLConfigurations(this.MIMode, this.executable, this.pipeProgram, this.setupCommandsBlock),
@@ -157,7 +159,7 @@ class OSXConfigurationProvider extends DefaultConfigurationProvider {
constructor() {
super();
this.configurations = [
new MIConfigurations(this.MIMode, this.executable, this.pipeProgram),
new MIConfigurations(this.MIMode, this.executable, this.pipeProgram),
];
}
}
@@ -177,7 +179,7 @@ class LinuxConfigurationProvider extends DefaultConfigurationProvider {
constructor() {
super();
this.configurations = [
new MIConfigurations(this.MIMode, this.executable, this.pipeProgram, this.setupCommandsBlock),
new MIConfigurations(this.MIMode, this.executable, this.pipeProgram, this.setupCommandsBlock),
new PipeTransportConfigurations(this.MIMode, this.executable, this.pipeProgram, this.setupCommandsBlock)
];
}
@@ -220,7 +222,7 @@ export class ConfigurationSnippetProvider implements vscode.CompletionItemProvid
items.map((item) => {
item.insertText = item.insertText + ','; // Add comma
});
});
}
return Promise.resolve(new vscode.CompletionList(items, true));
+16 -16
View File
@@ -31,7 +31,7 @@ function formatString(format: string, args: string[]): string {
return format;
}
function CreateLaunchString(name: string, type: string, executable: string): string {
function createLaunchString(name: string, type: string, executable: string): string {
return `"name": "${name}",
"type": "${type}",
"request": "launch",
@@ -44,7 +44,7 @@ function CreateLaunchString(name: string, type: string, executable: string): str
`;
}
function CreateAttachString(name: string, type: string, executable: string): string {
function createAttachString(name: string, type: string, executable: string): string {
return formatString(`
"name": "${name}",
"type": "${type}",
@@ -53,7 +53,7 @@ function CreateAttachString(name: string, type: string, executable: string): str
`, [type === "cppdbg" ? `${os.EOL}"program": "${"enter program name, for example $\{workspaceFolder\}/" + executable}",` : ""]);
}
function CreateRemoteAttachString(name: string, type: string, executable: string): string {
function createRemoteAttachString(name: string, type: string, executable: string): string {
return `
"name": "${name}",
"type": "${type}",
@@ -63,7 +63,7 @@ function CreateRemoteAttachString(name: string, type: string, executable: string
`;
}
function CreatePipeTransportString(pipeProgram: string, debuggerProgram: string, pipeArgs: string[] = []): string {
function createPipeTransportString(pipeProgram: string, debuggerProgram: string, pipeArgs: string[] = []): string {
return `
"pipeTransport": {
\t"debuggerPath": "/usr/bin/${debuggerProgram}",
@@ -106,7 +106,7 @@ export class MIConfigurations extends Configuration {
let name: string = `(${this.MIMode}) Launch`;
let body: string = formatString(`{
\t${indentJsonString(CreateLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createLaunchString(name, this.miDebugger, this.executable))},
\t"MIMode": "${this.MIMode}"{0}{1}
}`, [this.miDebugger === "cppdbg" && os.platform() === "win32" ? `,${os.EOL}\t"miDebuggerPath": "/path/to/gdb"` : "",
this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
@@ -124,7 +124,7 @@ this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalPrope
let name: string = `(${this.MIMode}) Attach`;
let body: string = formatString(`{
\t${indentJsonString(CreateAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createAttachString(name, this.miDebugger, this.executable))},
\t"MIMode": "${this.MIMode}"{0}{1}
}`, [this.miDebugger === "cppdbg" && os.platform() === "win32" ? `,${os.EOL}\t"miDebuggerPath": "/path/to/gdb"` : "",
this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
@@ -146,8 +146,8 @@ export class PipeTransportConfigurations extends Configuration {
let body: string = formatString(`
{
\t${indentJsonString(CreateLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.pipeProgram, this.MIMode))},
\t${indentJsonString(createLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.pipeProgram, this.MIMode))},
\t"MIMode": "${this.MIMode}"{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
@@ -165,8 +165,8 @@ export class PipeTransportConfigurations extends Configuration {
let body: string = formatString(`
{
\t${indentJsonString(CreateRemoteAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.pipeProgram, this.MIMode))},
\t${indentJsonString(createRemoteAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.pipeProgram, this.MIMode))},
\t"MIMode": "${this.MIMode}"{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
return {
@@ -186,7 +186,7 @@ export class WindowsConfigurations extends Configuration {
let body: string = `
{
\t${indentJsonString(CreateLaunchString(name, this.windowsDebugger, this.executable))}
\t${indentJsonString(createLaunchString(name, this.windowsDebugger, this.executable))}
}`;
return {
@@ -204,7 +204,7 @@ export class WindowsConfigurations extends Configuration {
let body: string = `
{
\t${indentJsonString(CreateAttachString(name, this.windowsDebugger, this.executable))}
\t${indentJsonString(createAttachString(name, this.windowsDebugger, this.executable))}
}`;
return {
@@ -226,8 +226,8 @@ export class WSLConfigurations extends Configuration {
let body: string = formatString(`
{
\t${indentJsonString(CreateLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0}
\t${indentJsonString(createLaunchString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
return {
@@ -243,8 +243,8 @@ export class WSLConfigurations extends Configuration {
let body: string = formatString(`
{
\t${indentJsonString(CreateRemoteAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(CreatePipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0}
\t${indentJsonString(createRemoteAttachString(name, this.miDebugger, this.executable))},
\t${indentJsonString(createPipeTransportString(this.bashPipeProgram, this.MIMode, ["-c"]))}{0}
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
return {
+1
View File
@@ -34,6 +34,7 @@ export function initialize(): void {
configurationProvider.getConfigurationSnippets();
const launchJsonDocumentSelector: vscode.DocumentSelector = [{
scheme: 'file',
language: 'jsonc',
pattern: '**/launch.json'
}];
+4 -3
View File
@@ -5,7 +5,8 @@
import * as child_process from 'child_process';
import * as os from 'os';
import { AttachItem, AttachItemsProvider } from './attachToProcess';
import { AttachItemsProvider } from './attachToProcess';
import { AttachItem } from './attachQuickPick';
class Process {
constructor(public name: string, public pid: string, public commandLine: string) { }
@@ -111,8 +112,8 @@ export class PsProcessParser {
// Note that comm on Linux systems is truncated to 16 characters:
// https://bugzilla.redhat.com/show_bug.cgi?id=429565
// Since 'args' contains the full path to the executable, even if truncated, searching will work as desired.
public static get psLinuxCommand(): string { return `ps -axww -o pid=,comm=${PsProcessParser.commColumnTitle},args=`; }
public static get psDarwinCommand(): string { return `ps -axww -o pid=,comm=${PsProcessParser.commColumnTitle},args= -c`; }
public static get psLinuxCommand(): string { return `ps axww -o pid=,comm=${PsProcessParser.commColumnTitle},args=`; }
public static get psDarwinCommand(): string { return `ps axww -o pid=,comm=${PsProcessParser.commColumnTitle},args= -c`; }
// Only public for tests.
public static ParseProcessFromPs(processes: string): Process[] {
File diff suppressed because it is too large Load Diff
@@ -9,6 +9,7 @@ import * as util from '../common';
import * as telemetry from '../telemetry';
import * as cpptools from './client';
import * as path from 'path';
import { getCustomConfigProviders } from './customProviders';
const defaultClientKey: string = "@@default@@";
export interface ClientKey {
@@ -118,7 +119,7 @@ export class ClientCollection {
this.languageClients.set(key, cpptools.createNullClient());
}
if (this.activeClient === client) {
if (this.activeClient === client && this.activeDocument) {
this.activeClient = this.getClientFor(this.activeDocument.uri);
this.activeClient.activeDocumentChanged(this.activeDocument);
}
@@ -153,12 +154,12 @@ export class ClientCollection {
client.TrackedDocuments.forEach(document => this.transferOwnership(document, client));
client.TrackedDocuments.clear();
if (this.activeClient === client) {
if (this.activeClient === client && this.activeDocument) {
// Need to make a different client the active client.
this.activeClient = this.getClientFor(this.activeDocument.uri);
this.activeClient.activeDocumentChanged(this.activeDocument);
// may not need this, the navigation UI should not have changed.
// this.activeClient.selectionChanged(vscode.window.activeTextEditor.selection.start);
// this.activeClient.selectionChanged(Range.create(vscode.window.activeTextEditor.selection.start, vscode.window.activeTextEditor.selection.end);
}
client.dispose();
@@ -187,7 +188,9 @@ export class ClientCollection {
} else {
let key: string = util.asFolder(folder.uri);
if (!this.languageClients.has(key)) {
this.languageClients.set(key, cpptools.createClient(this, folder));
let newClient: cpptools.Client = cpptools.createClient(this, folder);
this.languageClients.set(key, newClient);
getCustomConfigProviders().forEach(provider => newClient.onRegisterCustomConfigurationProvider(provider));
}
return this.languageClients.get(key);
}
+245 -144
View File
@@ -8,20 +8,25 @@ import * as path from 'path';
import * as fs from "fs";
import * as vscode from 'vscode';
import * as util from '../common';
import * as telemetry from '../telemetry';
import { PersistentFolderState } from './persistentState';
import { CppSettings } from './settings';
const configVersion: number = 3;
import { ABTestSettings, getABTestSettings } from '../abTesting';
import { getCustomConfigProviders } from './customProviders';
const configVersion: number = 4;
type Environment = { [key: string]: string | string[] };
// No properties are set in the config since we want to apply vscode settings first (if applicable).
// That code won't trigger if another value is already set.
// The property defaults are moved down to applyDefaultIncludePathsAndFrameworks.
function getDefaultConfig(): Configuration {
if (process.platform === 'darwin') {
return { name: "Mac", browse: {} };
return { name: "Mac" };
} else if (process.platform === 'win32') {
return { name: "Win32", browse: {} };
return { name: "Win32" };
} else {
return { name: "Linux", browse: {} };
return { name: "Linux" };
}
}
@@ -32,8 +37,9 @@ function getDefaultCppProperties(): ConfigurationJson {
};
}
interface ConfigurationJson {
export interface ConfigurationJson {
configurations: Configuration[];
env?: {[key: string]: string | string[]};
version: number;
}
@@ -44,10 +50,12 @@ export interface Configuration {
cppStandard?: string;
includePath?: string[];
macFrameworkPath?: string[];
windowsSdkVersion?: string;
defines?: string[];
intelliSenseMode?: string;
compileCommands?: string;
forcedInclude?: string[];
configurationProvider?: string;
browse?: Browse;
}
@@ -63,6 +71,7 @@ export interface CompilerDefaults {
cppStandard: string;
includes: string[];
frameworks: string[];
windowsSdkVersion: string;
intelliSenseMode: string;
}
@@ -80,10 +89,11 @@ export class CppProperties {
private defaultCppStandard: string = null;
private defaultIncludes: string[] = null;
private defaultFrameworks: string[] = null;
private defaultWindowsSdkVersion: 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 readonly configurationGlobPattern: string = "c_cpp_properties.json";
private disposables: vscode.Disposable[] = [];
private configurationsChanged = new vscode.EventEmitter<Configuration[]>();
private selectionChanged = new vscode.EventEmitter<number>();
@@ -106,7 +116,7 @@ export class CppProperties {
this.parsePropertiesFile();
}
if (!this.configurationJson) {
this.resetToDefaultSettings(this.CurrentConfiguration === -1);
this.resetToDefaultSettings(this.CurrentConfigurationIndex === -1);
}
this.configFileWatcher = vscode.workspace.createFileSystemWatcher(path.join(this.configFolder, this.configurationGlobPattern));
@@ -135,7 +145,15 @@ export class CppProperties {
public get SelectionChanged(): vscode.Event<number> { return this.selectionChanged.event; }
public get CompileCommandsChanged(): vscode.Event<string> { return this.compileCommandsChanged.event; }
public get Configurations(): Configuration[] { return this.configurationJson.configurations; }
public get CurrentConfiguration(): number { return this.currentConfigurationIndex.Value; }
public get CurrentConfigurationIndex(): number { return this.currentConfigurationIndex.Value; }
public get CurrentConfiguration(): Configuration { return this.Configurations[this.CurrentConfigurationIndex]; }
public get CurrentConfigurationProvider(): string|null {
if (this.CurrentConfiguration.configurationProvider) {
return this.CurrentConfiguration.configurationProvider;
}
return new CppSettings(this.rootUri).defaultConfigurationProvider;
}
public get ConfigurationNames(): string[] {
let result: string[] = [];
@@ -149,6 +167,7 @@ export class CppProperties {
this.defaultCppStandard = compilerDefaults.cppStandard;
this.defaultIncludes = compilerDefaults.includes;
this.defaultFrameworks = compilerDefaults.frameworks;
this.defaultWindowsSdkVersion = compilerDefaults.windowsSdkVersion;
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
@@ -165,7 +184,7 @@ export class CppProperties {
}
private onSelectionChanged(): void {
this.selectionChanged.fire(this.CurrentConfiguration);
this.selectionChanged.fire(this.CurrentConfigurationIndex);
}
private onCompileCommandsChanged(path: string): void {
@@ -185,8 +204,8 @@ export class CppProperties {
private resetToDefaultSettings(resetIndex: boolean): void {
this.configurationJson = getDefaultCppProperties();
if (resetIndex || this.CurrentConfiguration < 0 ||
this.CurrentConfiguration >= this.configurationJson.configurations.length) {
if (resetIndex || this.CurrentConfigurationIndex < 0 ||
this.CurrentConfigurationIndex >= this.configurationJson.configurations.length) {
this.currentConfigurationIndex.Value = this.getConfigIndexForPlatform(this.configurationJson);
}
this.configurationIncomplete = true;
@@ -194,8 +213,12 @@ export class CppProperties {
private applyDefaultIncludePathsAndFrameworks(): void {
if (this.configurationIncomplete && this.defaultIncludes && this.defaultFrameworks && this.vcpkgPathReady) {
let configuration: Configuration = this.configurationJson.configurations[this.CurrentConfiguration];
let configuration: Configuration = this.CurrentConfiguration;
let settings: CppSettings = new CppSettings(this.rootUri);
let isUnset: (input: any) => boolean = (input: any) => {
// default values for "default" config settings is null.
return input === null;
};
// 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
@@ -203,59 +226,69 @@ export class CppProperties {
// Only add settings from the default compiler if user hasn't explicitly set the corresponding VS Code setting.
if (!settings.defaultIncludePath) {
if (isUnset(settings.defaultIncludePath)) {
// We don't add system includes to the includePath anymore. The language server has this information.
configuration.includePath = ["${workspaceFolder}/**"].concat(this.vcpkgIncludes);
let abTestSettings: ABTestSettings = getABTestSettings();
let rootFolder: string = abTestSettings.UseRecursiveIncludes ? "${workspaceFolder}/**" : "${workspaceFolder}";
configuration.includePath = [rootFolder].concat(this.vcpkgIncludes);
}
if (!settings.defaultBrowsePath) {
// We don't add system includes to the includePath anymore. The language server has this information.
configuration.browse.path = ["${workspaceFolder}"].concat(this.vcpkgIncludes);
}
if (!settings.defaultDefines) {
// browse.path is not set by default anymore. When it is not set, the includePath will be used instead.
if (isUnset(settings.defaultDefines)) {
configuration.defines = (process.platform === 'win32') ? ["_DEBUG", "UNICODE", "_UNICODE"] : [];
}
if (!settings.defaultMacFrameworkPath && process.platform === 'darwin') {
if (isUnset(settings.defaultMacFrameworkPath) && process.platform === 'darwin') {
configuration.macFrameworkPath = this.defaultFrameworks;
}
if (!settings.defaultCompilerPath && this.defaultCompilerPath) {
if (isUnset(settings.defaultWindowsSdkVersion) && this.defaultWindowsSdkVersion && process.platform === 'win32') {
configuration.windowsSdkVersion = this.defaultWindowsSdkVersion;
}
if (isUnset(settings.defaultCompilerPath) && this.defaultCompilerPath) {
configuration.compilerPath = this.defaultCompilerPath;
}
if (!settings.defaultCStandard && this.defaultCStandard) {
if (isUnset(settings.defaultCStandard) && this.defaultCStandard) {
configuration.cStandard = this.defaultCStandard;
}
if (!settings.defaultCppStandard && this.defaultCppStandard) {
if (isUnset(settings.defaultCppStandard) && this.defaultCppStandard) {
configuration.cppStandard = this.defaultCppStandard;
}
if (!settings.defaultIntelliSenseMode) {
if (isUnset(settings.defaultIntelliSenseMode)) {
configuration.intelliSenseMode = this.defaultIntelliSenseMode;
}
this.configurationIncomplete = false;
}
}
private get ExtendedEnvironment(): Environment {
let result: Environment = {};
if (this.configurationJson.env) {
Object.assign(result, this.configurationJson.env);
}
result["workspaceFolderBasename"] = this.rootUri ? path.basename(this.rootUri.fsPath) : "";
return result;
}
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);
}
// Check for vcpkgRoot and include relevent paths if found.
let vcpkgRoot: string = util.getVcpkgRoot();
if (vcpkgRoot) {
let list: string[] = await util.readDir(vcpkgRoot);
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(vcpkgRoot, entry);
if (fs.existsSync(pathToCheck)) {
let p: string = path.join(pathToCheck, "include");
if (fs.existsSync(p)) {
p = p.replace(/\\/g, "/");
p = p.replace(vcpkgRoot, "${vcpkgRoot}");
this.vcpkgIncludes.push(p);
}
}
});
}
}
});
}
}
} catch (error) {} finally {
@@ -265,17 +298,13 @@ export class CppProperties {
}
private getConfigIndexForPlatform(config: any): number {
if (this.configurationJson.configurations.length > 3) {
return this.configurationJson.configurations.length - 1; // Default to the last custom configuration.
}
let nodePlatform: NodeJS.Platform = process.platform;
let plat: string;
if (nodePlatform === 'linux') {
plat = "Linux";
} else if (nodePlatform === 'darwin') {
if (process.platform === 'darwin') {
plat = "Mac";
} else if (nodePlatform === 'win32') {
} else if (process.platform === 'win32') {
plat = "Win32";
} else {
plat = "Linux";
}
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
if (config.configurations[i].name === plat) {
@@ -287,39 +316,71 @@ export class CppProperties {
private getIntelliSenseModeForPlatform(name: string): string {
// Do the built-in configs first.
if (name === "Linux" || name === "Mac") {
if (name === "Linux") {
return "gcc-x64";
} else if (name === "Mac") {
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 if (process.platform === 'darwin') {
return "clang-x64";
} else {
return "gcc-x64";
}
return "msvc-x64";
}
private includePathConverted(): boolean {
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
if (this.configurationJson.configurations[i].browse === undefined || this.configurationJson.configurations[i].browse.path === undefined) {
return false;
}
}
return true;
}
public addToIncludePathCommand(path: string): void {
this.handleConfigurationEditCommand((document: vscode.TextDocument) => {
telemetry.logLanguageServerEvent("addToIncludePath");
this.parsePropertiesFile(); // Clear out any modifications we may have made internally.
let config: Configuration = this.configurationJson.configurations[this.CurrentConfiguration];
let config: Configuration = 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();
this.handleConfigurationChange();
});
}
public updateCustomConfigurationProvider(providerId: string): Thenable<void> {
return new Promise<void>((resolve) => {
if (this.propertiesFile) {
this.handleConfigurationEditCommand((document: vscode.TextDocument) => {
this.parsePropertiesFile(); // Clear out any modifications we may have made internally.
let config: Configuration = this.CurrentConfiguration;
if (providerId) {
config.configurationProvider = providerId;
} else {
delete config.configurationProvider;
}
fs.writeFileSync(this.propertiesFile.fsPath, JSON.stringify(this.configurationJson, null, 4));
this.handleConfigurationChange();
resolve();
});
} else {
let settings: CppSettings = new CppSettings(this.rootUri);
if (providerId) {
settings.update("default.configurationProvider", providerId);
} else {
settings.update("default.configurationProvider", undefined); // delete the setting
}
this.CurrentConfiguration.configurationProvider = providerId;
resolve();
}
});
}
public setCompileCommands(path: string): void {
this.handleConfigurationEditCommand((document: vscode.TextDocument) => {
this.parsePropertiesFile(); // Clear out any modifications we may have made internally.
let config: Configuration = this.CurrentConfiguration;
config.compileCommands = path;
fs.writeFileSync(this.propertiesFile.fsPath, JSON.stringify(this.configurationJson, null, 4));
this.handleConfigurationChange();
});
}
@@ -336,7 +397,11 @@ export class CppProperties {
let result: string[] = [];
entries.forEach(entry => {
if (entry === "${default}") {
result = result.concat(defaultValue);
// package.json default values for string[] properties is null.
// If no default is set, return an empty array instead of an array with `null` in it.
if (defaultValue !== null) {
result = result.concat(defaultValue);
}
} else {
result.push(entry);
}
@@ -344,11 +409,11 @@ export class CppProperties {
return result;
}
private resolveAndSplit(paths: string[] | undefined, defaultValue: string[]): string[] {
private resolveAndSplit(paths: string[] | undefined, defaultValue: string[], env: Environment): 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, env).split(";").filter(e => e);
entries = this.resolveDefaults(entries, defaultValue);
result = result.concat(entries);
});
@@ -356,29 +421,29 @@ export class CppProperties {
return result;
}
private resolveVariables(input: string | boolean, defaultValue: string | boolean): string | boolean {
private resolveVariables(input: string | boolean, defaultValue: string | boolean, env: Environment): string | boolean {
if (input === undefined || input === "${default}") {
input = defaultValue;
}
if (typeof input === "boolean") {
return input;
}
return util.resolveVariables(input);
return util.resolveVariables(input, 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) {
private updateConfiguration(property: string[], defaultValue: string[], env: Environment): string[];
private updateConfiguration(property: string, defaultValue: string, env: Environment): string;
private updateConfiguration(property: string | boolean, defaultValue: boolean, env: Environment): boolean;
private updateConfiguration(property, defaultValue, env): any {
if (util.isString(property) || util.isString(defaultValue)) {
return this.resolveVariables(property, defaultValue, env);
} else if (util.isBoolean(property) || util.isBoolean(defaultValue)) {
return this.resolveVariables(property, defaultValue, env);
} else if (util.isArrayOfString(property) || util.isArrayOfString(defaultValue)) {
if (property) {
return this.resolveAndSplit(property, defaultValue);
return this.resolveAndSplit(property, defaultValue, env);
} else if (property === undefined && defaultValue) {
return this.resolveAndSplit(defaultValue, []);
return this.resolveAndSplit(defaultValue, [], env);
}
}
return property;
@@ -386,25 +451,44 @@ export class CppProperties {
private updateServerOnFolderSettingsChange(): void {
let settings: CppSettings = new CppSettings(this.rootUri);
let env: Environment = this.ExtendedEnvironment;
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let configuration: Configuration = this.configurationJson.configurations[i];
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);
configuration.includePath = this.updateConfiguration(configuration.includePath, settings.defaultIncludePath, env);
configuration.defines = this.updateConfiguration(configuration.defines, settings.defaultDefines, env);
configuration.macFrameworkPath = this.updateConfiguration(configuration.macFrameworkPath, settings.defaultMacFrameworkPath, env);
configuration.windowsSdkVersion = this.updateConfiguration(configuration.windowsSdkVersion, settings.defaultWindowsSdkVersion, env);
configuration.forcedInclude = this.updateConfiguration(configuration.forcedInclude, settings.defaultForcedInclude, env);
configuration.compileCommands = this.updateConfiguration(configuration.compileCommands, settings.defaultCompileCommands, env);
configuration.compilerPath = this.updateConfiguration(configuration.compilerPath, settings.defaultCompilerPath, env);
configuration.cStandard = this.updateConfiguration(configuration.cStandard, settings.defaultCStandard, env);
configuration.cppStandard = this.updateConfiguration(configuration.cppStandard, settings.defaultCppStandard, env);
configuration.intelliSenseMode = this.updateConfiguration(configuration.intelliSenseMode, settings.defaultIntelliSenseMode, env);
configuration.configurationProvider = this.updateConfiguration(configuration.configurationProvider, settings.defaultConfigurationProvider, env);
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);
if (!configuration.browse.path) {
if (settings.defaultBrowsePath) {
configuration.browse.path = settings.defaultBrowsePath;
} else if (configuration.includePath) {
// If the user doesn't set browse.path, copy the includePath over. Make sure ${workspaceFolder} is in there though...
configuration.browse.path = configuration.includePath.slice(0);
if (-1 === configuration.includePath.findIndex((value: string, index: number) => {
return !!value.match(/^\$\{(workspaceRoot|workspaceFolder)\}(\\|\\\*\*|\/|\/\*\*)?$/g);
})) {
configuration.browse.path.push("${workspaceFolder}");
}
}
} else {
configuration.browse.path = this.updateConfiguration(configuration.browse.path, settings.defaultBrowsePath, env);
}
configuration.browse.limitSymbolsToIncludedHeaders = this.updateConfiguration(configuration.browse.limitSymbolsToIncludedHeaders, settings.defaultLimitSymbolsToIncludedHeaders, env);
configuration.browse.databaseFilename = this.updateConfiguration(configuration.browse.databaseFilename, settings.defaultDatabaseFilename, env);
}
this.updateCompileCommandsFileWatchers();
@@ -446,15 +530,21 @@ export class CppProperties {
} else {
fs.mkdir(this.configFolder, (e: NodeJS.ErrnoException) => {
if (!e || e.code === 'EEXIST') {
let dirPathEscaped: string = this.configFolder.replace("#", "%23");
let fullPathToFile: string = path.join(dirPathEscaped, "c_cpp_properties.json");
let filePath: vscode.Uri = vscode.Uri.parse("untitled:" + fullPathToFile);
let fullPathToFile: string = path.join(this.configFolder, "c_cpp_properties.json");
let filePath: vscode.Uri = vscode.Uri.file(fullPathToFile).with({ scheme: "untitled" });
vscode.workspace.openTextDocument(filePath).then((document: vscode.TextDocument) => {
let edit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit();
if (this.configurationJson === undefined) {
if (this.configurationJson) {
this.resetToDefaultSettings(true);
}
this.applyDefaultIncludePathsAndFrameworks();
let settings: CppSettings = new CppSettings(this.rootUri);
if (settings.defaultConfigurationProvider) {
this.configurationJson.configurations.forEach(config => {
config.configurationProvider = settings.defaultConfigurationProvider;
});
settings.update("default.configurationProvider", undefined); // delete the setting
}
edit.insert(document.uri, new vscode.Position(0, 0), JSON.stringify(this.configurationJson, null, 4));
vscode.workspace.applyEdit(edit).then((status) => {
// Fix for issue 163
@@ -482,8 +572,8 @@ export class CppProperties {
// parsePropertiesFile can fail, but it won't overwrite an existing configurationJson in the event of failure.
// this.configurationJson should only be undefined here if we have never successfully parsed the propertiesFile.
if (this.configurationJson !== undefined) {
if (this.CurrentConfiguration < 0 ||
this.CurrentConfiguration >= this.configurationJson.configurations.length) {
if (this.CurrentConfigurationIndex < 0 ||
this.CurrentConfigurationIndex >= this.configurationJson.configurations.length) {
// If the index is out of bounds (during initialization or due to removal of configs), fix it.
this.currentConfigurationIndex.Value = this.getConfigIndexForPlatform(this.configurationJson);
}
@@ -511,48 +601,40 @@ 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 >= 0 && this.CurrentConfiguration < this.configurationJson.configurations.length) {
this.CurrentConfigurationIndex >= 0 && this.CurrentConfigurationIndex < 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) {
if (newJson.configurations[i].name === this.configurationJson.configurations[this.CurrentConfigurationIndex].name) {
this.currentConfigurationIndex.Value = i;
break;
}
}
}
this.configurationJson = newJson;
if (this.CurrentConfiguration < 0 || this.CurrentConfiguration >= newJson.configurations.length) {
if (this.CurrentConfigurationIndex < 0 || this.CurrentConfigurationIndex >= newJson.configurations.length) {
this.currentConfigurationIndex.Value = this.getConfigIndexForPlatform(newJson);
}
let dirty: boolean = false;
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let newId: string = getCustomConfigProviders().checkId(this.configurationJson.configurations[i].configurationProvider);
if (newId !== this.configurationJson.configurations[i].configurationProvider) {
dirty = true;
this.configurationJson.configurations[i].configurationProvider = newId;
}
}
// Remove disallowed variable overrides
if (this.configurationJson.env) {
delete this.configurationJson.env['workspaceRoot'];
delete this.configurationJson.env['workspaceFolder'];
delete this.configurationJson.env['workspaceFolderBasename'];
delete this.configurationJson.env['default'];
}
// Warning: There is a chance that this is incorrect in the event that the c_cpp_properties.json file was created before
// the system includes were available.
this.configurationIncomplete = false;
// Update intelliSenseMode, compilerPath, cStandard, and cppStandard with the defaults if they're missing.
// If VS Code settings exist for these properties, don't add them to c_cpp_properties.json
let dirty: boolean = false;
let settings: CppSettings = new CppSettings(this.rootUri);
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let config: Configuration = this.configurationJson.configurations[i];
if (config.intelliSenseMode === undefined && !settings.defaultIntelliSenseMode) {
dirty = true;
config.intelliSenseMode = this.getIntelliSenseModeForPlatform(config.name);
}
// Don't set the default if compileCommands exist, until it is fixed to have the correct value.
if (config.compilerPath === undefined && this.defaultCompilerPath && !config.compileCommands && !settings.defaultCompilerPath) {
config.compilerPath = this.defaultCompilerPath;
dirty = true;
}
if (!config.cStandard && this.defaultCStandard && !settings.defaultCStandard) {
config.cStandard = this.defaultCStandard;
dirty = true;
}
if (!config.cppStandard && this.defaultCppStandard && !settings.defaultCppStandard) {
config.cppStandard = this.defaultCppStandard;
dirty = true;
}
}
if (this.configurationJson.version !== configVersion) {
dirty = true;
if (this.configurationJson.version === undefined) {
@@ -561,6 +643,10 @@ export class CppProperties {
if (this.configurationJson.version === 2) {
this.updateToVersion3();
}
if (this.configurationJson.version === 3) {
this.updateToVersion4();
} else {
this.configurationJson.version = configVersion;
vscode.window.showErrorMessage('Unknown version number found in c_cpp_properties.json. Some features may not work as expected.');
@@ -570,7 +656,7 @@ export class CppProperties {
if (dirty) {
try {
fs.writeFileSync(this.propertiesFile.fsPath, JSON.stringify(this.configurationJson, null, 4));
} catch {
} catch (err) {
// 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?)');
}
@@ -583,17 +669,8 @@ export class CppProperties {
private updateToVersion2(): void {
this.configurationJson.version = 2;
if (!this.includePathConverted()) {
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let config: Configuration = this.configurationJson.configurations[i];
if (config.browse === undefined) {
config.browse = {};
}
if (config.browse.path === undefined && (this.defaultIncludes !== undefined || config.includePath !== undefined)) {
config.browse.path = (config.includePath === undefined) ? this.defaultIncludes.slice(0) : config.includePath.slice(0);
}
}
}
// no-op. We don't automatically populate the browse.path anymore.
// We use includePath if browse.path is not present which is what this code used to do.
}
private updateToVersion3(): void {
@@ -601,7 +678,7 @@ export class CppProperties {
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let config: Configuration = this.configurationJson.configurations[i];
// Look for Mac configs and extra configs on Mac systems
if (config.name === "Mac" || (process.platform === "darwin" && config.name !== "Win32" && config.name !== "Linux")) {
if (config.name === "Mac" || (process.platform === 'darwin' && config.name !== "Win32" && config.name !== "Linux")) {
if (config.macFrameworkPath === undefined) {
config.macFrameworkPath = [
"/System/Library/Frameworks",
@@ -612,6 +689,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");
@@ -0,0 +1,215 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
import * as vscode from 'vscode';
import { CustomConfigurationProvider, Version, SourceFileConfigurationItem, WorkspaceBrowseConfiguration } from 'vscode-cpptools';
import { CppSettings } from './settings';
/**
* An interface that is guaranteed to be backward compatible with version 0
*/
export interface CustomConfigurationProvider1 extends CustomConfigurationProvider {
isReady: boolean;
readonly isValid: boolean;
readonly version: Version;
}
/**
* Wraps the incoming CustomConfigurationProvider so that we can treat all of them as if they were the same version (e.g. latest)
*/
class CustomProviderWrapper implements CustomConfigurationProvider1 {
private provider: CustomConfigurationProvider;
private _isReady: boolean;
private _version: Version;
constructor(provider: CustomConfigurationProvider, version: Version) {
this._isReady = version < Version.v2;
this.provider = provider;
if (provider.extensionId && version === Version.v0) {
version = Version.v1; // provider implemented the new API but is interfacing with the extension using the old API version.
}
this._version = version;
}
public get isReady(): boolean {
return this._isReady;
}
public set isReady(ready: boolean) {
this._isReady = ready;
}
public get isValid(): boolean {
let valid: boolean = !!(this.provider.name && this.provider.canProvideConfiguration && this.provider.provideConfigurations);
if (valid && this._version > Version.v0) {
valid = !!(this.provider.extensionId && this.provider.dispose);
}
if (valid && this._version > Version.v1) {
valid = !!(this.provider.canProvideBrowseConfiguration && this.provider.provideBrowseConfiguration);
}
return valid;
}
public get version(): Version {
return this._version;
}
public get name(): string {
return this.provider.name;
}
public get extensionId(): string {
return this._version === Version.v0 ? this.provider.name : this.provider.extensionId;
}
public canProvideConfiguration(uri: vscode.Uri, token?: vscode.CancellationToken): Thenable<boolean> {
return this.provider.canProvideConfiguration(uri, token);
}
public provideConfigurations(uris: vscode.Uri[], token?: vscode.CancellationToken): Thenable<SourceFileConfigurationItem[]> {
return this.provider.provideConfigurations(uris, token);
}
public canProvideBrowseConfiguration(token?: vscode.CancellationToken): Thenable<boolean> {
return this._version < Version.v2 ? Promise.resolve(false) : this.provider.canProvideBrowseConfiguration(token);
}
public provideBrowseConfiguration(token?: vscode.CancellationToken): Thenable<WorkspaceBrowseConfiguration> {
console.assert(this._version >= Version.v2);
return this._version < Version.v2 ? Promise.resolve({browsePath: []}) : this.provider.provideBrowseConfiguration(token);
}
public dispose(): void {
if (this._version !== Version.v0) {
this.provider.dispose();
}
}
}
export class CustomConfigurationProviderCollection {
private providers: Map<string, CustomProviderWrapper> = new Map<string, CustomProviderWrapper>();
private logProblems(provider: CustomConfigurationProvider, version: Version): void {
let missing: string[] = [];
if (!provider.name) {
missing.push("'name'");
}
if (version !== Version.v0 && !provider.extensionId) {
missing.push("'extensionId'");
}
if (!provider.canProvideConfiguration) {
missing.push("'canProvideConfiguration'");
}
if (!provider.provideConfigurations) {
missing.push("'canProvideConfiguration'");
}
if (version !== Version.v0 && !provider.dispose) {
missing.push("'dispose'");
}
if (version >= Version.v2 && !provider.canProvideBrowseConfiguration) {
missing.push("'canProvideBrowseConfiguration'");
}
if (version >= Version.v2 && !provider.provideBrowseConfiguration) {
missing.push("'provideBrowseConfiguration'");
}
console.error(`CustomConfigurationProvider was not registered. The following properties are missing from the implementation: ${missing.join(", ")}.`);
}
private getId(provider: string|CustomConfigurationProvider): string {
if (typeof provider === "string") {
return provider;
} else if (provider.extensionId) {
return provider.extensionId;
} else if (provider.name) {
return provider.name;
} else {
console.error(`invalid provider: ${provider}`);
return "";
}
}
public get size(): number {
return this.providers.size;
}
public add(provider: CustomConfigurationProvider, version: Version): boolean {
if (new CppSettings().intelliSenseEngine === "Disabled") {
console.warn("IntelliSense is disabled. Provider will not be registered.");
return false;
}
let wrapper: CustomProviderWrapper = new CustomProviderWrapper(provider, version);
if (!wrapper.isValid) {
this.logProblems(provider, version);
return false;
}
let exists: boolean = this.providers.has(wrapper.extensionId);
if (exists) {
let existing: CustomProviderWrapper = this.providers.get(wrapper.extensionId);
exists = (existing.version === Version.v0 && wrapper.version === Version.v0);
}
if (!exists) {
this.providers.set(wrapper.extensionId, wrapper);
} else {
console.error(`CustomConfigurationProvider '${wrapper.extensionId}' has already been registered.`);
}
return !exists;
}
public get(provider: string|CustomConfigurationProvider): CustomConfigurationProvider1|null {
let id: string = this.getId(provider);
if (this.providers.has(id)) {
return this.providers.get(id);
}
return null;
}
public forEach(func: (provider: CustomConfigurationProvider1) => void): void {
this.providers.forEach(provider => func(provider));
}
public remove(provider: CustomConfigurationProvider): void {
let id: string = this.getId(provider);
if (this.providers.has(id)) {
this.providers.delete(id);
} else {
console.warn(`${id} is not registered`);
}
}
public checkId(providerId?: string): string {
if (!providerId) {
return providerId;
}
let found: CustomConfigurationProvider1[] = [];
let noUpdate: boolean = false;
this.forEach(provider => {
if (provider.extensionId === providerId) {
noUpdate = true;
} else if (provider.name === providerId && provider.version !== Version.v0) {
found.push(provider);
}
});
if (noUpdate) {
return providerId;
}
if (found.length === 1) {
return found[0].extensionId;
} else if (found.length > 1) {
console.warn("duplicate provider name found. Not upgrading.");
}
return providerId;
}
}
let providerCollection: CustomConfigurationProviderCollection = new CustomConfigurationProviderCollection();
export function getCustomConfigProviders(): CustomConfigurationProviderCollection {
return providerCollection;
}
+294 -65
View File
@@ -6,6 +6,7 @@
import * as path from 'path';
import * as vscode from 'vscode';
import * as os from 'os';
import * as fs from 'fs';
import * as util from '../common';
import * as telemetry from '../telemetry';
@@ -15,7 +16,13 @@ import { ClientCollection } from './clientCollection';
import { CppSettings } from './settings';
import { PersistentWorkspaceState } from './persistentState';
import { getLanguageConfig } from './languageConfig';
import * as os from 'os';
import { getCustomConfigProviders } from './customProviders';
import { PlatformInformation } from '../platform';
import { Range } from 'vscode-languageclient';
import { ChildProcess, spawn, execSync } from 'child_process';
import * as tmp from 'tmp';
import { getTargetBuildInfo } from '../githubAPI';
import { PackageVersion } from '../packageVersion';
let prevCrashFile: string;
let clients: ClientCollection;
@@ -24,9 +31,11 @@ let ui: UI;
let disposables: vscode.Disposable[] = [];
let languageConfigurations: vscode.Disposable[] = [];
let intervalTimer: NodeJS.Timer;
let insiderUpdateTimer: NodeJS.Timer;
let realActivationOccurred: boolean = false;
let tempCommands: vscode.Disposable[] = [];
let activatedPreviously: PersistentWorkspaceState<boolean>;
const insiderUpdateTimerInterval: number = 1000 * 60 * 60;
/**
* activate: set up the extension for language services
@@ -41,7 +50,7 @@ export function activate(activationEventOccurred: boolean): void {
activatedPreviously.Value = false;
realActivation();
}
registerCommands();
tempCommands.push(vscode.workspace.onDidOpenTextDocument(d => onDidOpenTextDocument(d)));
@@ -97,6 +106,10 @@ function onActivationEvent(): void {
}
function realActivation(): void {
if (new CppSettings().intelliSenseEngine === "Disabled") {
throw new Error("Do not activate the extension when IntelliSense is disabled.");
}
realActivationOccurred = true;
console.log("starting language server");
clients = new ClientCollection();
@@ -108,6 +121,12 @@ function realActivation(): void {
onDidChangeActiveTextEditor(vscode.window.activeTextEditor);
}
// There may have already been registered CustomConfigurationProviders.
// Request for configurations from those providers.
clients.forEach(client => {
getCustomConfigProviders().forEach(provider => client.onRegisterCustomConfigurationProvider(provider));
});
disposables.push(vscode.workspace.onDidChangeConfiguration(onDidChangeSettings));
disposables.push(vscode.workspace.onDidSaveTextDocument(onDidSaveTextDocument));
disposables.push(vscode.window.onDidChangeActiveTextEditor(onDidChangeActiveTextEditor));
@@ -118,6 +137,12 @@ function realActivation(): void {
reportMacCrashes();
const settings: CppSettings = new CppSettings(clients.ActiveClient.RootUri);
if (settings.updateChannel === 'Insiders') {
insiderUpdateTimer = setInterval(checkAndApplyUpdate, insiderUpdateTimerInterval, settings.updateChannel);
checkAndApplyUpdate(settings.updateChannel);
}
intervalTimer = setInterval(onInterval, 2500);
}
@@ -134,7 +159,19 @@ export function updateLanguageConfigurations(): void {
*********************************************/
function onDidChangeSettings(): void {
const changedActiveClientSettings: { [key: string] : string } = clients.ActiveClient.onDidChangeSettings();
clients.forEach(client => client.onDidChangeSettings());
const newUpdateChannel: string = changedActiveClientSettings['updateChannel'];
if (newUpdateChannel) {
if (newUpdateChannel === 'Default') {
clearInterval(insiderUpdateTimer);
} else if (newUpdateChannel === 'Insiders') {
insiderUpdateTimer = setInterval(checkAndApplyUpdate, insiderUpdateTimerInterval);
}
checkAndApplyUpdate(newUpdateChannel);
}
}
let saveMessageShown: boolean = false;
@@ -162,7 +199,7 @@ function onDidChangeActiveTextEditor(editor: vscode.TextEditor): void {
} else {
activeDocument = editor.document.uri.toString();
clients.activeDocumentChanged(editor.document);
clients.ActiveClient.selectionChanged(editor.selection.start);
clients.ActiveClient.selectionChanged(Range.create(editor.selection.start, editor.selection.end));
}
ui.activeDocumentChanged();
}
@@ -172,7 +209,7 @@ function onDidChangeTextEditorSelection(event: vscode.TextEditorSelectionChangeE
if (!event.textEditor || !vscode.window.activeTextEditor || event.textEditor.document.uri !== vscode.window.activeTextEditor.document.uri ||
(event.textEditor.document.languageId !== "cpp" && event.textEditor.document.languageId !== "c")) {
return;
}
}
if (activeDocument !== event.textEditor.document.uri.toString()) {
// For some strange (buggy?) reason we don't reliably get onDidChangeActiveTextEditor callbacks.
@@ -180,7 +217,7 @@ function onDidChangeTextEditorSelection(event: vscode.TextEditorSelectionChangeE
clients.activeDocumentChanged(event.textEditor.document);
ui.activeDocumentChanged();
}
clients.ActiveClient.selectionChanged(event.selections[0].start);
clients.ActiveClient.selectionChanged(Range.create(event.selections[0].start, event.selections[0].end));
}
function onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void {
@@ -192,6 +229,176 @@ function onInterval(): void {
clients.ActiveClient.onInterval();
}
/**
* Install a VSIX package. This helper function will exist until VSCode offers a command to do so.
* @param updateChannel The user's updateChannel setting.
*/
async function installVsix(vsixLocation: string, updateChannel: string): Promise<void> {
// Get the path to the VSCode command -- replace logic later when VSCode allows calling of
// workbench.extensions.action.installVSIX from TypeScript w/o instead popping up a file dialog
return PlatformInformation.GetPlatformInformation().then((platformInfo) => {
const vsCodeScriptPath: string = function(platformInfo): string {
if (platformInfo.platform === 'win32') {
const vsCodeBinName: string = path.basename(process.execPath);
let cmdFile: string; // Windows VS Code Insiders/Exploration breaks VS Code naming conventions
if (vsCodeBinName === 'Code - Insiders.exe') {
cmdFile = 'code-insiders.cmd';
} else if (vsCodeBinName === 'Code - Exploration.exe') {
cmdFile = 'code-exploration.cmd';
} else {
cmdFile = 'code.cmd';
}
const vsCodeExeDir: string = path.dirname(process.execPath);
return path.join(vsCodeExeDir, 'bin', cmdFile);
} else if (platformInfo.platform === 'darwin') {
return path.join(process.execPath, '..', '..', '..', '..', '..',
'Resources', 'app', 'bin', 'code');
} else {
const vsCodeBinName: string = path.basename(process.execPath);
try {
const stdout: Buffer = execSync('which ' + vsCodeBinName);
return stdout.toString().trim();
} catch (error) {
return undefined;
}
}
}(platformInfo);
if (!vsCodeScriptPath) {
return Promise.reject(new Error('Failed to find VS Code script'));
}
// 1.28.0 changes the CLI for making installations
let userVersion: PackageVersion = new PackageVersion(vscode.version);
let breakingVersion: PackageVersion = new PackageVersion('1.28.0');
if (userVersion.isGreaterThan(breakingVersion, 'insider')) {
return new Promise<void>((resolve, reject) => {
let process: ChildProcess;
try {
process = spawn(vsCodeScriptPath, ['--install-extension', vsixLocation, '--force']);
if (process.pid === undefined) {
throw new Error();
}
} catch (error) {
reject(new Error('Failed to launch VS Code script process for installation'));
return;
}
resolve();
});
}
return new Promise<void>((resolve, reject) => {
let process: ChildProcess;
try {
process = spawn(vsCodeScriptPath, ['--install-extension', vsixLocation]);
if (process.pid === undefined) {
throw new Error();
}
} catch (error) {
reject(new Error('Failed to launch VS Code script process for installation'));
return;
}
// Timeout the process if no response is sent back. Ensures this Promise resolves/rejects
const timer: NodeJS.Timer = setTimeout(() => {
process.kill();
reject(new Error('Failed to receive response from VS Code script process for installation within 30s.'));
}, 30000);
// If downgrading, the VS Code CLI will prompt whether the user is sure they would like to downgrade.
// Respond to this by writing 0 to stdin (the option to override and install the VSIX package)
let sentOverride: boolean = false;
process.stdout.on('data', () => {
if (sentOverride) {
return;
}
process.stdin.write('0\n');
sentOverride = true;
clearInterval(timer);
resolve();
});
});
});
}
/**
* Query package.json and the GitHub API to determine whether the user should update, if so then install the update.
* The update can be an upgrade or downgrade depending on the the updateChannel setting.
* @param updateChannel The user's updateChannel setting.
*/
async function checkAndApplyUpdate(updateChannel: string): Promise<void> {
// Wrap in new Promise to allow tmp.file callback to successfully resolve/reject
// as tmp.file does not do anything with the callback functions return value
const p: Promise<void> = new Promise<void>((resolve, reject) => {
getTargetBuildInfo(updateChannel).then(buildInfo => {
if (!buildInfo) {
resolve();
return;
}
// Create a temporary file, download the VSIX to it, then install the VSIX
tmp.file({postfix: '.vsix'}, async (err, vsixPath, fd, cleanupCallback) => {
if (err) {
reject(new Error('Failed to create vsix file'));
return;
}
// Place in try/catch as the .catch call catches a rejection in downloadFileToDestination
// then the .catch call will return a resolved promise
// Thusly, the .catch call must also throw, as a return would simply return an unused promise
// instead of returning early from this function scope
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
let originalProxySupport: string = config.inspect<string>('http.proxySupport').globalValue;
while (true) { // Might need to try again with a different http.proxySupport setting.
try {
await util.downloadFileToDestination(buildInfo.downloadUrl, vsixPath);
} catch {
// Try again with the proxySupport to "off".
if (originalProxySupport !== config.inspect<string>('http.proxySupport').globalValue) {
config.update('http.proxySupport', originalProxySupport, true); // Reset the http.proxySupport.
reject(new Error('Failed to download VSIX package with proxySupport off')); // Changing the proxySupport didn't help.
return;
}
if (config.get('http.proxySupport') !== "off" && originalProxySupport !== "off") {
config.update('http.proxySupport', "off", true);
continue;
}
reject(new Error('Failed to download VSIX package'));
return;
}
if (originalProxySupport !== config.inspect<string>('http.proxySupport').globalValue) {
config.update('http.proxySupport', originalProxySupport, true); // Reset the http.proxySupport.
telemetry.logLanguageServerEvent('installVsix', { 'error': "Success with proxySupport off", 'success': 'true' });
}
break;
}
try {
await installVsix(vsixPath, updateChannel);
} catch (error) {
reject(error);
return;
}
clearInterval(insiderUpdateTimer);
const message: string =
`The C/C++ Extension has been updated to version ${buildInfo.name}. Please reload the window for the changes to take effect.`;
util.promptReloadWindow(message);
telemetry.logLanguageServerEvent('installVsix', { 'success': 'true' });
resolve();
});
}, (error: Error) => {
// Handle getTargetBuildInfo rejection
reject(error);
});
});
await p.catch((error: Error) => {
// Handle .then following getTargetBuildInfo rejection
if (error.message.indexOf('/') !== -1 || error.message.indexOf('\\') !== -1) {
error.message = "Potential PII hidden";
}
telemetry.logLanguageServerEvent('installVsix', { 'error': error.message, 'success': 'false' });
});
}
/*********************************************
* registered commands
*********************************************/
@@ -203,10 +410,10 @@ function registerCommands(): void {
disposables.push(vscode.commands.registerCommand('C_Cpp.SwitchHeaderSource', onSwitchHeaderSource));
disposables.push(vscode.commands.registerCommand('C_Cpp.ResetDatabase', onResetDatabase));
disposables.push(vscode.commands.registerCommand('C_Cpp.ConfigurationSelect', onSelectConfiguration));
disposables.push(vscode.commands.registerCommand('C_Cpp.ConfigurationProviderSelect', onSelectConfigurationProvider));
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));
@@ -318,6 +525,15 @@ function onSelectConfiguration(): void {
}
}
function onSelectConfigurationProvider(): void {
onActivationEvent();
if (!isFolderOpen()) {
vscode.window.showInformationMessage('Open a folder first to select a configuration provider');
} else {
selectClient().then(client => client.handleConfigurationProviderSelectCommand(), rejected => {});
}
}
function onEditConfiguration(): void {
onActivationEvent();
if (!isFolderOpen()) {
@@ -344,47 +560,6 @@ 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.
@@ -471,33 +646,73 @@ function reportMacCrashes(): void {
}
}
function handleCrashFileRead(err: NodeJS.ErrnoException, data: string): void {
function logCrashTelemetry(data: string): void {
let crashObject: { [key: string]: string } = {};
if (err) {
crashObject["readFile: err.code"] = err.code;
telemetry.logLanguageServerEvent("MacCrash", crashObject, null);
return;
}
let startCrash: number = data.indexOf(" Crashed:");
if (startCrash < 0) {
startCrash = 0;
}
let endCrash: number = data.indexOf("Thread ", startCrash);
if (endCrash < startCrash) {
endCrash = data.length - 1;
}
data = data.substr(startCrash, endCrash - startCrash);
if (data.length > 16384) {
data = data.substr(0, 16384) + "...";
}
crashObject["CrashingThreadCallStack"] = data;
telemetry.logLanguageServerEvent("MacCrash", crashObject, null);
}
function handleCrashFileRead(err: NodeJS.ErrnoException, data: string): void {
if (err) {
return logCrashTelemetry("readFile: " + err.code);
}
// Extract the crashing thread's call stack.
const crashStart: string = " Crashed:";
let startCrash: number = data.indexOf(crashStart);
if (startCrash < 0) {
return logCrashTelemetry("No crash start");
}
startCrash += crashStart.length + 1; // Skip past crashStart.
let endCrash: number = data.indexOf("Thread ", startCrash);
if (endCrash < 0) {
endCrash = data.length - 1; // Not expected, but just in case.
}
if (endCrash <= startCrash) {
return logCrashTelemetry("No crash end");
}
data = data.substr(startCrash, endCrash - startCrash);
// Get rid of the memory addresses (which breaks being able get a hit count for each crash call stack).
data = data.replace(/0x................ /g, "");
// Get rid of the process names on each line and just add it to the start.
const process1: string = "Microsoft.VSCode.CPP.IntelliSense.Msvc.darwin\t";
const process2: string = "Microsoft.VSCode.CPP.Extension.darwin\t";
if (data.includes(process1)) {
data = data.replace(new RegExp(process1, "g"), "");
data = process1 + "\n" + data;
} else if (data.includes(process2)) {
data = data.replace(new RegExp(process2, "g"), "");
data = process2 + "\n" + data;
} else {
return logCrashTelemetry("No process"); // Not expected, but just in case.
}
// Remove runtime lines because they can be different on different machines.
let lines: string[] = data.split("\n");
data = "";
lines.forEach((line: string) => {
if (!line.includes(".dylib") && !line.includes("???")) {
line = line.replace(/^\d+\s+/, ""); // Remove <numbers><spaces> from the start of the line.
line = line.replace(/std::__1::/g, "std::"); // __1:: is not helpful.
data += (line + "\n");
}
});
data = data.trimRight();
if (data.length > 8192) { // The API has an 8k limit.
data = data.substr(0, 8189) + "...";
}
logCrashTelemetry(data);
}
export function deactivate(): Thenable<void> {
console.log("deactivating extension");
telemetry.logLanguageServerEvent("LanguageServerShutdown");
clearInterval(intervalTimer);
clearInterval(insiderUpdateTimer);
disposables.forEach(d => d.dispose());
languageConfigurations.forEach(d => d.dispose());
ui.dispose();
@@ -507,3 +722,17 @@ export function deactivate(): Thenable<void> {
export function isFolderOpen(): boolean {
return vscode.workspace.workspaceFolders !== undefined && vscode.workspace.workspaceFolders.length > 0;
}
export function getClients(): ClientCollection {
if (!realActivationOccurred) {
realActivation();
}
return clients;
}
export function getActiveClient(): Client {
if (!realActivationOccurred) {
realActivation();
}
return clients.ActiveClient;
}
@@ -20,12 +20,16 @@ class PersistentStateBase<T> {
}
public get Value(): T {
return this.state.get<T>(this.key, this.defaultvalue);
return this.state.get<T>(this.key, this.defaultvalue);
}
public set Value(newValue: T) {
this.state.update(this.key, newValue);
}
public get DefaultValue(): T {
return this.defaultvalue;
}
}
// Abstraction for global state that persists across activations but is not present in a settings file
+14 -10
View File
@@ -11,26 +11,30 @@ import { Client } from './client';
export function createProtocolFilter(me: Client, clients: ClientCollection): Middleware {
// Disabling lint for invoke handlers
/* tslint:disable */
let defaultHandler: (data: any, callback: (data: any) => void) => void = (data, callback: (data) => void) => { if (clients.ActiveClient === me) { callback(data); } };
let invoke1 = (a, callback: (a) => any) => { if (clients.ActiveClient === me) { return callback(a); } return null; };
let invoke2 = (a, b, callback: (a, b) => any) => { if (clients.ActiveClient === me) { return callback(a, b); } return null; };
let invoke3 = (a, b, c, callback: (a, b, c) => any) => { if (clients.ActiveClient === me) { return callback(a, b, c); } return null; };
let invoke4 = (a, b, c, d, callback: (a, b, c, d) => any) => { if (clients.ActiveClient === me) { return callback(a, b, c, d); } return null; };
let invoke5 = (a, b, c, d, e, callback: (a, b, c, d, e) => any) => { if (clients.ActiveClient === me) { return callback(a, b, c, d, e); } return null; };
let defaultHandler: (data: any, callback: (data: any) => void) => void = (data, callback: (data) => void) => { if (clients.ActiveClient === me) {me.notifyWhenReady(() => callback(data));}};
let invoke1 = (a, callback: (a) => any) => { if (clients.ActiveClient === me) { return me.requestWhenReady(() => callback(a)); } return null; };
let invoke2 = (a, b, callback: (a, b) => any) => { if (clients.ActiveClient === me) { return me.requestWhenReady(() => callback(a, b)); } return null; };
let invoke3 = (a, b, c, callback: (a, b, c) => any) => { if (clients.ActiveClient === me) { return me.requestWhenReady(() => callback(a, b, c)); } return null; };
let invoke4 = (a, b, c, d, callback: (a, b, c, d) => any) => { if (clients.ActiveClient === me) { return me.requestWhenReady(() => callback(a, b, c, d)); } return null; };
let invoke5 = (a, b, c, d, e, callback: (a, b, c, d, e) => any) => { if (clients.ActiveClient === me) { return me.requestWhenReady(() => callback(a, b, c, d, e)); } return null; };
/* tslint:enable */
return {
didOpen: (document, sendMessage) => {
if (clients.checkOwnership(me, document)) {
me.TrackedDocuments.add(document);
sendMessage(document);
me.provideCustomConfiguration(document).then(() => {
sendMessage(document);
}, () => {
sendMessage(document);
});
}
},
didChange: defaultHandler,
willSave: defaultHandler,
willSaveWaitUntil: (event, sendMessage) => {
if (clients.ActiveClient === me) {
return sendMessage(event);
return me.requestWhenReady(() => sendMessage(event));
}
return Promise.resolve([]);
},
@@ -39,11 +43,11 @@ export function createProtocolFilter(me: Client, clients: ClientCollection): Mid
if (clients.ActiveClient === me) {
console.assert(me.TrackedDocuments.has(document));
me.TrackedDocuments.delete(document);
sendMessage(document);
me.notifyWhenReady(() => sendMessage(document));
}
},
provideCompletionItem: invoke3,
provideCompletionItem: invoke4,
resolveCompletionItem: invoke2,
provideHover: invoke3,
provideSignatureHelp: invoke3,
+8
View File
@@ -40,23 +40,31 @@ export class CppSettings extends Settings {
public get intelliSenseEngineFallback(): string { return super.Section.get<string>("intelliSenseEngineFallback"); }
public get errorSquiggles(): string { return super.Section.get<string>("errorSquiggles"); }
public get dimInactiveRegions(): boolean { return super.Section.get<boolean>("dimInactiveRegions"); }
public get inactiveRegionOpacity(): number { return super.Section.get<number>("inactiveRegionOpacity"); }
public get inactiveRegionForegroundColor(): string { return super.Section.get<string>("inactiveRegionForegroundColor"); }
public get inactiveRegionBackgroundColor(): string { return super.Section.get<string>("inactiveRegionBackgroundColor"); }
public get autoComplete(): string { return super.Section.get<string>("autocomplete"); }
public get loggingLevel(): string { return super.Section.get<string>("loggingLevel"); }
public get navigationLength(): number { return super.Section.get<number>("navigation.length", 60); }
public get autoAddFileAssociations(): boolean { return super.Section.get<boolean>("autoAddFileAssociations"); }
public get workspaceParsingPriority(): boolean { return super.Section.get<boolean>("workspaceParsingPriority"); }
public get workspaceSymbols(): string { return super.Section.get<string>("workspaceSymbols"); }
public get exclusionPolicy(): boolean { return super.Section.get<boolean>("exclusionPolicy"); }
public get commentContinuationPatterns(): (string | CommentPattern)[] { return super.Section.get<(string | CommentPattern)[]>("commentContinuationPatterns"); }
public get configurationWarnings(): string { return super.Section.get<string>("configurationWarnings"); }
public get preferredPathSeparator(): string { return super.Section.get<string>("preferredPathSeparator"); }
public get updateChannel(): string { return super.Section.get<string>("updateChannel"); }
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 defaultWindowsSdkVersion(): string { return super.Section.get<string>("default.windowsSdkVersion"); }
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 defaultConfigurationProvider(): string { return super.Section.get<string>("default.configurationProvider"); }
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"); }
@@ -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;
}
+91 -17
View File
@@ -6,6 +6,7 @@
import * as vscode from 'vscode';
import { Client } from './client';
import { getCustomConfigProviders, CustomConfigurationProviderCollection } from './customProviders';
let ui: UI;
@@ -16,11 +17,24 @@ interface KeyedQuickPickItem extends vscode.QuickPickItem {
key: string;
}
// Higher numbers mean greater priority.
enum ConfigurationPriority {
IncludePath = 1,
CompileCommands = 2,
CustomProvider = 3,
}
interface ConfigurationResult {
configured: boolean;
priority: ConfigurationPriority;
}
export class UI {
private navigationStatusBarItem: vscode.StatusBarItem;
private configStatusBarItem: vscode.StatusBarItem;
private browseEngineStatusBarItem: vscode.StatusBarItem;
private intelliSenseStatusBarItem: vscode.StatusBarItem;
private configurationUIPromise: Thenable<ConfigurationResult>;
constructor() {
// 1000 = priority, it needs to be high enough to be on the left of the Ln/Col.
@@ -160,12 +174,39 @@ export class UI {
items.push({ label: "Edit Configurations...", description: "", index: configurationNames.length });
return vscode.window.showQuickPick(items, options)
.then(selection => {
if (!selection) {
return -1;
}
return selection.index;
});
.then(selection => (selection) ? selection.index : -1);
}
public showConfigurationProviders(currentProvider: string|null): Thenable<string|undefined> {
let options: vscode.QuickPickOptions = {};
options.placeHolder = "Select a Configuration Provider...";
let providers: CustomConfigurationProviderCollection = getCustomConfigProviders();
let items: KeyedQuickPickItem[] = [];
providers.forEach(provider => {
let label: string = provider.name;
if (provider.extensionId === currentProvider) {
label += " (active)";
}
items.push({ label: label, description: "", key: provider.extensionId });
});
items.push({ label: "(none)", description: "Disable the active configuration provider, if applicable.", key: "" });
return vscode.window.showQuickPick(items, options)
.then(selection => (selection) ? selection.key : undefined);
}
public showCompileCommands(paths: string[]): Thenable<number> {
let options: vscode.QuickPickOptions = {};
options.placeHolder = "Select a compile_commands.json...";
let items: IndexableQuickPickItem[] = [];
for (let i: number = 0; i < paths.length; i++) {
items.push({label: paths[i], description: "", index: i});
}
return vscode.window.showQuickPick(items, options)
.then(selection => (selection) ? selection.index : -1);
}
public showWorkspaces(workspaceNames: { name: string; key: string }[]): Thenable<string> {
@@ -176,12 +217,7 @@ export class UI {
workspaceNames.forEach(name => items.push({ label: name.name, description: "", key: name.key }));
return vscode.window.showQuickPick(items, options)
.then(selection => {
if (!selection) {
return "";
}
return selection.key;
});
.then(selection => (selection) ? selection.key : "");
}
public showParsingCommands(): Thenable<number> {
@@ -197,12 +233,50 @@ export class UI {
}
return vscode.window.showQuickPick(items, options)
.then(selection => {
if (!selection) {
return -1;
}
return selection.index;
.then(selection => (selection) ? selection.index : -1);
}
public showConfigureIncludePathMessage(prompt: () => Thenable<boolean>, onSkip: () => void): void {
setTimeout(() => {
this.showConfigurationPrompt(ConfigurationPriority.IncludePath, prompt, onSkip);
}, 10000);
}
public showConfigureCompileCommandsMessage(prompt: () => Thenable<boolean>, onSkip: () => void): void {
setTimeout(() => {
this.showConfigurationPrompt(ConfigurationPriority.CompileCommands, prompt, onSkip);
}, 5000);
}
public showConfigureCustomProviderMessage(prompt: () => Thenable<boolean>, onSkip: () => void): void {
this.showConfigurationPrompt(ConfigurationPriority.CustomProvider, prompt, onSkip);
}
private showConfigurationPrompt(priority: ConfigurationPriority, prompt: () => Thenable<boolean>, onSkip: () => void): void {
let showPrompt: () => Thenable<ConfigurationResult> = async () => {
let configured: boolean = await prompt();
return Promise.resolve({
priority: priority,
configured: configured
});
};
if (this.configurationUIPromise) {
this.configurationUIPromise = this.configurationUIPromise.then(result => {
if (priority > result.priority) {
return showPrompt();
} else if (!result.configured) {
return showPrompt();
}
onSkip();
return Promise.resolve({
priority: result.priority,
configured: true
});
});
} else {
this.configurationUIPromise = showPrompt();
}
}
public dispose(): void {
@@ -118,6 +118,7 @@ function copyBinaryDependencies(): void {
copy(miEngineRoot, DebugAdapterBinPath, "Microsoft.MIDebugEngine.dll");
copy(miEngineRoot, DebugAdapterBinPath, "Microsoft.MIDebugEngine.dll.mdb");
copy(miEngineRoot, DebugAdapterBinPath, "osxlaunchhelper.scpt");
copy(miEngineRoot, DebugAdapterBinPath, "Microsoft.VisualStudio.Debugger.Interop.15.0.dll");
copy(openDebugRoot, DebugAdapterBinPath, "Microsoft.VisualStudio.Debugger.Interop.10.0.dll");
copy(openDebugRoot, DebugAdapterBinPath, "Microsoft.VisualStudio.Debugger.Interop.11.0.dll");
@@ -129,6 +130,8 @@ function copyBinaryDependencies(): void {
copy(openDebugRoot, DebugAdapterBinPath, "OpenDebugAD7.exe.config");
copy(openDebugRoot, DebugAdapterBinPath, "OpenDebugAD7.exe.mdb");
copy(openDebugRoot, DebugAdapterBinPath, "Newtonsoft.Json.dll");
copy(openDebugRoot, DebugAdapterBinPath, "WindowsDebugLauncher.exe");
copy(openDebugRoot, DebugAdapterBinPath, "Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.dll");
}
function copyMonoDependencies(): void {
+92 -78
View File
@@ -4,93 +4,107 @@
* ------------------------------------------------------------------------------------------ */
'use strict';
import * as url from 'url';
import * as https from 'https';
import { ClientRequest } from 'http';
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as util from './common';
import * as Telemetry from './telemetry';
import { PersistentState } from './LanguageServer/persistentState';
import * as fs from 'fs';
const userBucketMax: number = 100;
const userBucketString: string = "CPP.UserBucket";
const localConfigFile: string = "cpptools.json";
export function activate(context: vscode.ExtensionContext): void {
if (context.globalState.get<number>(userBucketString, -1) === -1) {
let bucket: number = Math.floor(Math.random() * userBucketMax) + 1; // Range is [1, userBucketMax].
context.globalState.update(userBucketString, bucket);
}
interface Settings {
defaultIntelliSenseEngine?: number;
recursiveIncludes?: number;
gotoDefIntelliSense?: number;
}
export class ABTestSettings {
private settings: Settings;
private intelliSenseEngineDefault: PersistentState<number>;
private recursiveIncludesDefault: PersistentState<number>;
private gotoDefIntelliSenseDefault: PersistentState<number>;
private bucket: PersistentState<number>;
constructor() {
this.intelliSenseEngineDefault = new PersistentState<number>("ABTest.1", 100);
this.recursiveIncludesDefault = new PersistentState<number>("ABTest.2", 100);
this.gotoDefIntelliSenseDefault = new PersistentState<number>("ABTest.3", 100);
this.settings = {
defaultIntelliSenseEngine: this.intelliSenseEngineDefault.Value,
recursiveIncludes: this.recursiveIncludesDefault.Value,
gotoDefIntelliSense: this.gotoDefIntelliSenseDefault.Value
};
this.bucket = new PersistentState<number>(userBucketString, -1);
if (this.bucket.Value === -1) {
this.bucket.Value = Math.floor(Math.random() * userBucketMax) + 1; // Range is [1, userBucketMax].
}
this.updateSettings();
// Redownload cpptools.json after initialization so it's not blocked.
// It'll be used the next time the extension reloads.
this.downloadCpptoolsJsonPkgAsync();
setInterval(() => {
// Redownload occasionally to prevent an extra reload during long sessions.
downloadCpptoolsJsonPkg();
}, 30 * 60 * 1000); // 30 minutes.
}
setInterval(() => { this.downloadCpptoolsJsonPkgAsync(); }, 30 * 60 * 1000); // 30 minutes.
}
// NOTE: Code is copied from DownloadPackage in packageManager.ts, but with ~75% fewer lines.
function downloadCpptoolsJson(urlString): Promise<void> {
return new Promise<void>((resolve, reject) => {
let parsedUrl: url.Url = url.parse(urlString);
let request: ClientRequest = https.request({
host: parsedUrl.host,
path: parsedUrl.path,
agent: util.GetHttpsProxyAgent(),
rejectUnauthorized: vscode.workspace.getConfiguration().get("http.proxyStrictSSL", true)
}, (response) => {
if (response.statusCode === 301 || response.statusCode === 302) {
let redirectUrl: string | string[];
if (typeof response.headers.location === "string") {
redirectUrl = response.headers.location;
} else {
redirectUrl = response.headers.location[0];
}
return resolve(downloadCpptoolsJson(redirectUrl)); // Redirect - download from new location
public get UseDefaultIntelliSenseEngine(): boolean {
return util.isNumber(this.settings.defaultIntelliSenseEngine) ? this.settings.defaultIntelliSenseEngine >= this.bucket.Value : true;
}
public get UseRecursiveIncludes(): boolean {
return util.isNumber(this.settings.recursiveIncludes) ? this.settings.recursiveIncludes >= this.bucket.Value : true;
}
public get UseGoToDefIntelliSense(): boolean {
return util.isNumber(this.settings.gotoDefIntelliSense) ? this.settings.gotoDefIntelliSense >= this.bucket.Value : true;
}
private updateSettings(): void {
const cpptoolsJsonFile: string = util.getExtensionFilePath(localConfigFile);
try {
const exists: boolean = fs.existsSync(cpptoolsJsonFile);
if (exists) {
const fileContent: string = fs.readFileSync(cpptoolsJsonFile).toString();
let newSettings: Settings = <Settings>JSON.parse(fileContent);
this.intelliSenseEngineDefault.Value = util.isNumber(newSettings.defaultIntelliSenseEngine) ? newSettings.defaultIntelliSenseEngine : this.intelliSenseEngineDefault.DefaultValue;
this.recursiveIncludesDefault.Value = util.isNumber(newSettings.recursiveIncludes) ? newSettings.recursiveIncludes : this.recursiveIncludesDefault.DefaultValue;
this.gotoDefIntelliSenseDefault.Value = util.isNumber(newSettings.gotoDefIntelliSense) ? newSettings.gotoDefIntelliSense : this.gotoDefIntelliSenseDefault.DefaultValue;
this.settings = {
defaultIntelliSenseEngine: this.intelliSenseEngineDefault.Value,
recursiveIncludes: this.recursiveIncludesDefault.Value,
gotoDefIntelliSense: this.gotoDefIntelliSenseDefault.Value
};
}
if (response.statusCode !== 200) {
return reject();
}
let downloadedBytes = 0; // tslint:disable-line
let cppToolsJsonFile: fs.WriteStream = fs.createWriteStream(util.getExtensionFilePath("cpptools.json"));
response.on('data', (data) => { downloadedBytes += data.length; });
response.on('end', () => { cppToolsJsonFile.close(); });
cppToolsJsonFile.on('close', () => { resolve(); });
response.on('error', (error) => { reject(); });
response.pipe(cppToolsJsonFile, { end: false });
});
request.on('error', (error) => { reject(); });
request.end();
});
}
export function downloadCpptoolsJsonPkg(): Promise<void> {
let hasError: boolean = false;
let telemetryProperties: { [key: string]: string } = {};
return downloadCpptoolsJson("https://go.microsoft.com/fwlink/?linkid=852750")
.catch((error) => {
// More specific error info is not likely to be helpful, and we get detailed download data from the initial install.
hasError = true;
})
.then(() => {
telemetryProperties['success'] = (!hasError).toString();
Telemetry.logDebuggerEvent("cpptoolsJsonDownload", telemetryProperties);
});
}
export function processCpptoolsJson(cpptoolsString: string): Promise<void> {
let cpptoolsObject: any = JSON.parse(cpptoolsString);
let intelliSenseEnginePercentage: number = cpptoolsObject.intelliSenseEngine_default_percentage;
let packageJson: any = util.getRawPackageJson();
if (!packageJson.extensionFolderPath.includes(".vscode-insiders")) {
let prevIntelliSenseEngineDefault: any = packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default;
if (util.extensionContext.globalState.get<number>(userBucketString, userBucketMax + 1) <= intelliSenseEnginePercentage) {
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Default";
} else {
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Tag Parser";
}
if (prevIntelliSenseEngineDefault !== packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default) {
return util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson));
} catch (error) {
// Ignore any cpptoolsJsonFile errors
}
}
}
private downloadCpptoolsJsonPkgAsync(): Promise<void> {
let hasError: boolean = false;
let telemetryProperties: { [key: string]: string } = {};
const localConfigPath: string = util.getExtensionFilePath(localConfigFile);
return util.downloadFileToDestination("https://go.microsoft.com/fwlink/?linkid=2026205", localConfigPath)
.catch((error) => {
// More specific error info is not likely to be helpful, and we get detailed download data from the initial install.
hasError = true;
})
.then(() => {
this.updateSettings();
telemetryProperties['success'] = (!hasError).toString();
Telemetry.logDebuggerEvent("cpptoolsJsonDownload", telemetryProperties);
});
}
}
let settings: ABTestSettings;
export function getABTestSettings(): ABTestSettings {
if (!settings) {
settings = new ABTestSettings();
}
return settings;
}
+10 -1
View File
@@ -11,10 +11,12 @@ class TemporaryCommandRegistrar {
// Used to save/re-execute commands used before the extension has activated (e.g. delayed by dependency downloading).
private delayedCommandsToExecute: Set<string>;
private tempCommands: vscode.Disposable[]; // Need to save this to unregister/dispose the temporary commands.
private isLanguageServerDisabled: boolean;
private commandsToRegister: string[] = [
"C_Cpp.ConfigurationEdit",
"C_Cpp.ConfigurationSelect",
"C_Cpp.ConfigurationProviderSelect",
"C_Cpp.SwitchHeaderSource",
"C_Cpp.Navigate",
"C_Cpp.GoToDeclaration",
@@ -22,7 +24,6 @@ class TemporaryCommandRegistrar {
"C_Cpp.ToggleErrorSquiggles",
"C_Cpp.ToggleIncludeFallback",
"C_Cpp.ToggleDimInactiveRegions",
"C_Cpp.ToggleSnippets",
"C_Cpp.ShowReleaseNotes",
"C_Cpp.ResetDatabase",
"C_Cpp.PauseParsing",
@@ -43,10 +44,18 @@ class TemporaryCommandRegistrar {
public registerTempCommand(command: string): void {
this.tempCommands.push(vscode.commands.registerCommand(command, () => {
if (this.isLanguageServerDisabled) {
vscode.window.showInformationMessage("The command is disabled because \"C_Cpp.intelliSenseEngine\" is set to \"Disabled\".");
return;
}
this.delayedCommandsToExecute.add(command);
}));
}
public disableLanguageServer(): void {
this.isLanguageServerDisabled = true;
}
public activateLanguageServer(): void {
// Main activation code.
this.tempCommands.forEach((command) => {
+227 -34
View File
@@ -14,6 +14,8 @@ import * as url from 'url';
import { PlatformInformation } from './platform';
import { getOutputChannelLogger, showOutputChannel } from './logger';
import * as assert from 'assert';
import * as https from 'https';
import { ClientRequest, OutgoingHttpHeaders } from 'http';
export let extensionContext: vscode.ExtensionContext;
export function setExtensionContext(context: vscode.ExtensionContext): void {
@@ -57,6 +59,32 @@ export function getVcpkgPathDescriptorFile(): string {
}
}
let vcpkgRoot: string;
export function getVcpkgRoot(): string {
if (!vcpkgRoot && vcpkgRoot !== "") {
vcpkgRoot = "";
// Check for vcpkg instance.
if (fs.existsSync(getVcpkgPathDescriptorFile())) {
let vcpkgRootTemp: string = fs.readFileSync(getVcpkgPathDescriptorFile()).toString();
vcpkgRootTemp = vcpkgRootTemp.trim();
if (fs.existsSync(vcpkgRootTemp)) {
vcpkgRoot = path.join(vcpkgRootTemp, "/installed").replace(/\\/g, "/");
}
}
}
return vcpkgRoot;
}
/**
* This is a fuzzy determination of whether a uri represents a header file.
* For the purposes of this function, a header file has no extension, or an extension that begins with the letter 'h'.
* @param document The document to check.
*/
export function isHeader(document: vscode.TextDocument): boolean {
let ext: string = path.extname(document.uri.fsPath);
return !ext || ext.startsWith(".h") || ext.startsWith(".H");
}
// Extension is ready if install.lock exists and debugAdapters folder exist.
export async function isExtensionReady(): Promise<boolean> {
const doesInstallLockFileExist: boolean = await checkInstallLockFile();
@@ -139,42 +167,113 @@ export function getProgressExecutableSuccess(): number { return progressExecutab
export function getProgressParseRootSuccess(): number { return progressParseRootSuccess; } // Parse root was successful (i.e. not blocked by processing taking too long).
export function getProgressIntelliSenseNoSquiggles(): number { return progressIntelliSenseNoSquiggles; } // IntelliSense was successful and the user got no squiggles.
export function showReleaseNotes(): void {
vscode.commands.executeCommand('vscode.previewHtml', vscode.Uri.file(getExtensionFilePath("ReleaseNotes.html")), vscode.ViewColumn.One, "C/C++ Extension Release Notes");
let releaseNotesPanel: vscode.WebviewPanel = undefined;
export async function showReleaseNotes(): Promise<void> {
if (releaseNotesPanel) {
releaseNotesPanel.reveal();
} else {
releaseNotesPanel = vscode.window.createWebviewPanel('releaseNotes', "C/C++ Extension Release Notes", vscode.ViewColumn.One);
releaseNotesPanel.webview.html = await readFileText(getExtensionFilePath("ReleaseNotes.html"));
releaseNotesPanel.onDidDispose(() => releaseNotesPanel = undefined, null, extensionContext.subscriptions);
}
}
export function resolveVariables(input: string): string {
export function isUri(input: any): input is vscode.Uri {
return input && input instanceof vscode.Uri;
}
export function isString(input: any): input is string {
return typeof(input) === "string";
}
export function isNumber(input: any): input is number {
return typeof(input) === "number";
}
export function isBoolean(input: any): input is boolean {
return typeof(input) === "boolean";
}
export function isArray(input: any): input is any[] {
return input instanceof Array;
}
export function isOptionalString(input: any): input is string|undefined {
return input === undefined || isString(input);
}
export function isArrayOfString(input: any): input is string[] {
return isArray(input) && input.every(item => isString(item));
}
export function isOptionalArrayOfString(input: any): input is string[]|undefined {
return input === undefined || isArrayOfString(input);
}
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 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
if (varType === undefined) {
varType = "env";
}
let newValue: string = undefined;
switch (varType) {
case "env": { newValue = process.env[name]; break; }
case "config": {
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
let keys: string[] = name.split('.');
keys.forEach((key: string) => { config = (config) ? config.get(key) : config; });
newValue = (config) ? config.toString() : undefined;
break;
let regexp: () => RegExp = () => /\$\{((env|config|workspaceFolder)(\.|:))?(.*?)\}/g;
let ret: string = input;
let cycleCache: Set<string> = new Set();
while (!cycleCache.has(ret)) {
cycleCache.add(ret);
ret = ret.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
if (varType === undefined) {
varType = "env";
}
default: { assert.fail("unknown varType matched"); }
}
return (newValue) ? newValue : match;
});
let newValue: string;
switch (varType) {
case "env": {
let v: string | string[] = additionalEnvironment[name];
if (isString(v)) {
newValue = v;
} else if (input === match && isArrayOfString(v)) {
newValue = v.join(";");
}
if (!isString(newValue)) {
newValue = process.env[name];
}
break;
}
case "config": {
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration();
if (config) {
newValue = config.get<string>(name);
}
break;
}
case "workspaceFolder": {
// Only replace ${workspaceFolder:name} variables for now.
// We may consider doing replacement of ${workspaceFolder} here later, but we would have to update the language server and also
// intercept messages with paths in them and add the ${workspaceFolder} variable back in (e.g. for light bulb suggestions)
if (name && vscode.workspace && vscode.workspace.workspaceFolders) {
let folder: vscode.WorkspaceFolder = vscode.workspace.workspaceFolders.find(folder => folder.name.toLocaleLowerCase() === name.toLocaleLowerCase());
if (folder) {
newValue = folder.uri.fsPath;
}
}
break;
}
default: { assert.fail("unknown varType matched"); }
}
return (isString(newValue)) ? newValue : match;
});
}
// Resolve '~' at the start of the path.
regexp = /^\~/g;
ret = ret.replace(regexp, (match: string, name: string) => {
let newValue: string = process.env.HOME;
regexp = () => /^\~/g;
ret = ret.replace(regexp(), (match: string, name: string) => {
let newValue: string = (process.platform === 'win32') ? process.env.USERPROFILE : process.env.HOME;
return (newValue) ? newValue : match;
});
@@ -206,7 +305,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;
@@ -307,10 +406,9 @@ export function readFileText(filePath: string, encoding: string = "utf8"): Promi
fs.readFile(filePath, encoding, (err, data) => {
if (err) {
reject(err);
return;
} else {
resolve(data);
}
resolve(data);
});
});
}
@@ -321,14 +419,29 @@ export function writeFileText(filePath: string, content: string, encoding: strin
fs.writeFile(filePath, content, { encoding }, (err) => {
if (err) {
reject(err);
return;
} else {
resolve();
}
resolve();
});
});
}
export function deleteFile(filePath: string): Promise<void> {
return new Promise<void>((resolve, reject) => {
if (fs.existsSync(filePath)) {
fs.unlink(filePath, (err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
} else {
resolve();
}
});
}
// Get the path of the lock file. This is used to indicate that the platform-specific dependencies have been downloaded.
export function getInstallLockPath(): string {
return getExtensionFilePath("install.lock");
@@ -336,7 +449,7 @@ export function getInstallLockPath(): string {
export function getReadmeMessage(): string {
const readmePath: string = getExtensionFilePath("README.md");
const readmeMessage: string = `Please refer to ${readmePath} for troubleshooting information. Issues can be created at https://github.com/Microsoft/vscppsamples/issues`;
const readmeMessage: string = `Please refer to ${readmePath} for troubleshooting information. Issues can be created at https://github.com/Microsoft/vscode-cpptools/issues`;
return readmeMessage;
}
@@ -476,4 +589,84 @@ export async function renamePromise(oldName: string, newName: string): Promise<v
return resolve();
});
});
}
export function promptForReloadWindowDueToSettingsChange(): void {
promptReloadWindow("Reload the workspace for the settings change to take effect.");
}
export function promptReloadWindow(message: string): void {
let reload: string = "Reload";
vscode.window.showInformationMessage(message, reload).then((value: string) => {
if (value === reload) {
vscode.commands.executeCommand("workbench.action.reloadWindow");
}
});
}
export function downloadFileToDestination(urlStr: string, destinationPath: string, headers?: OutgoingHttpHeaders): Promise<void> {
return new Promise<void>((resolve, reject) => {
let parsedUrl: url.Url = url.parse(urlStr);
let request: ClientRequest = https.request({
host: parsedUrl.host,
path: parsedUrl.path,
agent: getHttpsProxyAgent(),
rejectUnauthorized: vscode.workspace.getConfiguration().get('http.proxyStrictSSL', true),
headers: headers
}, (response) => {
if (response.statusCode === 301 || response.statusCode === 302) { // If redirected
// Download from new location
let redirectUrl: string;
if (typeof response.headers.location === 'string') {
redirectUrl = response.headers.location;
} else {
redirectUrl = response.headers.location[0];
}
return resolve(downloadFileToDestination(redirectUrl, destinationPath, headers));
}
if (response.statusCode !== 200) { // If request is not successful
return reject();
}
// Write file using downloaded data
let createdFile: fs.WriteStream = fs.createWriteStream(destinationPath);
createdFile.on('finish', () => { resolve(); });
response.on('error', (error) => { reject(error); });
response.pipe(createdFile);
});
request.on('error', (error) => { reject(error); });
request.end();
});
}
export function downloadFileToStr(urlStr: string, headers?: OutgoingHttpHeaders): Promise<any> {
return new Promise<string>((resolve, reject) => {
let parsedUrl: url.Url = url.parse(urlStr);
let request: ClientRequest = https.request({
host: parsedUrl.host,
path: parsedUrl.path,
agent: getHttpsProxyAgent(),
rejectUnauthorized: vscode.workspace.getConfiguration().get('http.proxyStrictSSL', true),
headers: headers
}, (response) => {
if (response.statusCode === 301 || response.statusCode === 302) { // If redirected
// Download from new location
let redirectUrl: string;
if (typeof response.headers.location === 'string') {
redirectUrl = response.headers.location;
} else {
redirectUrl = response.headers.location[0];
}
return resolve(downloadFileToStr(redirectUrl, headers));
}
if (response.statusCode !== 200) { // If request is not successful
return reject();
}
let downloadedData: string = '';
response.on('data', (data) => { downloadedData += data; });
response.on('error', (error) => { reject(error); });
response.on('end', () => { resolve(downloadedData); });
});
request.on('error', (error) => { reject(error); });
request.end();
});
}
+124
View File
@@ -0,0 +1,124 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
import { CustomConfigurationProvider, Version } from 'vscode-cpptools';
import { CppToolsTestApi, CppToolsTestHook } from 'vscode-cpptools/out/testApi';
import { CustomConfigurationProvider1, getCustomConfigProviders, CustomConfigurationProviderCollection } from './LanguageServer/customProviders';
import { getOutputChannel } from './logger';
import * as LanguageServer from './LanguageServer/extension';
import * as test from './testHook';
export class CppTools implements CppToolsTestApi {
private version: Version;
private providers: CustomConfigurationProvider1[] = [];
private failedRegistrations: CustomConfigurationProvider[] = [];
private timers = new Map<string, NodeJS.Timer>();
constructor(version: Version) {
if (version > Version.latest) {
console.warn(`version ${version} is not supported by this version of cpptools`);
console.warn(` using ${Version.latest} instead`);
version = Version.latest;
}
this.version = version;
}
private addNotifyReadyTimer(provider: CustomConfigurationProvider1): void {
if (this.version >= Version.v2) {
const timeout: number = 30;
let timer: NodeJS.Timer = setTimeout(() => {
console.warn(`registered provider ${provider.extensionId} did not call 'notifyReady' within ${timeout} seconds`);
}, timeout * 1000);
this.timers.set(provider.extensionId, timer);
}
}
private removeNotifyReadyTimer(provider: CustomConfigurationProvider1): void {
if (this.version >= Version.v2) {
let timer: NodeJS.Timer = this.timers.get(provider.extensionId);
if (timer) {
this.timers.delete(provider.extensionId);
clearTimeout(timer);
}
}
}
public getVersion(): Version {
return this.version;
}
public registerCustomConfigurationProvider(provider: CustomConfigurationProvider): void {
let providers: CustomConfigurationProviderCollection = getCustomConfigProviders();
if (providers.add(provider, this.version)) {
let added: CustomConfigurationProvider1 = providers.get(provider);
getOutputChannel().appendLine(`Custom configuration provider '${added.name}' registered`);
this.providers.push(added);
LanguageServer.getClients().forEach(client => client.onRegisterCustomConfigurationProvider(added));
this.addNotifyReadyTimer(added);
} else {
this.failedRegistrations.push(provider);
}
}
public notifyReady(provider: CustomConfigurationProvider): void {
let providers: CustomConfigurationProviderCollection = getCustomConfigProviders();
let p: CustomConfigurationProvider1 = providers.get(provider);
if (p) {
this.removeNotifyReadyTimer(p);
p.isReady = true;
LanguageServer.getClients().forEach(client => {
client.updateCustomConfigurations(p);
client.updateCustomBrowseConfiguration(p);
});
} else if (this.failedRegistrations.find(p => p === provider)) {
console.warn("provider not successfully registered, 'notifyReady' ignored");
} else {
console.warn("provider should be registered before signaling it's ready to provide configurations");
}
}
public didChangeCustomConfiguration(provider: CustomConfigurationProvider): void {
let providers: CustomConfigurationProviderCollection = getCustomConfigProviders();
let p: CustomConfigurationProvider1 = providers.get(provider);
if (p) {
if (!p.isReady) {
console.warn("didChangeCustomConfiguration was invoked before notifyReady");
}
LanguageServer.getClients().forEach(client => client.updateCustomConfigurations(p));
} else if (this.failedRegistrations.find(p => p === provider)) {
console.warn("provider not successfully registered, 'didChangeCustomConfiguration' ignored");
} else {
console.warn("provider should be registered before sending config change messages");
}
}
public didChangeCustomBrowseConfiguration(provider: CustomConfigurationProvider): void {
let providers: CustomConfigurationProviderCollection = getCustomConfigProviders();
let p: CustomConfigurationProvider1 = providers.get(provider);
if (p) {
LanguageServer.getClients().forEach(client => client.updateCustomBrowseConfiguration(p));
} else if (this.failedRegistrations.find(p => p === provider)) {
console.warn("provider not successfully registered, 'didChangeCustomBrowseConfiguration' ignored");
} else {
console.warn("provider should be registered before sending config change messages");
}
}
public dispose(): void {
this.providers.forEach(provider => {
getCustomConfigProviders().remove(provider);
provider.dispose();
});
this.providers = [];
}
public getTestHook(): CppToolsTestHook {
return test.getTestHook();
}
}
+65
View File
@@ -0,0 +1,65 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
import { CustomConfigurationProvider, Version, CppToolsApi } from 'vscode-cpptools';
import { CppToolsTestApi, CppToolsTestHook, CppToolsTestExtension } from 'vscode-cpptools/out/testApi';
import { CppTools } from './cppTools';
/**
* This class implements both interfaces since the extension returned CppToolsApi for v0,
* but returns CppToolsTestExtension for v1 and later.
*/
export class CppTools1 implements CppToolsTestApi, CppToolsTestExtension {
private backupApi: CppTools;
private get BackupApi(): CppToolsTestApi {
if (!this.backupApi) {
this.backupApi = new CppTools(Version.v0);
}
return this.backupApi;
}
getApi(version: Version): CppToolsApi {
switch (version) {
case Version.v0:
return this.BackupApi;
default:
return new CppTools(version);
}
}
getTestApi(version: Version): CppToolsTestApi {
return <CppToolsTestApi>this.getApi(version);
}
getVersion(): Version {
return this.BackupApi.getVersion();
}
registerCustomConfigurationProvider(provider: CustomConfigurationProvider): void {
this.BackupApi.registerCustomConfigurationProvider(provider);
}
notifyReady(provider: CustomConfigurationProvider): void {
this.BackupApi.notifyReady(provider);
}
didChangeCustomConfiguration(provider: CustomConfigurationProvider): void {
this.BackupApi.didChangeCustomConfiguration(provider);
}
didChangeCustomBrowseConfiguration(provider: CustomConfigurationProvider): void {
this.BackupApi.didChangeCustomBrowseConfiguration(provider);
}
dispose(): void {
}
getTestHook(): CppToolsTestHook {
return this.BackupApi.getTestHook();
}
}
+281
View File
@@ -0,0 +1,281 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
import { PackageVersion } from './packageVersion';
import * as util from './common';
import { PlatformInformation } from './platform';
import { OutgoingHttpHeaders } from 'http';
/**
* The object representation of a Build Asset. Each Asset corresponds to information about a release file on GitHub.
*/
interface Asset {
name: string;
browser_download_url: string;
}
/**
* The object representation of a release in the GitHub API's release JSON.
* Named Build so as to reduce confusion between a "Release" release and "Insiders" release.
*/
interface Build {
name: string;
assets: Asset[];
}
/**
* Search each Asset by name to retrieve the download URL for a VSIX package
* @param vsixName The name of the VSIX to search for
* @return The download URL of the VSIX
*/
function getVsixDownloadUrl(build: Build, vsixName: string): string {
const downloadUrl: string = build.assets.find(asset => {
return asset.name === vsixName;
}).browser_download_url;
if (!downloadUrl) {
throw new Error('Failed to find VSIX: ' + vsixName + ' in build: ' + build.name);
}
return downloadUrl;
}
/**
* Determine whether an object is of type Asset.
* @param input Incoming object.
* @return Whether input is of type Asset.
*/
function isAsset(input: any): input is Asset {
return input && input.name && typeof(input.name) === "string" &&
input.browser_download_url && typeof(input.browser_download_url) === "string";
}
/**
* Determine whether an object is of type Build. Note that earlier releases of the extension
* do not have 4 or greater Assets (Mac, Win, Linux 32/64). Only call this on more recent Builds.
* @param input Incoming object.
* @return Whether input is of type Build.
*/
function isBuild(input: any): input is Build {
return input && input.name && typeof(input.name) === "string" && isArrayOfAssets(input.assets) && input.assets.length >= 4;
}
/**
* Determine whether an object is of type Asset[].
* @param input Incoming object.
* @return Whether input is of type Asset[].
*/
function isArrayOfAssets(input: any): input is Asset[] {
return input instanceof Array && input.every(item => isAsset(item));
}
/**
* Determine whether an object is of type Build[].
* @param input Incoming object.
* @return Whether input is of type Build[].
*/
function isArrayOfBuilds(input: any): input is Build[] {
if (!input || !(input instanceof Array) || input.length === 0) {
return false;
}
// Only check the five most recent builds for validity -- no need to check all of them
for (let i: number = 0; i < 5 && i < input.length; i++) {
if (!isBuild(input[i])) {
return false;
}
}
return true;
}
/**
* Match the user's platform information to the VSIX name relevant to them.
* @param info Information about the user's operating system.
* @return VSIX filename for the extension's releases matched to the user's platform.
*/
function vsixNameForPlatform(info: PlatformInformation): string {
const vsixName: string = function(platformInfo): string {
switch (platformInfo.platform) {
case 'win32': return 'cpptools-win32.vsix';
case 'darwin': return 'cpptools-osx.vsix';
default: {
switch (platformInfo.architecture) {
case 'x86_64': return 'cpptools-linux.vsix';
case 'x86':
case 'i386':
case 'i686': return 'cpptools-linux32.vsix';
}
}
}
}(info);
if (!vsixName) {
throw new Error('Failed to match VSIX name for: ' + info.platform + ':' + info.architecture);
}
return vsixName;
}
/**
* Interface for return value of getTargetBuildInfo containing the download URL and version of a Build.
*/
export interface BuildInfo {
downloadUrl: string;
name: string;
}
/**
* Use the GitHub API to retrieve the download URL of the extension version the user should update to, if any.
* @param updateChannel The user's updateChannel setting.
* @return Download URL for the extension VSIX package that the user should install. If the user
* does not need to update, resolves to undefined.
*/
export async function getTargetBuildInfo(updateChannel: string): Promise<BuildInfo> {
return getReleaseJson()
.then(builds => {
if (!builds || builds.length === 0) {
return undefined;
}
// If the user version is greater than or incomparable to the latest available verion then there is no need to update
// Allows testing pre-releases without accidentally downgrading to the latest version
const userVersion: PackageVersion = new PackageVersion(util.packageJson.version);
const latestVersion: PackageVersion = new PackageVersion(builds[0].name);
if (userVersion.isGreaterThan(latestVersion) || (userVersion.suffix && userVersion.suffix !== 'insiders')) {
return undefined;
}
return getTargetBuild(builds, userVersion, updateChannel);
})
.then(async build => {
if (!build) {
return Promise.resolve(undefined);
}
try {
const platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation();
const vsixName: string = vsixNameForPlatform(platformInfo);
const downloadUrl: string = getVsixDownloadUrl(build, vsixName);
return { downloadUrl: downloadUrl, name: build.name };
} catch (error) {
return Promise.reject(error);
}
});
}
/**
* Determines whether there exists a Build in the given Build[] that should be installed.
* @param builds The GitHub release list parsed as an array of Builds.
* @param userVersion The verion of the extension that the user is running.
* @param updateChannel The user's updateChannel setting.
* @return The Build if the user should update to it, otherwise undefined.
*/
function getTargetBuild(builds: Build[], userVersion: PackageVersion, updateChannel: string): Build {
// Get predicates to determine the build to install, if any
let needsUpdate: (installed: PackageVersion, target: PackageVersion) => boolean;
let useBuild: (build: Build) => boolean;
if (updateChannel === 'Insiders') {
needsUpdate = (installed: PackageVersion, target: PackageVersion) => { return target.isGreaterThan(installed); };
useBuild = (build: Build): boolean => { return true; };
} else if (updateChannel === 'Default') {
needsUpdate = function(installed: PackageVersion, target: PackageVersion): boolean { return installed.isGreaterThan(target); };
useBuild = (build: Build): boolean => { return build.name.indexOf('-') === -1; };
} else {
throw new Error('Incorrect updateChannel setting provided');
}
// Get the build to install
const targetBuild: Build = builds.find((build) => useBuild(build));
if (!targetBuild) {
throw new Error('Failed to determine installation candidate');
}
// Check current version against target's version to determine if the installation should happen
const targetVersion: PackageVersion = new PackageVersion(targetBuild.name);
return needsUpdate(userVersion, targetVersion) ? targetBuild : undefined;
}
interface Rate {
remaining: number;
}
interface RateLimit {
rate: Rate;
}
function isRate(input: any): input is Rate {
return input && input.remaining && util.isNumber(input.remaining);
}
function isRateLimit(input: any): input is RateLimit {
return input && isRate(input.rate);
}
async function getRateLimit(): Promise<RateLimit> {
const header: OutgoingHttpHeaders = { 'User-Agent': 'vscode-cpptools' };
const data: string = await util.downloadFileToStr('https://api.github.com/rate_limit', header)
.catch((error) => {
if (error.code && error.code !== "ENOENT") {
// Only throw if the user is connected to the Internet.
throw new Error('Failed to download rate limit JSON');
}
});
if (!data) {
return Promise.resolve(null);
}
let rateLimit: any;
try {
rateLimit = JSON.parse(data);
} catch (error) {
throw new Error('Failed to parse rate limit JSON');
}
if (isRateLimit(rateLimit)) {
return Promise.resolve(rateLimit);
} else {
throw new Error('Rate limit JSON is not of type RateLimit');
}
}
async function rateLimitExceeded(): Promise<boolean> {
const rateLimit: RateLimit = await getRateLimit();
return rateLimit && rateLimit.rate.remaining <= 0;
}
/**
* Download and parse the release list JSON from the GitHub API into a Build[].
* @return Information about the released builds of the C/C++ extension.
*/
async function getReleaseJson(): Promise<Build[]> {
if (await rateLimitExceeded()) {
throw new Error('Failed to stay within GitHub API rate limit');
}
// Download release JSON
const releaseUrl: string = 'https://api.github.com/repos/Microsoft/vscode-cpptools/releases';
const header: OutgoingHttpHeaders = { 'User-Agent': 'vscode-cpptools' };
const data: string = await util.downloadFileToStr(releaseUrl, header)
.catch((error) => {
if (error.code && error.code !== "ENOENT") {
// Only throw if the user is connected to the Internet.
throw new Error('Failed to download release JSON');
}
});
if (!data) {
return Promise.resolve(null);
}
// Parse the file
let releaseJson: any;
try {
releaseJson = JSON.parse(data);
} catch (error) {
throw new Error('Failed to parse release JSON');
}
// Type check
if (isArrayOfBuilds(releaseJson)) {
return releaseJson;
} else {
throw new Error('Release JSON is not of type Build[]');
}
}
+7 -11
View File
@@ -3,7 +3,7 @@
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
export class InstallationInformation {
export class InstallationInformation {
stage: string;
hasError: boolean;
telemetryProperties: { [key: string]: string };
@@ -14,19 +14,15 @@ export class InstallationInformation {
}
}
let installBlob: InstallationInformation ;
let installBlob: InstallationInformation;
export function initializeInstallationInformation(): void {
installBlob = new InstallationInformation ();
}
export function getInstallationInformationInstance(): InstallationInformation {
export function getInstallationInformation(): InstallationInformation {
if (!installBlob) {
installBlob = new InstallationInformation();
}
return installBlob;
}
export function setInstallationStage(stage: string): void {
if (!installBlob) {
initializeInstallationInformation();
}
installBlob.stage = stage;
getInstallationInformation().stage = stage;
}
+65 -34
View File
@@ -13,32 +13,43 @@ import * as Telemetry from './telemetry';
import * as util from './common';
import * as vscode from 'vscode';
import { CppToolsApi, CppToolsExtension } from 'vscode-cpptools';
import { getTemporaryCommandRegistrarInstance, initializeTemporaryCommandRegistrar } from './commands';
import { PlatformInformation } from './platform';
import { PackageManager, PackageManagerError, PackageManagerWebResponseError, IPackage } from './packageManager';
import { PackageManager, PackageManagerError, IPackage } from './packageManager';
import { PersistentState } from './LanguageServer/persistentState';
import { initializeInstallationInformation, getInstallationInformationInstance, InstallationInformation, setInstallationStage } from './installationInformation';
import { getInstallationInformation, InstallationInformation, setInstallationStage } from './installationInformation';
import { Logger, getOutputChannelLogger, showOutputChannel } from './logger';
import { CppTools1 } from './cppTools1';
const releaseNotesVersion: number = 3;
const cppTools: CppTools1 = new CppTools1();
let languageServiceDisabled: boolean = false;
let reloadMessageShown: boolean = false;
let disposables: vscode.Disposable[] = [];
export function activate(context: vscode.ExtensionContext): void | Promise<void> {
export async function activate(context: vscode.ExtensionContext): Promise<CppToolsApi & CppToolsExtension> {
initializeTemporaryCommandRegistrar();
util.setExtensionContext(context);
Telemetry.activate();
util.setProgress(0);
cpptoolsJsonUtils.activate(context);
initializeInstallationInformation();
// Initialize the DebuggerExtension and register the related commands and providers.
DebuggerExtension.initialize();
return processRuntimeDependencies();
await processRuntimeDependencies();
return cppTools;
}
export function deactivate(): Thenable<void> {
DebuggerExtension.dispose();
Telemetry.deactivate();
disposables.forEach(d => d.dispose());
if (languageServiceDisabled) {
return;
}
return LanguageServer.deactivate();
}
@@ -53,6 +64,9 @@ async function processRuntimeDependencies(): Promise<void> {
} catch (error) {
getOutputChannelLogger().showErrorMessage('The installation of the C/C++ extension failed. Please see the output window for more information.');
showOutputChannel();
// Send the failure telemetry since postInstall will not be called.
sendTelemetry(await PlatformInformation.GetPlatformInformation());
}
// The extension have been installed and activated before.
} else {
@@ -64,6 +78,9 @@ async function processRuntimeDependencies(): Promise<void> {
await onlineInstallation();
} catch (error) {
handleError(error);
// Send the failure telemetry since postInstall will not be called.
sendTelemetry(await PlatformInformation.GetPlatformInformation());
}
}
}
@@ -169,23 +186,12 @@ function touchInstallLockFile(): Promise<void> {
}
function handleError(error: any): void {
let installationInformation: InstallationInformation = getInstallationInformationInstance();
let installationInformation: InstallationInformation = getInstallationInformation();
installationInformation.hasError = true;
installationInformation.telemetryProperties['stage'] = installationInformation.stage;
let errorMessage: string;
if (error instanceof PackageManagerError) {
// If this is a WebResponse error, log the IP that it resolved from the package URL
if (error instanceof PackageManagerWebResponseError) {
let webRequestPackageError: PackageManagerWebResponseError = error;
if (webRequestPackageError.socket) {
let address: any = webRequestPackageError.socket.address();
if (address) {
installationInformation.telemetryProperties['error.targetIP'] = address.address + ':' + address.port;
}
}
}
let packageError: PackageManagerError = error;
installationInformation.telemetryProperties['error.methodName'] = packageError.methodName;
@@ -224,7 +230,7 @@ function handleError(error: any): void {
}
function sendTelemetry(info: PlatformInformation): boolean {
let installBlob: InstallationInformation = getInstallationInformationInstance();
let installBlob: InstallationInformation = getInstallationInformation();
const success: boolean = !installBlob.hasError;
installBlob.telemetryProperties['success'] = success.toString();
@@ -270,23 +276,48 @@ async function postInstall(info: PlatformInformation): Promise<void> {
}
async function finalizeExtensionActivation(): Promise<void> {
const cpptoolsJsonFile: string = util.getExtensionFilePath("cpptools.json");
try {
const exists: boolean = await util.checkFileExists(cpptoolsJsonFile);
if (exists) {
const cpptoolsString: string = await util.readFileText(cpptoolsJsonFile);
await cpptoolsJsonUtils.processCpptoolsJson(cpptoolsString);
}
} catch (error) {
// Ignore any cpptoolsJsonFile errors
if (vscode.workspace.getConfiguration("C_Cpp", null).get<string>("intelliSenseEngine") === "Disabled") {
languageServiceDisabled = true;
getTemporaryCommandRegistrarInstance().disableLanguageServer();
disposables.push(vscode.workspace.onDidChangeConfiguration(() => {
if (!reloadMessageShown && vscode.workspace.getConfiguration("C_Cpp", null).get<string>("intelliSenseEngine") !== "Disabled") {
reloadMessageShown = true;
util.promptForReloadWindowDueToSettingsChange();
}
}));
return;
}
disposables.push(vscode.workspace.onDidChangeConfiguration(() => {
if (!reloadMessageShown && vscode.workspace.getConfiguration("C_Cpp", null).get<string>("intelliSenseEngine") === "Disabled") {
reloadMessageShown = true;
util.promptForReloadWindowDueToSettingsChange();
}
}));
getTemporaryCommandRegistrarInstance().activateLanguageServer();
// Redownload cpptools.json after activation so it's not blocked.
// It'll be used after the extension reloads.
cpptoolsJsonUtils.downloadCpptoolsJsonPkg();
// Update default for C_Cpp.intelliSenseEngine based on A/B testing settings.
// (this may result in rewriting the package.json file)
let packageJsonPath: string = util.getExtensionFilePath("package.json");
if (!packageJsonPath.includes(".vscode-insiders") && !packageJsonPath.includes(".vscode-exploration")) {
let abTestSettings: cpptoolsJsonUtils.ABTestSettings = cpptoolsJsonUtils.getABTestSettings();
let packageJson: any = util.getRawPackageJson();
let prevIntelliSenseEngineDefault: any = packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default;
if (abTestSettings.UseDefaultIntelliSenseEngine) {
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Default";
} else {
packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default = "Tag Parser";
}
if (prevIntelliSenseEngineDefault !== packageJson.contributes.configuration.properties["C_Cpp.intelliSenseEngine"].default) {
return util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson));
}
} else {
let packageJson: any = util.getRawPackageJson();
if (packageJson.contributes.configuration.properties['C_Cpp.updateChannel'].default === 'Default') {
packageJson.contributes.configuration.properties['C_Cpp.updateChannel'].default = 'Insiders';
return util.writeFileText(util.getPackageJsonPath(), util.stringifyPackageJson(packageJson));
}
}
}
function rewriteManifest(): Promise<void> {
@@ -300,6 +331,7 @@ function rewriteManifest(): Promise<void> {
"onCommand:extension.pickRemoteNativeProcess",
"onCommand:C_Cpp.ConfigurationEdit",
"onCommand:C_Cpp.ConfigurationSelect",
"onCommand:C_Cpp.ConfigurationProviderSelect",
"onCommand:C_Cpp.SwitchHeaderSource",
"onCommand:C_Cpp.Navigate",
"onCommand:C_Cpp.GoToDeclaration",
@@ -307,7 +339,6 @@ 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",
+3 -4
View File
@@ -183,11 +183,10 @@ export class PackageManager {
} catch (error) {
retryCount += 1;
lastError = error;
if (retryCount >= MAX_RETRIES) {
if (retryCount > MAX_RETRIES) {
this.AppendChannel(` Failed to download ` + pkg.url);
throw error;
} else {
// This will skip the success = true.
this.AppendChannel(` Failed. Retrying...`);
continue;
}
@@ -198,7 +197,7 @@ export class PackageManager {
if (retryCount !== 0) {
// Log telemetry to see if retrying helps.
let telemetryProperties: { [key: string]: string } = {};
telemetryProperties["success"] = `OnRetry${retryCount}`;
telemetryProperties["success"] = success ? `OnRetry${retryCount}` : 'false';
if (lastError instanceof PackageManagerError) {
let packageError: PackageManagerError = lastError;
telemetryProperties['error.methodName'] = packageError.methodName;
@@ -223,7 +222,7 @@ export class PackageManager {
let options: https.RequestOptions = {
host: parsedUrl.host,
path: parsedUrl.path,
agent: util.GetHttpsProxyAgent(),
agent: util.getHttpsProxyAgent(),
rejectUnauthorized: proxyStrictSSL
};
+61
View File
@@ -0,0 +1,61 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
export class PackageVersion {
major: number;
minor: number;
patch: number;
suffix?: string;
suffixVersion: number;
constructor(version: string) {
const tokens: string[] = version.split(new RegExp('[-\\.]', 'g')); // Match against dots and dashes
if (tokens.length < 3) {
throw new Error('Failed to parse version string: ' + version);
}
this.major = parseInt(tokens[0]);
this.minor = parseInt(tokens[1]);
this.patch = parseInt(tokens[2]);
if (tokens.length > 3) {
const firstDigitOffset: number = tokens[3].search(new RegExp(/(\d)/)); // Find first occurrence of 0-9
if (firstDigitOffset !== -1) {
this.suffix = tokens[3].substring(0, firstDigitOffset);
this.suffixVersion = parseInt(tokens[3].substring(firstDigitOffset));
} else {
this.suffix = tokens[3];
this.suffixVersion = 1;
}
} else {
this.suffix = undefined;
this.suffixVersion = 0;
}
if (this.major === undefined || this.minor === undefined || this.patch === undefined) {
throw new Error('Failed to parse version string: ' + version);
}
}
public isGreaterThan(other: PackageVersion, suffixStr: string = 'insiders'): boolean {
if ((this.suffix && !this.suffix.startsWith(suffixStr)) || (other.suffix && !other.suffix.startsWith(suffixStr))) {
return false;
}
let diff: number = this.major - other.major;
if (diff) {
return diff > 0;
} else if (diff = this.minor - other.minor) {
return diff > 0;
} else if (diff = this.patch - other.patch) {
return diff > 0;
} else if (this.suffix) {
return (other.suffix && this.suffixVersion > other.suffixVersion);
} else {
return other.suffix ? true : false;
}
}
}
+38
View File
@@ -0,0 +1,38 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
import { CppToolsTestHook, Status } from 'vscode-cpptools/out/testApi';
import * as vscode from 'vscode';
export class TestHook implements CppToolsTestHook {
private statusChangedEvent: vscode.EventEmitter<Status> = new vscode.EventEmitter<Status>();
public get StatusChanged(): vscode.Event<Status> {
return this.statusChangedEvent.event;
}
public get valid(): boolean {
return !!this.statusChangedEvent;
}
public updateStatus(status: Status): void {
this.statusChangedEvent.fire(status);
}
public dispose(): void {
this.statusChangedEvent.dispose();
this.statusChangedEvent = null;
}
}
let testHook: TestHook;
export function getTestHook(): TestHook {
if (!testHook || !testHook.valid) {
testHook = new TestHook();
}
return testHook;
}
@@ -6,10 +6,10 @@
import * as vscode from 'vscode';
import * as assert from 'assert';
suite(`Debug Integration Test: `, function() {
suiteSetup(async function() {
let extension = vscode.extensions.getExtension("ms-vscode.cpptools");
if (!extension.isActive) {
suite(`Debug Integration Test: `, function(): void {
suiteSetup(async function(): Promise<void> {
let extension: vscode.Extension<any> = vscode.extensions.getExtension("ms-vscode.cpptools");
if (!extension.isActive) {
await extension.activate();
}
});
@@ -17,14 +17,14 @@ suite(`Debug Integration Test: `, function() {
test("Starting (gdb) Launch from the workspace root should create an Active Debug Session", async () => {
await vscode.debug.startDebugging(vscode.workspace.workspaceFolders[0], "(gdb) Launch");
let debugSessionTerminated = new Promise(resolve => {
let debugSessionTerminated: Promise<void> = new Promise(resolve => {
vscode.debug.onDidTerminateDebugSession((e) => resolve());
});
try {
assert.equal(vscode.debug.activeDebugSession.type, "cppdbg");
} catch (e) {
assert.fail("Debugger failed to launch. Did the extension activate correctly?")
assert.fail("Debugger failed to launch. Did the extension activate correctly?");
}
await debugSessionTerminated;
@@ -6,11 +6,15 @@
import * as vscode from 'vscode';
import * as assert from 'assert';
import { getLanguageConfigFromPatterns } from '../../src/LanguageServer/languageConfig';
import * as util from '../../src/common';
import * as api from 'vscode-cpptools';
import * as apit from 'vscode-cpptools/out/testApi';
import * as config from '../../src/LanguageServer/configurations';
import { CppSettings } from '../../src/LanguageServer/settings';
import { getActiveClient } from '../../src/LanguageServer/extension';
suite("multiline comment setting tests", function() {
suiteSetup(async function() {
suite("multiline comment setting tests", function(): void {
suiteSetup(async function(): Promise<void> {
let extension: vscode.Extension<any> = vscode.extensions.getExtension("ms-vscode.cpptools");
if (!extension.isActive) {
await extension.activate();
@@ -78,6 +82,267 @@ suite("multiline comment setting tests", function() {
});
/******************************************************************************/
function cppPropertiesPath(): string {
return vscode.workspace.workspaceFolders[0].uri.fsPath + "/.vscode/c_cpp_properties.json";
}
async function changeCppProperties(cppProperties: config.ConfigurationJson, disposables: vscode.Disposable[]): Promise<void> {
let promise: Promise<void> = new Promise<void>((resolve, reject) => {
disposables.push(getActiveClient().ActiveConfigChanged(name => {
if (name === cppProperties.configurations[0].name) {
resolve();
}
}));
// Can't trust the file watcher, so we need to allocate additional time for the backup watcher to fire.
setTimeout(() => { reject(new Error("timeout")); }, 4000);
});
await util.writeFileText(cppPropertiesPath(), JSON.stringify(cppProperties));
let contents: string = await util.readFileText(cppPropertiesPath());
console.log(" wrote c_cpp_properties.json: " + contents);
return promise;
}
/******************************************************************************/
suite("extensibility tests v2", function(): void {
let cpptools: apit.CppToolsTestApi;
let lastResult: api.SourceFileConfigurationItem[];
let defaultConfig: api.SourceFileConfiguration = {
includePath: [ "${workspaceFolder}", "/v2/folder" ],
defines: [ "${workspaceFolder}" ],
intelliSenseMode: "msvc-x64",
standard: "c++17"
};
let lastBrowseResult: api.WorkspaceBrowseConfiguration;
let defaultBrowseConfig: api.WorkspaceBrowseConfiguration = {
browsePath: [ "/v2/folder" ],
compilerPath: "",
standard: "c++14",
windowsSdkVersion: "8.1"
};
// Has to be 'any' instead of api.CustomConfigurationProvider because of missing interface members.
let provider: api.CustomConfigurationProvider = {
name: "cpptoolsTest-v2",
extensionId: "ms-vscode.cpptools-test2",
canProvideConfiguration(document: vscode.Uri): Thenable<boolean> {
return Promise.resolve(true);
},
provideConfigurations(uris: vscode.Uri[]): Thenable<api.SourceFileConfigurationItem[]> {
let result: api.SourceFileConfigurationItem[] = [];
uris.forEach(uri => {
result.push({
uri: uri.toString(),
configuration: defaultConfig
});
});
lastResult = result;
return Promise.resolve(result);
},
canProvideBrowseConfiguration(): Thenable<boolean> {
return Promise.resolve(true);
},
provideBrowseConfiguration(): Thenable<api.WorkspaceBrowseConfiguration> {
lastBrowseResult = defaultBrowseConfig;
return Promise.resolve(defaultBrowseConfig);
},
dispose(): void {
console.log(" disposed");
}
};
let disposables: vscode.Disposable[] = [];
suiteSetup(async function(): Promise<void> {
cpptools = await apit.getCppToolsTestApi(api.Version.v2);
cpptools.registerCustomConfigurationProvider(provider);
cpptools.notifyReady(provider);
disposables.push(cpptools);
await changeCppProperties({
configurations: [ {name: "test2", configurationProvider: provider.extensionId} ],
version: 4
},
disposables);
});
suiteTeardown(function(): void {
disposables.forEach(d => d.dispose());
});
test("Check provider", async () => {
// Open a c++ file to start the language server.
let path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/main2.cpp";
let uri: vscode.Uri = vscode.Uri.file(path);
let testHook: apit.CppToolsTestHook = cpptools.getTestHook();
let testResult: any = new Promise<void>((resolve, reject) => {
disposables.push(testHook.StatusChanged(status => {
if (status === apit.Status.IntelliSenseReady) {
let expected: api.SourceFileConfigurationItem[] = [ {uri: uri.toString(), configuration: defaultConfig} ];
assert.deepEqual(lastResult, expected);
assert.deepEqual(lastBrowseResult, defaultBrowseConfig);
resolve();
}
}));
setTimeout(() => { reject(new Error("timeout")); }, 2500);
});
disposables.push(testHook);
await vscode.workspace.openTextDocument(path);
await testResult;
});
});
/******************************************************************************/
suite("extensibility tests v1", function(): void {
let cpptools: apit.CppToolsTestApi;
let lastResult: api.SourceFileConfigurationItem[];
let defaultConfig: api.SourceFileConfiguration = {
includePath: [ "${workspaceFolder}" ],
defines: [ "${workspaceFolder}" ],
intelliSenseMode: "msvc-x64",
standard: "c++17"
};
// Has to be 'any' instead of api.CustomConfigurationProvider because of missing interface members.
let provider: any = {
name: "cpptoolsTest-v1",
extensionId: "ms-vscode.cpptools-test",
canProvideConfiguration(document: vscode.Uri): Thenable<boolean> {
return Promise.resolve(true);
},
provideConfigurations(uris: vscode.Uri[]): Thenable<api.SourceFileConfigurationItem[]> {
let result: api.SourceFileConfigurationItem[] = [];
uris.forEach(uri => {
result.push({
uri: uri.toString(),
configuration: defaultConfig
});
});
lastResult = result;
return Promise.resolve(result);
},
dispose(): void {
console.log(" disposed");
}
};
let disposables: vscode.Disposable[] = [];
suiteSetup(async function(): Promise<void> {
cpptools = await apit.getCppToolsTestApi(api.Version.v1);
cpptools.registerCustomConfigurationProvider(provider);
disposables.push(cpptools);
await changeCppProperties({
configurations: [ {name: "test1", configurationProvider: provider.extensionId} ],
version: 4
},
disposables);
});
suiteTeardown(function(): void {
disposables.forEach(d => d.dispose());
});
test("Check provider", async () => {
// Open a c++ file to start the language server.
let path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/main1.cpp";
let uri: vscode.Uri = vscode.Uri.file(path);
let testHook: apit.CppToolsTestHook = cpptools.getTestHook();
let testResult: any = new Promise<void>((resolve, reject) => {
disposables.push(testHook.StatusChanged(status => {
if (status === apit.Status.IntelliSenseReady) {
let expected: api.SourceFileConfigurationItem[] = [ {uri: uri.toString(), configuration: defaultConfig} ];
assert.deepEqual(lastResult, expected);
resolve();
}
}));
setTimeout(() => { reject(new Error("timeout")); }, 2500);
});
disposables.push(testHook);
await vscode.workspace.openTextDocument(path);
await testResult;
});
});
/******************************************************************************/
suite("extensibility tests v0", function(): void {
let cpptools: apit.CppToolsTestApi;
let lastResult: api.SourceFileConfigurationItem[];
let defaultConfig: api.SourceFileConfiguration = {
includePath: [ "${workspaceFolder}" ],
defines: [ "${workspaceFolder}" ],
intelliSenseMode: "msvc-x64",
standard: "c++17"
};
// Has to be 'any' instead of api.CustomConfigurationProvider because of missing interface members.
let provider: any = {
name: "cpptoolsTest-v0",
canProvideConfiguration(document: vscode.Uri): Thenable<boolean> {
return Promise.resolve(true);
},
provideConfigurations(uris: vscode.Uri[]): Thenable<api.SourceFileConfigurationItem[]> {
let result: api.SourceFileConfigurationItem[] = [];
uris.forEach(uri => {
result.push({
uri: uri.toString(),
configuration: defaultConfig
});
});
lastResult = result;
return Promise.resolve(result);
}
};
let disposables: vscode.Disposable[] = [];
suiteSetup(async function(): Promise<void> {
cpptools = await apit.getCppToolsTestApi(api.Version.v0);
cpptools.registerCustomConfigurationProvider(provider);
disposables.push(cpptools); // This is a no-op for v0, but do it anyway to make sure nothing breaks.
await changeCppProperties({
configurations: [ { name: "test0", configurationProvider: provider.name } ],
version: 4
},
disposables);
});
suiteTeardown(async function(): Promise<void> {
disposables.forEach(d => d.dispose());
await util.deleteFile(cppPropertiesPath());
});
test("Check provider", async () => {
// Open a C++ file to start the language server.
let path: string = vscode.workspace.workspaceFolders[0].uri.fsPath + "/main.cpp";
let uri: vscode.Uri = vscode.Uri.file(path);
let testHook: apit.CppToolsTestHook = cpptools.getTestHook();
let testResult: any = new Promise<void>((resolve, reject) => {
disposables.push(testHook.StatusChanged(status => {
if (status === apit.Status.IntelliSenseReady) {
let expected: api.SourceFileConfigurationItem[] = [ {uri: uri.toString(), configuration: defaultConfig} ];
assert.deepEqual(lastResult, expected);
resolve();
}
}));
setTimeout(() => { reject(new Error("timeout")); }, 2500);
});
disposables.push(testHook);
await vscode.workspace.openTextDocument(path);
await testResult;
});
});
/*
suite("configuration tests", function() {
suiteSetup(async function() {
@@ -93,8 +358,6 @@ suite("configuration tests", function() {
// Delete c_cpp_properties.json
});
test("Check default configuration", () => {
let rootUri: vscode.Uri;
if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) {
@@ -1,16 +1,34 @@
{
"version": "0.1.0",
"version": "2.0.0",
"tasks": [
{
"taskName": "build",
"command": "g++",
"isShellCommand": true,
"args": ["main.cpp", "-g", "-o", "program"],
"showOutput": "always",
"isBuildCommand": true,
"windows": {
"command": "C:\\MinGW\\bin\\g++.exe"
}
"label": "build",
"command": "g++",
"type": "shell",
"args": [
"main.cpp",
"-g",
"-o",
"program"
],
"group":{
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"windows": {
"command": "C:\\MinGW\\bin\\g++.exe"
},
"problemMatcher": [
"$gcc"
]
}
]
}
@@ -0,0 +1,3 @@
int main(int argc, char* arv[]) {
return 0;
}
@@ -0,0 +1,3 @@
int main(int argc, char* arv[]) {
return 0;
}
@@ -5,11 +5,23 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
child_process = require('child_process');
path = require('path');
async_child_process = require('async-child-process');
if (process.env.CODE_TESTS_PATH
&& process.env.CODE_TESTS_PATH.startsWith('.')){
process.env.CODE_TESTS_PATH = path.join(process.cwd(), process.env.CODE_TESTS_PATH.substr(2));
}
require(path.resolve(__dirname, '../node_modules/vscode/bin/test'));
let optionsWithFullEnvironment = {
cwd: path.resolve(__dirname, '..'),
stdio: 'inherit',
env: {
...process.env,
}
};
spawn = child_process.spawn('node', [path.resolve(__dirname, '../node_modules/vscode/bin/test')], optionsWithFullEnvironment);
return async_child_process.join(spawn);
+234
View File
@@ -0,0 +1,234 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* See 'LICENSE' in the project root for license information.
* ------------------------------------------------------------------------------------------ */
import * as assert from "assert";
import { resolveVariables } from "../../src/common";
suite("Common Utility validation", () => {
suite("resolveVariables", () => {
const success: string = "success";
const home: string = process.env.HOME || process.env.USERPROFILE;
test("raw input", () => {
const input: string = "test";
inputAndEnvironment(input, {})
.shouldResolveTo(input);
});
test("raw input with tilde", () => {
inputAndEnvironment("~/test", {})
.shouldResolveTo(`${home}/test`);
});
test("env input with tilde", () => {
inputAndEnvironment("${path}/test", {
path: home
})
.shouldResolveTo(`${home}/test`);
});
test("solo env input resulting in array", () => {
inputAndEnvironment("${test}", {
test: ["foo", "bar"]
})
.shouldResolveTo("foo;bar");
});
test("solo env input with empty array env value", () => {
resolveVariablesWithInput("${empty}")
.withEnvironment({
"empty": []
})
.shouldResolveTo("");
});
test("mixed raw and env input resulting in array", () => {
const input: string = "baz${test}";
resolveVariablesWithInput(input)
.withEnvironment({
test: ["foo", "bar"]
})
.shouldResolveTo(input);
});
test("solo env input not in env config finds process env", () => {
const processKey: string = `cpptoolstests_${Date.now()}`;
const input: string = "foo${" + processKey + "}";
let actual: string;
try {
process.env[processKey] = "bar";
actual = resolveVariables(input, {});
} finally {
delete process.env[processKey];
}
assert.equal(actual, "foobar");
});
test("env input", () => {
resolveVariablesWithInput("${test}")
.withEnvironment({
"test": success
})
.shouldResolveTo(success);
});
test("env input mixed with plain text", () => {
resolveVariablesWithInput("${test}bar")
.withEnvironment({
"test": "foo"
})
.shouldResolveTo("foobar");
});
test("env input with two variables", () => {
resolveVariablesWithInput("f${a}${b}r")
.withEnvironment({
a: "oo",
b: "ba"
})
.shouldResolveTo("foobar");
});
test("env input not in env", () => {
const input: string = "${test}";
resolveVariablesWithInput(input)
.withEnvironment({})
.shouldResolveTo(input);
});
test("env with macro inside environment definition", () => {
resolveVariablesWithInput("${arm6.include}")
.withEnvironment({
"envRoot": "apps/tool/buildenv",
"arm6.include": "${envRoot}/arm6/include"
})
.shouldResolveTo("apps/tool/buildenv/arm6/include");
});
test("env nested with half open variable", () => {
resolveVariablesWithInput("${arm6.include}")
.withEnvironment({
"envRoot": "apps/tool/buildenv",
"arm6.include": "${envRoot/arm6/include"
})
.shouldResolveTo("${envRoot/arm6/include");
});
test("env nested with half closed variable", () => {
resolveVariablesWithInput("${arm6.include}")
.withEnvironment({
"envRoot": "apps/tool/buildenv",
"arm6.include": "envRoot}/arm6/include"
})
.shouldResolveTo("envRoot}/arm6/include");
});
test("env nested with a cycle", () => {
resolveVariablesWithInput("${a}")
.withEnvironment({
"a": "${b}",
"b": "${c}",
"c": "${a}"
})
.shouldResolveTo("${a}");
});
test("env input with 1 level of nested variables anchored at end", () => {
resolveVariablesWithInput("${foo${test}}")
.withEnvironment({
"foobar": success,
"test": "bar"
})
.shouldResolveTo("${foo${test}}");
});
test("env input with 1 level of nested variables anchored in the middle", () => {
resolveVariablesWithInput("${f${test}r}")
.withEnvironment({
"foobar": success,
"test": "ooba"
})
.shouldResolveTo("${f${test}r}");
});
test("env input with 1 level of nested variable anchored at front", () => {
resolveVariablesWithInput("${${test}bar}")
.withEnvironment({
"foobar": success,
"test": "foo"
})
.shouldResolveTo("${${test}bar}");
});
test("env input with 3 levels of nested variables", () => {
resolveVariablesWithInput("${foo${a${b${c}}}}")
.withEnvironment({
"foobar": success,
"a1": "bar",
"b2": "1",
"c": "2"
})
.shouldResolveTo("${foo${a${b${c}}}}");
});
test("env input contains env", () => {
resolveVariablesWithInput("${envRoot}")
.shouldLookupSymbol("envRoot");
});
test("env input contains config", () => {
resolveVariablesWithInput("${configRoot}")
.shouldLookupSymbol("configRoot");
});
test("env input contains workspaceFolder", () => {
resolveVariablesWithInput("${workspaceFolderRoot}")
.shouldLookupSymbol("workspaceFolderRoot");
});
test("input contains env.", () => {
resolveVariablesWithInput("${env.Root}")
.shouldLookupSymbol("Root");
});
test("input contains env:", () => {
resolveVariablesWithInput("${env:Root}")
.shouldLookupSymbol("Root");
});
interface ResolveTestFlowEnvironment {
withEnvironment(additionalEnvironment: {[key: string]: string | string[]}): ResolveTestFlowAssert;
shouldLookupSymbol: (key: string) => void;
}
interface ResolveTestFlowAssert {
shouldResolveTo: (x: string) => void;
}
function resolveVariablesWithInput(input: string): ResolveTestFlowEnvironment {
return {
withEnvironment: (additionalEnvironment: {[key: string]: string | string[]}) => {
return inputAndEnvironment(input, additionalEnvironment);
},
shouldLookupSymbol: (symbol: string) => {
const environment: {[key: string]: string | string[]} = {};
environment[symbol] = success;
return inputAndEnvironment(input, environment)
.shouldResolveTo(success);
}
};
}
function inputAndEnvironment(input: string, additionalEnvironment: {[key: string]: string | string[]}): ResolveTestFlowAssert {
return {
shouldResolveTo: (expected: string) => {
const actual: string = resolveVariables(input, additionalEnvironment);
const msg: string = `Expected ${expected}. Got ${actual} with input ${input} and environment ${JSON.stringify(additionalEnvironment)}.`;
assert.equal(actual, expected, msg);
}
};
}
});
});
+125
View File
@@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as fs from 'fs';
import * as os from 'os';
function appendFieldsToObject(reference: any, obj: any): any {
// Make sure it is an object type
if (typeof obj === 'object') {
for (let referenceKey in reference) {
// If key exists in original object and is an object.
if (obj.hasOwnProperty(referenceKey)) {
obj[referenceKey] = appendFieldsToObject(reference[referenceKey], obj[referenceKey]);
} else {
// Does not exist in current object context
obj[referenceKey] = reference[referenceKey];
}
}
}
return obj;
}
// Combines two object's fields, giving the parentDefault a higher precedence.
function mergeDefaults(parentDefault: any, childDefault: any): any {
let newDefault: any = {};
for (let attrname in childDefault) {
newDefault[attrname] = childDefault[attrname];
}
for (let attrname in parentDefault) {
newDefault[attrname] = parentDefault[attrname];
}
return newDefault;
}
function updateDefaults(object: any, defaults: any): any {
if (defaults !== null) {
for (let key in object) {
if (object[key].hasOwnProperty('type') && object[key].type === 'object' && object[key].properties !== null) {
object[key].properties = updateDefaults(object[key].properties, mergeDefaults(defaults, object[key].default));
} else if (key in defaults) {
object[key].default = defaults[key];
}
}
}
return object;
}
function refReplace(definitions: any, ref: any): any {
// $ref is formatted as "#/definitions/ObjectName"
let referenceStringArray: string[] = ref['$ref'].split('/');
// Getting "ObjectName"
let referenceName: string = referenceStringArray[referenceStringArray.length - 1];
// Make sure reference has replaced its own $ref fields and hope there are no recursive references.
definitions[referenceName] = replaceReferences(definitions, definitions[referenceName]);
// Retrieve ObjectName from definitions. (TODO: Does not retrieve inner objects)
// Need to deep copy, there are no functions in these objects.
let reference: any = JSON.parse(JSON.stringify(definitions[referenceName]));
ref = appendFieldsToObject(reference, ref);
// Remove $ref field
delete ref['$ref'];
return ref;
}
function replaceReferences(definitions: any, objects: any): any {
for (let key in objects) {
if (objects[key].hasOwnProperty('$ref')) {
objects[key] = refReplace(definitions, objects[key]);
}
// Recursively replace references if this object has properties.
if (objects[key].hasOwnProperty('type') && objects[key].type === 'object' && objects[key].properties !== null) {
objects[key].properties = replaceReferences(definitions, objects[key].properties);
objects[key].properties = updateDefaults(objects[key].properties, objects[key].default);
}
// Recursively replace references if the array has objects in items.
if (objects[key].hasOwnProperty('type') && objects[key].type === "array" && objects[key].items !== null && objects[key].items.hasOwnProperty('$ref')) {
objects[key].items = refReplace(definitions, objects[key].items);
}
}
return objects;
}
export function generateOptionsSchema(): void {
let packageJSON: any = JSON.parse(fs.readFileSync('package.json').toString());
let schemaJSON: any = JSON.parse(fs.readFileSync('tools/OptionsSchema.json').toString());
schemaJSON.definitions = replaceReferences(schemaJSON.definitions, schemaJSON.definitions);
// Hard Code adding in configurationAttributes launch and attach.
// cppdbg
packageJSON.contributes.debuggers[0].configurationAttributes.launch = schemaJSON.definitions.CppdbgLaunchOptions;
packageJSON.contributes.debuggers[0].configurationAttributes.attach = schemaJSON.definitions.CppdbgAttachOptions;
// cppvsdbg
packageJSON.contributes.debuggers[1].configurationAttributes.launch = schemaJSON.definitions.CppvsdbgLaunchOptions;
packageJSON.contributes.debuggers[1].configurationAttributes.attach = schemaJSON.definitions.CppvsdbgAttachOptions;
let content: string = JSON.stringify(packageJSON, null, 2);
if (os.platform() === 'win32') {
content = content.replace(/\n/gm, "\r\n");
}
// We use '\u200b' (unicode zero-length space character) to break VS Code's URL detection regex for URLs that are examples. This process will
// convert that from the readable espace sequence, to just an invisible character. Convert it back to the visible espace sequence.
content = content.replace(/\u200b/gm, "\\u200b");
fs.writeFileSync('package.json', content);
}
generateOptionsSchema();
+566
View File
@@ -0,0 +1,566 @@
{
"_comment": "See README.md for information about this file",
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "VS Code launch/attach options",
"description": "A json schema for the VS Code attach and launch options",
"type": "object",
"definitions": {
"PipeTransport": {
"type": "object",
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).",
"default": {
"pipeCwd": "/usr/bin",
"pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'",
"pipeArgs": [],
"debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
},
"properties": {
"pipeCwd": {
"type": "string",
"description": "The fully qualified path to the working directory for the pipe program.",
"default": "/usr/bin"
},
"pipeProgram": {
"type": "string",
"description": "The fully qualified pipe command to execute.",
"default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'"
},
"pipeArgs": {
"type": "array",
"description": "Command line arguments passed to the pipe program to configure the connection.",
"items": {
"type": "string"
},
"default": []
},
"debuggerPath": {
"type": "string",
"description": "The full path to the debugger on the target machine, for example /usr/bin/gdb.",
"default": "The full path to the debugger on the target machine, for example /usr/bin/gdb."
},
"pipeEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Environment variables passed to the pipe program.",
"default": {}
}
}
},
"Logging": {
"type": "object",
"default": {},
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"properties": {
"exceptions": {
"type": "boolean",
"description": "Optional flag to determine whether exception messages should be logged to the Debug Console. Defaults to true.",
"default": true
},
"moduleLoad": {
"type": "boolean",
"description": "Optional flag to determine whether module load events should be logged to the Debug Console. Defaults to true.",
"default": true
},
"programOutput": {
"type": "boolean",
"description": "Optional flag to determine whether program output should be logged to the Debug Console. Defaults to true.",
"default": true
},
"engineLogging": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic engine logs should be logged to the Debug Console. Defaults to false.",
"default": false
},
"trace": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic adapter command tracing should be logged to the Debug Console. Defaults to false.",
"default": false
},
"traceResponse": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic adapter command and response tracing should be logged to the Debug Console. Defaults to false.",
"default": false
}
}
},
"SetupCommandsConfiguration": {
"type": "object",
"default": {},
"properties": {
"text": {
"type": "string",
"description": "The debugger command to execute.",
"default": ""
},
"description": {
"type": "string",
"description": "Optional description for the command.",
"default": ""
},
"ignoreFailures": {
"type": "boolean",
"description": "If true, failures from the command should be ignored. Default value is false.",
"default": false
}
}
},
"KeyValuePair": {
"type": "object",
"default": {},
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"CppdbgLaunchOptions": {
"type": "object",
"default": {},
"required": [
"program"
],
"properties": {
"program": {
"type": "string",
"description": "Full path to program executable.",
"default": "${workspaceRoot}/a.out"
},
"args": {
"type": "array",
"description": "Command line arguments passed to the program.",
"items": {
"type": "string"
},
"default": []
},
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppdbg\".",
"default": "cppdbg"
},
"targetArchitecture": {
"type": "string",
"description": "The architecture of the debuggee. This will automatically be detected unless this parameter is set. Allowed values are x86, arm, arm64, mips, x64, amd64, x86_64.",
"default": "x64"
},
"cwd": {
"type": "string",
"description": "The working directory of the target",
"default": "."
},
"setupCommands": {
"type": "array",
"description": "One or more GDB/LLDB commands to execute in order to setup the underlying debugger. Example: \"setupCommands\": [ { \"text\": \"-enable-pretty-printing\", \"description\": \"Enable GDB pretty printing\", \"ignoreFailures\": true }].",
"items": {
"$ref": "#/definitions/SetupCommandsConfiguration"
},
"default": []
},
"customLaunchSetupCommands": {
"type": "array",
"description": "If provided, this replaces the default commands used to launch a target with some other commands. For example, this can be \"-target-attach\" in order to attach to a target process. An empty command list replaces the launch commands with nothing, which can be useful if the debugger is being provided launch options as command line options. Example: \"customLaunchSetupCommands\": [ { \"text\": \"target-run\", \"description\": \"run target\", \"ignoreFailures\": false }].",
"items": {
"$ref": "#/definitions/SetupCommandsConfiguration"
},
"default": []
},
"launchCompleteCommand": {
"enum": [
"exec-run",
"exec-continue",
"None"
],
"description": "The command to execute after the debugger is fully setup in order to cause the target process to run. Allowed values are \"exec-run\", \"exec-continue\", \"None\". The default value is \"exec-run\".",
"default": "exec-run"
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process. This option is not compatible with GDB pretty printing. Please also see \"showDisplayString\" if using this setting.",
"default": ""
},
"showDisplayString": {
"type": "boolean",
"description": "When a visualizerFile is specified, showDisplayString will enable the display string. Turning this option on can cause slower performance during debugging.",
"default": true
},
"environment": {
"type": "array",
"description": "Environment variables to add to the environment for the program. Example: [ { \"name\": \"squid\", \"value\": \"clam\" } ].",
"items": {
"$ref": "#/definitions/KeyValuePair"
},
"default": []
},
"additionalSOLibSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for .so files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"MIMode": {
"type": "string",
"description": "Indicates the console debugger that the MIDebugEngine will connect to. Allowed values are \"gdb\" \"lldb\".",
"default": "gdb"
},
"miDebuggerPath": {
"type": "string",
"description": "The path to the mi debugger (such as gdb). When unspecified, it will search path first for the debugger.",
"default": "/usr/bin/gdb"
},
"miDebuggerArgs": {
"type": "string",
"description": "Arguments for the mi debugger (such as gdb) to use. When unspecified.",
"default": ""
},
"miDebuggerServerAddress": {
"type": "string",
"description": "Network address of the MI Debugger Server to connect to (example: localhost:1234).",
"default": "serveraddress:port"
},
"stopAtEntry": {
"type": "boolean",
"description": "Optional parameter. If true, the debugger should stop at the entrypoint of the target. If processId is passed, has no effect.",
"default": false
},
"debugServerPath": {
"type": "string",
"description": "Optional full path to debug server to launch. Defaults to null.",
"default": ""
},
"debugServerArgs": {
"type": "string",
"description": "Optional debug server args. Defaults to null.",
"default": ""
},
"serverStarted": {
"type": "string",
"description": "Optional server-started pattern to look for in the debug server output. Defaults to null.",
"default": ""
},
"filterStdout": {
"type": "boolean",
"description": "Search stdout stream for server-started pattern and log stdout to debug output. Defaults to true.",
"default": true
},
"filterStderr": {
"type": "boolean",
"description": "Search stderr stream for server-started pattern and log stderr to debug output. Defaults to false.",
"default": false
},
"serverLaunchTimeout": {
"type": "integer",
"description": "Optional time, in milliseconds, for the debugger to wait for the debugServer to start up. Default is 10000.",
"default": "10000"
},
"coreDumpPath": {
"type": "string",
"description": "Optional full path to a core dump file for the specified program. Defaults to null.",
"default": ""
},
"externalConsole": {
"type": "boolean",
"description": "If true, a console is launched for the debuggee. If false, on Linux and Windows, it will appear in the Integrated Console.",
"default": false
},
"avoidWindowsConsoleRedirection": {
"type": "boolean",
"description": "If true, disables debuggee console redirection that is required for Integrated Terminal support.",
"default": false
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"$ref": "#/definitions/Logging",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console."
},
"pipeTransport": {
"$ref": "#/definitions/PipeTransport",
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb)."
}
}
},
"CppdbgAttachOptions": {
"type": "object",
"default": {},
"required": [
"program",
"processId"
],
"properties": {
"program": {
"type": "string",
"description": "Full path to program executable.",
"default": "${workspaceRoot}/a.out"
},
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppdbg\".",
"default": "cppdbg"
},
"targetArchitecture": {
"type": "string",
"description": "The architecture of the debuggee. This will automatically be detected unless this parameter is set. Allowed values are x86, arm, arm64, mips, x64, amd64, x86_64.",
"default": "x64"
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process. This option is not compatible with GDB pretty printing. Please also see \"showDisplayString\" if using this setting.",
"default": ""
},
"showDisplayString": {
"type": "boolean",
"description": "When a visualizerFile is specified, showDisplayString will enable the display string. Turning this option on can cause slower performance during debugging.",
"default": true
},
"additionalSOLibSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for .so files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"MIMode": {
"type": "string",
"description": "Indicates the console debugger that the MIDebugEngine will connect to. Allowed values are \"gdb\" \"lldb\".",
"default": "gdb"
},
"miDebuggerPath": {
"type": "string",
"description": "The path to the mi debugger (such as gdb). When unspecified, it will search path first for the debugger.",
"default": "/usr/bin/gdb"
},
"miDebuggerServerAddress": {
"type": "string",
"description": "Network address of the MI Debugger Server to connect to (example: localhost:1234).",
"default": "serveraddress:port"
},
"processId": {
"anyOf": [
{
"type": "string",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": "${command:pickProcess}"
},
{
"type": "integer",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": 0
}
]
},
"filterStdout": {
"type": "boolean",
"description": "Search stdout stream for server-started pattern and log stdout to debug output. Defaults to true.",
"default": true
},
"filterStderr": {
"type": "boolean",
"description": "Search stderr stream for server-started pattern and log stderr to debug output. Defaults to false.",
"default": false
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"$ref": "#/definitions/Logging",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console."
},
"pipeTransport": {
"$ref": "#/definitions/PipeTransport",
"description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb)."
},
"setupCommands": {
"type": "array",
"description": "One or more GDB/LLDB commands to execute in order to setup the underlying debugger. Example: \"setupCommands\": [ { \"text\": \"-enable-pretty-printing\", \"description\": \"Enable GDB pretty printing\", \"ignoreFailures\": true }].",
"items": {
"$ref": "#/definitions/SetupCommandsConfiguration"
},
"default": []
}
}
},
"CppvsdbgLaunchOptions": {
"type": "object",
"default": {},
"required": [
"program",
"cwd"
],
"properties": {
"program": {
"type": "string",
"description": "Full path to program executable.",
"default": "${workspaceRoot}/program.exe"
},
"args": {
"type": "array",
"description": "Command line arguments passed to the program.",
"items": {
"type": "string"
},
"default": []
},
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppvsdbg\".",
"default": "cppvsdbg"
},
"cwd": {
"type": "string",
"description": "The working directory of the target.",
"default": "${workspaceRoot}"
},
"environment": {
"type": "array",
"description": "Environment variables to add to the environment for the program. Example: [ { \"name\": \"squid\", \"value\": \"clam\" } ].",
"items": {
"$ref": "#/definitions/KeyValuePair"
},
"default": []
},
"symbolSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for symbol (that is, pdb) files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"stopAtEntry": {
"type": "boolean",
"description": "Optional parameter. If true, the debugger should stop at the entrypoint of the target. If processId is passed, has no effect.",
"default": false
},
"dumpPath": {
"type": "string",
"description": "Optional full path to a dump file for the specified program. Example: \"c:\\temp\\app.dmp\". Defaults to null.",
"default": ""
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process.",
"default": ""
},
"externalConsole": {
"type": "boolean",
"description": "If true, a console is launched for the debuggee. If false, no console is launched.",
"default": false
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"default": {},
"properties": {
"exceptions": {
"type": "boolean",
"description": "Optional flag to determine whether exception messages should be logged to the Debug Console. Defaults to true.",
"default": true
},
"moduleLoad": {
"type": "boolean",
"description": "Optional flag to determine whether module load events should be logged to the Debug Console. Defaults to true.",
"default": true
},
"programOutput": {
"type": "boolean",
"description": "Optional flag to determine whether program output should be logged to the Debug Console. Defaults to true.",
"default": true
},
"engineLogging": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic debug engine messages should be logged to the Debug Console. Defaults to false.",
"default": false
}
}
}
}
},
"CppvsdbgAttachOptions": {
"type": "object",
"default": {},
"required": [
"processId"
],
"properties": {
"type": {
"type": "string",
"description": "The type of the engine. Must be \"cppvsdbg\".",
"default": "cppvsdbg"
},
"symbolSearchPath": {
"type": "string",
"description": "Semicolon separated list of directories to use to search for symbol (that is, pdb) files. Example: \"c:\\dir1;c:\\dir2\".",
"default": ""
},
"processId": {
"anyOf": [
{
"type": "string",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": "${command:pickProcess}"
},
{
"type": "integer",
"description": "Optional process id to attach the debugger to. Use \"${command:pickProcesss}\" to get a list of local running processes to attach to. Note that some platforms require administrator privileges in order to attach to a process.",
"default": 0
}
]
},
"visualizerFile": {
"type": "string",
"description": ".natvis file to be used when debugging this process.",
"default": ""
},
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"/original/source/path\":\"/current/source/path\" }'",
"default": {
"<source-path>": "<target-path>"
}
},
"logging": {
"type": "object",
"description": "Optional flags to determine what types of messages should be logged to the Debug Console.",
"default": {},
"properties": {
"exceptions": {
"type": "boolean",
"description": "Optional flag to determine whether exception messages should be logged to the Debug Console. Defaults to true.",
"default": true
},
"moduleLoad": {
"type": "boolean",
"description": "Optional flag to determine whether module load events should be logged to the Debug Console. Defaults to true.",
"default": true
},
"programOutput": {
"type": "boolean",
"description": "Optional flag to determine whether program output should be logged to the Debug Console. Defaults to true.",
"default": true
},
"trace": {
"type": "boolean",
"description": "Optional flag to determine whether diagnostic adapter command tracing should be logged to the Debug Console. Defaults to false.",
"default": false
}
}
}
}
}
}
}
+14
View File
@@ -0,0 +1,14 @@
# OptionsSchema
OptionsSchema.json defines the type for Launch/Attach options.
# GenerateOptionsSchema
If there are any modifications to the OptionsSchema.json file. Please run `npm run generateOptionsSchema` at the repo root.
This will call GenerateOptionsSchema and update the package.json file.
### Important notes:
1. Any manual changes to package.json's object.contributes.debuggers[0].configurationAttributes (cppdbg) or object.contributes.debuggers[0].configurationAttributes (cppvsdbg) will be
replaced by this generator.
If there is any other type of options added in the future, you will need to modify the GenerateOptionsSchema function
to have it appear in package.json. It only adds launch and attach.
+10 -1
View File
@@ -1,6 +1,11 @@
{
"rules": {
"curly": true,
"ext-variable-name": [
true,
["class", "pascal"],
["function", "camel"]
],
"file-header": [true, ".*"],
"indent": [true, "spaces", 4],
"new-parens": true,
@@ -18,5 +23,9 @@
"typedef": [true, "variable-declaration", "call-signature"],
"whitespace": [true, "check-branch", "check-operator", "check-separator", "check-preblock", "check-type"]
},
"rulesDirectory": ["node_modules/tslint-microsoft-contrib", "node_modules/tslint-no-unused-expression-chai/rules"]
"rulesDirectory": [
"node_modules/tslint-microsoft-contrib",
"node_modules/tslint-no-unused-expression-chai/rules",
"node_modules/vrsource-tslint-rules/rules"
]
}
-24
View File
@@ -1,24 +0,0 @@
<!--
If this is a performance issue report, please use the VS Code Issue reporter via command palette (f1 -> Help: Report Issue).
Set the field 'This is a' to be 'Performance Issue', the field 'File on' to be 'An Extension', and set 'Extension' to be 'C/C++'.
You may toggle off the data you wish to not send, but with more information we can help.
Fill out the title and steps to reproduce with as much info as you can.
Clicking on 'Preview on GitHub' will open up a webpage for you to submit your issue.
If this is a bug report, please give us as much information as possible so we can reproduce your issue.
Examples of information that can help us find and fix bugs:
* Operating System and version
* VS Code version and if you are using the Insiders build
* C/C++ extension version
* Other extensions you installed and if the issue persists after disabling them
* step-by-step instructions to reproduce the issue
* A small code sample, zipped up project, or open source repo we can use to verify the bug
* Relevant settings from your settings.json, c_cpp_properties.json, and/or launch.json files
* Any log messages present in the Output window (use "C_Cpp.loggingLevel": "Information" in settings.json)
* Debugger logs (use "logging": { "engineLogging": true } in your launch.json)
Please also take a look at our documentation, as we may already have answers for your questions:
* https://github.com/Microsoft/vscode-cpptools/tree/master/Documentation
Thank you!
-->
+1 -1
View File
@@ -16,7 +16,7 @@ You can learn how to use the extension at [VS Code for C/C++](https://code.visua
If you clone this repository, you can also try out our [Code Samples](Code%20Samples).
If you have any questions, check out our our [**Documentation**](Documentation) folder. If you do not find your answer there, feel free to ask it in our [issues page](https://github.com/Microsoft/vscode-cpptools/issues).
If you have any questions, check out our [**Documentation**](Documentation) folder. If you do not find your answer there, feel free to ask it in our [issues page](https://github.com/Microsoft/vscode-cpptools/issues).
### Contribution
+20 -12
View File
@@ -2,27 +2,32 @@
The **launch.json** file is used to configure the debugger in Visual Studio Code.
Visual Studio Code generates a **launch.json** with almost all of the required information. To get started
Visual Studio Code generates a **launch.json** with almost all of the required information. To get started
debugging you need to fill in the `program` field with the path to the executable you plan to debug. This must be specified for
both the launch and attach (if you plan to attach to a running instance at any point) configurations.
The generated file contains two sections. One that configures debugging for launch and a second that configures debugging for attach.
The generated file contains two sections. One that configures debugging for launch and a second that configures debugging for attach.
# Configure VS Code's debugging behavior
Set or change the following options to control VS Code's behavior during debugging
Set or change the following options to control VS Code's behavior during debugging:
* #### `program` (required)
Specifies the full path to executable the debugger will launch or attach to.
* #### `symbolSearchPath`
Tells the _Visual Studio Windows Debugger_ what paths to search for symbol (.pdb) files. Separate multiple paths with a semicolon. Example `"C:\\Symbols;C:\\SymbolDir2"`
Tells the _Visual Studio Windows Debugger_ what paths to search for symbol (.pdb) files. Separate multiple paths with a semicolon. Example `"C:\\Symbols;C:\\SymbolDir2"`.
* #### `additionalSOLibSearchPath`
Tells _GDB or LLDB_ what paths to search for .so files. Separate multiple paths with a semicolon. Example: `"/Users/user/dir1;/Users/user/dir2"`.
* #### `externalConsole`
If set to `true`, launches an external console for the application. If `false`, no console is launched and VS Code's debugging console is used. Note this option is ignored in some cases for technical reasons.
Windows: When set to true, it will spawn an external console. When set to false, it will use VS Code's integratedTerminal.
Linux: When set to true, it will notify VS Code to spawn an external console. When set to false, it will use VS Code's integratedTerminal.
macOS: When set to true, it will spawn an external console through `lldb-mi`. When set to false, the output can be seen in VS Code's debugConsole. Due to limitations within `lldb-mi`, integratedTerminal support is not available.
* #### `avoidWindowsConsoleRedirection`
In order to support VSCode's Integrated terminal with gdb on Windows, the extension adds console redirection commands to the debuggee's arguments to have console input and output show up in the integrated terminal. Setting this option to `true` will disable it.
* #### `logging`
Optional flags to determine what types of messages should be logged to the Debug Console.
@@ -73,7 +78,7 @@ The following options enable you to modify the state of the target application w
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.
Sets the working directory of the application launched by the debugger.
* #### `environment`
Environment variables to add to the environment for the program. Example: `[ { "name": "squid", "value": "clam" } ]`.
@@ -94,13 +99,16 @@ The following options enable you to modify the state of the target application w
## Customizing GDB or LLDB
You can change the behavior of GDB or LLDB by setting the following options.
You can change the behavior of GDB or LLDB by setting the following options:
* #### `MIMode`
Indicates the debugger that VS Code will connect to. Must be set to `gdb` or `lldb`. This is pre-configured on a per-operating system basis and can be changed as needed.
Indicates the debugger that VS Code will connect to. Must be set to `gdb` or `lldb`. This is pre-configured on a per-operating system basis and can be changed as needed.
* #### `miDebuggerPath`
The path to the debugger (such as gdb). When only the executable is specified, it will search the operating system's PATH variable for a debugger (GDB on Linux and Windows, LLDB on OS X).
* #### `miDebuggerArgs`
Additional arguments to pass to the debugger (such as gdb).
* #### `stopAtEntry`
If set to true, the debugger should stop at the entry-point of the target (ignored on attach). Default value is `false`.
@@ -149,7 +157,7 @@ The C/C++ extension enables debugging dump files on Windows and core dump files
If you want to debug a Windows dump file, set this to the path to the dump file to start debugging in the `launch` configuration.
* #### `coreDumpPath`
Full path to a core dump file to debug for the specified program. Set this to the path to the core dump file to start debugging in the `launch` configuration.
Full path to a core dump file to debug for the specified program. Set this to the path to the core dump file to start debugging in the `launch` configuration.
_Note: core dump debugging is not supported with MinGw._
## Remote debugging or debugging with a local debugger server
@@ -161,7 +169,7 @@ _Note: core dump debugging is not supported with MinGw._
Full path to debug server to launch.
* #### `debugServerArgs`
Arguments for the the debugger server.
Arguments for the debugger server.
* #### `serverStarted`
Server-started pattern to look for in the debug server output.
@@ -172,7 +180,7 @@ _Note: core dump debugging is not supported with MinGw._
## Additional properties
* #### `processId`
Defaults to `${command.pickProcess}` which will display a list of available processes the debugger can attach to. It is recommended to leave this default, but the property can be explicitly set to a specific process ID for the debugger to attach to.
Defaults to `${command.pickProcess}` which will display a list of available processes the debugger can attach to. It is recommended to leave this default, but the property can be explicitly set to a specific process ID for the debugger to attach to.
* #### `request`
Indicates whether the configuration section is intended to `launch` the program or `attach` to an already running instance.
@@ -181,7 +189,7 @@ _Note: core dump debugging is not supported with MinGw._
`Deprecated` This option is no longer needed as the target architecture is automatically detected.
* #### `type`
Indicates the underlying debugger being used. Must be `cppvsdbg` when using the Visual Studio Windows debugger, and `cppdbg` when using GDB or LLDB. This is automatically set to the correct value when the
Indicates the underlying debugger being used. Must be `cppvsdbg` when using the Visual Studio Windows debugger, and `cppdbg` when using GDB or LLDB. This is automatically set to the correct value when the
**launch.json** file is created.
* #### `sourceFileMap`