diff --git a/.github/classifier.yml b/.github/classifier.yml index 3236507a472..330cc3d0aa1 100644 --- a/.github/classifier.yml +++ b/.github/classifier.yml @@ -52,7 +52,7 @@ editor-symbols: [], editor-textbuffer: [], editor-wrapping: [], - emmet: [ octref, ramya-rao-a ], + emmet: [ octref ], error-list: [], explorer-custom: [], extension-host: [], @@ -63,7 +63,7 @@ assignLabel: false }, file-explorer: { - assignees: [ isidorn ], + assignees: [ ], assignLabel: false }, file-glob: [], diff --git a/.github/commands.yml b/.github/commands.yml index f20079caab8..c9279232529 100644 --- a/.github/commands.yml +++ b/.github/commands.yml @@ -105,7 +105,7 @@ { type: 'comment', name: 'a11ymas', - allowUsers: ['AccessibilityTestingTeam-TCS'], + allowUsers: ['AccessibilityTestingTeam-TCS', 'dixitsonali95', 'Mohini78', 'ChitrarupaSharma', 'mspatil110', 'umasarath52', 'v-umnaik'], action: 'updateLabels', addLabel: 'a11ymas' }, diff --git a/.gitignore b/.gitignore index 57bc86f3664..68834eb43ad 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,9 @@ out-vscode-min/ out-vscode-reh/ out-vscode-reh-min/ out-vscode-reh-pkg/ +out-vscode-web/ +out-vscode-web-min/ +out-vscode-web-pkg/ src/vs/server resources/server build/node_modules diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 55cfea092a6..b4336e7d127 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -4,6 +4,7 @@ "recommendations": [ "ms-vscode.vscode-typescript-tslint-plugin", "dbaeumer.vscode-eslint", + "EditorConfig.EditorConfig", "msjsdiag.debugger-for-chrome" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index af8b3803709..3fa04b1ee95 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -56,5 +56,8 @@ "url": "./.vscode/cglicenses.schema.json" } ], - "git.ignoreLimitWarning": true -} \ No newline at end of file + "git.ignoreLimitWarning": true, + "remote.extensionKind": { + "msjsdiag.debugger-for-chrome": "workspace" + } +} diff --git a/.yarnrc b/.yarnrc index 7e63643de04..441b5a2e69a 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,3 +1,3 @@ disturl "https://atom.io/download/electron" -target "4.2.3" +target "4.2.5" runtime "electron" diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index df0fad7f826..1d854430864 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -5,108 +5,70 @@ Do Not Translate or Localize This project incorporates components from the projects listed below. The original copyright notices and the licenses under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted herein, whether by implication, estoppel or otherwise. -1. atom/language-c version 0.58.1 (https://github.com/atom/language-c) -2. atom/language-clojure version 0.22.7 (https://github.com/atom/language-clojure) -3. atom/language-coffee-script version 0.49.3 (https://github.com/atom/language-coffee-script) -4. atom/language-java version 0.31.2 (https://github.com/atom/language-java) -5. atom/language-objective-c version 0.15.0 (https://github.com/atom/language-objective-c) -6. atom/language-sass version 0.61.4 (https://github.com/atom/language-sass) -7. atom/language-shellscript version 0.26.0 (https://github.com/atom/language-shellscript) -8. atom/language-xml version 0.35.2 (https://github.com/atom/language-xml) -9. Colorsublime-Themes version 0.1.0 (https://github.com/Colorsublime/Colorsublime-Themes) -10. daaain/Handlebars version 1.8.0 (https://github.com/daaain/Handlebars) -11. davidrios/pug-tmbundle (https://github.com/davidrios/pug-tmbundle) -12. definitelytyped (https://github.com/DefinitelyTyped/DefinitelyTyped) -13. demyte/language-cshtml version 0.3.0 (https://github.com/demyte/language-cshtml) -14. Document Object Model version 4.0.0 (https://www.w3.org/DOM/) -15. dotnet/csharp-tmLanguage version 0.1.0 (https://github.com/dotnet/csharp-tmLanguage) -16. expand-abbreviation version 0.5.8 (https://github.com/emmetio/expand-abbreviation) -17. fadeevab/make.tmbundle (https://github.com/fadeevab/make.tmbundle) -18. freebroccolo/atom-language-swift (https://github.com/freebroccolo/atom-language-swift) -19. HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/) -20. Ikuyadeu/vscode-R version 0.5.5 (https://github.com/Ikuyadeu/vscode-R) -21. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site) -22. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar) -23. jeff-hykin/cpp-textmate-grammar version 1.8.15 (https://github.com/jeff-hykin/cpp-textmate-grammar) -24. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify) -25. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert) -26. language-docker (https://github.com/moby/moby) -27. language-go version 0.44.3 (https://github.com/atom/language-go) -28. language-less version 0.34.2 (https://github.com/atom/language-less) -29. language-php version 0.44.1 (https://github.com/atom/language-php) -30. language-rust version 0.4.12 (https://github.com/zargony/atom-language-rust) -31. MagicStack/MagicPython version 1.1.1 (https://github.com/MagicStack/MagicPython) -32. marked version 0.6.2 (https://github.com/markedjs/marked) -33. mdn-data version 1.1.12 (https://github.com/mdn/data) -34. Microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/Microsoft/TypeScript-TmLanguage) -35. Microsoft/vscode-JSON.tmLanguage (https://github.com/Microsoft/vscode-JSON.tmLanguage) -36. Microsoft/vscode-mssql version 1.4.0 (https://github.com/Microsoft/vscode-mssql) -37. mmims/language-batchfile version 0.7.5 (https://github.com/mmims/language-batchfile) -38. octicons version 8.3.0 (https://github.com/primer/octicons) -39. octref/language-css version 0.42.11 (https://github.com/octref/language-css) -40. PowerShell/EditorSyntax (https://github.com/powershell/editorsyntax) -41. promise-polyfill version 8.0.0 (https://github.com/taylorhakes/promise-polyfill) -42. seti-ui version 0.1.0 (https://github.com/jesseweed/seti-ui) -43. shaders-tmLanguage version 0.1.0 (https://github.com/tgjones/shaders-tmLanguage) -44. textmate/asp.vb.net.tmbundle (https://github.com/textmate/asp.vb.net.tmbundle) -45. textmate/c.tmbundle (https://github.com/textmate/c.tmbundle) -46. textmate/diff.tmbundle (https://github.com/textmate/diff.tmbundle) -47. textmate/git.tmbundle (https://github.com/textmate/git.tmbundle) -48. textmate/groovy.tmbundle (https://github.com/textmate/groovy.tmbundle) -49. textmate/html.tmbundle (https://github.com/textmate/html.tmbundle) -50. textmate/ini.tmbundle (https://github.com/textmate/ini.tmbundle) -51. textmate/javascript.tmbundle (https://github.com/textmate/javascript.tmbundle) -52. textmate/lua.tmbundle (https://github.com/textmate/lua.tmbundle) -53. textmate/markdown.tmbundle (https://github.com/textmate/markdown.tmbundle) -54. textmate/perl.tmbundle (https://github.com/textmate/perl.tmbundle) -55. textmate/ruby.tmbundle (https://github.com/textmate/ruby.tmbundle) -56. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle) -57. TypeScript-TmLanguage version 0.1.8 (https://github.com/Microsoft/TypeScript-TmLanguage) -58. TypeScript-TmLanguage version 1.0.0 (https://github.com/Microsoft/TypeScript-TmLanguage) -59. Unicode version 12.0.0 (http://www.unicode.org/) -60. vscode-logfile-highlighter version 2.4.1 (https://github.com/emilast/vscode-logfile-highlighter) -61. vscode-octicons-font version 1.3.0 (https://github.com/Microsoft/vscode-octicons-font) -62. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift) -63. Web Background Synchronization (https://github.com/WICG/BackgroundSync) +1. atom/language-clojure version 0.22.7 (https://github.com/atom/language-clojure) +2. atom/language-coffee-script version 0.49.3 (https://github.com/atom/language-coffee-script) +3. atom/language-java version 0.31.2 (https://github.com/atom/language-java) +4. atom/language-sass version 0.61.4 (https://github.com/atom/language-sass) +5. atom/language-shellscript version 0.26.0 (https://github.com/atom/language-shellscript) +6. atom/language-xml version 0.35.2 (https://github.com/atom/language-xml) +7. Colorsublime-Themes version 0.1.0 (https://github.com/Colorsublime/Colorsublime-Themes) +8. daaain/Handlebars version 1.8.0 (https://github.com/daaain/Handlebars) +9. davidrios/pug-tmbundle (https://github.com/davidrios/pug-tmbundle) +10. definitelytyped (https://github.com/DefinitelyTyped/DefinitelyTyped) +11. demyte/language-cshtml version 0.3.0 (https://github.com/demyte/language-cshtml) +12. Document Object Model version 4.0.0 (https://www.w3.org/DOM/) +13. dotnet/csharp-tmLanguage version 0.1.0 (https://github.com/dotnet/csharp-tmLanguage) +14. expand-abbreviation version 0.5.8 (https://github.com/emmetio/expand-abbreviation) +15. fadeevab/make.tmbundle (https://github.com/fadeevab/make.tmbundle) +16. freebroccolo/atom-language-swift (https://github.com/freebroccolo/atom-language-swift) +17. HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/) +18. Ikuyadeu/vscode-R version 0.5.5 (https://github.com/Ikuyadeu/vscode-R) +19. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site) +20. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar) +21. jeff-hykin/cpp-textmate-grammar version 1.11.0 (https://github.com/jeff-hykin/cpp-textmate-grammar) +22. jeff-hykin/cpp-textmate-grammar version 1.11.7 (https://github.com/jeff-hykin/cpp-textmate-grammar) +23. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify) +24. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert) +25. language-docker (https://github.com/moby/moby) +26. language-go version 0.44.3 (https://github.com/atom/language-go) +27. language-less version 0.34.2 (https://github.com/atom/language-less) +28. language-php version 0.44.1 (https://github.com/atom/language-php) +29. language-rust version 0.4.12 (https://github.com/zargony/atom-language-rust) +30. MagicStack/MagicPython version 1.1.1 (https://github.com/MagicStack/MagicPython) +31. marked version 0.6.2 (https://github.com/markedjs/marked) +32. mdn-data version 1.1.12 (https://github.com/mdn/data) +33. Microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/Microsoft/TypeScript-TmLanguage) +34. Microsoft/vscode-JSON.tmLanguage (https://github.com/Microsoft/vscode-JSON.tmLanguage) +35. Microsoft/vscode-mssql version 1.4.0 (https://github.com/Microsoft/vscode-mssql) +36. mmims/language-batchfile version 0.7.5 (https://github.com/mmims/language-batchfile) +37. octicons version 8.3.0 (https://github.com/primer/octicons) +38. octref/language-css version 0.42.11 (https://github.com/octref/language-css) +39. PowerShell/EditorSyntax (https://github.com/powershell/editorsyntax) +40. promise-polyfill version 8.0.0 (https://github.com/taylorhakes/promise-polyfill) +41. seti-ui version 0.1.0 (https://github.com/jesseweed/seti-ui) +42. shaders-tmLanguage version 0.1.0 (https://github.com/tgjones/shaders-tmLanguage) +43. textmate/asp.vb.net.tmbundle (https://github.com/textmate/asp.vb.net.tmbundle) +44. textmate/c.tmbundle (https://github.com/textmate/c.tmbundle) +45. textmate/diff.tmbundle (https://github.com/textmate/diff.tmbundle) +46. textmate/git.tmbundle (https://github.com/textmate/git.tmbundle) +47. textmate/groovy.tmbundle (https://github.com/textmate/groovy.tmbundle) +48. textmate/html.tmbundle (https://github.com/textmate/html.tmbundle) +49. textmate/ini.tmbundle (https://github.com/textmate/ini.tmbundle) +50. textmate/javascript.tmbundle (https://github.com/textmate/javascript.tmbundle) +51. textmate/lua.tmbundle (https://github.com/textmate/lua.tmbundle) +52. textmate/markdown.tmbundle (https://github.com/textmate/markdown.tmbundle) +53. textmate/perl.tmbundle (https://github.com/textmate/perl.tmbundle) +54. textmate/ruby.tmbundle (https://github.com/textmate/ruby.tmbundle) +55. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle) +56. TypeScript-TmLanguage version 0.1.8 (https://github.com/Microsoft/TypeScript-TmLanguage) +57. TypeScript-TmLanguage version 1.0.0 (https://github.com/Microsoft/TypeScript-TmLanguage) +58. Unicode version 12.0.0 (http://www.unicode.org/) +59. vscode-logfile-highlighter version 2.4.1 (https://github.com/emilast/vscode-logfile-highlighter) +60. vscode-octicons-font version 1.3.1 (https://github.com/Microsoft/vscode-octicons-font) +61. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift) +62. Web Background Synchronization (https://github.com/WICG/BackgroundSync) -%% atom/language-c NOTICES AND INFORMATION BEGIN HERE -========================================= -The MIT License (MIT) - -Copyright (c) 2014 GitHub Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -This package was derived from a TextMate bundle located at -https://github.com/textmate/c.tmbundle and distributed under the following -license, located in `README.mdown`: - -Permission to copy, use, modify, sell and distribute this -software is granted. This software is provided "as is" without -express or implied warranty, and with no claim as to its -suitability for any purpose. -========================================= -END OF atom/language-c NOTICES AND INFORMATION - %% atom/language-clojure NOTICES AND INFORMATION BEGIN HERE ========================================= Copyright (c) 2014 GitHub Inc. @@ -251,43 +213,6 @@ suitability for any purpose. ========================================= END OF atom/language-java NOTICES AND INFORMATION -%% atom/language-objective-c NOTICES AND INFORMATION BEGIN HERE -========================================= -The MIT License (MIT) - -Copyright (c) 2014 GitHub Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -This package was derived from a TextMate bundle located at -https://github.com/textmate/objective-c.tmbundle and distributed under the following -license, located in `README.mdown`: - -Permission to copy, use, modify, sell and distribute this -software is granted. This software is provided "as is" without -express or implied warranty, and with no claim as to its -suitability for any purpose. -========================================= -END OF atom/language-objective-c NOTICES AND INFORMATION - %% atom/language-sass NOTICES AND INFORMATION BEGIN HERE ========================================= The MIT License (MIT) diff --git a/build/.cachesalt b/build/.cachesalt new file mode 100644 index 00000000000..56a6051ca2b --- /dev/null +++ b/build/.cachesalt @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/build/.nativeignore b/build/.nativeignore index 132cb1baeb8..a4823bf719c 100644 --- a/build/.nativeignore +++ b/build/.nativeignore @@ -67,14 +67,6 @@ windows-process-tree/build/** windows-process-tree/src/** !windows-process-tree/**/*.node -gc-signals/binding.gyp -gc-signals/build/** -gc-signals/src/** -gc-signals/deps/** - -!gc-signals/build/Release/*.node -!gc-signals/src/index.js - keytar/binding.gyp keytar/build/** keytar/src/** @@ -91,25 +83,25 @@ node-pty/deps/** !node-pty/build/Release/*.dll !node-pty/build/Release/*.node -vscode-nsfw/binding.gyp -vscode-nsfw/build/** -vscode-nsfw/src/** -vscode-nsfw/openpa/** -vscode-nsfw/includes/** -!vscode-nsfw/build/Release/*.node -!vscode-nsfw/**/*.a +nsfw/binding.gyp +nsfw/build/** +nsfw/src/** +nsfw/openpa/** +nsfw/includes/** +!nsfw/build/Release/*.node +!nsfw/**/*.a +vsda/build/** +vsda/ci/** +vsda/src/** +vsda/.gitignore vsda/binding.gyp vsda/README.md -vsda/build/** -vsda/*.bat -vsda/*.sh -vsda/*.cpp -vsda/*.h +vsda/targets !vsda/build/Release/vsda.node vscode-windows-ca-certs/**/* !vscode-windows-ca-certs/package.json !vscode-windows-ca-certs/**/*.node -node-addon-api/**/* \ No newline at end of file +node-addon-api/**/* diff --git a/build/azure-pipelines/common/extract-telemetry.sh b/build/azure-pipelines/common/extract-telemetry.sh new file mode 100755 index 00000000000..916c87c82ce --- /dev/null +++ b/build/azure-pipelines/common/extract-telemetry.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -e + +cd $BUILD_STAGINGDIRECTORY +git clone https://github.com/microsoft/vscode-telemetry-extractor.git +cd vscode-telemetry-extractor +git checkout 4e64f3de30f8fccb58ebdc0d85c4861a135d46cf +npm i +npm run compile +cd src +mkdir telemetry-sources +cd telemetry-sources +git clone --depth 1 https://github.com/Microsoft/vscode-extension-telemetry.git +git clone --depth 1 https://github.com/Microsoft/vscode-chrome-debug-core.git +git clone --depth 1 https://github.com/Microsoft/vscode-chrome-debug.git +git clone --depth 1 https://github.com/Microsoft/vscode-node-debug2.git +git clone --depth 1 https://github.com/Microsoft/vscode-node-debug.git +git clone --depth 1 https://github.com/Microsoft/vscode-docker.git +git clone --depth 1 https://github.com/Microsoft/vscode-go.git +git clone --depth 1 https://github.com/Microsoft/vscode-azure-account.git +git clone --depth 1 https://github.com/Microsoft/vscode-html-languageservice.git +git clone --depth 1 https://github.com/Microsoft/vscode-json-languageservice.git +git clone --depth 1 https://github.com/Microsoft/vscode-mono-debug.git +git clone --depth 1 https://github.com/Microsoft/TypeScript.git +cd ../../ +node ./out/cli-extract.js --sourceDir $BUILD_SOURCESDIRECTORY --excludedDirPattern extensions --outputDir . --applyEndpoints --includeIsMeasurement +node ./out/cli-extract-extensions.js --sourceDir ./src/telemetry-sources --outputDir . --applyEndpoints --includeIsMeasurement +mkdir -p $BUILD_SOURCESDIRECTORY/.build/telemetry +mv declarations-resolved.json $BUILD_SOURCESDIRECTORY/.build/telemetry/telemetry-core.json +mv declarations-extensions-resolved.json $BUILD_SOURCESDIRECTORY/.build/telemetry/telemetry-extensions.json \ No newline at end of file diff --git a/build/azure-pipelines/common/installDistroDependencies.ts b/build/azure-pipelines/common/installDistroDependencies.ts deleted file mode 100644 index a0dd3a295db..00000000000 --- a/build/azure-pipelines/common/installDistroDependencies.ts +++ /dev/null @@ -1,38 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as cp from 'child_process'; -import * as path from 'path'; -import * as fs from 'fs'; - -function yarnInstall(packageName: string, cwd: string): void { - console.log(`yarn add --no-lockfile ${packageName}`, cwd); - cp.execSync(`yarn add --no-lockfile ${packageName}`, { cwd, stdio: 'inherit' }); -} - -/** - * Install additional dependencies listed on each quality `package.json` file. - */ -function main() { - const quality = process.env['VSCODE_QUALITY']; - - if (!quality) { - throw new Error('Missing VSCODE_QUALITY, can\'t install distro'); - } - - const rootPath = path.dirname(path.dirname(path.dirname(__dirname))); - const qualityPath = path.join(rootPath, 'quality', quality); - const packagePath = path.join(qualityPath, 'package.json'); - const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8')); - const dependencies = pkg.dependencies || {} as { [name: string]: string; }; - - Object.keys(dependencies).forEach(name => { - const url = dependencies[name]; - const cwd = process.argv.length < 3 ? process.cwd() : path.join(process.cwd(), process.argv[2]); - yarnInstall(url, cwd); - }); -} - -main(); \ No newline at end of file diff --git a/build/azure-pipelines/common/publish.ts b/build/azure-pipelines/common/publish.ts index 724939da318..62113c8f3b3 100644 --- a/build/azure-pipelines/common/publish.ts +++ b/build/azure-pipelines/common/publish.ts @@ -151,13 +151,6 @@ async function publish(commit: string, quality: string, platform: string, type: const queuedBy = process.env['BUILD_QUEUEDBY']!; const sourceBranch = process.env['BUILD_SOURCEBRANCH']!; - const isReleased = ( - // Insiders: nightly build from master - (quality === 'insider' && /^master$|^refs\/heads\/master$/.test(sourceBranch) && /Project Collection Service Accounts|Microsoft.VisualStudio.Services.TFS/.test(queuedBy)) || - - // Exploration: any build from electron-4.0.x branch - (quality === 'exploration' && /^electron-4.0.x$|^refs\/heads\/electron-4.0.x$/.test(sourceBranch)) - ); console.log('Publishing...'); console.log('Quality:', quality); @@ -167,7 +160,6 @@ async function publish(commit: string, quality: string, platform: string, type: console.log('Version:', version); console.log('Commit:', commit); console.log('Is Update:', isUpdate); - console.log('Is Released:', isReleased); console.log('File:', file); const stat = await new Promise((c, e) => fs.stat(file, (err, stat) => err ? e(err) : c(stat))); @@ -226,7 +218,7 @@ async function publish(commit: string, quality: string, platform: string, type: id: commit, timestamp: (new Date()).getTime(), version, - isReleased: config.frozen ? false : isReleased, + isReleased: false, sourceBranch, queuedBy, assets: [] as Array, @@ -245,11 +237,6 @@ async function publish(commit: string, quality: string, platform: string, type: } function main(): void { - if (process.env['VSCODE_BUILD_SKIP_PUBLISH']) { - console.warn('Skipping publish due to VSCODE_BUILD_SKIP_PUBLISH'); - return; - } - const commit = process.env['BUILD_SOURCEVERSION']; if (!commit) { diff --git a/build/azure-pipelines/common/release.ts b/build/azure-pipelines/common/release.ts new file mode 100644 index 00000000000..1220bd62e68 --- /dev/null +++ b/build/azure-pipelines/common/release.ts @@ -0,0 +1,109 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { DocumentClient } from 'documentdb'; + +interface Config { + id: string; + frozen: boolean; +} + +function createDefaultConfig(quality: string): Config { + return { + id: quality, + frozen: false + }; +} + +function getConfig(quality: string): Promise { + const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT']!, { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] }); + const collection = 'dbs/builds/colls/config'; + const query = { + query: `SELECT TOP 1 * FROM c WHERE c.id = @quality`, + parameters: [ + { name: '@quality', value: quality } + ] + }; + + return new Promise((c, e) => { + client.queryDocuments(collection, query).toArray((err, results) => { + if (err && err.code !== 409) { return e(err); } + + c(!results || results.length === 0 ? createDefaultConfig(quality) : results[0] as any as Config); + }); + }); +} + +function doRelease(commit: string, quality: string): Promise { + const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT']!, { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] }); + const collection = 'dbs/builds/colls/' + quality; + const query = { + query: 'SELECT TOP 1 * FROM c WHERE c.id = @id', + parameters: [{ name: '@id', value: commit }] + }; + + let updateTries = 0; + + function update(): Promise { + updateTries++; + + return new Promise((c, e) => { + client.queryDocuments(collection, query).toArray((err, results) => { + if (err) { return e(err); } + if (results.length !== 1) { return e(new Error('No documents')); } + + const release = results[0]; + release.isReleased = true; + + client.replaceDocument(release._self, release, err => { + if (err && err.code === 409 && updateTries < 5) { return c(update()); } + if (err) { return e(err); } + + console.log('Build successfully updated.'); + c(); + }); + }); + }); + } + + return update(); +} + +async function release(commit: string, quality: string): Promise { + const config = await getConfig(quality); + + console.log('Quality config:', config); + + if (config.frozen) { + console.log(`Skipping release because quality ${quality} is frozen.`); + return; + } + + await doRelease(commit, quality); +} + +function env(name: string): string { + const result = process.env[name]; + + if (!result) { + throw new Error(`Skipping release due to missing env: ${name}`); + } + + return result; +} + +async function main(): Promise { + const commit = env('BUILD_SOURCEVERSION'); + const quality = env('VSCODE_QUALITY'); + + await release(commit, quality); +} + +main().catch(err => { + console.error(err); + process.exit(1); +}); diff --git a/build/azure-pipelines/common/symbols.ts b/build/azure-pipelines/common/symbols.ts index a42342ce7f7..153be4f25b1 100644 --- a/build/azure-pipelines/common/symbols.ts +++ b/build/azure-pipelines/common/symbols.ts @@ -146,6 +146,10 @@ async function ensureVersionAndSymbols(options: IOptions) { // Check version does not exist console.log(`HockeyApp: checking for existing version ${options.versions.code} (${options.platform})`); const versions = await getVersions({ accessToken: options.access.hockeyAppToken, appId: options.access.hockeyAppId }); + if (!Array.isArray(versions.app_versions)) { + throw new Error(`Unexpected response: ${JSON.stringify(versions)}`); + } + if (versions.app_versions.some(v => v.version === options.versions.code)) { console.log(`HockeyApp: Returning without uploading symbols because version ${options.versions.code} (${options.platform}) was already found`); return; @@ -184,6 +188,10 @@ const hockeyAppToken = process.argv[3]; const is64 = process.argv[4] === 'x64'; const hockeyAppId = process.argv[5]; +if (process.argv.length !== 6) { + throw new Error(`HockeyApp: Unexpected number of arguments. Got ${process.argv}`); +} + let platform: Platform; if (process.platform === 'darwin') { platform = Platform.MAC_OS; @@ -211,7 +219,9 @@ if (repository && codeVersion && electronVersion && (product.quality === 'stable }).then(() => { console.log('HockeyApp: done'); }).catch(error => { - console.error(`HockeyApp: error (${error})`); + console.error(`HockeyApp: error ${error} (AppID: ${hockeyAppId})`); + + return process.exit(1); }); } else { console.log(`HockeyApp: skipping due to unexpected context (repository: ${repository}, codeVersion: ${codeVersion}, electronVersion: ${electronVersion}, quality: ${product.quality})`); diff --git a/build/azure-pipelines/common/sync-mooncake.ts b/build/azure-pipelines/common/sync-mooncake.ts index af0db530683..1eac8f34e92 100644 --- a/build/azure-pipelines/common/sync-mooncake.ts +++ b/build/azure-pipelines/common/sync-mooncake.ts @@ -153,11 +153,6 @@ async function sync(commit: string, quality: string): Promise { } function main(): void { - if (process.env['VSCODE_BUILD_SKIP_PUBLISH']) { - error('Skipping publish due to VSCODE_BUILD_SKIP_PUBLISH'); - return; - } - const commit = process.env['BUILD_SOURCEVERSION']; if (!commit) { diff --git a/build/azure-pipelines/darwin/build.sh b/build/azure-pipelines/darwin/build.sh deleted file mode 100755 index a47546249fc..00000000000 --- a/build/azure-pipelines/darwin/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -set -e -yarn gulp vscode-darwin-min -yarn gulp vscode-reh-darwin-min -yarn gulp upload-vscode-sourcemaps \ No newline at end of file diff --git a/build/azure-pipelines/darwin/continuous-build-darwin.yml b/build/azure-pipelines/darwin/continuous-build-darwin.yml index 776c1172bea..018719423fe 100644 --- a/build/azure-pipelines/darwin/continuous-build-darwin.yml +++ b/build/azure-pipelines/darwin/continuous-build-darwin.yml @@ -4,19 +4,19 @@ steps: versionSpec: "10.15.1" - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + keyfile: '.yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' targetfolder: '**/node_modules, !**/node_modules/**/node_modules' vstsFeed: '$(ArtifactFeed)' - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: versionSpec: "1.10.1" - script: | - yarn + yarn --frozen-lockfile displayName: Install Dependencies - condition: ne(variables['CacheRestored'], 'true') + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 inputs: - keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + keyfile: '.yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' targetfolder: '**/node_modules, !**/node_modules/**/node_modules' vstsFeed: '$(ArtifactFeed)' condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index f136f2b4496..d8b2c009c4a 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -1,4 +1,23 @@ steps: +- script: | + mkdir -p .build + echo -n $BUILD_SOURCEVERSION > .build/commit + displayName: Prepare cache flag + +- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 + inputs: + keyfile: '.build/commit' + targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + vstsFeed: 'npm-vscode' + platformIndependent: true + alias: 'Compilation' + +- script: | + set -e + exit 1 + displayName: Check RestoreCache + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + - task: NodeTool@0 inputs: versionSpec: "10.15.1" @@ -17,8 +36,6 @@ steps: set -e cat << EOF > ~/.netrc - machine monacotools.visualstudio.com - password $(devops-pat) machine github.com login vscode password $(github-distro-mixin-password) @@ -26,24 +43,55 @@ steps: git config user.email "vscode@microsoft.com" git config user.name "VSCode" + displayName: Prepare tooling + +- script: | + set -e git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" git fetch distro git merge $(node -p "require('./package.json').distro") + displayName: Merge distro - yarn - yarn gulp mixin - yarn gulp hygiene - yarn monaco-compile-check - node build/azure-pipelines/common/installDistroDependencies.js - node build/azure-pipelines/common/installDistroDependencies.js remote - node build/lib/builtInExtensions.js - displayName: Prepare build +- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 + inputs: + keyfile: 'build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + targetfolder: '**/node_modules, !**/node_modules/**/node_modules' + vstsFeed: 'npm-vscode' + +- script: | + set -e + CHILD_CONCURRENCY=1 yarn --frozen-lockfile + displayName: Install dependencies + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) + +- task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 + inputs: + keyfile: 'build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + targetfolder: '**/node_modules, !**/node_modules/**/node_modules' + vstsFeed: 'npm-vscode' + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) + +- script: | + set -e + yarn postinstall + displayName: Run postinstall scripts + condition: and(succeeded(), eq(variables['CacheRestored'], 'true')) + +- script: | + set -e + node build/azure-pipelines/mixin + displayName: Mix in quality - script: | set -e VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-darwin-min-ci + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-reh-darwin-min-ci + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-web-darwin-min-ci AZURE_STORAGE_ACCESS_KEY="$(ticino-storage-key)" \ - ./build/azure-pipelines/darwin/build.sh + yarn gulp upload-vscode-sourcemaps displayName: Build - script: | @@ -52,11 +100,13 @@ steps: # APP_NAME="`ls $(agent.builddirectory)/VSCode-darwin | head -n 1`" # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-darwin/$APP_NAME" displayName: Run unit tests + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e ./scripts/test-integration.sh --build --tfs "Integration Tests" displayName: Run integration tests + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e diff --git a/build/azure-pipelines/distro-build.yml b/build/azure-pipelines/distro-build.yml index 639456ad4ce..4057894f025 100644 --- a/build/azure-pipelines/distro-build.yml +++ b/build/azure-pipelines/distro-build.yml @@ -30,7 +30,13 @@ steps: git remote add distro "https://github.com/$VSCODE_MIXIN_REPO.git" git fetch distro - git push distro origin/master:refs/heads/master + + # Push master branch into master and oss/master + git push distro origin/master:refs/heads/master origin/master:refs/heads/oss/master + + # Push every release branch into oss/release + git for-each-ref --format="%(refname:short)" refs/remotes/origin/release/* | sed 's/^origin\/\(.*\)$/\0:refs\/heads\/oss\/\1/' | xargs git push distro + git merge $(node -p "require('./package.json').distro") displayName: Sync & Merge Distro \ No newline at end of file diff --git a/build/azure-pipelines/linux/build.sh b/build/azure-pipelines/linux/build.sh deleted file mode 100755 index 1c79d764862..00000000000 --- a/build/azure-pipelines/linux/build.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -set -e -yarn gulp "vscode-linux-$VSCODE_ARCH-min" - -if [[ "$VSCODE_ARCH" != "ia32" ]]; then - yarn gulp vscode-reh-linux-$VSCODE_ARCH-min -fi \ No newline at end of file diff --git a/build/azure-pipelines/linux/continuous-build-linux.yml b/build/azure-pipelines/linux/continuous-build-linux.yml index ee47a8d4320..6f3008f73d2 100644 --- a/build/azure-pipelines/linux/continuous-build-linux.yml +++ b/build/azure-pipelines/linux/continuous-build-linux.yml @@ -12,19 +12,19 @@ steps: versionSpec: "10.15.1" - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + keyfile: '.yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' targetfolder: '**/node_modules, !**/node_modules/**/node_modules' vstsFeed: '$(ArtifactFeed)' - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 inputs: versionSpec: "1.10.1" - script: | - yarn + yarn --frozen-lockfile displayName: Install Dependencies - condition: ne(variables['CacheRestored'], 'true') + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 inputs: - keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + keyfile: '.yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' targetfolder: '**/node_modules, !**/node_modules/**/node_modules' vstsFeed: '$(ArtifactFeed)' condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) diff --git a/build/azure-pipelines/linux/build-arm.sh b/build/azure-pipelines/linux/multiarch/alpine/build.sh similarity index 100% rename from build/azure-pipelines/linux/build-arm.sh rename to build/azure-pipelines/linux/multiarch/alpine/build.sh diff --git a/build/azure-pipelines/linux/prebuild-arm.sh b/build/azure-pipelines/linux/multiarch/alpine/prebuild.sh similarity index 100% rename from build/azure-pipelines/linux/prebuild-arm.sh rename to build/azure-pipelines/linux/multiarch/alpine/prebuild.sh diff --git a/build/azure-pipelines/linux/publish-arm.sh b/build/azure-pipelines/linux/multiarch/alpine/publish.sh similarity index 100% rename from build/azure-pipelines/linux/publish-arm.sh rename to build/azure-pipelines/linux/multiarch/alpine/publish.sh diff --git a/build/azure-pipelines/linux/multiarch/armhf/build.sh b/build/azure-pipelines/linux/multiarch/armhf/build.sh new file mode 100755 index 00000000000..4f01bc9a7e5 --- /dev/null +++ b/build/azure-pipelines/linux/multiarch/armhf/build.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -e +echo 'noop' \ No newline at end of file diff --git a/build/azure-pipelines/linux/multiarch/armhf/prebuild.sh b/build/azure-pipelines/linux/multiarch/armhf/prebuild.sh new file mode 100755 index 00000000000..4f01bc9a7e5 --- /dev/null +++ b/build/azure-pipelines/linux/multiarch/armhf/prebuild.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -e +echo 'noop' \ No newline at end of file diff --git a/build/azure-pipelines/linux/multiarch/armhf/publish.sh b/build/azure-pipelines/linux/multiarch/armhf/publish.sh new file mode 100755 index 00000000000..4f01bc9a7e5 --- /dev/null +++ b/build/azure-pipelines/linux/multiarch/armhf/publish.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -e +echo 'noop' \ No newline at end of file diff --git a/build/azure-pipelines/linux/product-build-linux-arm.yml b/build/azure-pipelines/linux/product-build-linux-arm.yml deleted file mode 100644 index 55350cce295..00000000000 --- a/build/azure-pipelines/linux/product-build-linux-arm.yml +++ /dev/null @@ -1,65 +0,0 @@ -steps: -- task: NodeTool@0 - inputs: - versionSpec: "10.15.1" - -- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 - inputs: - versionSpec: "1.10.1" - -- task: AzureKeyVault@1 - displayName: 'Azure Key Vault: Get Secrets' - inputs: - azureSubscription: 'vscode-builds-subscription' - KeyVaultName: vscode - -- task: Docker@1 - displayName: 'Pull image' - inputs: - azureSubscriptionEndpoint: 'vscode-builds-subscription' - azureContainerRegistry: vscodehub.azurecr.io - command: 'Run an image' - imageName: 'vscode-linux-build-agent:armhf' - containerCommand: uname - -- script: | - set -e - - cat << EOF > ~/.netrc - machine monacotools.visualstudio.com - password $(devops-pat) - machine github.com - login vscode - password $(github-distro-mixin-password) - EOF - - git config user.email "vscode@microsoft.com" - git config user.name "VSCode" - git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" - git fetch distro - git merge $(node -p "require('./package.json').distro") - - CHILD_CONCURRENCY=1 yarn - yarn gulp mixin - yarn gulp hygiene - yarn monaco-compile-check - ./build/azure-pipelines/linux/prebuild-arm.sh - displayName: Prepare build - -- script: | - set -e - ./build/azure-pipelines/linux/build-arm.sh - displayName: Build - -- script: | - set -e - AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ - AZURE_STORAGE_ACCESS_KEY_2="$(vscode-storage-key)" \ - VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - VSCODE_HOCKEYAPP_TOKEN="$(vscode-hockeyapp-token)" \ - ./build/azure-pipelines/linux/publish-arm.sh - displayName: Publish - -- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - continueOnError: true \ No newline at end of file diff --git a/build/azure-pipelines/linux/product-build-linux-multiarch.yml b/build/azure-pipelines/linux/product-build-linux-multiarch.yml new file mode 100644 index 00000000000..c4e1e05e502 --- /dev/null +++ b/build/azure-pipelines/linux/product-build-linux-multiarch.yml @@ -0,0 +1,115 @@ +steps: +- script: | + mkdir -p .build + echo -n $BUILD_SOURCEVERSION > .build/commit + displayName: Prepare cache flag + +- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 + inputs: + keyfile: '.build/commit' + targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + vstsFeed: 'npm-vscode' + platformIndependent: true + alias: 'Compilation' + +- script: | + set -e + exit 1 + displayName: Check RestoreCache + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + +- task: NodeTool@0 + inputs: + versionSpec: "10.15.1" + +- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 + inputs: + versionSpec: "1.10.1" + +- task: AzureKeyVault@1 + displayName: 'Azure Key Vault: Get Secrets' + inputs: + azureSubscription: 'vscode-builds-subscription' + KeyVaultName: vscode + +- task: Docker@1 + displayName: 'Pull image' + inputs: + azureSubscriptionEndpoint: 'vscode-builds-subscription' + azureContainerRegistry: vscodehub.azurecr.io + command: 'Run an image' + imageName: 'vscode-linux-build-agent:$(VSCODE_ARCH)' + containerCommand: uname + +- script: | + set -e + + cat << EOF > ~/.netrc + machine github.com + login vscode + password $(github-distro-mixin-password) + EOF + + git config user.email "vscode@microsoft.com" + git config user.name "VSCode" + displayName: Prepare tooling + +- script: | + set -e + git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" + git fetch distro + git merge $(node -p "require('./package.json').distro") + displayName: Merge distro + +- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 + inputs: + keyfile: 'build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + targetfolder: '**/node_modules, !**/node_modules/**/node_modules' + vstsFeed: 'npm-vscode' + +- script: | + set -e + CHILD_CONCURRENCY=1 yarn --frozen-lockfile + displayName: Install dependencies + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) + +- task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 + inputs: + keyfile: 'build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + targetfolder: '**/node_modules, !**/node_modules/**/node_modules' + vstsFeed: 'npm-vscode' + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) + +- script: | + set -e + yarn postinstall + displayName: Run postinstall scripts + condition: and(succeeded(), eq(variables['CacheRestored'], 'true')) + +- script: | + set -e + node build/azure-pipelines/mixin + displayName: Mix in quality + +- script: | + set -e + CHILD_CONCURRENCY=1 ./build/azure-pipelines/linux/multiarch/$(VSCODE_ARCH)/prebuild.sh + displayName: Prebuild + +- script: | + set -e + ./build/azure-pipelines/linux/multiarch/$(VSCODE_ARCH)/build.sh + displayName: Build + +- script: | + set -e + AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ + AZURE_STORAGE_ACCESS_KEY_2="$(vscode-storage-key)" \ + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + VSCODE_HOCKEYAPP_TOKEN="$(vscode-hockeyapp-token)" \ + ./build/azure-pipelines/linux/multiarch/$(VSCODE_ARCH)/publish.sh + displayName: Publish + +- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 + displayName: 'Component Detection' + continueOnError: true \ No newline at end of file diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index c1386b93f71..76c86e32323 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -1,4 +1,23 @@ steps: +- script: | + mkdir -p .build + echo -n $BUILD_SOURCEVERSION > .build/commit + displayName: Prepare cache flag + +- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 + inputs: + keyfile: '.build/commit' + targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + vstsFeed: 'npm-vscode' + platformIndependent: true + alias: 'Compilation' + +- script: | + set -e + exit 1 + displayName: Check RestoreCache + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + - task: NodeTool@0 inputs: versionSpec: "10.15.1" @@ -18,8 +37,6 @@ steps: export npm_config_arch="$(VSCODE_ARCH)" cat << EOF > ~/.netrc - machine monacotools.visualstudio.com - password $(devops-pat) machine github.com login vscode password $(github-distro-mixin-password) @@ -27,23 +44,53 @@ steps: git config user.email "vscode@microsoft.com" git config user.name "VSCode" + displayName: Prepare tooling + +- script: | + set -e git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" git fetch distro git merge $(node -p "require('./package.json').distro") + displayName: Merge distro - CHILD_CONCURRENCY=1 yarn - yarn gulp mixin - yarn gulp hygiene - yarn monaco-compile-check - node build/azure-pipelines/common/installDistroDependencies.js - node build/azure-pipelines/common/installDistroDependencies.js remote - node build/lib/builtInExtensions.js - displayName: Prepare build +- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 + inputs: + keyfile: 'build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + targetfolder: '**/node_modules, !**/node_modules/**/node_modules' + vstsFeed: 'npm-vscode' + +- script: | + set -e + CHILD_CONCURRENCY=1 yarn --frozen-lockfile + displayName: Install dependencies + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) + +- task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 + inputs: + keyfile: 'build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + targetfolder: '**/node_modules, !**/node_modules/**/node_modules' + vstsFeed: 'npm-vscode' + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) + +- script: | + set -e + yarn postinstall + displayName: Run postinstall scripts + condition: and(succeeded(), eq(variables['CacheRestored'], 'true')) + +- script: | + set -e + node build/azure-pipelines/mixin + displayName: Mix in quality - script: | set -e VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - ./build/azure-pipelines/linux/build.sh + yarn gulp vscode-linux-$VSCODE_ARCH-min-ci + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-reh-linux-$VSCODE_ARCH-min-ci + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-web-linux-$VSCODE_ARCH-min-ci displayName: Build - script: | @@ -56,6 +103,7 @@ steps: DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests" # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)" displayName: Run unit tests + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e @@ -66,12 +114,12 @@ steps: ./build/azure-pipelines/linux/publish.sh displayName: Publish -- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: 'Component Detection' - continueOnError: true - - task: PublishPipelineArtifact@0 displayName: 'Publish Pipeline Artifact' inputs: artifactName: snap-$(VSCODE_ARCH) targetPath: .build/linux/snap-tarball + +- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 + displayName: 'Component Detection' + continueOnError: true diff --git a/build/azure-pipelines/linux/snap-build-linux.yml b/build/azure-pipelines/linux/snap-build-linux.yml index 9d98e9fa472..9dbe920b87b 100644 --- a/build/azure-pipelines/linux/snap-build-linux.yml +++ b/build/azure-pipelines/linux/snap-build-linux.yml @@ -47,7 +47,7 @@ steps: PACKAGEJSON="$(ls $SNAP_ROOT/code*/usr/share/code*/resources/app/package.json)" VERSION=$(node -p "require(\"$PACKAGEJSON\").version") SNAP_PATH="$SNAP_ROOT/$SNAP_FILENAME" - (cd $SNAP_ROOT/code-* && sudo snapcraft snap --output "$SNAP_PATH") + (cd $SNAP_ROOT/code-* && sudo --preserve-env snapcraft snap --output "$SNAP_PATH") # Publish snap package AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ diff --git a/build/gulpfile.mixin.js b/build/azure-pipelines/mixin.js similarity index 90% rename from build/gulpfile.mixin.js rename to build/azure-pipelines/mixin.js index 0f9b1d990f3..efb7d4d1ca9 100644 --- a/build/gulpfile.mixin.js +++ b/build/azure-pipelines/mixin.js @@ -5,7 +5,6 @@ 'use strict'; -const gulp = require('gulp'); const json = require('gulp-json-editor'); const buffer = require('gulp-buffer'); const filter = require('gulp-filter'); @@ -14,7 +13,7 @@ const vfs = require('vinyl-fs'); const fancyLog = require('fancy-log'); const ansiColors = require('ansi-colors'); -gulp.task('mixin', function () { +function main() { const quality = process.env['VSCODE_QUALITY']; if (!quality) { @@ -28,7 +27,6 @@ gulp.task('mixin', function () { return vfs .src(`quality/${quality}/**`, { base: `quality/${quality}` }) .pipe(filter(f => !f.isDirectory())) - .pipe(filter(['**', '!**/package.json'])) .pipe(productJsonFilter) .pipe(buffer()) .pipe(json(o => Object.assign({}, require('../product.json'), o))) @@ -37,5 +35,7 @@ gulp.task('mixin', function () { fancyLog(ansiColors.blue('[mixin]'), f.relative, ansiColors.green('✔︎')); return f; })) - .pipe(gulp.dest('.')); -}); \ No newline at end of file + .pipe(vfs.dest('.')); +} + +main(); \ No newline at end of file diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index ac9ce03b593..0c4dba0333a 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -4,39 +4,58 @@ resources: image: vscodehub.azurecr.io/vscode-linux-build-agent:x64 endpoint: VSCodeHub - container: snapcraft - image: snapcore/snapcraft + image: snapcore/snapcraft:stable jobs: -- job: Windows - condition: eq(variables['VSCODE_BUILD_WIN32'], 'true') - pool: - vmImage: VS2017-Win2016 - variables: - VSCODE_ARCH: x64 - steps: - - template: win32/product-build-win32.yml - -- job: Windows32 - condition: eq(variables['VSCODE_BUILD_WIN32_32BIT'], 'true') - pool: - vmImage: VS2017-Win2016 - variables: - VSCODE_ARCH: ia32 - steps: - - template: win32/product-build-win32.yml - -- job: Linux - condition: eq(variables['VSCODE_BUILD_LINUX'], 'true') +- job: Compile pool: vmImage: 'Ubuntu-16.04' variables: VSCODE_ARCH: x64 container: vscode-x64 steps: + - template: product-compile.yml + +- job: Windows + condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_WIN32'], 'true')) + timeoutInMinutes: 120 + pool: + vmImage: VS2017-Win2016 + variables: + VSCODE_ARCH: x64 + dependsOn: + - Compile + steps: + - template: win32/product-build-win32.yml + +- job: Windows32 + condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_WIN32_32BIT'], 'true')) + timeoutInMinutes: 120 + pool: + vmImage: VS2017-Win2016 + variables: + VSCODE_ARCH: ia32 + dependsOn: + - Compile + steps: + - template: win32/product-build-win32.yml + +- job: Linux + condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_LINUX'], 'true')) + timeoutInMinutes: 120 + pool: + vmImage: 'Ubuntu-16.04' + variables: + VSCODE_ARCH: x64 + container: vscode-x64 + dependsOn: + - Compile + steps: - template: linux/product-build-linux.yml - job: LinuxSnap - condition: eq(variables['VSCODE_BUILD_LINUX'], 'true') + condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_LINUX'], 'true')) + timeoutInMinutes: 120 pool: vmImage: 'Ubuntu-16.04' variables: @@ -47,31 +66,72 @@ jobs: - template: linux/snap-build-linux.yml - job: LinuxArmhf - condition: eq(variables['VSCODE_BUILD_LINUX_ARMHF'], 'true') + condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_LINUX_ARMHF'], 'true'), ne(variables['VSCODE_QUALITY'], 'stable')) + timeoutInMinutes: 120 pool: vmImage: 'Ubuntu-16.04' variables: VSCODE_ARCH: armhf + dependsOn: + - Compile steps: - - template: linux/product-build-linux-arm.yml + - template: linux/product-build-linux-multiarch.yml + +- job: LinuxAlpine + condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_LINUX_ALPINE'], 'true'), ne(variables['VSCODE_QUALITY'], 'stable')) + timeoutInMinutes: 120 + pool: + vmImage: 'Ubuntu-16.04' + variables: + VSCODE_ARCH: alpine + dependsOn: + - Compile + steps: + - template: linux/product-build-linux-multiarch.yml - job: macOS - condition: eq(variables['VSCODE_BUILD_MACOS'], 'true') + condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_MACOS'], 'true')) + timeoutInMinutes: 120 pool: vmImage: macOS 10.13 + dependsOn: + - Compile steps: - template: darwin/product-build-darwin.yml -- job: Mooncake +- job: Release + condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), or(eq(variables['VSCODE_RELEASE'], 'true'), and(or(eq(variables['VSCODE_QUALITY'], 'insider'), eq(variables['VSCODE_QUALITY'], 'exploration')), eq(variables['Build.Reason'], 'Schedule')))) pool: vmImage: 'Ubuntu-16.04' - condition: true dependsOn: - Windows - Windows32 - Linux - LinuxSnap - LinuxArmhf + - LinuxAlpine - macOS steps: - - template: sync-mooncake.yml \ No newline at end of file + - template: release.yml + +- job: Mooncake + pool: + vmImage: 'Ubuntu-16.04' + condition: and(succeededOrFailed(), eq(variables['VSCODE_COMPILE_ONLY'], 'false')) + dependsOn: + - Windows + - Windows32 + - Linux + - LinuxSnap + - LinuxArmhf + - LinuxAlpine + - macOS + steps: + - template: sync-mooncake.yml + +schedules: +- cron: "0 5 * * Mon-Fri" + displayName: Mon-Fri at 7:00 + branches: + include: + - master \ No newline at end of file diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml new file mode 100644 index 00000000000..5b425f60fb6 --- /dev/null +++ b/build/azure-pipelines/product-compile.yml @@ -0,0 +1,119 @@ +steps: +- script: | + mkdir -p .build + echo -n $BUILD_SOURCEVERSION > .build/commit + displayName: Prepare cache flag + +- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 + inputs: + keyfile: '.build/commit' + targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + vstsFeed: 'npm-vscode' + platformIndependent: true + alias: 'Compilation' + +- task: NodeTool@0 + inputs: + versionSpec: "10.15.1" + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + +- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 + inputs: + versionSpec: "1.10.1" + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + +- task: AzureKeyVault@1 + displayName: 'Azure Key Vault: Get Secrets' + inputs: + azureSubscription: 'vscode-builds-subscription' + KeyVaultName: vscode + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + +- script: | + set -e + export npm_config_arch="$(VSCODE_ARCH)" + + cat << EOF > ~/.netrc + machine github.com + login vscode + password $(github-distro-mixin-password) + EOF + + git config user.email "vscode@microsoft.com" + git config user.name "VSCode" + displayName: Prepare tooling + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + +- script: | + set -e + git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" + git fetch distro + git merge $(node -p "require('./package.json').distro") + displayName: Merge distro + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + +- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 + inputs: + keyfile: 'build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + targetfolder: '**/node_modules, !**/node_modules/**/node_modules' + vstsFeed: 'npm-vscode' + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + +- script: | + set -e + CHILD_CONCURRENCY=1 yarn --frozen-lockfile + displayName: Install dependencies + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true'), ne(variables['CacheRestored'], 'true')) + +- task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 + inputs: + keyfile: 'build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + targetfolder: '**/node_modules, !**/node_modules/**/node_modules' + vstsFeed: 'npm-vscode' + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true'), ne(variables['CacheRestored'], 'true')) + +- script: | + set -e + yarn postinstall + displayName: Run postinstall scripts + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true'), eq(variables['CacheRestored'], 'true')) + +# Mixin must run before optimize, because the CSS loader will +# inline small SVGs +- script: | + set -e + node build/azure-pipelines/mixin + displayName: Mix in quality + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + +- script: | + set -e + yarn gulp hygiene + yarn monaco-compile-check + displayName: Run hygiene checks + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + +- script: | + set - + ./build/azure-pipelines/common/extract-telemetry.sh + displayName: Extract Telemetry + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + +- script: | + set -e + yarn gulp compile-build + yarn gulp compile-extensions-build + yarn gulp minify-vscode + yarn gulp minify-vscode-reh + yarn gulp minify-vscode-web + displayName: Compile + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + +- task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 + inputs: + keyfile: '.build/commit' + targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + vstsFeed: 'npm-vscode' + platformIndependent: true + alias: 'Compilation' + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) \ No newline at end of file diff --git a/build/azure-pipelines/release.yml b/build/azure-pipelines/release.yml new file mode 100644 index 00000000000..eee54a1d8b7 --- /dev/null +++ b/build/azure-pipelines/release.yml @@ -0,0 +1,22 @@ +steps: +- task: NodeTool@0 + inputs: + versionSpec: "10.x" + +- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 + inputs: + versionSpec: "1.x" + +- task: AzureKeyVault@1 + displayName: 'Azure Key Vault: Get Secrets' + inputs: + azureSubscription: 'vscode-builds-subscription' + KeyVaultName: vscode + +- script: | + set -e + + (cd build ; yarn) + + AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ + node build/azure-pipelines/common/release.js diff --git a/build/azure-pipelines/win32/build.ps1 b/build/azure-pipelines/win32/build.ps1 deleted file mode 100644 index 8334a87e029..00000000000 --- a/build/azure-pipelines/win32/build.ps1 +++ /dev/null @@ -1,5 +0,0 @@ -. build/azure-pipelines/win32/exec.ps1 -$ErrorActionPreference = "Stop" -exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-min" } -exec { yarn gulp "vscode-reh-win32-$env:VSCODE_ARCH-min" } -exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-inno-updater" } \ No newline at end of file diff --git a/build/azure-pipelines/win32/continuous-build-win32.yml b/build/azure-pipelines/win32/continuous-build-win32.yml index 36336276814..9b6d61ee974 100644 --- a/build/azure-pipelines/win32/continuous-build-win32.yml +++ b/build/azure-pipelines/win32/continuous-build-win32.yml @@ -11,16 +11,16 @@ steps: addToPath: true - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + keyfile: '.yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' targetfolder: '**/node_modules, !**/node_modules/**/node_modules' vstsFeed: '$(ArtifactFeed)' - powershell: | - yarn + yarn --frozen-lockfile displayName: Install Dependencies - condition: ne(variables['CacheRestored'], 'true') + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 inputs: - keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + keyfile: '.yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' targetfolder: '**/node_modules, !**/node_modules/**/node_modules' vstsFeed: '$(ArtifactFeed)' condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 339bdde1b9c..fc14cc0abec 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -1,4 +1,23 @@ steps: +- powershell: | + mkdir .build -ea 0 + "$env:BUILD_SOURCEVERSION" | Out-File -Encoding ascii -NoNewLine .build\commit + displayName: Prepare cache flag + +- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 + inputs: + keyfile: '.build/commit' + targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + vstsFeed: 'npm-vscode' + platformIndependent: true + alias: 'Compilation' + +- powershell: | + $ErrorActionPreference = "Stop" + exit 1 + displayName: Check RestoreCache + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + - task: NodeTool@0 inputs: versionSpec: "10.15.1" @@ -21,30 +40,66 @@ steps: - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" - "machine monacotools.visualstudio.com`npassword $(devops-pat)`nmachine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII - $env:npm_config_arch="$(VSCODE_ARCH)" - $env:CHILD_CONCURRENCY="1" + "machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII exec { git config user.email "vscode@microsoft.com" } exec { git config user.name "VSCode" } + + mkdir .build -ea 0 + "$(VSCODE_ARCH)" | Out-File -Encoding ascii -NoNewLine .build\arch + displayName: Prepare tooling + +- powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" exec { git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" } exec { git fetch distro } exec { git merge $(node -p "require('./package.json').distro") } + displayName: Merge distro - exec { yarn } - exec { yarn gulp mixin } - exec { yarn gulp hygiene } - exec { yarn monaco-compile-check } - exec { node build/azure-pipelines/common/installDistroDependencies.js } - exec { node build/azure-pipelines/common/installDistroDependencies.js remote } - exec { node build/lib/builtInExtensions.js } - displayName: Prepare build +- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 + inputs: + keyfile: 'build/.cachesalt, .build/arch, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + targetfolder: '**/node_modules, !**/node_modules/**/node_modules' + vstsFeed: 'npm-vscode' + +- powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $env:npm_config_arch="$(VSCODE_ARCH)" + $env:CHILD_CONCURRENCY="1" + exec { yarn --frozen-lockfile } + displayName: Install dependencies + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) + +- task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 + inputs: + keyfile: 'build/.cachesalt, .build/arch, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' + targetfolder: '**/node_modules, !**/node_modules/**/node_modules' + vstsFeed: 'npm-vscode' + condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) + +- powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { yarn postinstall } + displayName: Run postinstall scripts + condition: and(succeeded(), eq(variables['CacheRestored'], 'true')) + +- powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { node build/azure-pipelines/mixin } + displayName: Mix in quality - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" - .\build\azure-pipelines\win32\build.ps1 + exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-min-ci" } + exec { yarn gulp "vscode-reh-win32-$env:VSCODE_ARCH-min-ci" } + exec { yarn gulp "vscode-web-win32-$env:VSCODE_ARCH-min-ci" } + exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-inno-updater" } displayName: Build - powershell: | @@ -52,8 +107,8 @@ steps: $ErrorActionPreference = "Stop" exec { yarn gulp "electron-$(VSCODE_ARCH)" } exec { .\scripts\test.bat --build --tfs "Unit Tests" } - # yarn smoketest -- --build "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" displayName: Run unit tests + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - powershell: | . build/azure-pipelines/win32/exec.ps1 @@ -61,6 +116,7 @@ steps: exec { yarn gulp "electron-$(VSCODE_ARCH)" } exec { .\scripts\test-integration.bat --build --tfs "Integration Tests" } displayName: Run integration tests + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1 inputs: @@ -142,6 +198,7 @@ steps: $env:AZURE_STORAGE_ACCESS_KEY_2 = "$(vscode-storage-key)" $env:AZURE_DOCUMENTDB_MASTERKEY = "$(builds-docdb-key-readwrite)" $env:VSCODE_HOCKEYAPP_TOKEN = "$(vscode-hockeyapp-token)" + $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" .\build\azure-pipelines\win32\publish.ps1 displayName: Publish diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index ed6d6c2662d..f044a0e5384 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.35.2", + "version": "1.35.3", "repo": "https://github.com/Microsoft/vscode-node-debug", "metadata": { "id": "b6ded8fb-a0a0-4c1c-acbd-ab2a3bc995a6", @@ -31,7 +31,7 @@ }, { "name": "ms-vscode.references-view", - "version": "0.0.27", + "version": "0.0.28", "repo": "https://github.com/Microsoft/vscode-reference-view", "metadata": { "id": "dc489f46-520d-4556-ae85-1f9eab3c412d", diff --git a/build/builtin/main.js b/build/builtin/main.js index 849027ad2b9..b094a67cac5 100644 --- a/build/builtin/main.js +++ b/build/builtin/main.js @@ -10,7 +10,7 @@ const path = require('path'); let window = null; app.once('ready', () => { - window = new BrowserWindow({ width: 800, height: 600 }); + window = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, webviewTag: true } }); window.setMenuBarVisibility(false); window.loadURL(url.format({ pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true })); // window.webContents.openDevTools(); diff --git a/build/download/download.js b/build/download/download.js deleted file mode 100644 index c70bae336a6..00000000000 --- a/build/download/download.js +++ /dev/null @@ -1,91 +0,0 @@ -"use strict"; -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -Object.defineProperty(exports, "__esModule", { value: true }); -const https = require("https"); -const fs = require("fs"); -const path = require("path"); -const cp = require("child_process"); -function ensureDir(filepath) { - if (!fs.existsSync(filepath)) { - ensureDir(path.dirname(filepath)); - fs.mkdirSync(filepath); - } -} -function download(options, destination) { - ensureDir(path.dirname(destination)); - return new Promise((c, e) => { - const fd = fs.openSync(destination, 'w'); - const req = https.get(options, (res) => { - res.on('data', (chunk) => { - fs.writeSync(fd, chunk); - }); - res.on('end', () => { - fs.closeSync(fd); - c(); - }); - }); - req.on('error', (reqErr) => { - console.error(`request to ${options.host}${options.path} failed.`); - console.error(reqErr); - e(reqErr); - }); - }); -} -const MARKER_ARGUMENT = `_download_fork_`; -function base64encode(str) { - return Buffer.from(str, 'utf8').toString('base64'); -} -function base64decode(str) { - return Buffer.from(str, 'base64').toString('utf8'); -} -function downloadInExternalProcess(options) { - const url = `https://${options.requestOptions.host}${options.requestOptions.path}`; - console.log(`Downloading ${url}...`); - return new Promise((c, e) => { - const child = cp.fork(__filename, [MARKER_ARGUMENT, base64encode(JSON.stringify(options))], { - stdio: ['pipe', 'pipe', 'pipe', 'ipc'] - }); - let stderr = []; - child.stderr.on('data', (chunk) => { - stderr.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk); - }); - child.on('exit', (code) => { - if (code === 0) { - // normal termination - console.log(`Finished downloading ${url}.`); - c(); - } - else { - // abnormal termination - console.error(Buffer.concat(stderr).toString()); - e(new Error(`Download of ${url} failed.`)); - } - }); - }); -} -exports.downloadInExternalProcess = downloadInExternalProcess; -function _downloadInExternalProcess() { - let options; - try { - options = JSON.parse(base64decode(process.argv[3])); - } - catch (err) { - console.error(`Cannot read arguments`); - console.error(err); - process.exit(-1); - return; - } - download(options.requestOptions, options.destinationPath).then(() => { - process.exit(0); - }, (err) => { - console.error(err); - process.exit(-2); - }); -} -if (process.argv.length >= 4 && process.argv[2] === MARKER_ARGUMENT) { - // running as forked download script - _downloadInExternalProcess(); -} diff --git a/build/download/download.ts b/build/download/download.ts deleted file mode 100644 index 01ac8864d0b..00000000000 --- a/build/download/download.ts +++ /dev/null @@ -1,111 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as https from 'https'; -import * as fs from 'fs'; -import * as path from 'path'; -import * as cp from 'child_process'; - -function ensureDir(filepath: string) { - if (!fs.existsSync(filepath)) { - ensureDir(path.dirname(filepath)); - fs.mkdirSync(filepath); - } -} - -function download(options: https.RequestOptions, destination: string): Promise { - ensureDir(path.dirname(destination)); - - return new Promise((c, e) => { - const fd = fs.openSync(destination, 'w'); - const req = https.get(options, (res) => { - res.on('data', (chunk) => { - fs.writeSync(fd, chunk); - }); - res.on('end', () => { - fs.closeSync(fd); - c(); - }); - }); - req.on('error', (reqErr) => { - console.error(`request to ${options.host}${options.path} failed.`); - console.error(reqErr); - e(reqErr); - }); - }); -} - -const MARKER_ARGUMENT = `_download_fork_`; - -function base64encode(str: string): string { - return Buffer.from(str, 'utf8').toString('base64'); -} - -function base64decode(str: string): string { - return Buffer.from(str, 'base64').toString('utf8'); -} - -export interface IDownloadRequestOptions { - host: string; - path: string; -} - -export interface IDownloadOptions { - requestOptions: IDownloadRequestOptions; - destinationPath: string; -} - -export function downloadInExternalProcess(options: IDownloadOptions): Promise { - const url = `https://${options.requestOptions.host}${options.requestOptions.path}`; - console.log(`Downloading ${url}...`); - return new Promise((c, e) => { - const child = cp.fork( - __filename, - [MARKER_ARGUMENT, base64encode(JSON.stringify(options))], - { - stdio: ['pipe', 'pipe', 'pipe', 'ipc'] - } - ); - let stderr: Buffer[] = []; - child.stderr.on('data', (chunk) => { - stderr.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk); - }); - child.on('exit', (code) => { - if (code === 0) { - // normal termination - console.log(`Finished downloading ${url}.`); - c(); - } else { - // abnormal termination - console.error(Buffer.concat(stderr).toString()); - e(new Error(`Download of ${url} failed.`)); - } - }); - }); -} - -function _downloadInExternalProcess() { - let options: IDownloadOptions; - try { - options = JSON.parse(base64decode(process.argv[3])); - } catch (err) { - console.error(`Cannot read arguments`); - console.error(err); - process.exit(-1); - return; - } - - download(options.requestOptions, options.destinationPath).then(() => { - process.exit(0); - }, (err) => { - console.error(err); - process.exit(-2); - }); -} - -if (process.argv.length >= 4 && process.argv[2] === MARKER_ARGUMENT) { - // running as forked download script - _downloadInExternalProcess(); -} diff --git a/build/gulpfile.compile.js b/build/gulpfile.compile.js index 0dd2e5abf19..21aa7896558 100644 --- a/build/gulpfile.compile.js +++ b/build/gulpfile.compile.js @@ -5,14 +5,12 @@ 'use strict'; +const gulp = require('gulp'); const util = require('./lib/util'); const task = require('./lib/task'); const compilation = require('./lib/compilation'); -const { compileExtensionsBuildTask } = require('./gulpfile.extensions'); // Full compile, including nls and inline sources in sourcemaps, for build -const compileClientBuildTask = task.define('compile-client-build', task.series(util.rimraf('out-build'), compilation.compileTask('src', 'out-build', true))); - -// All Build -const compileBuildTask = task.define('compile-build', task.parallel(compileClientBuildTask, compileExtensionsBuildTask)); +const compileBuildTask = task.define('compile-build', task.series(util.rimraf('out-build'), compilation.compileTask('src', 'out-build', true))); +gulp.task(compileBuildTask); exports.compileBuildTask = compileBuildTask; \ No newline at end of file diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index c72b26cafed..e4f7b58d50a 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -22,6 +22,7 @@ const root = path.dirname(__dirname); const commit = util.getVersion(root); const plumber = require('gulp-plumber'); const _ = require('underscore'); +const ext = require('./lib/extensions'); const extensionsPath = path.join(path.dirname(__dirname), 'extensions'); @@ -135,11 +136,7 @@ const tasks = compilations.map(function (tsconfigFile) { gulp.task(compileTask); gulp.task(watchTask); - return { - compileTask: compileTask, - watchTask: watchTask, - compileBuildTask: compileBuildTask - }; + return { compileTask, watchTask, compileBuildTask }; }); const compileExtensionsTask = task.define('compile-extensions', task.parallel(...tasks.map(t => t.compileTask))); @@ -150,5 +147,17 @@ const watchExtensionsTask = task.define('watch-extensions', task.parallel(...tas gulp.task(watchExtensionsTask); exports.watchExtensionsTask = watchExtensionsTask; -const compileExtensionsBuildTask = task.define('compile-extensions-build', task.parallel(...tasks.map(t => t.compileBuildTask))); -exports.compileExtensionsBuildTask = compileExtensionsBuildTask; +const compileExtensionsBuildLegacyTask = task.define('compile-extensions-build-legacy', task.parallel(...tasks.map(t => t.compileBuildTask))); +gulp.task(compileExtensionsBuildLegacyTask); + +// Azure Pipelines + +const cleanExtensionsBuildTask = task.define('clean-extensions-build', util.rimraf('.build/extensions')); +const compileExtensionsBuildTask = task.define('compile-extensions-build', task.series( + cleanExtensionsBuildTask, + task.define('bundle-extensions-build', () => ext.packageLocalExtensionsStream().pipe(gulp.dest('.build'))), + task.define('bundle-marketplace-extensions-build', () => ext.packageMarketplaceExtensionsStream().pipe(gulp.dest('.build'))), +)); + +gulp.task(compileExtensionsBuildTask); +exports.compileExtensionsBuildTask = compileExtensionsBuildTask; \ No newline at end of file diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index 50082693334..b49bc069366 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -175,6 +175,17 @@ gulp.task('tslint', () => { function hygiene(some) { let errorCount = 0; + const productJson = es.through(function (file) { + const product = JSON.parse(file.contents.toString('utf8')); + + if (product.extensionsGallery) { + console.error('product.json: Contains "extensionsGallery"'); + errorCount++; + } + + this.emit('data', file); + }); + const indentation = es.through(function (file) { const lines = file.contents.toString('utf8').split(/\r\n|\r|\n/); file.__lines = lines; @@ -258,8 +269,13 @@ function hygiene(some) { input = some; } + const productJsonFilter = filter('product.json', { restore: true }); + const result = input .pipe(filter(f => !f.stat.isDirectory())) + .pipe(productJsonFilter) + .pipe(process.env['BUILD_SOURCEVERSION'] ? es.through() : productJson) + .pipe(productJsonFilter.restore) .pipe(filter(indentationFilter)) .pipe(indentation) .pipe(filter(copyrightFilter)) diff --git a/build/gulpfile.reh.js b/build/gulpfile.reh.js index 83eebc9d69d..8828a0d394f 100644 --- a/build/gulpfile.reh.js +++ b/build/gulpfile.reh.js @@ -11,16 +11,29 @@ const path = require('path'); const es = require('event-stream'); const util = require('./lib/util'); const task = require('./lib/task'); - const vfs = require('vinyl-fs'); const flatmap = require('gulp-flatmap'); const gunzip = require('gulp-gunzip'); const untar = require('gulp-untar'); const File = require('vinyl'); const fs = require('fs'); +const remote = require('gulp-remote-src'); +const rename = require('gulp-rename'); +const filter = require('gulp-filter'); +const cp = require('child_process'); const REPO_ROOT = path.dirname(__dirname); +const BUILD_TARGETS = [ + { platform: 'win32', arch: 'ia32', pkgTarget: 'node8-win-x86' }, + { platform: 'win32', arch: 'x64', pkgTarget: 'node8-win-x64' }, + { platform: 'darwin', arch: null, pkgTarget: 'node8-macos-x64' }, + { platform: 'linux', arch: 'ia32', pkgTarget: 'node8-linux-x86' }, + { platform: 'linux', arch: 'x64', pkgTarget: 'node8-linux-x64' }, + { platform: 'linux', arch: 'armhf', pkgTarget: 'node8-linux-armv7' }, + { platform: 'linux', arch: 'alpine', pkgTarget: 'node8-linux-alpine' }, +]; + const noop = () => { return Promise.resolve(); }; gulp.task('vscode-reh-win32-ia32-min', noop); @@ -28,7 +41,13 @@ gulp.task('vscode-reh-win32-x64-min', noop); gulp.task('vscode-reh-darwin-min', noop); gulp.task('vscode-reh-linux-x64-min', noop); gulp.task('vscode-reh-linux-armhf-min', noop); +gulp.task('vscode-reh-linux-alpine-min', noop); +gulp.task('vscode-web-win32-ia32-min', noop); +gulp.task('vscode-web-win32-x64-min', noop); +gulp.task('vscode-web-darwin-min', noop); +gulp.task('vscode-web-linux-x64-min', noop); +gulp.task('vscode-web-linux-alpine-min', noop); function getNodeVersion() { const yarnrc = fs.readFileSync(path.join(REPO_ROOT, 'remote', '.yarnrc'), 'utf8'); @@ -36,52 +55,46 @@ function getNodeVersion() { return target; } -function ensureDirs(dirPath) { - if (!fs.existsSync(dirPath)) { - ensureDirs(path.dirname(dirPath)); - fs.mkdirSync(dirPath); +const nodeVersion = getNodeVersion(); + +BUILD_TARGETS.forEach(({ platform, arch }) => { + if (platform === 'darwin') { + arch = 'x64'; } + + gulp.task(task.define(`node-${platform}-${arch}`, () => { + const nodePath = path.join('.build', 'node', `v${nodeVersion}`, `${platform}-${arch}`); + + if (!fs.existsSync(nodePath)) { + util.rimraf(nodePath); + + return nodejs(platform, arch) + .pipe(vfs.dest(nodePath)); + } + + return Promise.resolve(null); + })); +}); + +const defaultNodeTask = gulp.task(`node-${process.platform}-${process.arch}`); + +if (defaultNodeTask) { + gulp.task(task.define('node', defaultNodeTask)); } -/* Downloads the node executable used for the remote server to ./build/node-remote */ -gulp.task(task.define('node-remote', () => { - const VERSION = getNodeVersion(); - const nodePath = path.join('.build', 'node-remote'); - const nodeVersionPath = path.join(nodePath, 'version'); - if (!fs.existsSync(nodeVersionPath) || fs.readFileSync(nodeVersionPath).toString() !== VERSION) { - ensureDirs(nodePath); - util.rimraf(nodePath); - fs.writeFileSync(nodeVersionPath, VERSION); - return nodejs(process.platform, process.arch).pipe(vfs.dest(nodePath)); - } - return vfs.src(nodePath); -})); - function nodejs(platform, arch) { - const VERSION = getNodeVersion(); - if (arch === 'ia32') { arch = 'x86'; } if (platform === 'win32') { - const downloadPath = `/dist/v${VERSION}/win-${arch}/node.exe`; + return remote(`/dist/v${nodeVersion}/win-${arch}/node.exe`, { base: 'https://nodejs.org' }) + .pipe(rename('node.exe')); + } - return ( - util.download({ host: 'nodejs.org', path: downloadPath }) - .pipe(es.through(function (data) { - // base comes in looking like `https:\nodejs.org\dist\v10.2.1\win-x64\node.exe` - this.emit('data', new File({ - path: data.path, - base: data.base.replace(/\\node\.exe$/, ''), - contents: data.contents, - stat: { - isFile: true, - mode: /* 100755 */ 33261 - } - })); - })) - ); + if (arch === 'alpine') { + const contents = cp.execSync(`docker run --rm node:${nodeVersion}-alpine /bin/sh -c 'cat \`which node\`'`, { maxBuffer: 100 * 1024 * 1024, encoding: 'buffer' }); + return es.readArray([new File({ path: 'node', contents, stat: { mode: parseInt('755', 8) } })]); } if (platform === 'darwin') { @@ -92,26 +105,39 @@ function nodejs(platform, arch) { arch = 'armv7l'; } - const downloadPath = `/dist/v${VERSION}/node-v${VERSION}-${platform}-${arch}.tar.gz`; - - return ( - util.download({ host: 'nodejs.org', path: downloadPath }) - .pipe(flatmap(stream => stream.pipe(gunzip()).pipe(untar()))) - .pipe(es.through(function (data) { - // base comes in looking like `https:/nodejs.org/dist/v8.9.3/node-v8.9.3-darwin-x64.tar.gz` - // => we must remove the `.tar.gz` - // Also, keep only bin/node - if (/\/bin\/node$/.test(data.path)) { - this.emit('data', new File({ - path: data.path.replace(/bin\/node$/, 'node'), - base: data.base.replace(/\.tar\.gz$/, ''), - contents: data.contents, - stat: { - isFile: true, - mode: /* 100755 */ 33261 - } - })); - } - })) - ); + return remote(`/dist/v${nodeVersion}/node-v${nodeVersion}-${platform}-${arch}.tar.gz`, { base: 'https://nodejs.org' }) + .pipe(flatmap(stream => stream.pipe(gunzip()).pipe(untar()))) + .pipe(filter('**/node')) + .pipe(util.setExecutableBit('**')) + .pipe(rename('node')); } + +function mixinServer(watch) { + const packageJSONPath = path.join(path.dirname(__dirname), 'package.json'); + function exec(cmdLine) { + console.log(cmdLine); + cp.execSync(cmdLine, { stdio: "inherit" }); + } + function checkout() { + const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString()); + exec('git fetch distro'); + exec(`git checkout ${packageJSON['distro']} -- src/vs/server resources/server`); + exec('git reset HEAD src/vs/server resources/server'); + } + checkout(); + if (watch) { + console.log('Enter watch mode (observing package.json)'); + const watcher = fs.watch(packageJSONPath); + watcher.addListener('change', () => { + try { + checkout(); + } catch (e) { + console.log(e); + } + }); + } + return Promise.resolve(); +} + +gulp.task(task.define('mixin-server', () => mixinServer(false))); +gulp.task(task.define('mixin-server-watch', () => mixinServer(true))); diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 9c32df0bf81..a3478121f28 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -21,7 +21,6 @@ const json = require('gulp-json-editor'); const _ = require('underscore'); const util = require('./lib/util'); const task = require('./lib/task'); -const ext = require('./lib/extensions'); const buildfile = require('../src/buildfile'); const common = require('./lib/optimize'); const root = path.dirname(__dirname); @@ -35,6 +34,7 @@ const getElectronVersion = require('./lib/electron').getElectronVersion; const createAsar = require('./lib/asar').createAsar; const minimist = require('minimist'); const { compileBuildTask } = require('./gulpfile.compile'); +const { compileExtensionsBuildTask } = require('./gulpfile.extensions'); const productionDependencies = deps.getProductionDependencies(path.dirname(__dirname)); // @ts-ignore @@ -49,6 +49,7 @@ const nodeModules = ['electron', 'original-fs'] const vscodeEntryPoints = _.flatten([ buildfile.entrypoint('vs/workbench/workbench.main'), buildfile.base, + buildfile.serviceWorker, buildfile.workbench, buildfile.code ]); @@ -76,8 +77,8 @@ const vscodeResources = [ 'out-build/vs/**/markdown.css', 'out-build/vs/workbench/contrib/tasks/**/*.json', 'out-build/vs/workbench/contrib/welcome/walkThrough/**/*.md', - 'out-build/vs/workbench/services/files/**/*.exe', - 'out-build/vs/workbench/services/files/**/*.md', + 'out-build/vs/platform/files/**/*.exe', + 'out-build/vs/platform/files/**/*.md', 'out-build/vs/code/electron-browser/workbench/**', 'out-build/vs/code/electron-browser/sharedProcess/sharedProcess.js', 'out-build/vs/code/electron-browser/issue/issueReporter.js', @@ -92,10 +93,7 @@ const BUNDLED_FILE_HEADER = [ ].join('\n'); const optimizeVSCodeTask = task.define('optimize-vscode', task.series( - task.parallel( - util.rimraf('out-vscode'), - compileBuildTask - ), + util.rimraf('out-vscode'), common.optimizeTask({ src: 'out-build', entryPoints: vscodeEntryPoints, @@ -106,26 +104,21 @@ const optimizeVSCodeTask = task.define('optimize-vscode', task.series( bundleInfo: undefined }) )); +gulp.task(optimizeVSCodeTask); - -const optimizeIndexJSTask = task.define('optimize-index-js', task.series( +const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`; +const minifyVSCodeTask = task.define('minify-vscode', task.series( optimizeVSCodeTask, + util.rimraf('out-vscode-min'), () => { const fullpath = path.join(process.cwd(), 'out-vscode/bootstrap-window.js'); const contents = fs.readFileSync(fullpath).toString(); const newContents = contents.replace('[/*BUILD->INSERT_NODE_MODULES*/]', JSON.stringify(nodeModules)); fs.writeFileSync(fullpath, newContents); - } -)); - -const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`; -const minifyVSCodeTask = task.define('minify-vscode', task.series( - task.parallel( - util.rimraf('out-vscode-min'), - optimizeIndexJSTask - ), + }, common.minifyTask('out-vscode', `${sourceMappingURLBase}/core`) )); +gulp.task(minifyVSCodeTask); // Package @@ -277,9 +270,8 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op const root = path.resolve(path.join(__dirname, '..')); - const sources = es.merge(src, ext.packageExtensionsStream({ - sourceMappingURLBase: sourceMappingURLBase - })); + const extensions = gulp.src('.build/extensions/**', { base: '.build', dot: true }); + const sources = es.merge(src, extensions); let version = packageJson.version; // @ts-ignore JSON checking: quality is optional @@ -315,22 +307,21 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op // TODO the API should be copied to `out` during compile, not here const api = gulp.src('src/vs/vscode.d.ts').pipe(rename('out/vs/vscode.d.ts')); - const depsSrc = [ - ..._.flatten(productionDependencies.map(d => path.relative(root, d.path)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`])), - // @ts-ignore JSON checking: dependencies is optional - ..._.flatten(Object.keys(product.dependencies || {}).map(d => [`node_modules/${d}/**`, `!node_modules/${d}/**/{test,tests}/**`])) - ]; + const telemetry = gulp.src('.build/telemetry/**', { base: '.build/telemetry', dot: true }); - const deps = gulp.src(depsSrc, { base: '.', dot: true }) + const dependenciesSrc = _.flatten(productionDependencies.map(d => path.relative(root, d.path)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`])); + + const deps = gulp.src(dependenciesSrc, { base: '.', dot: true }) .pipe(filter(['**', '!**/package-lock.json'])) .pipe(util.cleanNodeModules(path.join(__dirname, '.nativeignore'))) .pipe(createAsar(path.join(process.cwd(), 'node_modules'), ['**/*.node', '**/vscode-ripgrep/bin/*', '**/node-pty/build/Release/*'], 'app/node_modules.asar')); let all = es.merge( - packageJsonStream, + packageJsonStream, productJsonStream, license, api, + telemetry, sources, deps ); @@ -380,7 +371,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op .pipe(util.skipDirectories()) .pipe(util.fixWin32DirectoryPermissions()) .pipe(electron(_.extend({}, config, { platform, arch, ffmpegChromium: true }))) - .pipe(filter(['**', '!LICENSE', '!LICENSES.chromium.html', '!version'])); + .pipe(filter(['**', '!LICENSE', '!LICENSES.chromium.html', '!version'], { dot: true })); // result = es.merge(result, gulp.src('resources/completions/**', { base: '.' })); @@ -444,13 +435,18 @@ BUILD_TARGETS.forEach(buildTarget => { const sourceFolderName = `out-vscode${dashed(minified)}`; const destinationFolderName = `VSCode${dashed(platform)}${dashed(arch)}`; - const vscodeTask = task.define(`vscode${dashed(platform)}${dashed(arch)}${dashed(minified)}`, task.series( - task.parallel( - minified ? minifyVSCodeTask : optimizeVSCodeTask, - util.rimraf(path.join(buildRoot, destinationFolderName)) - ), + const vscodeTaskCI = task.define(`vscode${dashed(platform)}${dashed(arch)}${dashed(minified)}-ci`, task.series( + util.rimraf(path.join(buildRoot, destinationFolderName)), packageTask(platform, arch, sourceFolderName, destinationFolderName, opts) )); + gulp.task(vscodeTaskCI); + + const vscodeTask = task.define(`vscode${dashed(platform)}${dashed(arch)}${dashed(minified)}`, task.series( + compileBuildTask, + compileExtensionsBuildTask, + minified ? minifyVSCodeTask : optimizeVSCodeTask, + vscodeTaskCI + )); gulp.task(vscodeTask); }); }); @@ -479,6 +475,8 @@ const apiToken = process.env.TRANSIFEX_API_TOKEN; gulp.task(task.define( 'vscode-translations-push', task.series( + compileBuildTask, + compileExtensionsBuildTask, optimizeVSCodeTask, function () { const pathToMetadata = './out-vscode/nls.metadata.json'; @@ -498,6 +496,8 @@ gulp.task(task.define( gulp.task(task.define( 'vscode-translations-export', task.series( + compileBuildTask, + compileExtensionsBuildTask, optimizeVSCodeTask, function () { const pathToMetadata = './out-vscode/nls.metadata.json'; diff --git a/build/gulpfile.vscode.win32.js b/build/gulpfile.vscode.win32.js index 46543316de9..b20efebdb62 100644 --- a/build/gulpfile.vscode.win32.js +++ b/build/gulpfile.vscode.win32.js @@ -25,7 +25,7 @@ const zipDir = arch => path.join(repoPath, '.build', `win32-${arch}`, 'archive') const zipPath = arch => path.join(zipDir(arch), `VSCode-win32-${arch}.zip`); const setupDir = (arch, target) => path.join(repoPath, '.build', `win32-${arch}`, `${target}-setup`); const issPath = path.join(__dirname, 'win32', 'code.iss'); -const innoSetupPath = path.join(path.dirname(path.dirname(require.resolve('innosetup-compiler'))), 'bin', 'ISCC.exe'); +const innoSetupPath = path.join(path.dirname(path.dirname(require.resolve('innosetup'))), 'bin', 'ISCC.exe'); const signPS1 = path.join(repoPath, 'build', 'azure-pipelines', 'win32', 'sign.ps1'); function packageInnoSetup(iss, options, cb) { diff --git a/build/lib/compilation.js b/build/lib/compilation.js index 592a5d087ce..62aff873509 100644 --- a/build/lib/compilation.js +++ b/build/lib/compilation.js @@ -112,7 +112,6 @@ class MonacoGenerator { this._executeSoonTimer = null; this._isWatch = isWatch; this.stream = es.through(); - this._watchers = []; this._watchedFiles = {}; let onWillReadFile = (moduleId, filePath) => { if (!this._isWatch) { @@ -122,26 +121,10 @@ class MonacoGenerator { return; } this._watchedFiles[filePath] = true; - const watcher = fs.watch(filePath); - watcher.addListener('change', () => { + fs.watchFile(filePath, () => { this._declarationResolver.invalidateCache(moduleId); this._executeSoon(); }); - watcher.addListener('error', (err) => { - console.error(`Encountered error while watching ${filePath}.`); - console.log(err); - delete this._watchedFiles[filePath]; - for (let i = 0; i < this._watchers.length; i++) { - if (this._watchers[i] === watcher) { - this._watchers.splice(i, 1); - break; - } - } - watcher.close(); - this._declarationResolver.invalidateCache(moduleId); - this._executeSoon(); - }); - this._watchers.push(watcher); }; this._fsProvider = new class extends monacodts.FSProvider { readFileSync(moduleId, filePath) { @@ -151,11 +134,9 @@ class MonacoGenerator { }; this._declarationResolver = new monacodts.DeclarationResolver(this._fsProvider); if (this._isWatch) { - const recipeWatcher = fs.watch(monacodts.RECIPE_PATH); - recipeWatcher.addListener('change', () => { + fs.watchFile(monacodts.RECIPE_PATH, () => { this._executeSoon(); }); - this._watchers.push(recipeWatcher); } } _executeSoon() { @@ -168,9 +149,6 @@ class MonacoGenerator { this.execute(); }, 20); } - dispose() { - this._watchers.forEach(watcher => watcher.close()); - } _run() { let r = monacodts.run3(this._declarationResolver); if (!r && !this._isWatch) { diff --git a/build/lib/compilation.ts b/build/lib/compilation.ts index b431a134f6c..f9544af9cc5 100644 --- a/build/lib/compilation.ts +++ b/build/lib/compilation.ts @@ -137,7 +137,6 @@ class MonacoGenerator { private readonly _isWatch: boolean; public readonly stream: NodeJS.ReadWriteStream; - private readonly _watchers: fs.FSWatcher[]; private readonly _watchedFiles: { [filePath: string]: boolean; }; private readonly _fsProvider: monacodts.FSProvider; private readonly _declarationResolver: monacodts.DeclarationResolver; @@ -145,7 +144,6 @@ class MonacoGenerator { constructor(isWatch: boolean) { this._isWatch = isWatch; this.stream = es.through(); - this._watchers = []; this._watchedFiles = {}; let onWillReadFile = (moduleId: string, filePath: string) => { if (!this._isWatch) { @@ -156,26 +154,10 @@ class MonacoGenerator { } this._watchedFiles[filePath] = true; - const watcher = fs.watch(filePath); - watcher.addListener('change', () => { + fs.watchFile(filePath, () => { this._declarationResolver.invalidateCache(moduleId); this._executeSoon(); }); - watcher.addListener('error', (err) => { - console.error(`Encountered error while watching ${filePath}.`); - console.log(err); - delete this._watchedFiles[filePath]; - for (let i = 0; i < this._watchers.length; i++) { - if (this._watchers[i] === watcher) { - this._watchers.splice(i, 1); - break; - } - } - watcher.close(); - this._declarationResolver.invalidateCache(moduleId); - this._executeSoon(); - }); - this._watchers.push(watcher); }; this._fsProvider = new class extends monacodts.FSProvider { public readFileSync(moduleId: string, filePath: string): Buffer { @@ -186,11 +168,9 @@ class MonacoGenerator { this._declarationResolver = new monacodts.DeclarationResolver(this._fsProvider); if (this._isWatch) { - const recipeWatcher = fs.watch(monacodts.RECIPE_PATH); - recipeWatcher.addListener('change', () => { + fs.watchFile(monacodts.RECIPE_PATH, () => { this._executeSoon(); }); - this._watchers.push(recipeWatcher); } } @@ -206,10 +186,6 @@ class MonacoGenerator { }, 20); } - public dispose(): void { - this._watchers.forEach(watcher => watcher.close()); - } - private _run(): monacodts.IMonacoDeclarationResult | null { let r = monacodts.run3(this._declarationResolver); if (!r && !this._isWatch) { diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 18c668d6432..e12f8f14568 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -23,17 +23,20 @@ const buffer = require('gulp-buffer'); const json = require("gulp-json-editor"); const webpack = require('webpack'); const webpackGulp = require('webpack-stream'); -const root = path.resolve(path.join(__dirname, '..', '..')); -function fromLocal(extensionPath, sourceMappingURLBase) { +const util = require('./util'); +const root = path.dirname(path.dirname(__dirname)); +const commit = util.getVersion(root); +const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`; +function fromLocal(extensionPath) { const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js'); if (fs.existsSync(webpackFilename)) { - return fromLocalWebpack(extensionPath, sourceMappingURLBase); + return fromLocalWebpack(extensionPath); } else { return fromLocalNormal(extensionPath); } } -function fromLocalWebpack(extensionPath, sourceMappingURLBase) { +function fromLocalWebpack(extensionPath) { const result = es.through(); const packagedDependencies = []; const packageJsonConfig = require(path.join(extensionPath, 'package.json')); @@ -78,7 +81,7 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) { return data; })) .pipe(packageJsonFilter.restore); - const webpackStreams = webpackConfigLocations.map(webpackConfigPath => () => { + const webpackStreams = webpackConfigLocations.map(webpackConfigPath => { const webpackDone = (err, stats) => { fancyLog(`Bundled extension: ${ansiColors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`); if (err) { @@ -104,22 +107,20 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) { // source map handling: // * rewrite sourceMappingURL // * save to disk so that upload-task picks this up - if (sourceMappingURLBase) { - const contents = data.contents.toString('utf8'); - data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { - return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`; - }), 'utf8'); - if (/\.js\.map$/.test(data.path)) { - if (!fs.existsSync(path.dirname(data.path))) { - fs.mkdirSync(path.dirname(data.path)); - } - fs.writeFileSync(data.path, data.contents); + const contents = data.contents.toString('utf8'); + data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { + return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`; + }), 'utf8'); + if (/\.js\.map$/.test(data.path)) { + if (!fs.existsSync(path.dirname(data.path))) { + fs.mkdirSync(path.dirname(data.path)); } + fs.writeFileSync(data.path, data.contents); } this.emit('data', data); })); }); - es.merge(sequence(webpackStreams), patchFilesStream) + es.merge(...webpackStreams, patchFilesStream) // .pipe(es.through(function (data) { // // debug // console.log('out', data.path, data.contents.length); @@ -185,30 +186,7 @@ const excludedExtensions = [ 'ms-vscode.node-debug2', ]; const builtInExtensions = require('../builtInExtensions.json'); -/** - * We're doing way too much stuff at once, with webpack et al. So much stuff - * that while downloading extensions from the marketplace, node js doesn't get enough - * stack frames to complete the download in under 2 minutes, at which point the - * marketplace server cuts off the http request. So, we sequentialize the extensino tasks. - */ -function sequence(streamProviders) { - const result = es.through(); - function pop() { - if (streamProviders.length === 0) { - result.emit('end'); - } - else { - const fn = streamProviders.shift(); - fn() - .on('end', function () { setTimeout(pop, 0); }) - .pipe(result, { end: false }); - } - } - pop(); - return result; -} -function packageExtensionsStream(optsIn) { - const opts = optsIn || {}; +function packageLocalExtensionsStream() { const localExtensionDescriptions = glob.sync('extensions/*/package.json') .map(manifestPath => { const extensionPath = path.dirname(path.join(root, manifestPath)); @@ -216,21 +194,21 @@ function packageExtensionsStream(optsIn) { return { name: extensionName, path: extensionPath }; }) .filter(({ name }) => excludedExtensions.indexOf(name) === -1) - .filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true) .filter(({ name }) => builtInExtensions.every(b => b.name !== name)); - const localExtensions = () => sequence([...localExtensionDescriptions.map(extension => () => { - return fromLocal(extension.path, opts.sourceMappingURLBase) - .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - })]); - const localExtensionDependencies = () => gulp.src('extensions/node_modules/**', { base: '.' }); - const marketplaceExtensions = () => es.merge(...builtInExtensions - .filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true) - .map(extension => { - return fromMarketplace(extension.name, extension.version, extension.metadata) + return es.merge(gulp.src('extensions/node_modules/**', { base: '.' }), ...localExtensionDescriptions.map(extension => { + return fromLocal(extension.path) .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - })); - return sequence([localExtensions, localExtensionDependencies, marketplaceExtensions]) + })) .pipe(util2.setExecutableBit(['**/*.sh'])) .pipe(filter(['**', '!**/*.js.map'])); } -exports.packageExtensionsStream = packageExtensionsStream; +exports.packageLocalExtensionsStream = packageLocalExtensionsStream; +function packageMarketplaceExtensionsStream() { + return es.merge(builtInExtensions.map(extension => { + return fromMarketplace(extension.name, extension.version, extension.metadata) + .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); + })) + .pipe(util2.setExecutableBit(['**/*.sh'])) + .pipe(filter(['**', '!**/*.js.map'])); +} +exports.packageMarketplaceExtensionsStream = packageMarketplaceExtensionsStream; diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 188deaf1a1f..381d56e2abb 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -23,19 +23,21 @@ const buffer = require('gulp-buffer'); import json = require('gulp-json-editor'); const webpack = require('webpack'); const webpackGulp = require('webpack-stream'); +const util = require('./util'); +const root = path.dirname(path.dirname(__dirname)); +const commit = util.getVersion(root); +const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`; -const root = path.resolve(path.join(__dirname, '..', '..')); - -function fromLocal(extensionPath: string, sourceMappingURLBase?: string): Stream { +function fromLocal(extensionPath: string): Stream { const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js'); if (fs.existsSync(webpackFilename)) { - return fromLocalWebpack(extensionPath, sourceMappingURLBase); + return fromLocalWebpack(extensionPath); } else { return fromLocalNormal(extensionPath); } } -function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string | undefined): Stream { +function fromLocalWebpack(extensionPath: string): Stream { const result = es.through(); const packagedDependencies: string[] = []; @@ -91,7 +93,7 @@ function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string | .pipe(packageJsonFilter.restore); - const webpackStreams = webpackConfigLocations.map(webpackConfigPath => () => { + const webpackStreams = webpackConfigLocations.map(webpackConfigPath => { const webpackDone = (err: any, stats: any) => { fancyLog(`Bundled extension: ${ansiColors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`); @@ -123,24 +125,22 @@ function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string | // source map handling: // * rewrite sourceMappingURL // * save to disk so that upload-task picks this up - if (sourceMappingURLBase) { - const contents = (data.contents).toString('utf8'); - data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { - return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`; - }), 'utf8'); + const contents = (data.contents).toString('utf8'); + data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { + return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`; + }), 'utf8'); - if (/\.js\.map$/.test(data.path)) { - if (!fs.existsSync(path.dirname(data.path))) { - fs.mkdirSync(path.dirname(data.path)); - } - fs.writeFileSync(data.path, data.contents); + if (/\.js\.map$/.test(data.path)) { + if (!fs.existsSync(path.dirname(data.path))) { + fs.mkdirSync(path.dirname(data.path)); } + fs.writeFileSync(data.path, data.contents); } this.emit('data', data); })); }); - es.merge(sequence(webpackStreams), patchFilesStream) + es.merge(...webpackStreams, patchFilesStream) // .pipe(es.through(function (data) { // // debug // console.log('out', data.path, data.contents.length); @@ -210,14 +210,6 @@ export function fromMarketplace(extensionName: string, version: string, metadata .pipe(packageJsonFilter.restore); } -interface IPackageExtensionsOptions { - /** - * Set to undefined to package all of them. - */ - desiredExtensions?: string[]; - sourceMappingURLBase?: string; -} - const excludedExtensions = [ 'vscode-api-tests', 'vscode-colorize-tests', @@ -235,33 +227,7 @@ interface IBuiltInExtension { const builtInExtensions: IBuiltInExtension[] = require('../builtInExtensions.json'); -/** - * We're doing way too much stuff at once, with webpack et al. So much stuff - * that while downloading extensions from the marketplace, node js doesn't get enough - * stack frames to complete the download in under 2 minutes, at which point the - * marketplace server cuts off the http request. So, we sequentialize the extensino tasks. - */ -function sequence(streamProviders: { (): Stream }[]): Stream { - const result = es.through(); - - function pop() { - if (streamProviders.length === 0) { - result.emit('end'); - } else { - const fn = streamProviders.shift()!; - fn() - .on('end', function () { setTimeout(pop, 0); }) - .pipe(result, { end: false }); - } - } - - pop(); - return result; -} - -export function packageExtensionsStream(optsIn?: IPackageExtensionsOptions): NodeJS.ReadWriteStream { - const opts = optsIn || {}; - +export function packageLocalExtensionsStream(): NodeJS.ReadWriteStream { const localExtensionDescriptions = (glob.sync('extensions/*/package.json')) .map(manifestPath => { const extensionPath = path.dirname(path.join(root, manifestPath)); @@ -269,26 +235,24 @@ export function packageExtensionsStream(optsIn?: IPackageExtensionsOptions): Nod return { name: extensionName, path: extensionPath }; }) .filter(({ name }) => excludedExtensions.indexOf(name) === -1) - .filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true) .filter(({ name }) => builtInExtensions.every(b => b.name !== name)); - const localExtensions = () => sequence([...localExtensionDescriptions.map(extension => () => { - return fromLocal(extension.path, opts.sourceMappingURLBase) - .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - })]); - - const localExtensionDependencies = () => gulp.src('extensions/node_modules/**', { base: '.' }); - - const marketplaceExtensions = () => es.merge( - ...builtInExtensions - .filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true) - .map(extension => { - return fromMarketplace(extension.name, extension.version, extension.metadata) - .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - }) - ); - - return sequence([localExtensions, localExtensionDependencies, marketplaceExtensions]) + return es.merge( + gulp.src('extensions/node_modules/**', { base: '.' }), + ...localExtensionDescriptions.map(extension => { + return fromLocal(extension.path) + .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); + }) + ) + .pipe(util2.setExecutableBit(['**/*.sh'])) + .pipe(filter(['**', '!**/*.js.map'])); +} + +export function packageMarketplaceExtensionsStream(): NodeJS.ReadWriteStream { + return es.merge(builtInExtensions.map(extension => { + return fromMarketplace(extension.name, extension.version, extension.metadata) + .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); + })) .pipe(util2.setExecutableBit(['**/*.sh'])) .pipe(filter(['**', '!**/*.js.map'])); } diff --git a/build/lib/node.js b/build/lib/node.js new file mode 100644 index 00000000000..403ae3d9657 --- /dev/null +++ b/build/lib/node.js @@ -0,0 +1,15 @@ +"use strict"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +const path = require("path"); +const fs = require("fs"); +const root = path.dirname(path.dirname(__dirname)); +const yarnrcPath = path.join(root, 'remote', '.yarnrc'); +const yarnrc = fs.readFileSync(yarnrcPath, 'utf8'); +const version = /^target\s+"([^"]+)"$/m.exec(yarnrc)[1]; +const node = process.platform === 'win32' ? 'node.exe' : 'node'; +const nodePath = path.join(root, '.build', 'node', `v${version}`, `${process.platform}-${process.arch}`, node); +console.log(nodePath); diff --git a/build/lib/node.ts b/build/lib/node.ts new file mode 100644 index 00000000000..64397034461 --- /dev/null +++ b/build/lib/node.ts @@ -0,0 +1,16 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as path from 'path'; +import * as fs from 'fs'; + +const root = path.dirname(path.dirname(__dirname)); +const yarnrcPath = path.join(root, 'remote', '.yarnrc'); +const yarnrc = fs.readFileSync(yarnrcPath, 'utf8'); +const version = /^target\s+"([^"]+)"$/m.exec(yarnrc)![1]; +const node = process.platform === 'win32' ? 'node.exe' : 'node'; +const nodePath = path.join(root, '.build', 'node', `v${version}`, `${process.platform}-${process.arch}`, node); + +console.log(nodePath); \ No newline at end of file diff --git a/build/lib/test/i18n.test.js b/build/lib/test/i18n.test.js index 298104865ab..3dd104259fa 100644 --- a/build/lib/test/i18n.test.js +++ b/build/lib/test/i18n.test.js @@ -27,14 +27,14 @@ suite('XLF Parser Tests', () => { }); test('JSON file source path to Transifex resource match', () => { const editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench'; - const platform = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/contrib/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/files', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject }; + const platform = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/contrib/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/textfile', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject }; assert.deepEqual(i18n.getResource('vs/platform/actions/browser/menusExtensionPoint'), platform); assert.deepEqual(i18n.getResource('vs/editor/contrib/clipboard/browser/clipboard'), editorContrib); assert.deepEqual(i18n.getResource('vs/editor/common/modes/modesRegistry'), editor); assert.deepEqual(i18n.getResource('vs/base/common/errorMessage'), base); assert.deepEqual(i18n.getResource('vs/code/electron-main/window'), code); assert.deepEqual(i18n.getResource('vs/workbench/contrib/html/browser/webview'), workbenchParts); - assert.deepEqual(i18n.getResource('vs/workbench/services/files/node/fileService'), workbenchServices); + assert.deepEqual(i18n.getResource('vs/workbench/services/textfile/node/testFileService'), workbenchServices); assert.deepEqual(i18n.getResource('vs/workbench/browser/parts/panel/panelActions'), workbench); }); }); diff --git a/build/lib/test/i18n.test.ts b/build/lib/test/i18n.test.ts index eebc7742457..29a0f665799 100644 --- a/build/lib/test/i18n.test.ts +++ b/build/lib/test/i18n.test.ts @@ -39,7 +39,7 @@ suite('XLF Parser Tests', () => { base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/contrib/html', project: workbenchProject }, - workbenchServices = { name: 'vs/workbench/services/files', project: workbenchProject }, + workbenchServices = { name: 'vs/workbench/services/textfile', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject}; assert.deepEqual(i18n.getResource('vs/platform/actions/browser/menusExtensionPoint'), platform); @@ -48,7 +48,7 @@ suite('XLF Parser Tests', () => { assert.deepEqual(i18n.getResource('vs/base/common/errorMessage'), base); assert.deepEqual(i18n.getResource('vs/code/electron-main/window'), code); assert.deepEqual(i18n.getResource('vs/workbench/contrib/html/browser/webview'), workbenchParts); - assert.deepEqual(i18n.getResource('vs/workbench/services/files/node/fileService'), workbenchServices); + assert.deepEqual(i18n.getResource('vs/workbench/services/textfile/node/testFileService'), workbenchServices); assert.deepEqual(i18n.getResource('vs/workbench/browser/parts/panel/panelActions'), workbench); }); }); \ No newline at end of file diff --git a/build/lib/util.js b/build/lib/util.js index 6a210d3decc..be2670261d7 100644 --- a/build/lib/util.js +++ b/build/lib/util.js @@ -13,8 +13,6 @@ const fs = require("fs"); const _rimraf = require("rimraf"); const git = require("./git"); const VinylFile = require("vinyl"); -const download_1 = require("../download/download"); -const REPO_ROOT = path.join(__dirname, '../../'); const NoCancellationToken = { isCancellationRequested: () => false }; function incremental(streamProvider, initial, supportsCancellation) { const input = es.through(); @@ -68,6 +66,9 @@ function fixWin32DirectoryPermissions() { exports.fixWin32DirectoryPermissions = fixWin32DirectoryPermissions; function setExecutableBit(pattern) { const setBit = es.mapSync(f => { + if (!f.stat) { + f.stat = { isFile() { return true; } }; + } f.stat.mode = /* 100755 */ 33261; return f; }); @@ -177,7 +178,7 @@ function rimraf(dir) { return cb(err); }); }; - retry.taskName = `clean-${path.basename(dir)}`; + retry.taskName = `clean-${path.basename(dir).toLowerCase()}`; return retry; } exports.rimraf = rimraf; @@ -218,38 +219,3 @@ function versionStringToNumber(versionStr) { return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10); } exports.versionStringToNumber = versionStringToNumber; -function download(requestOptions) { - const result = es.through(); - const filename = path.join(REPO_ROOT, `.build/tmp-${Date.now()}-${path.posix.basename(requestOptions.path)}`); - const opts = { - requestOptions: requestOptions, - destinationPath: filename - }; - download_1.downloadInExternalProcess(opts).then(() => { - fs.stat(filename, (err, stat) => { - if (err) { - result.emit('error', err); - return; - } - fs.readFile(filename, (err, data) => { - if (err) { - result.emit('error', err); - return; - } - fs.unlink(filename, () => { - result.emit('data', new VinylFile({ - path: path.normalize(requestOptions.path), - stat: stat, - base: path.normalize(requestOptions.path), - contents: data - })); - result.emit('end'); - }); - }); - }); - }, (err) => { - result.emit('error', err); - }); - return result; -} -exports.download = download; diff --git a/build/lib/util.ts b/build/lib/util.ts index e87c0650ec3..578271e6648 100644 --- a/build/lib/util.ts +++ b/build/lib/util.ts @@ -17,9 +17,6 @@ import * as git from './git'; import * as VinylFile from 'vinyl'; import { ThroughStream } from 'through'; import * as sm from 'source-map'; -import { IDownloadOptions, downloadInExternalProcess, IDownloadRequestOptions } from '../download/download'; - -const REPO_ROOT = path.join(__dirname, '../../'); export interface ICancellationToken { isCancellationRequested(): boolean; @@ -96,6 +93,9 @@ export function fixWin32DirectoryPermissions(): NodeJS.ReadWriteStream { export function setExecutableBit(pattern?: string | string[]): NodeJS.ReadWriteStream { const setBit = es.mapSync(f => { + if (!f.stat) { + f.stat = { isFile() { return true; } } as any; + } f.stat.mode = /* 100755 */ 33261; return f; }); @@ -234,7 +234,7 @@ export function rimraf(dir: string): (cb: any) => void { return cb(err); }); }; - retry.taskName = `clean-${path.basename(dir)}`; + retry.taskName = `clean-${path.basename(dir).toLowerCase()}`; return retry; } @@ -281,38 +281,3 @@ export function versionStringToNumber(versionStr: string) { return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10); } - -export function download(requestOptions: IDownloadRequestOptions): NodeJS.ReadWriteStream { - const result = es.through(); - const filename = path.join(REPO_ROOT, `.build/tmp-${Date.now()}-${path.posix.basename(requestOptions.path)}`); - const opts: IDownloadOptions = { - requestOptions: requestOptions, - destinationPath: filename - }; - downloadInExternalProcess(opts).then(() => { - fs.stat(filename, (err, stat) => { - if (err) { - result.emit('error', err); - return; - } - fs.readFile(filename, (err, data) => { - if (err) { - result.emit('error', err); - return; - } - fs.unlink(filename, () => { - result.emit('data', new VinylFile({ - path: path.normalize(requestOptions.path), - stat: stat, - base: path.normalize(requestOptions.path), - contents: data - })); - result.emit('end'); - }); - }); - }); - }, (err) => { - result.emit('error', err); - }); - return result; -} diff --git a/build/npm/postinstall.js b/build/npm/postinstall.js index edc5e35ade3..80a4f0eeb5c 100644 --- a/build/npm/postinstall.js +++ b/build/npm/postinstall.js @@ -20,13 +20,10 @@ function yarnInstall(location, opts) { const raw = process.env['npm_config_argv'] || '{}'; const argv = JSON.parse(raw); const original = argv.original || []; - const args = ['install']; + const args = original.filter(arg => arg === '--ignore-optional' || arg === '--frozen-lockfile'); - if (original.indexOf('--ignore-optional') > -1) { - args.push('--ignore-optional'); - } - - console.log('Installing dependencies in \'%s\'.', location); + console.log(`Installing dependencies in ${location}...`); + console.log(`$ yarn ${args.join(' ')}`); const result = cp.spawnSync(yarn, args, opts); if (result.error || result.status !== 0) { diff --git a/build/npm/update-distro.js b/build/npm/update-distro.js new file mode 100644 index 00000000000..947a4967d60 --- /dev/null +++ b/build/npm/update-distro.js @@ -0,0 +1,18 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const cp = require('child_process'); +const path = require('path'); +const fs = require('fs'); + +const rootPath = path.dirname(path.dirname(path.dirname(__dirname))); +const vscodePath = path.join(rootPath, 'vscode'); +const distroPath = path.join(rootPath, 'vscode-distro'); +const commit = cp.execSync('git rev-parse HEAD', { cwd: distroPath, encoding: 'utf8' }).trim(); +const packageJsonPath = path.join(vscodePath, 'package.json'); +const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); + +packageJson.distro = commit; +fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); \ No newline at end of file diff --git a/build/npm/update-grammar.js b/build/npm/update-grammar.js index 522b2941218..5321b7b1dcd 100644 --- a/build/npm/update-grammar.js +++ b/build/npm/update-grammar.js @@ -82,7 +82,7 @@ function getCommitSha(repoId, repoPath) { }); } -exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'master') { +exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'master', packageJsonPathOverride = '') { var contentPath = 'https://raw.githubusercontent.com/' + repoId + `/${version}/` + repoPath; console.log('Reading from ' + contentPath); return download(contentPath).then(function (content) { @@ -128,7 +128,11 @@ exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'mas // Add commit sha to cgmanifest. if (currentCommitDate > commitDate) { - let packageJsonPath = 'https://raw.githubusercontent.com/' + repoId + `/${info.commitSha}/package.json`; + let packageJsonPath = 'https://raw.githubusercontent.com/' + repoId + `/${info.commitSha}/`; + if (packageJsonPathOverride) { + packageJsonPath += packageJsonPathOverride; + } + packageJsonPath += '/package.json'; for (let i = 0; i < cgmanifestRead.registrations.length; i++) { if (cgmanifestRead.registrations[i].component.git.repositoryUrl.substr(cgmanifestRead.registrations[i].component.git.repositoryUrl.length - repoId.length, repoId.length) === repoId) { cgmanifestRead.registrations[i].component.git.commitHash = info.commitSha; diff --git a/build/package.json b/build/package.json index 9b3c626c360..622b7b59351 100644 --- a/build/package.json +++ b/build/package.json @@ -40,7 +40,7 @@ "minimist": "^1.2.0", "request": "^2.85.0", "tslint": "^5.9.1", - "typescript": "3.5.1", + "typescript": "3.5.2", "vsce": "1.48.0", "xml2js": "^0.4.17" }, diff --git a/build/win32/Cargo.lock b/build/win32/Cargo.lock index dcc1440b35e..3c95fb34cdf 100644 --- a/build/win32/Cargo.lock +++ b/build/win32/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "build_const" version = "0.2.0" @@ -27,7 +29,7 @@ dependencies = [ [[package]] name = "inno_updater" -version = "0.7.1" +version = "0.8.0" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/build/win32/code.iss b/build/win32/code.iss index ea31a50c9bf..831b31a3c71 100644 --- a/build/win32/code.iss +++ b/build/win32/code.iss @@ -1034,7 +1034,7 @@ begin AltArch := '32'; end; - if not Result then begin + if not Result and not WizardSilent() then begin MsgBox('Please uninstall the ' + AltArch + '-bit version of {#NameShort} before installing this ' + ThisArch + '-bit version.', mbInformation, MB_OK); end; end; diff --git a/build/win32/inno_updater.exe b/build/win32/inno_updater.exe index 140065f673c..baca28361d1 100644 Binary files a/build/win32/inno_updater.exe and b/build/win32/inno_updater.exe differ diff --git a/build/yarn.lock b/build/yarn.lock index da572cd1465..3bba51751e1 100644 --- a/build/yarn.lock +++ b/build/yarn.lock @@ -1894,10 +1894,10 @@ typed-rest-client@^0.9.0: tunnel "0.0.4" underscore "1.8.3" -typescript@3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.1.tgz#ba72a6a600b2158139c5dd8850f700e231464202" - integrity sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw== +typescript@3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.2.tgz#a09e1dc69bc9551cadf17dba10ee42cf55e5d56c" + integrity sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA== uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.5" diff --git a/cglicenses.json b/cglicenses.json index 3d96813f3ef..469cdedc9ad 100644 --- a/cglicenses.json +++ b/cglicenses.json @@ -6,694 +6,742 @@ // DO NOT EDIT THIS FILE UNLESS THE OSS TOOL INDICATES THAT YOU SHOULD. // [ -{ - // Reason: The license at https://github.com/aadsm/jschardet/blob/master/LICENSE - // does not include a clear Copyright statement and does not credit authors. - "name": "jschardet", - "licenseDetail": [ - "Chardet was originally ported from C++ by Mark Pilgrim. It is now maintained", - " by Dan Blanchard and Ian Cordasco, and was formerly maintained by Erik Rose.", - " JSChardet was ported from python to JavaScript by António Afonso ", - " (https://github.com/aadsm/jschardet) and transformed into an npm package by ", - "Markus Ast (https://github.com/brainafk)", - "", - "GNU LESSER GENERAL PUBLIC LICENSE", - "\t\t Version 2.1, February 1999", - "", - " Copyright (C) 1991,", - "1999 Free Software Foundation, Inc.", - " 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA", - " Everyone is permitted to copy and distribute verbatim copies", - " of this license document, but changing it is not allowed.", - "", - "[This is the first released version of the Lesser GPL. It also counts", - " as the successor of the GNU Library Public License, version 2, hence", - " the version number 2.1.", - "]", - "", - "\t\t\t Preamble", - "", - " The licenses for most software are designed to take away your", - "freedom to share and change it. By contrast, the GNU General Public", - "Licenses are intended to guarantee your freedom to share and change", - "free software--to make sure the software is free for all its users.", - "", - " This license, the Lesser General Public License, applies to some", - "specially designated software packages--typically libraries--of the", - "Free Software Foundation and other authors who decide to use it. You", - "can use it too, but we suggest you first think carefully about whether", - "this license or the ordinary General Public License is the better", - "strategy to use in any particular case, based on the explanations below.", - "", - " When we speak of free software, we are referring to freedom of use,", - "not price. Our General Public Licenses are designed to make sure that", - "you have the freedom to distribute copies of free software (and charge", - "for this service if you wish); that you receive source code or can get", - "it if you want it; that you can change the software and use pieces of", - "it in new free programs; and that you are informed that you can do", - "these things.", - "", - " To protect your rights, we need to make restrictions that forbid", - "distributors to deny you these rights or to ask you to surrender these", - "rights. These restrictions translate to certain responsibilities for", - "you if you distribute copies of the library or if you modify it.", - "", - " For example, if you distribute copies of the library, whether gratis", - "or for a fee, you must give the recipients all the rights that we gave", - "you. You must make sure that they, too, receive or can get the source", - "code. If you link other code with the library, you must provide", - "complete object files to the recipients, so that they can relink them", - "with the library after making changes to the library and recompiling", - "it. And you must show them these terms so they know their rights.", - "", - " We protect your rights with a two-step method: (1) we copyright the", - "library, and (2) we offer you this license, which gives you legal", - "permission to copy, distribute and/or modify the library.", - "", - " To protect each distributor, we want to make it very clear that", - "there is no warranty for the free library. Also, if the library is", - "modified by someone else and passed on, the recipients should know", - "that what they have is not the original version, so that the original", - "author's reputation will not be affected by problems that might be", - "introduced by others.", - "", - " Finally, software patents pose a constant threat to the existence of", - "any free program. We wish to make sure that a company cannot", - "effectively restrict the users of a free program by obtaining a", - "restrictive license from a patent holder. Therefore, we insist that", - "any patent license obtained for a version of the library must be", - "consistent with the full freedom of use specified in this license.", - "", - " Most GNU software, including some libraries, is covered by the", - "ordinary GNU General Public License. This license, the GNU Lesser", - "General Public License, applies to certain designated libraries, and", - "is quite different from the ordinary General Public License. We use", - "this license for certain libraries in order to permit linking those", - "libraries into non-free programs.", - "", - " When a program is linked with a library, whether statically or using", - "a shared library, the combination of the two is legally speaking a", - "combined work, a derivative of the original library. The ordinary", - "General Public License therefore permits such linking only if the", - "entire combination fits its criteria of freedom. The Lesser General", - "Public License permits more lax criteria for linking other code with", - "the library.", - "", - " We call this license the \"Lesser\" General Public License because it", - "does Less to protect the user's freedom than the ordinary General", - "Public License. It also provides other free software developers Less", - "of an advantage over competing non-free programs. These disadvantages", - "are the reason we use the ordinary General Public License for many", - "libraries. However, the Lesser license provides advantages in certain", - "special circumstances.", - "", - " For example, on rare occasions, there may be a special need to", - "encourage the widest possible use of a certain library, so that it becomes", - "a de-facto standard. To achieve this, non-free programs must be", - "allowed to use the library. A more frequent case is that a free", - "library does the same job as widely used non-free libraries. In this", - "case, there is little to gain by limiting the free library to free", - "software only, so we use the Lesser General Public License.", - "", - " In other cases, permission to use a particular library in non-free", - "programs enables a greater number of people to use a large body of", - "free software. For example, permission to use the GNU C Library in", - "non-free programs enables many more people to use the whole GNU", - "operating system, as well as its variant, the GNU/Linux operating", - "system.", - "", - " Although the Lesser General Public License is Less protective of the", - "users' freedom, it does ensure that the user of a program that is", - "linked with the Library has the freedom and the wherewithal to run", - "that program using a modified version of the Library.", - "", - " The precise terms and conditions for copying, distribution and", - "modification follow. Pay close attention to the difference between a", - "\"work based on the library\" and a \"work that uses the library\". The", - "former contains code derived from the library, whereas the latter must", - "be combined with the library in order to run.", - "", - "\t\t GNU LESSER GENERAL PUBLIC LICENSE", - " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION", - "", - " 0. This License Agreement applies to any software library or other", - "program which contains a notice placed by the copyright holder or", - "other authorized party saying it may be distributed under the terms of", - "this Lesser General Public License (also called \"this License\").", - "Each licensee is addressed as \"you\".", - "", - " A \"library\" means a collection of software functions and/or data", - "prepared so as to be conveniently linked with application programs", - "(which use some of those functions and data) to form executables.", - "", - " The \"Library\", below, refers to any such software library or work", - "which has been distributed under these terms. A \"work based on the", - "Library\" means either the Library or any derivative work under", - "copyright law: that is to say, a work containing the Library or a", - "portion of it, either verbatim or with modifications and/or translated", - "straightforwardly into another language. (Hereinafter, translation is", - "included without limitation in the term \"modification\".)", - "", - " \"Source code\" for a work means the preferred form of the work for", - "making modifications to it. For a library, complete source code means", - "all the source code for all modules it contains, plus any associated", - "interface definition files, plus the scripts used to control compilation", - "and installation of the library.", - "", - " Activities other than copying, distribution and modification are not", - "covered by this License; they are outside its scope. The act of", - "running a program using the Library is not restricted, and output from", - "such a program is covered only if its contents constitute a work based", - "on the Library (independent of the use of the Library in a tool for", - "writing it). Whether that is true depends on what the Library does", - "and what the program that uses the Library does.", - "", - " 1. You may copy and distribute verbatim copies of the Library's", - "complete source code as you receive it, in any medium, provided that", - "you conspicuously and appropriately publish on each copy an", - "appropriate copyright notice and disclaimer of warranty; keep intact", - "all the notices that refer to this License and to the absence of any", - "warranty; and distribute a copy of this License along with the", - "Library.", - "", - " You may charge a fee for the physical act of transferring a copy,", - "and you may at your option offer warranty protection in exchange for a", - "fee.", - "", - " 2. You may modify your copy or copies of the Library or any portion", - "of it, thus forming a work based on the Library, and copy and", - "distribute such modifications or work under the terms of Section 1", - "above, provided that you also meet all of these conditions:", - "", - " a) The modified work must itself be a software library.", - "", - " b) You must cause the files modified to carry prominent notices", - " stating that you changed the files and the date of any change.", - "", - " c) You must cause the whole of the work to be licensed at no", - " charge to all third parties under the terms of this License.", - "", - " d) If a facility in the modified Library refers to a function or a", - " table of data to be supplied by an application program that uses", - " the facility, other than as an argument passed when the facility", - " is invoked, then you must make a good faith effort to ensure that,", - " in the event an application does not supply such function or", - " table, the facility still operates, and performs whatever part of", - " its purpose remains meaningful.", - "", - " (For example, a function in a library to compute square roots has", - " a purpose that is entirely well-defined independent of the", - " application. Therefore, Subsection 2d requires that any", - " application-supplied function or table used by this function must", - " be optional: if the application does not supply it, the square", - " root function must still compute square roots.)", - "", - "These requirements apply to the modified work as a whole. If", - "identifiable sections of that work are not derived from the Library,", - "and can be reasonably considered independent and separate works in", - "themselves, then this License, and its terms, do not apply to those", - "sections when you distribute them as separate works. But when you", - "distribute the same sections as part of a whole which is a work based", - "on the Library, the distribution of the whole must be on the terms of", - "this License, whose permissions for other licensees extend to the", - "entire whole, and thus to each and every part regardless of who wrote", - "it.", - "", - "Thus, it is not the intent of this section to claim rights or contest", - "your rights to work written entirely by you; rather, the intent is to", - "exercise the right to control the distribution of derivative or", - "collective works based on the Library.", - "", - "In addition, mere aggregation of another work not based on the Library", - "with the Library (or with a work based on the Library) on a volume of", - "a storage or distribution medium does not bring the other work under", - "the scope of this License.", - "", - " 3. You may opt to apply the terms of the ordinary GNU General Public", - "License instead of this License to a given copy of the Library. To do", - "this, you must alter all the notices that refer to this License, so", - "that they refer to the ordinary GNU General Public License, version 2,", - "instead of to this License. (If a newer version than version 2 of the", - "ordinary GNU General Public License has appeared, then you can specify", - "that version instead if you wish.) Do not make any other change in", - "these notices.", - "", - " Once this change is made in a given copy, it is irreversible for", - "that copy, so the ordinary GNU General Public License applies to all", - "subsequent copies and derivative works made from that copy.", - "", - " This option is useful when you wish to copy part of the code of", - "the Library into a program that is not a library.", - "", - " 4. You may copy and distribute the Library (or a portion or", - "derivative of it, under Section 2) in object code or executable form", - "under the terms of Sections 1 and 2 above provided that you accompany", - "it with the complete corresponding machine-readable source code, which", - "must be distributed under the terms of Sections 1 and 2 above on a", - "medium customarily used for software interchange.", - "", - " If distribution of object code is made by offering access to copy", - "from a designated place, then offering equivalent access to copy the", - "source code from the same place satisfies the requirement to", - "distribute the source code, even though third parties are not", - "compelled to copy the source along with the object code.", - "", - " 5. A program that contains no derivative of any portion of the", - "Library, but is designed to work with the Library by being compiled or", - "linked with it, is called a \"work that uses the Library\". Such a", - "work, in isolation, is not a derivative work of the Library, and", - "therefore falls outside the scope of this License.", - "", - " However, linking a \"work that uses the Library\" with the Library", - "creates an executable that is a derivative of the Library (because it", - "contains portions of the Library), rather than a \"work that uses the", - "library\". The executable is therefore covered by this License.", - "Section 6 states terms for distribution of such executables.", - "", - " When a \"work that uses the Library\" uses material from a header file", - "that is part of the Library, the object code for the work may be a", - "derivative work of the Library even though the source code is not.", - "Whether this is true is especially significant if the work can be", - "linked without the Library, or if the work is itself a library. The", - "threshold for this to be true is not precisely defined by law.", - "", - " If such an object file uses only numerical parameters, data", - "structure layouts and accessors, and small macros and small inline", - "functions (ten lines or less in length), then the use of the object", - "file is unrestricted, regardless of whether it is legally a derivative", - "work. (Executables containing this object code plus portions of the", - "Library will still fall under Section 6.)", - "", - " Otherwise, if the work is a derivative of the Library, you may", - "distribute the object code for the work under the terms of Section 6.", - "Any executables containing that work also fall under Section 6,", - "whether or not they are linked directly with the Library itself.", - "", - " 6. As an exception to the Sections above, you may also combine or", - "link a \"work that uses the Library\" with the Library to produce a", - "work containing portions of the Library, and distribute that work", - "under terms of your choice, provided that the terms permit", - "modification of the work for the customer's own use and reverse", - "engineering for debugging such modifications.", - "", - " You must give prominent notice with each copy of the work that the", - "Library is used in it and that the Library and its use are covered by", - "this License. You must supply a copy of this License. If the work", - "during execution displays copyright notices, you must include the", - "copyright notice for the Library among them, as well as a reference", - "directing the user to the copy of this License. Also, you must do one", - "of these things:", - "", - " a) Accompany the work with the complete corresponding", - " machine-readable source code for the Library including whatever", - " changes were used in the work (which must be distributed under", - " Sections 1 and 2 above); and, if the work is an executable linked", - " with the Library, with the complete machine-readable \"work that", - " uses the Library\", as object code and/or source code, so that the", - " user can modify the Library and then relink to produce a modified", - " executable containing the modified Library. (It is understood", - " that the user who changes the contents of definitions files in the", - " Library will not necessarily be able to recompile the application", - " to use the modified definitions.)", - "", - " b) Use a suitable shared library mechanism for linking with the", - " Library. A suitable mechanism is one that (1) uses at run time a", - " copy of the library already present on the user's computer system,", - " rather than copying library functions into the executable, and (2)", - " will operate properly with a modified version of the library, if", - " the user installs one, as long as the modified version is", - " interface-compatible with the version that the work was made with.", - "", - " c) Accompany the work with a written offer, valid for at", - " least three years, to give the same user the materials", - " specified in Subsection 6a, above, for a charge no more", - " than the cost of performing this distribution.", - "", - " d) If distribution of the work is made by offering access to copy", - " from a designated place, offer equivalent access to copy the above", - " specified materials from the same place.", - "", - " e) Verify that the user has already received a copy of these", - " materials or that you have already sent this user a copy.", - "", - " For an executable, the required form of the \"work that uses the", - "Library\" must include any data and utility programs needed for", - "reproducing the executable from it. However, as a special exception,", - "the materials to be distributed need not include anything that is", - "normally distributed (in either source or binary form) with the major", - "components (compiler, kernel, and so on) of the operating system on", - "which the executable runs, unless that component itself accompanies", - "the executable.", - "", - " It may happen that this requirement contradicts the license", - "restrictions of other proprietary libraries that do not normally", - "accompany the operating system. Such a contradiction means you cannot", - "use both them and the Library together in an executable that you", - "distribute.", - "", - " 7. You may place library facilities that are a work based on the", - "Library side-by-side in a single library together with other library", - "facilities not covered by this License, and distribute such a combined", - "library, provided that the separate distribution of the work based on", - "the Library and of the other library facilities is otherwise", - "permitted, and provided that you do these two things:", - "", - " a) Accompany the combined library with a copy of the same work", - " based on the Library, uncombined with any other library", - " facilities. This must be distributed under the terms of the", - " Sections above.", - "", - " b) Give prominent notice with the combined library of the fact", - " that part of it is a work based on the Library, and explaining", - " where to find the accompanying uncombined form of the same work.", - "", - " 8. You may not copy, modify, sublicense, link with, or distribute", - "the Library except as expressly provided under this License. Any", - "attempt otherwise to copy, modify, sublicense, link with, or", - "distribute the Library is void, and will automatically terminate your", - "rights under this License. However, parties who have received copies,", - "or rights, from you under this License will not have their licenses", - "terminated so long as such parties remain in full compliance.", - "", - " 9. You are not required to accept this License, since you have not", - "signed it. However, nothing else grants you permission to modify or", - "distribute the Library or its derivative works. These actions are", - "prohibited by law if you do not accept this License. Therefore, by", - "modifying or distributing the Library (or any work based on the", - "Library), you indicate your acceptance of this License to do so, and", - "all its terms and conditions for copying, distributing or modifying", - "the Library or works based on it.", - "", - " 10. Each time you redistribute the Library (or any work based on the", - "Library), the recipient automatically receives a license from the", - "original licensor to copy, distribute, link with or modify the Library", - "subject to these terms and conditions. You may not impose any further", - "restrictions on the recipients' exercise of the rights granted herein.", - "You are not responsible for enforcing compliance by third parties with", - "this License.", - "", - " 11. If, as a consequence of a court judgment or allegation of patent", - "infringement or for any other reason (not limited to patent issues),", - "conditions are imposed on you (whether by court order, agreement or", - "otherwise) that contradict the conditions of this License, they do not", - "excuse you from the conditions of this License. If you cannot", - "distribute so as to satisfy simultaneously your obligations under this", - "License and any other pertinent obligations, then as a consequence you", - "may not distribute the Library at all. For example, if a patent", - "license would not permit royalty-free redistribution of the Library by", - "all those who receive copies directly or indirectly through you, then", - "the only way you could satisfy both it and this License would be to", - "refrain entirely from distribution of the Library.", - "", - "If any portion of this section is held invalid or unenforceable under any", - "particular circumstance, the balance of the section is intended to apply,", - "and the section as a whole is intended to apply in other circumstances.", - "", - "It is not the purpose of this section to induce you to infringe any", - "patents or other property right claims or to contest validity of any", - "such claims; this section has the sole purpose of protecting the", - "integrity of the free software distribution system which is", - "implemented by public license practices. Many people have made", - "generous contributions to the wide range of software distributed", - "through that system in reliance on consistent application of that", - "system; it is up to the author/donor to decide if he or she is willing", - "to distribute software through any other system and a licensee cannot", - "impose that choice.", - "", - "This section is intended to make thoroughly clear what is believed to", - "be a consequence of the rest of this License.", - "", - " 12. If the distribution and/or use of the Library is restricted in", - "certain countries either by patents or by copyrighted interfaces, the", - "original copyright holder who places the Library under this License may add", - "an explicit geographical distribution limitation excluding those countries,", - "so that distribution is permitted only in or among countries not thus", - "excluded. In such case, this License incorporates the limitation as if", - "written in the body of this License.", - "", - " 13. The Free Software Foundation may publish revised and/or new", - "versions of the Lesser General Public License from time to time.", - "Such new versions will be similar in spirit to the present version,", - "but may differ in detail to address new problems or concerns.", - "", - "Each version is given a distinguishing version number. If the Library", - "specifies a version number of this License which applies to it and", - "\"any later version\", you have the option of following the terms and", - "conditions either of that version or of any later version published by", - "the Free Software Foundation. If the Library does not specify a", - "license version number, you may choose any version ever published by", - "the Free Software Foundation.", - "", - " 14. If you wish to incorporate parts of the Library into other free", - "programs whose distribution conditions are incompatible with these,", - "write to the author to ask for permission. For software which is", - "copyrighted by the Free Software Foundation, write to the Free", - "Software Foundation; we sometimes make exceptions for this. Our", - "decision will be guided by the two goals of preserving the free status", - "of all derivatives of our free software and of promoting the sharing", - "and reuse of software generally.", - "", - "\t\t\t NO WARRANTY", - "", - " 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO", - "WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.", - "EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR", - "OTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY", - "KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE", - "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR", - "PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE", - "LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME", - "THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.", - "", - " 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN", - "WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY", - "AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU", - "FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR", - "CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE", - "LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING", - "RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A", - "FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF", - "SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH", - "DAMAGES.", - "", - "\t\t END OF TERMS AND CONDITIONS", - "", - " How to Apply These Terms to Your New Libraries", - "", - " If you develop a new library, and you want it to be of the greatest", - "possible use to the public, we recommend making it free software that", - "everyone can redistribute and change. You can do so by permitting", - "redistribution under these terms (or, alternatively, under the terms of the", - "ordinary General Public License).", - "", - " To apply these terms, attach the following notices to the library. It is", - "safest to attach them to the start of each source file to most effectively", - "convey the exclusion of warranty; and each file should have at least the", - "\"copyright\" line and a pointer to where the full notice is found.", - "", - " ", - " Copyright (C) ", - "", - " This library is free software; you can redistribute it and/or", - " modify it under the terms of the GNU Lesser General Public", - " License as published by the Free Software Foundation; either", - " version 2.1 of the License, or (at your option) any later version.", - "", - " This library is distributed in the hope that it will be useful,", - " but WITHOUT ANY WARRANTY; without even the implied warranty of", - " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU", - " Lesser General Public License for more details.", - "", - " You should have received a copy of the GNU Lesser General Public", - " License along with this library; if not, write to the Free Software", - " Foundation, Inc.,", - "51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA", - "", - "Also add information on how to contact you by electronic and paper mail.", - "", - "You should also get your employer (if you work as a programmer) or your", - "school, if any, to sign a \"copyright disclaimer\" for the library, if", - "necessary. Here is a sample; alter the names:", - "", - " Yoyodyne, Inc., hereby disclaims all copyright interest in the", - " library `Frob' (a library for tweaking knobs) written by James Random Hacker.", - "", - " ,", - "1 April 1990", - " Ty Coon, President of Vice", - "", - "That's all there is to it!" - ] -}, -{ - // Added here because the module `parse5` has a dependency to it. - // The module `parse5` is shipped via the `extension-editing` built-in extension. - // The module `parse5` does not want to remove it https://github.com/inikulin/parse5/issues/225 - "name": "@types/node", - "licenseDetail": [ - "This project is licensed under the MIT license.", - "Copyrights are respective of each contributor listed at the beginning of each definition file.", - "", - "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", - "", - "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", - "", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." - ] -}, -{ - // We override the license that gets discovered at - // https://github.com/Microsoft/TypeScript/blob/master/LICENSE.txt - // because it does not contain a Copyright statement - "name": "typescript", - "licenseDetail": [ - "Copyright (c) Microsoft Corporation. All rights reserved.", - "", - "Apache License", - "", - "Version 2.0, January 2004", - "", - "http://www.apache.org/licenses/", - "", - "TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION", - "", - "1. Definitions.", - "", - "\"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.", - "", - "\"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.", - "", - "\"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.", - "", - "\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.", - "", - "\"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.", - "", - "\"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.", - "", - "\"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).", - "", - "\"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.", - "", - "\"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"", - "", - "\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.", - "", - "2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.", - "", - "3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.", - "", - "4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:", - "", - "You must give any other recipients of the Work or Derivative Works a copy of this License; and", - "", - "You must cause any modified files to carry prominent notices stating that You changed the files; and", - "", - "You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and", - "", - "If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.", - "", - "5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.", - "", - "6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.", - "", - "7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.", - "", - "8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.", - "", - "9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.", - "", - "END OF TERMS AND CONDITIONS" - ] -}, -{ - // This module comes in from https://github.com/Microsoft/vscode-node-debug2/blob/master/package-lock.json - "name": "@types/source-map", - "licenseDetail": [ - "This project is licensed under the MIT license.", - "Copyrights are respective of each contributor listed at the beginning of each definition file.", - "", - "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", - "", - "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", - "", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." - ] -}, -{ - "name": "tunnel-agent", - "licenseDetail": [ - "Copyright (c) tunnel-agent authors", - "", - "Apache License", - "", - "Version 2.0, January 2004", - "", - "http://www.apache.org/licenses/", - "", - "TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION", - "", - "1. Definitions.", - "", - "\"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.", - "", - "\"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.", - "", - "\"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.", - "", - "\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.", - "", - "\"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.", - "", - "\"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.", - "", - "\"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).", - "", - "\"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.", - "", - "\"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"", - "", - "\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.", - "", - "2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.", - "", - "3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.", - "", - "4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:", - "", - "You must give any other recipients of the Work or Derivative Works a copy of this License; and", - "", - "You must cause any modified files to carry prominent notices stating that You changed the files; and", - "", - "You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and", - "", - "If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.", - "", - "5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.", - "", - "6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.", - "", - "7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.", - "", - "8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.", - "", - "9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.", - "", - "END OF TERMS AND CONDITIONS" - ] -}, -{ - // Waiting for https://github.com/segmentio/noop-logger/issues/2 - "name": "noop-logger", - "licenseDetail": [ - "This project is licensed under the MIT license.", - "Copyrights are respective of each contributor listed at the beginning of each definition file.", - "", - "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", - "", - "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", - "", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." - ] -} -] \ No newline at end of file + { + // Reason: The license at https://github.com/aadsm/jschardet/blob/master/LICENSE + // does not include a clear Copyright statement and does not credit authors. + "name": "jschardet", + "licenseDetail": [ + "Chardet was originally ported from C++ by Mark Pilgrim. It is now maintained", + " by Dan Blanchard and Ian Cordasco, and was formerly maintained by Erik Rose.", + " JSChardet was ported from python to JavaScript by António Afonso ", + " (https://github.com/aadsm/jschardet) and transformed into an npm package by ", + "Markus Ast (https://github.com/brainafk)", + "", + "GNU LESSER GENERAL PUBLIC LICENSE", + "\t\t Version 2.1, February 1999", + "", + " Copyright (C) 1991,", + "1999 Free Software Foundation, Inc.", + " 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA", + " Everyone is permitted to copy and distribute verbatim copies", + " of this license document, but changing it is not allowed.", + "", + "[This is the first released version of the Lesser GPL. It also counts", + " as the successor of the GNU Library Public License, version 2, hence", + " the version number 2.1.", + "]", + "", + "\t\t\t Preamble", + "", + " The licenses for most software are designed to take away your", + "freedom to share and change it. By contrast, the GNU General Public", + "Licenses are intended to guarantee your freedom to share and change", + "free software--to make sure the software is free for all its users.", + "", + " This license, the Lesser General Public License, applies to some", + "specially designated software packages--typically libraries--of the", + "Free Software Foundation and other authors who decide to use it. You", + "can use it too, but we suggest you first think carefully about whether", + "this license or the ordinary General Public License is the better", + "strategy to use in any particular case, based on the explanations below.", + "", + " When we speak of free software, we are referring to freedom of use,", + "not price. Our General Public Licenses are designed to make sure that", + "you have the freedom to distribute copies of free software (and charge", + "for this service if you wish); that you receive source code or can get", + "it if you want it; that you can change the software and use pieces of", + "it in new free programs; and that you are informed that you can do", + "these things.", + "", + " To protect your rights, we need to make restrictions that forbid", + "distributors to deny you these rights or to ask you to surrender these", + "rights. These restrictions translate to certain responsibilities for", + "you if you distribute copies of the library or if you modify it.", + "", + " For example, if you distribute copies of the library, whether gratis", + "or for a fee, you must give the recipients all the rights that we gave", + "you. You must make sure that they, too, receive or can get the source", + "code. If you link other code with the library, you must provide", + "complete object files to the recipients, so that they can relink them", + "with the library after making changes to the library and recompiling", + "it. And you must show them these terms so they know their rights.", + "", + " We protect your rights with a two-step method: (1) we copyright the", + "library, and (2) we offer you this license, which gives you legal", + "permission to copy, distribute and/or modify the library.", + "", + " To protect each distributor, we want to make it very clear that", + "there is no warranty for the free library. Also, if the library is", + "modified by someone else and passed on, the recipients should know", + "that what they have is not the original version, so that the original", + "author's reputation will not be affected by problems that might be", + "introduced by others.", + "", + " Finally, software patents pose a constant threat to the existence of", + "any free program. We wish to make sure that a company cannot", + "effectively restrict the users of a free program by obtaining a", + "restrictive license from a patent holder. Therefore, we insist that", + "any patent license obtained for a version of the library must be", + "consistent with the full freedom of use specified in this license.", + "", + " Most GNU software, including some libraries, is covered by the", + "ordinary GNU General Public License. This license, the GNU Lesser", + "General Public License, applies to certain designated libraries, and", + "is quite different from the ordinary General Public License. We use", + "this license for certain libraries in order to permit linking those", + "libraries into non-free programs.", + "", + " When a program is linked with a library, whether statically or using", + "a shared library, the combination of the two is legally speaking a", + "combined work, a derivative of the original library. The ordinary", + "General Public License therefore permits such linking only if the", + "entire combination fits its criteria of freedom. The Lesser General", + "Public License permits more lax criteria for linking other code with", + "the library.", + "", + " We call this license the \"Lesser\" General Public License because it", + "does Less to protect the user's freedom than the ordinary General", + "Public License. It also provides other free software developers Less", + "of an advantage over competing non-free programs. These disadvantages", + "are the reason we use the ordinary General Public License for many", + "libraries. However, the Lesser license provides advantages in certain", + "special circumstances.", + "", + " For example, on rare occasions, there may be a special need to", + "encourage the widest possible use of a certain library, so that it becomes", + "a de-facto standard. To achieve this, non-free programs must be", + "allowed to use the library. A more frequent case is that a free", + "library does the same job as widely used non-free libraries. In this", + "case, there is little to gain by limiting the free library to free", + "software only, so we use the Lesser General Public License.", + "", + " In other cases, permission to use a particular library in non-free", + "programs enables a greater number of people to use a large body of", + "free software. For example, permission to use the GNU C Library in", + "non-free programs enables many more people to use the whole GNU", + "operating system, as well as its variant, the GNU/Linux operating", + "system.", + "", + " Although the Lesser General Public License is Less protective of the", + "users' freedom, it does ensure that the user of a program that is", + "linked with the Library has the freedom and the wherewithal to run", + "that program using a modified version of the Library.", + "", + " The precise terms and conditions for copying, distribution and", + "modification follow. Pay close attention to the difference between a", + "\"work based on the library\" and a \"work that uses the library\". The", + "former contains code derived from the library, whereas the latter must", + "be combined with the library in order to run.", + "", + "\t\t GNU LESSER GENERAL PUBLIC LICENSE", + " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION", + "", + " 0. This License Agreement applies to any software library or other", + "program which contains a notice placed by the copyright holder or", + "other authorized party saying it may be distributed under the terms of", + "this Lesser General Public License (also called \"this License\").", + "Each licensee is addressed as \"you\".", + "", + " A \"library\" means a collection of software functions and/or data", + "prepared so as to be conveniently linked with application programs", + "(which use some of those functions and data) to form executables.", + "", + " The \"Library\", below, refers to any such software library or work", + "which has been distributed under these terms. A \"work based on the", + "Library\" means either the Library or any derivative work under", + "copyright law: that is to say, a work containing the Library or a", + "portion of it, either verbatim or with modifications and/or translated", + "straightforwardly into another language. (Hereinafter, translation is", + "included without limitation in the term \"modification\".)", + "", + " \"Source code\" for a work means the preferred form of the work for", + "making modifications to it. For a library, complete source code means", + "all the source code for all modules it contains, plus any associated", + "interface definition files, plus the scripts used to control compilation", + "and installation of the library.", + "", + " Activities other than copying, distribution and modification are not", + "covered by this License; they are outside its scope. The act of", + "running a program using the Library is not restricted, and output from", + "such a program is covered only if its contents constitute a work based", + "on the Library (independent of the use of the Library in a tool for", + "writing it). Whether that is true depends on what the Library does", + "and what the program that uses the Library does.", + "", + " 1. You may copy and distribute verbatim copies of the Library's", + "complete source code as you receive it, in any medium, provided that", + "you conspicuously and appropriately publish on each copy an", + "appropriate copyright notice and disclaimer of warranty; keep intact", + "all the notices that refer to this License and to the absence of any", + "warranty; and distribute a copy of this License along with the", + "Library.", + "", + " You may charge a fee for the physical act of transferring a copy,", + "and you may at your option offer warranty protection in exchange for a", + "fee.", + "", + " 2. You may modify your copy or copies of the Library or any portion", + "of it, thus forming a work based on the Library, and copy and", + "distribute such modifications or work under the terms of Section 1", + "above, provided that you also meet all of these conditions:", + "", + " a) The modified work must itself be a software library.", + "", + " b) You must cause the files modified to carry prominent notices", + " stating that you changed the files and the date of any change.", + "", + " c) You must cause the whole of the work to be licensed at no", + " charge to all third parties under the terms of this License.", + "", + " d) If a facility in the modified Library refers to a function or a", + " table of data to be supplied by an application program that uses", + " the facility, other than as an argument passed when the facility", + " is invoked, then you must make a good faith effort to ensure that,", + " in the event an application does not supply such function or", + " table, the facility still operates, and performs whatever part of", + " its purpose remains meaningful.", + "", + " (For example, a function in a library to compute square roots has", + " a purpose that is entirely well-defined independent of the", + " application. Therefore, Subsection 2d requires that any", + " application-supplied function or table used by this function must", + " be optional: if the application does not supply it, the square", + " root function must still compute square roots.)", + "", + "These requirements apply to the modified work as a whole. If", + "identifiable sections of that work are not derived from the Library,", + "and can be reasonably considered independent and separate works in", + "themselves, then this License, and its terms, do not apply to those", + "sections when you distribute them as separate works. But when you", + "distribute the same sections as part of a whole which is a work based", + "on the Library, the distribution of the whole must be on the terms of", + "this License, whose permissions for other licensees extend to the", + "entire whole, and thus to each and every part regardless of who wrote", + "it.", + "", + "Thus, it is not the intent of this section to claim rights or contest", + "your rights to work written entirely by you; rather, the intent is to", + "exercise the right to control the distribution of derivative or", + "collective works based on the Library.", + "", + "In addition, mere aggregation of another work not based on the Library", + "with the Library (or with a work based on the Library) on a volume of", + "a storage or distribution medium does not bring the other work under", + "the scope of this License.", + "", + " 3. You may opt to apply the terms of the ordinary GNU General Public", + "License instead of this License to a given copy of the Library. To do", + "this, you must alter all the notices that refer to this License, so", + "that they refer to the ordinary GNU General Public License, version 2,", + "instead of to this License. (If a newer version than version 2 of the", + "ordinary GNU General Public License has appeared, then you can specify", + "that version instead if you wish.) Do not make any other change in", + "these notices.", + "", + " Once this change is made in a given copy, it is irreversible for", + "that copy, so the ordinary GNU General Public License applies to all", + "subsequent copies and derivative works made from that copy.", + "", + " This option is useful when you wish to copy part of the code of", + "the Library into a program that is not a library.", + "", + " 4. You may copy and distribute the Library (or a portion or", + "derivative of it, under Section 2) in object code or executable form", + "under the terms of Sections 1 and 2 above provided that you accompany", + "it with the complete corresponding machine-readable source code, which", + "must be distributed under the terms of Sections 1 and 2 above on a", + "medium customarily used for software interchange.", + "", + " If distribution of object code is made by offering access to copy", + "from a designated place, then offering equivalent access to copy the", + "source code from the same place satisfies the requirement to", + "distribute the source code, even though third parties are not", + "compelled to copy the source along with the object code.", + "", + " 5. A program that contains no derivative of any portion of the", + "Library, but is designed to work with the Library by being compiled or", + "linked with it, is called a \"work that uses the Library\". Such a", + "work, in isolation, is not a derivative work of the Library, and", + "therefore falls outside the scope of this License.", + "", + " However, linking a \"work that uses the Library\" with the Library", + "creates an executable that is a derivative of the Library (because it", + "contains portions of the Library), rather than a \"work that uses the", + "library\". The executable is therefore covered by this License.", + "Section 6 states terms for distribution of such executables.", + "", + " When a \"work that uses the Library\" uses material from a header file", + "that is part of the Library, the object code for the work may be a", + "derivative work of the Library even though the source code is not.", + "Whether this is true is especially significant if the work can be", + "linked without the Library, or if the work is itself a library. The", + "threshold for this to be true is not precisely defined by law.", + "", + " If such an object file uses only numerical parameters, data", + "structure layouts and accessors, and small macros and small inline", + "functions (ten lines or less in length), then the use of the object", + "file is unrestricted, regardless of whether it is legally a derivative", + "work. (Executables containing this object code plus portions of the", + "Library will still fall under Section 6.)", + "", + " Otherwise, if the work is a derivative of the Library, you may", + "distribute the object code for the work under the terms of Section 6.", + "Any executables containing that work also fall under Section 6,", + "whether or not they are linked directly with the Library itself.", + "", + " 6. As an exception to the Sections above, you may also combine or", + "link a \"work that uses the Library\" with the Library to produce a", + "work containing portions of the Library, and distribute that work", + "under terms of your choice, provided that the terms permit", + "modification of the work for the customer's own use and reverse", + "engineering for debugging such modifications.", + "", + " You must give prominent notice with each copy of the work that the", + "Library is used in it and that the Library and its use are covered by", + "this License. You must supply a copy of this License. If the work", + "during execution displays copyright notices, you must include the", + "copyright notice for the Library among them, as well as a reference", + "directing the user to the copy of this License. Also, you must do one", + "of these things:", + "", + " a) Accompany the work with the complete corresponding", + " machine-readable source code for the Library including whatever", + " changes were used in the work (which must be distributed under", + " Sections 1 and 2 above); and, if the work is an executable linked", + " with the Library, with the complete machine-readable \"work that", + " uses the Library\", as object code and/or source code, so that the", + " user can modify the Library and then relink to produce a modified", + " executable containing the modified Library. (It is understood", + " that the user who changes the contents of definitions files in the", + " Library will not necessarily be able to recompile the application", + " to use the modified definitions.)", + "", + " b) Use a suitable shared library mechanism for linking with the", + " Library. A suitable mechanism is one that (1) uses at run time a", + " copy of the library already present on the user's computer system,", + " rather than copying library functions into the executable, and (2)", + " will operate properly with a modified version of the library, if", + " the user installs one, as long as the modified version is", + " interface-compatible with the version that the work was made with.", + "", + " c) Accompany the work with a written offer, valid for at", + " least three years, to give the same user the materials", + " specified in Subsection 6a, above, for a charge no more", + " than the cost of performing this distribution.", + "", + " d) If distribution of the work is made by offering access to copy", + " from a designated place, offer equivalent access to copy the above", + " specified materials from the same place.", + "", + " e) Verify that the user has already received a copy of these", + " materials or that you have already sent this user a copy.", + "", + " For an executable, the required form of the \"work that uses the", + "Library\" must include any data and utility programs needed for", + "reproducing the executable from it. However, as a special exception,", + "the materials to be distributed need not include anything that is", + "normally distributed (in either source or binary form) with the major", + "components (compiler, kernel, and so on) of the operating system on", + "which the executable runs, unless that component itself accompanies", + "the executable.", + "", + " It may happen that this requirement contradicts the license", + "restrictions of other proprietary libraries that do not normally", + "accompany the operating system. Such a contradiction means you cannot", + "use both them and the Library together in an executable that you", + "distribute.", + "", + " 7. You may place library facilities that are a work based on the", + "Library side-by-side in a single library together with other library", + "facilities not covered by this License, and distribute such a combined", + "library, provided that the separate distribution of the work based on", + "the Library and of the other library facilities is otherwise", + "permitted, and provided that you do these two things:", + "", + " a) Accompany the combined library with a copy of the same work", + " based on the Library, uncombined with any other library", + " facilities. This must be distributed under the terms of the", + " Sections above.", + "", + " b) Give prominent notice with the combined library of the fact", + " that part of it is a work based on the Library, and explaining", + " where to find the accompanying uncombined form of the same work.", + "", + " 8. You may not copy, modify, sublicense, link with, or distribute", + "the Library except as expressly provided under this License. Any", + "attempt otherwise to copy, modify, sublicense, link with, or", + "distribute the Library is void, and will automatically terminate your", + "rights under this License. However, parties who have received copies,", + "or rights, from you under this License will not have their licenses", + "terminated so long as such parties remain in full compliance.", + "", + " 9. You are not required to accept this License, since you have not", + "signed it. However, nothing else grants you permission to modify or", + "distribute the Library or its derivative works. These actions are", + "prohibited by law if you do not accept this License. Therefore, by", + "modifying or distributing the Library (or any work based on the", + "Library), you indicate your acceptance of this License to do so, and", + "all its terms and conditions for copying, distributing or modifying", + "the Library or works based on it.", + "", + " 10. Each time you redistribute the Library (or any work based on the", + "Library), the recipient automatically receives a license from the", + "original licensor to copy, distribute, link with or modify the Library", + "subject to these terms and conditions. You may not impose any further", + "restrictions on the recipients' exercise of the rights granted herein.", + "You are not responsible for enforcing compliance by third parties with", + "this License.", + "", + " 11. If, as a consequence of a court judgment or allegation of patent", + "infringement or for any other reason (not limited to patent issues),", + "conditions are imposed on you (whether by court order, agreement or", + "otherwise) that contradict the conditions of this License, they do not", + "excuse you from the conditions of this License. If you cannot", + "distribute so as to satisfy simultaneously your obligations under this", + "License and any other pertinent obligations, then as a consequence you", + "may not distribute the Library at all. For example, if a patent", + "license would not permit royalty-free redistribution of the Library by", + "all those who receive copies directly or indirectly through you, then", + "the only way you could satisfy both it and this License would be to", + "refrain entirely from distribution of the Library.", + "", + "If any portion of this section is held invalid or unenforceable under any", + "particular circumstance, the balance of the section is intended to apply,", + "and the section as a whole is intended to apply in other circumstances.", + "", + "It is not the purpose of this section to induce you to infringe any", + "patents or other property right claims or to contest validity of any", + "such claims; this section has the sole purpose of protecting the", + "integrity of the free software distribution system which is", + "implemented by public license practices. Many people have made", + "generous contributions to the wide range of software distributed", + "through that system in reliance on consistent application of that", + "system; it is up to the author/donor to decide if he or she is willing", + "to distribute software through any other system and a licensee cannot", + "impose that choice.", + "", + "This section is intended to make thoroughly clear what is believed to", + "be a consequence of the rest of this License.", + "", + " 12. If the distribution and/or use of the Library is restricted in", + "certain countries either by patents or by copyrighted interfaces, the", + "original copyright holder who places the Library under this License may add", + "an explicit geographical distribution limitation excluding those countries,", + "so that distribution is permitted only in or among countries not thus", + "excluded. In such case, this License incorporates the limitation as if", + "written in the body of this License.", + "", + " 13. The Free Software Foundation may publish revised and/or new", + "versions of the Lesser General Public License from time to time.", + "Such new versions will be similar in spirit to the present version,", + "but may differ in detail to address new problems or concerns.", + "", + "Each version is given a distinguishing version number. If the Library", + "specifies a version number of this License which applies to it and", + "\"any later version\", you have the option of following the terms and", + "conditions either of that version or of any later version published by", + "the Free Software Foundation. If the Library does not specify a", + "license version number, you may choose any version ever published by", + "the Free Software Foundation.", + "", + " 14. If you wish to incorporate parts of the Library into other free", + "programs whose distribution conditions are incompatible with these,", + "write to the author to ask for permission. For software which is", + "copyrighted by the Free Software Foundation, write to the Free", + "Software Foundation; we sometimes make exceptions for this. Our", + "decision will be guided by the two goals of preserving the free status", + "of all derivatives of our free software and of promoting the sharing", + "and reuse of software generally.", + "", + "\t\t\t NO WARRANTY", + "", + " 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO", + "WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.", + "EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR", + "OTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY", + "KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE", + "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR", + "PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE", + "LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME", + "THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.", + "", + " 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN", + "WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY", + "AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU", + "FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR", + "CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE", + "LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING", + "RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A", + "FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF", + "SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH", + "DAMAGES.", + "", + "\t\t END OF TERMS AND CONDITIONS", + "", + " How to Apply These Terms to Your New Libraries", + "", + " If you develop a new library, and you want it to be of the greatest", + "possible use to the public, we recommend making it free software that", + "everyone can redistribute and change. You can do so by permitting", + "redistribution under these terms (or, alternatively, under the terms of the", + "ordinary General Public License).", + "", + " To apply these terms, attach the following notices to the library. It is", + "safest to attach them to the start of each source file to most effectively", + "convey the exclusion of warranty; and each file should have at least the", + "\"copyright\" line and a pointer to where the full notice is found.", + "", + " ", + " Copyright (C) ", + "", + " This library is free software; you can redistribute it and/or", + " modify it under the terms of the GNU Lesser General Public", + " License as published by the Free Software Foundation; either", + " version 2.1 of the License, or (at your option) any later version.", + "", + " This library is distributed in the hope that it will be useful,", + " but WITHOUT ANY WARRANTY; without even the implied warranty of", + " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU", + " Lesser General Public License for more details.", + "", + " You should have received a copy of the GNU Lesser General Public", + " License along with this library; if not, write to the Free Software", + " Foundation, Inc.,", + "51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA", + "", + "Also add information on how to contact you by electronic and paper mail.", + "", + "You should also get your employer (if you work as a programmer) or your", + "school, if any, to sign a \"copyright disclaimer\" for the library, if", + "necessary. Here is a sample; alter the names:", + "", + " Yoyodyne, Inc., hereby disclaims all copyright interest in the", + " library `Frob' (a library for tweaking knobs) written by James Random Hacker.", + "", + " ,", + "1 April 1990", + " Ty Coon, President of Vice", + "", + "That's all there is to it!" + ] + }, + { + // Added here because the module `parse5` has a dependency to it. + // The module `parse5` is shipped via the `extension-editing` built-in extension. + // The module `parse5` does not want to remove it https://github.com/inikulin/parse5/issues/225 + "name": "@types/node", + "licenseDetail": [ + "This project is licensed under the MIT license.", + "Copyrights are respective of each contributor listed at the beginning of each definition file.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + ] + }, + { + // We override the license that gets discovered at + // https://github.com/Microsoft/TypeScript/blob/master/LICENSE.txt + // because it does not contain a Copyright statement + "name": "typescript", + "licenseDetail": [ + "Copyright (c) Microsoft Corporation. All rights reserved.", + "", + "Apache License", + "", + "Version 2.0, January 2004", + "", + "http://www.apache.org/licenses/", + "", + "TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION", + "", + "1. Definitions.", + "", + "\"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.", + "", + "\"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.", + "", + "\"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.", + "", + "\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.", + "", + "\"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.", + "", + "\"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.", + "", + "\"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).", + "", + "\"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.", + "", + "\"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"", + "", + "\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.", + "", + "2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.", + "", + "3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.", + "", + "4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:", + "", + "You must give any other recipients of the Work or Derivative Works a copy of this License; and", + "", + "You must cause any modified files to carry prominent notices stating that You changed the files; and", + "", + "You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and", + "", + "If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.", + "", + "5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.", + "", + "6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.", + "", + "7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.", + "", + "8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.", + "", + "9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.", + "", + "END OF TERMS AND CONDITIONS" + ] + }, + { + // This module comes in from https://github.com/Microsoft/vscode-node-debug2/blob/master/package-lock.json + "name": "@types/source-map", + "licenseDetail": [ + "This project is licensed under the MIT license.", + "Copyrights are respective of each contributor listed at the beginning of each definition file.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + ] + }, + { + "name": "tunnel-agent", + "licenseDetail": [ + "Copyright (c) tunnel-agent authors", + "", + "Apache License", + "", + "Version 2.0, January 2004", + "", + "http://www.apache.org/licenses/", + "", + "TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION", + "", + "1. Definitions.", + "", + "\"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.", + "", + "\"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.", + "", + "\"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.", + "", + "\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.", + "", + "\"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.", + "", + "\"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.", + "", + "\"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).", + "", + "\"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.", + "", + "\"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"", + "", + "\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.", + "", + "2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.", + "", + "3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.", + "", + "4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:", + "", + "You must give any other recipients of the Work or Derivative Works a copy of this License; and", + "", + "You must cause any modified files to carry prominent notices stating that You changed the files; and", + "", + "You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and", + "", + "If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.", + "", + "5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.", + "", + "6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.", + "", + "7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.", + "", + "8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.", + "", + "9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.", + "", + "END OF TERMS AND CONDITIONS" + ] + }, + { + // Waiting for https://github.com/segmentio/noop-logger/issues/2 + "name": "noop-logger", + "licenseDetail": [ + "This project is licensed under the MIT license.", + "Copyrights are respective of each contributor listed at the beginning of each definition file.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + ] + }, + { + "name": "xterm-addon-search", + "licenseDetail": [ + "Copyright (c) 2017, The xterm.js authors (https://github.com/xtermjs/xterm.js)", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and associated documentation files (the \"Software\"), to deal", + "in the Software without restriction, including without limitation the rights", + "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell", + "copies of the Software, and to permit persons to whom the Software is", + "furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", + "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE", + "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,", + "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN", + "THE SOFTWARE." + ] + }, + { + "name": "xterm-addon-web-links", + "licenseDetail": [ + "Copyright (c) 2017, The xterm.js authors (https://github.com/xtermjs/xterm.js)", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and associated documentation files (the \"Software\"), to deal", + "in the Software without restriction, including without limitation the rights", + "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell", + "copies of the Software, and to permit persons to whom the Software is", + "furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", + "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE", + "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,", + "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN", + "THE SOFTWARE." + ] + } +] diff --git a/cgmanifest.json b/cgmanifest.json index 6cebbffd6b9..b8c4f3bfefc 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -60,12 +60,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "c1b5a1cfc8a14a337540193daecfa5d0f50dd7bb" + "commitHash": "5d67ec3da5376a5058990e8a9557bc9124ad59a8" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "4.2.3" + "version": "4.2.5" }, { "component": { diff --git a/extensions/cpp/build/update-grammars.js b/extensions/cpp/build/update-grammars.js index 406b326156c..29761cdaf95 100644 --- a/extensions/cpp/build/update-grammars.js +++ b/extensions/cpp/build/update-grammars.js @@ -6,8 +6,8 @@ var updateGrammar = require('../../../build/npm/update-grammar'); -updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/c.tmLanguage.json', './syntaxes/c.tmLanguage.json'); -updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/cpp.tmLanguage.json', './syntaxes/cpp.tmLanguage.json'); +updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/c.tmLanguage.json', './syntaxes/c.tmLanguage.json', undefined, 'master', 'source/languages/cpp'); +updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/cpp.tmLanguage.json', './syntaxes/cpp.tmLanguage.json', undefined, 'master', 'source/languages/cpp'); // `source.c.platform` which is still included by other grammars updateGrammar.update('textmate/c.tmbundle', 'Syntaxes/Platform.tmLanguage', './syntaxes/platform.tmLanguage.json'); diff --git a/extensions/cpp/cgmanifest.json b/extensions/cpp/cgmanifest.json index f67719029ef..6716fa1a223 100644 --- a/extensions/cpp/cgmanifest.json +++ b/extensions/cpp/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "jeff-hykin/cpp-textmate-grammar", "repositoryUrl": "https://github.com/jeff-hykin/cpp-textmate-grammar", - "commitHash": "85ef67461698ec3c0b64411a53705daa0b68fc13" + "commitHash": "992c5ba8789288707f2a13778452d644677d9699" } }, "license": "MIT", - "version": "1.11.3", + "version": "1.12.18", "description": "The files syntaxes/c.json and syntaxes/c++.json were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle." }, { diff --git a/extensions/cpp/language-configuration.json b/extensions/cpp/language-configuration.json index b0b1de59d45..fcf971bc11f 100644 --- a/extensions/cpp/language-configuration.json +++ b/extensions/cpp/language-configuration.json @@ -14,7 +14,7 @@ { "open": "(", "close": ")" }, { "open": "'", "close": "'", "notIn": ["string", "comment"] }, { "open": "\"", "close": "\"", "notIn": ["string"] }, - { "open": "/*", "close": " */", "notIn": ["string", "comment"] } + { "open": "/**", "close": " */", "notIn": ["string", "comment"] } ], "surroundingPairs": [ ["{", "}"], diff --git a/extensions/cpp/package.json b/extensions/cpp/package.json index b4285b3b8c3..c300ebe326c 100644 --- a/extensions/cpp/package.json +++ b/extensions/cpp/package.json @@ -18,7 +18,7 @@ }, { "id": "cpp", - "extensions": [ ".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".ino", ".inl", ".ipp" ], + "extensions": [ ".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".ino", ".inl", ".ipp", ".hpp.in", ".h.in" ], "aliases": [ "C++", "Cpp", "cpp"], "configuration": "./language-configuration.json" }], diff --git a/extensions/cpp/syntaxes/c.tmLanguage.json b/extensions/cpp/syntaxes/c.tmLanguage.json index ae463d31f62..91be1a66bdf 100644 --- a/extensions/cpp/syntaxes/c.tmLanguage.json +++ b/extensions/cpp/syntaxes/c.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/f88ac364a66b447bc16b966a66af52ae8b31795c", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/1a24b4aa383169919f0d92cf2735ac35a3e7db3c", "name": "C", "scopeName": "source.c", "patterns": [ @@ -372,1754 +372,135 @@ } ], "repository": { - "probably_a_parameter": { - "match": "(?<=(?:[a-zA-Z_0-9] |[&*>\\]\\)]))\\s*([a-zA-Z_]\\w*)\\s*(?=(?:\\[\\]\\s*)?(?:,|\\)))", - "captures": { - "1": { - "name": "variable.parameter.probably.c" - } - } - }, - "access-method": { - "name": "meta.function-call.member.c", - "begin": "([a-zA-Z_][a-zA-Z_0-9]*|(?<=[\\]\\)]))\\s*(?:(\\.)|(->))((?:(?:[a-zA-Z_][a-zA-Z_0-9]*)\\s*(?:(?:\\.)|(?:->)))*)\\s*([a-zA-Z_][a-zA-Z_0-9]*)(\\()", + "default_statement": { + "name": "meta.conditional.case.c", + "begin": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?", - "name": "punctuation.separator.pointer-access.c" - }, - { - "match": "[a-zA-Z_][a-zA-Z_0-9]*", - "name": "variable.object.c" - }, - { - "name": "everything.else.c", - "match": ".+" + "match": "\\*", + "name": "comment.block.c" } ] }, "5": { - "name": "entity.name.function.member.c" - }, - "6": { - "name": "punctuation.section.arguments.begin.bracket.round.function.member.c" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.arguments.end.bracket.round.function.member.c" - } - }, - "patterns": [ - { - "include": "#function-call-innards" - } - ] - }, - "block": { - "patterns": [ - { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.block.begin.bracket.curly.c" - } - }, - "end": "}|(?=\\s*#\\s*(?:elif|else|endif)\\b)", - "endCaptures": { - "0": { - "name": "punctuation.section.block.end.bracket.curly.c" - } - }, - "name": "meta.block.c", - "patterns": [ - { - "include": "#block_innards" - } - ] - } - ] - }, - "block_innards": { - "patterns": [ - { - "include": "#preprocessor-rule-enabled-block" - }, - { - "include": "#preprocessor-rule-disabled-block" - }, - { - "include": "#preprocessor-rule-conditional-block" - }, - { - "include": "#method_access" - }, - { - "include": "#member_access" - }, - { - "include": "#c_function_call" - }, - { - "name": "meta.initialization.c", - "begin": "(?x)\n(?:\n (?:\n\t(?=\\s)(?=+!]+ | \\(\\) | \\[\\]))\n)\n\\s*(\\() # opening bracket", - "beginCaptures": { - "1": { - "name": "variable.other.c" - }, - "2": { - "name": "punctuation.section.parens.begin.bracket.round.initialization.c" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.parens.end.bracket.round.initialization.c" - } - }, - "patterns": [ - { - "include": "#function-call-innards" - } - ] - }, - { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.block.begin.bracket.curly.c" - } - }, - "end": "}|(?=\\s*#\\s*(?:elif|else|endif)\\b)", - "endCaptures": { - "0": { - "name": "punctuation.section.block.end.bracket.curly.c" - } - }, - "patterns": [ - { - "include": "#block_innards" - } - ] - }, - { - "include": "#parens-block" - }, - { - "include": "$base" - } - ] - }, - "c_function_call": { - "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(?=\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++\\s*\\( # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", - "end": "(?<=\\))(?!\\w)", - "name": "meta.function-call.c", - "patterns": [ - { - "include": "#function-call-innards" - } - ] - }, - "comments": { - "patterns": [ - { - "captures": { - "1": { - "name": "meta.toc-list.banner.block.c" - } - }, - "match": "^/\\* =(\\s*.*?)\\s*= \\*/$\\n?", - "name": "comment.block.c" - }, - { - "begin": "/\\*", - "beginCaptures": { - "0": { - "name": "punctuation.definition.comment.begin.c" - } - }, - "end": "\\*/", - "endCaptures": { - "0": { - "name": "punctuation.definition.comment.end.c" - } - }, - "name": "comment.block.c" - }, - { - "captures": { - "1": { - "name": "meta.toc-list.banner.line.c" - } - }, - "match": "^// =(\\s*.*?)\\s*=\\s*$\\n?", - "name": "comment.line.banner.c" - }, - { - "begin": "(^[ \\t]+)?(?=//)", - "beginCaptures": { - "1": { - "name": "punctuation.whitespace.comment.leading.c" - } - }, - "end": "(?!\\G)", - "patterns": [ - { - "begin": "//", - "beginCaptures": { - "0": { - "name": "punctuation.definition.comment.c" - } - }, - "end": "(?=\\n)", - "name": "comment.line.double-slash.c", - "patterns": [ - { - "include": "#line_continuation_character" - } - ] - } - ] - } - ] - }, - "disabled": { - "begin": "^\\s*#\\s*if(n?def)?\\b.*$", - "end": "^\\s*#\\s*endif\\b", - "patterns": [ - { - "include": "#disabled" - }, - { - "include": "#pragma-mark" - } - ] - }, - "line_continuation_character": { - "patterns": [ - { - "match": "(\\\\)\\n", - "captures": { - "1": { - "name": "constant.character.escape.line-continuation.c" - } - } - } - ] - }, - "parens": { - "name": "meta.parens.c", - "begin": "\\(", - "beginCaptures": { - "0": { - "name": "punctuation.section.parens.begin.bracket.round.c" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.parens.end.bracket.round.c" - } - }, - "patterns": [ - { - "include": "$base" - } - ] - }, - "parens-block": { - "name": "meta.parens.block.c", - "begin": "\\(", - "beginCaptures": { - "0": { - "name": "punctuation.section.parens.begin.bracket.round.c" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.parens.end.bracket.round.c" - } - }, - "patterns": [ - { - "include": "#block_innards" - }, - { - "match": "(?-mix:(?>=|\\|=", - "name": "keyword.operator.assignment.compound.bitwise.c" - }, - { - "match": "<<|>>", - "name": "keyword.operator.bitwise.shift.c" - }, - { - "match": "!=|<=|>=|==|<|>", - "name": "keyword.operator.comparison.c" - }, - { - "match": "&&|!|\\|\\|", - "name": "keyword.operator.logical.c" - }, - { - "match": "&|\\||\\^|~", - "name": "keyword.operator.c" - }, - { - "match": "=", - "name": "keyword.operator.assignment.c" - }, - { - "match": "%|\\*|/|-|\\+", - "name": "keyword.operator.c" - }, - { - "begin": "(\\?)", - "beginCaptures": { - "1": { - "name": "keyword.operator.ternary.c" - } - }, - "end": "(:)", - "endCaptures": { - "1": { - "name": "keyword.operator.ternary.c" - } - }, - "patterns": [ - { - "include": "#function-call-innards" - }, - { - "include": "$base" - } - ] - } - ] - }, - "strings": { - "patterns": [ - { - "begin": "\"", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.c" - } - }, - "end": "\"", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.c" - } - }, - "name": "string.quoted.double.c", - "patterns": [ - { - "include": "#string_escaped_char" - }, - { - "include": "#string_placeholder" - }, - { - "include": "#line_continuation_character" - } - ] - }, - { - "begin": "'", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.c" - } - }, - "end": "'", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.c" - } - }, - "name": "string.quoted.single.c", - "patterns": [ - { - "include": "#string_escaped_char" - }, - { - "include": "#line_continuation_character" - } - ] - } - ] - }, - "string_escaped_char": { - "patterns": [ - { - "match": "(?x)\\\\ (\n\\\\\t\t\t |\n[abefnprtv'\"?] |\n[0-3]\\d{,2}\t |\n[4-7]\\d?\t\t|\nx[a-fA-F0-9]{,2} |\nu[a-fA-F0-9]{,4} |\nU[a-fA-F0-9]{,8} )", - "name": "constant.character.escape.c" - }, - { - "match": "\\\\.", - "name": "invalid.illegal.unknown-escape.c" - } - ] - }, - "string_placeholder": { - "patterns": [ - { - "match": "(?x) %\n(\\d+\\$)?\t\t\t\t\t\t # field (argument #)\n[#0\\- +']*\t\t\t\t\t\t # flags\n[,;:_]?\t\t\t\t\t\t\t # separator character (AltiVec)\n((-?\\d+)|\\*(-?\\d+\\$)?)?\t\t # minimum field width\n(\\.((-?\\d+)|\\*(-?\\d+\\$)?)?)?\t# precision\n(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)? # length modifier\n[diouxXDOUeEfFgGaACcSspn%]\t\t # conversion type", - "name": "constant.other.placeholder.c" - }, - { - "match": "(%)(?!\"\\s*(PRI|SCN))", - "captures": { - "1": { - "name": "invalid.illegal.placeholder.c" - } - } - } - ] - }, - "storage_types": { - "patterns": [ - { - "match": "(?-mix:(?=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", - "end": "(?<=\\))(?!\\w)|(?=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", - "beginCaptures": { - "1": { - "name": "entity.name.function.c" - }, - "2": { - "name": "punctuation.section.arguments.begin.bracket.round.c" - } - }, - "end": "(\\))|(?=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", - "beginCaptures": { - "1": { - "name": "entity.name.function.c" - }, - "2": { - "name": "punctuation.section.parameters.begin.bracket.round.c" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.parameters.end.bracket.round.c" - } - }, - "patterns": [ - { - "include": "#probably_a_parameter" - }, - { - "include": "#function-innards" - } - ] - }, - { - "begin": "\\(", - "beginCaptures": { - "0": { - "name": "punctuation.section.parens.begin.bracket.round.c" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.parens.end.bracket.round.c" - } - }, - "patterns": [ - { - "include": "#function-innards" - } - ] - }, - { - "include": "$base" - } - ] - }, - "function-call-innards": { - "patterns": [ - { - "include": "#comments" - }, - { - "include": "#storage_types" - }, - { - "include": "#method_access" - }, - { - "include": "#member_access" - }, - { - "include": "#operators" - }, - { - "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++ # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", - "beginCaptures": { - "1": { - "name": "entity.name.function.c" - }, - "2": { - "name": "punctuation.section.arguments.begin.bracket.round.c" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.arguments.end.bracket.round.c" - } - }, - "patterns": [ - { - "include": "#function-call-innards" - } - ] - }, - { - "begin": "\\(", - "beginCaptures": { - "0": { - "name": "punctuation.section.parens.begin.bracket.round.c" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.parens.end.bracket.round.c" - } - }, - "patterns": [ - { - "include": "#function-call-innards" - } - ] - }, - { - "include": "#block_innards" - } - ] - }, - "default_statement": { - "name": "meta.conditional.case.c", - "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", "beginCaptures": { "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.c punctuation.definition.comment.begin.c" + }, + "3": { + "name": "comment.block.c" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.c punctuation.definition.comment.end.c" + }, + { + "match": "\\*", + "name": "comment.block.c" + } + ] + }, + "5": { "name": "punctuation.section.parens.begin.bracket.round.conditional.switch.c" } }, @@ -2195,24 +601,77 @@ }, "patterns": [ { - "include": "#conditional_context" + "include": "#evaluation_context" + }, + { + "include": "#c_conditional_context" } ] }, "static_assert": { - "begin": "(static_assert|_Static_assert)\\s*(\\()", + "begin": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", "beginCaptures": { "1": { - "name": "keyword.other.static_assert.c" + "patterns": [ + { + "include": "#inline_comment" + } + ] }, "2": { - "name": "punctuation.section.arguments.begin.bracket.round.c" + "name": "comment.block.c punctuation.definition.comment.begin.c" + }, + "3": { + "name": "comment.block.c" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.c punctuation.definition.comment.end.c" + }, + { + "match": "\\*", + "name": "comment.block.c" + } + ] + }, + "5": { + "name": "keyword.other.static_assert.c" + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.c punctuation.definition.comment.begin.c" + }, + "8": { + "name": "comment.block.c" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.c punctuation.definition.comment.end.c" + }, + { + "match": "\\*", + "name": "comment.block.c" + } + ] + }, + "10": { + "name": "punctuation.section.arguments.begin.bracket.round.static_assert.c" } }, "end": "(\\))", "endCaptures": { "1": { - "name": "punctuation.section.arguments.end.bracket.round.c" + "name": "punctuation.section.arguments.end.bracket.round.static_assert.c" } }, "patterns": [ @@ -2221,7 +680,7 @@ "begin": "(,)\\s*(?=(?:L|u8|u|U\\s*\\\")?)", "beginCaptures": { "1": { - "name": "comma.c punctuation.separator.delimiter.c" + "name": "punctuation.separator.delimiter.comma.c" } }, "end": "(?=\\))", @@ -2235,11 +694,15 @@ ] }, { - "include": "#function_call_context" + "include": "#evaluation_context" } ] }, - "conditional_context": { + "backslash_escapes": { + "match": "(?x)\\\\ (\n\\\\\t\t\t |\n[abefnprtv'\"?] |\n[0-3]\\d{,2}\t |\n[4-7]\\d?\t\t|\nx[a-fA-F0-9]{,2} |\nu[a-fA-F0-9]{,4} |\nU[a-fA-F0-9]{,8} )", + "name": "constant.character.escape.c" + }, + "c_conditional_context": { "patterns": [ { "include": "$base" @@ -2249,8 +712,18 @@ } ] }, + "evalutation_context": { + "patterns": [ + { + "include": "#function-call-innards" + }, + { + "include": "$base" + } + ] + }, "member_access": { - "match": "((?:[a-zA-Z_]\\w*|(?<=\\]|\\)))\\s*)(?:((?:\\.\\*|\\.))|((?:->\\*|->)))((?:[a-zA-Z_]\\w*\\s*(?-mix:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*(\\b(?!(?:void|char|short|int|signed|unsigned|long|float|double|bool|_Bool|_Complex|_Imaginary|u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|div_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t|pthread_attr_t|pthread_cond_t|pthread_condattr_t|pthread_mutex_t|pthread_mutexattr_t|pthread_once_t|pthread_rwlock_t|pthread_rwlockattr_t|pthread_t|pthread_key_t|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t|memory_order|atomic_bool|atomic_char|atomic_schar|atomic_uchar|atomic_short|atomic_ushort|atomic_int|atomic_uint|atomic_long|atomic_ulong|atomic_llong|atomic_ullong|atomic_char16_t|atomic_char32_t|atomic_wchar_t|atomic_int_least8_t|atomic_uint_least8_t|atomic_int_least16_t|atomic_uint_least16_t|atomic_int_least32_t|atomic_uint_least32_t|atomic_int_least64_t|atomic_uint_least64_t|atomic_int_fast8_t|atomic_uint_fast8_t|atomic_int_fast16_t|atomic_uint_fast16_t|atomic_int_fast32_t|atomic_uint_fast32_t|atomic_int_fast64_t|atomic_uint_fast64_t|atomic_intptr_t|atomic_uintptr_t|atomic_size_t|atomic_ptrdiff_t|atomic_intmax_t|atomic_uintmax_t))[a-zA-Z_]\\w*\\b(?!\\())", + "match": "((?:[a-zA-Z_]\\w*|(?<=\\]|\\)))\\s*)(?:((?:\\.\\*|\\.))|((?:->\\*|->)))((?:[a-zA-Z_]\\w*\\s*(?:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*(\\b(?!(?:void|char|short|int|signed|unsigned|long|float|double|bool|_Bool|_Complex|_Imaginary|u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|div_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t|pthread_attr_t|pthread_cond_t|pthread_condattr_t|pthread_mutex_t|pthread_mutexattr_t|pthread_once_t|pthread_rwlock_t|pthread_rwlockattr_t|pthread_t|pthread_key_t|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t|memory_order|atomic_bool|atomic_char|atomic_schar|atomic_uchar|atomic_short|atomic_ushort|atomic_int|atomic_uint|atomic_long|atomic_ulong|atomic_llong|atomic_ullong|atomic_char16_t|atomic_char32_t|atomic_wchar_t|atomic_int_least8_t|atomic_uint_least8_t|atomic_int_least16_t|atomic_uint_least16_t|atomic_int_least32_t|atomic_uint_least32_t|atomic_int_least64_t|atomic_uint_least64_t|atomic_int_fast8_t|atomic_uint_fast8_t|atomic_int_fast16_t|atomic_uint_fast16_t|atomic_int_fast32_t|atomic_uint_fast32_t|atomic_int_fast64_t|atomic_uint_fast64_t|atomic_intptr_t|atomic_uintptr_t|atomic_size_t|atomic_ptrdiff_t|atomic_intmax_t|atomic_uintmax_t)\\b)[a-zA-Z_]\\w*\\b(?!\\())", "captures": { "1": { "name": "variable.other.object.access.c" @@ -2292,7 +765,7 @@ }, "method_access": { "contentName": "meta.function-call.member.c", - "begin": "((?:[a-zA-Z_]\\w*|(?<=\\]|\\)))\\s*)(?:((?:\\.\\*|\\.))|((?:->\\*|->)))((?:[a-zA-Z_]\\w*\\s*(?-mix:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*([a-zA-Z_]\\w*)(\\()", + "begin": "((?:[a-zA-Z_]\\w*|(?<=\\]|\\)))\\s*)(?:((?:\\.\\*|\\.))|((?:->\\*|->)))((?:[a-zA-Z_]\\w*\\s*(?:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*([a-zA-Z_]\\w*)(\\()", "beginCaptures": { "1": { "name": "variable.other.object.access.c" @@ -3368,10 +1841,10 @@ }, "numbers": { "begin": "(?\\]\\)]))\\s*([a-zA-Z_]\\w*)\\s*(?=(?:\\[\\]\\s*)?(?:,|\\)))", + "captures": { + "1": { + "name": "variable.parameter.probably.c" + } + } + }, + "access-method": { + "name": "meta.function-call.member.c", + "begin": "([a-zA-Z_][a-zA-Z_0-9]*|(?<=[\\]\\)]))\\s*(?:(\\.)|(->))((?:(?:[a-zA-Z_][a-zA-Z_0-9]*)\\s*(?:(?:\\.)|(?:->)))*)\\s*([a-zA-Z_][a-zA-Z_0-9]*)(\\()", + "beginCaptures": { + "1": { + "name": "variable.object.c" + }, + "2": { + "name": "punctuation.separator.dot-access.c" + }, + "3": { + "name": "punctuation.separator.pointer-access.c" + }, + "4": { + "patterns": [ + { + "match": "\\.", + "name": "punctuation.separator.dot-access.c" + }, + { + "match": "->", + "name": "punctuation.separator.pointer-access.c" + }, + { + "match": "[a-zA-Z_][a-zA-Z_0-9]*", + "name": "variable.object.c" + }, + { + "name": "everything.else.c", + "match": ".+" + } + ] + }, + "5": { + "name": "entity.name.function.member.c" + }, + "6": { + "name": "punctuation.section.arguments.begin.bracket.round.function.member.c" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.arguments.end.bracket.round.function.member.c" + } + }, + "patterns": [ + { + "include": "#function-call-innards" + } + ] + }, + "block": { + "patterns": [ + { + "begin": "{", + "beginCaptures": { + "0": { + "name": "punctuation.section.block.begin.bracket.curly.c" + } + }, + "end": "}|(?=\\s*#\\s*(?:elif|else|endif)\\b)", + "endCaptures": { + "0": { + "name": "punctuation.section.block.end.bracket.curly.c" + } + }, + "name": "meta.block.c", + "patterns": [ + { + "include": "#block_innards" + } + ] + } + ] + }, + "block_innards": { + "patterns": [ + { + "include": "#preprocessor-rule-enabled-block" + }, + { + "include": "#preprocessor-rule-disabled-block" + }, + { + "include": "#preprocessor-rule-conditional-block" + }, + { + "include": "#method_access" + }, + { + "include": "#member_access" + }, + { + "include": "#c_function_call" + }, + { + "name": "meta.initialization.c", + "begin": "(?x)\n(?:\n (?:\n\t(?=\\s)(?=+!]+ | \\(\\) | \\[\\]))\n)\n\\s*(\\() # opening bracket", + "beginCaptures": { + "1": { + "name": "variable.other.c" + }, + "2": { + "name": "punctuation.section.parens.begin.bracket.round.initialization.c" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parens.end.bracket.round.initialization.c" + } + }, + "patterns": [ + { + "include": "#function-call-innards" + } + ] + }, + { + "begin": "{", + "beginCaptures": { + "0": { + "name": "punctuation.section.block.begin.bracket.curly.c" + } + }, + "end": "}|(?=\\s*#\\s*(?:elif|else|endif)\\b)", + "endCaptures": { + "0": { + "name": "punctuation.section.block.end.bracket.curly.c" + } + }, + "patterns": [ + { + "include": "#block_innards" + } + ] + }, + { + "include": "#parens-block" + }, + { + "include": "$base" + } + ] + }, + "c_function_call": { + "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(?=\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++\\s*\\( # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", + "end": "(?<=\\))(?!\\w)", + "name": "meta.function-call.c", + "patterns": [ + { + "include": "#function-call-innards" + } + ] + }, + "comments": { + "patterns": [ + { + "captures": { + "1": { + "name": "meta.toc-list.banner.block.c" + } + }, + "match": "^/\\* =(\\s*.*?)\\s*= \\*/$\\n?", + "name": "comment.block.c" + }, + { + "begin": "/\\*", + "beginCaptures": { + "0": { + "name": "punctuation.definition.comment.begin.c" + } + }, + "end": "\\*/", + "endCaptures": { + "0": { + "name": "punctuation.definition.comment.end.c" + } + }, + "name": "comment.block.c" + }, + { + "captures": { + "1": { + "name": "meta.toc-list.banner.line.c" + } + }, + "match": "^// =(\\s*.*?)\\s*=\\s*$\\n?", + "name": "comment.line.banner.c" + }, + { + "begin": "(^[ \\t]+)?(?=//)", + "beginCaptures": { + "1": { + "name": "punctuation.whitespace.comment.leading.c" + } + }, + "end": "(?!\\G)", + "patterns": [ + { + "begin": "//", + "beginCaptures": { + "0": { + "name": "punctuation.definition.comment.c" + } + }, + "end": "(?=\\n)", + "name": "comment.line.double-slash.c", + "patterns": [ + { + "include": "#line_continuation_character" + } + ] + } + ] + } + ] + }, + "disabled": { + "begin": "^\\s*#\\s*if(n?def)?\\b.*$", + "end": "^\\s*#\\s*endif\\b", + "patterns": [ + { + "include": "#disabled" + }, + { + "include": "#pragma-mark" + } + ] + }, + "line_continuation_character": { + "patterns": [ + { + "match": "(\\\\)\\n", + "captures": { + "1": { + "name": "constant.character.escape.line-continuation.c" + } + } + } + ] + }, + "parens": { + "name": "meta.parens.c", + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.section.parens.begin.bracket.round.c" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parens.end.bracket.round.c" + } + }, + "patterns": [ + { + "include": "$base" + } + ] + }, + "parens-block": { + "name": "meta.parens.block.c", + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.section.parens.begin.bracket.round.c" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parens.end.bracket.round.c" + } + }, + "patterns": [ + { + "include": "#block_innards" + }, + { + "match": "(?-mix:(?>=|\\|=", + "name": "keyword.operator.assignment.compound.bitwise.c" + }, + { + "match": "<<|>>", + "name": "keyword.operator.bitwise.shift.c" + }, + { + "match": "!=|<=|>=|==|<|>", + "name": "keyword.operator.comparison.c" + }, + { + "match": "&&|!|\\|\\|", + "name": "keyword.operator.logical.c" + }, + { + "match": "&|\\||\\^|~", + "name": "keyword.operator.c" + }, + { + "match": "=", + "name": "keyword.operator.assignment.c" + }, + { + "match": "%|\\*|/|-|\\+", + "name": "keyword.operator.c" + }, + { + "begin": "(\\?)", + "beginCaptures": { + "1": { + "name": "keyword.operator.ternary.c" + } + }, + "end": "(:)", + "endCaptures": { + "1": { + "name": "keyword.operator.ternary.c" + } + }, + "patterns": [ + { + "include": "#function-call-innards" + }, + { + "include": "$base" + } + ] + } + ] + }, + "strings": { + "patterns": [ + { + "begin": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.c" + } + }, + "end": "\"", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.c" + } + }, + "name": "string.quoted.double.c", + "patterns": [ + { + "include": "#string_escaped_char" + }, + { + "include": "#string_placeholder" + }, + { + "include": "#line_continuation_character" + } + ] + }, + { + "begin": "'", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.c" + } + }, + "end": "'", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.c" + } + }, + "name": "string.quoted.single.c", + "patterns": [ + { + "include": "#string_escaped_char" + }, + { + "include": "#line_continuation_character" + } + ] + } + ] + }, + "string_escaped_char": { + "patterns": [ + { + "match": "(?x)\\\\ (\n\\\\\t\t\t |\n[abefnprtv'\"?] |\n[0-3]\\d{,2}\t |\n[4-7]\\d?\t\t|\nx[a-fA-F0-9]{,2} |\nu[a-fA-F0-9]{,4} |\nU[a-fA-F0-9]{,8} )", + "name": "constant.character.escape.c" + }, + { + "match": "\\\\.", + "name": "invalid.illegal.unknown-escape.c" + } + ] + }, + "string_placeholder": { + "patterns": [ + { + "match": "(?x) %\n(\\d+\\$)?\t\t\t\t\t\t # field (argument #)\n[#0\\- +']*\t\t\t\t\t\t # flags\n[,;:_]?\t\t\t\t\t\t\t # separator character (AltiVec)\n((-?\\d+)|\\*(-?\\d+\\$)?)?\t\t # minimum field width\n(\\.((-?\\d+)|\\*(-?\\d+\\$)?)?)?\t# precision\n(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)? # length modifier\n[diouxXDOUeEfFgGaACcSspn%]\t\t # conversion type", + "name": "constant.other.placeholder.c" + }, + { + "match": "(%)(?!\"\\s*(PRI|SCN))", + "captures": { + "1": { + "name": "invalid.illegal.placeholder.c" + } + } + } + ] + }, + "storage_types": { + "patterns": [ + { + "match": "(?-mix:(?=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", + "end": "(?<=\\))(?!\\w)|(?=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", + "beginCaptures": { + "1": { + "name": "entity.name.function.c" + }, + "2": { + "name": "punctuation.section.arguments.begin.bracket.round.c" + } + }, + "end": "(\\))|(?=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", + "beginCaptures": { + "1": { + "name": "entity.name.function.c" + }, + "2": { + "name": "punctuation.section.parameters.begin.bracket.round.c" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parameters.end.bracket.round.c" + } + }, + "patterns": [ + { + "include": "#probably_a_parameter" + }, + { + "include": "#function-innards" + } + ] + }, + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.section.parens.begin.bracket.round.c" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parens.end.bracket.round.c" + } + }, + "patterns": [ + { + "include": "#function-innards" + } + ] + }, + { + "include": "$base" + } + ] + }, + "function-call-innards": { + "patterns": [ + { + "include": "#comments" + }, + { + "include": "#storage_types" + }, + { + "include": "#method_access" + }, + { + "include": "#member_access" + }, + { + "include": "#operators" + }, + { + "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++ # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", + "beginCaptures": { + "1": { + "name": "entity.name.function.c" + }, + "2": { + "name": "punctuation.section.arguments.begin.bracket.round.c" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.arguments.end.bracket.round.c" + } + }, + "patterns": [ + { + "include": "#function-call-innards" + } + ] + }, + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.section.parens.begin.bracket.round.c" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parens.end.bracket.round.c" + } + }, + "patterns": [ + { + "include": "#function-call-innards" + } + ] + }, + { + "include": "#block_innards" + } + ] } } } \ No newline at end of file diff --git a/extensions/cpp/syntaxes/cpp.tmLanguage.json b/extensions/cpp/syntaxes/cpp.tmLanguage.json index 56fc61039e8..f7495aee6e3 100644 --- a/extensions/cpp/syntaxes/cpp.tmLanguage.json +++ b/extensions/cpp/syntaxes/cpp.tmLanguage.json @@ -4,129 +4,118 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/85ef67461698ec3c0b64411a53705daa0b68fc13", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/992c5ba8789288707f2a13778452d644677d9699", "name": "C++", "scopeName": "source.cpp", "patterns": [ { - "include": "#source_wrapper" + "include": "#ever_present_context" + }, + { + "include": "#constructor_root" + }, + { + "include": "#destructor_root" + }, + { + "include": "#function_definition" + }, + { + "include": "#operator_overload" + }, + { + "include": "#using_namespace" + }, + { + "include": "#type_alias" + }, + { + "include": "#using_name" + }, + { + "include": "#namespace_alias" + }, + { + "include": "#namespace_block" + }, + { + "include": "#extern_block" + }, + { + "include": "#typedef_class" + }, + { + "include": "#typedef_struct" + }, + { + "include": "#typedef_union" + }, + { + "include": "#typedef_keyword" + }, + { + "include": "#standard_declares" + }, + { + "include": "#class_block" + }, + { + "include": "#struct_block" + }, + { + "include": "#union_block" + }, + { + "include": "#enum_block" + }, + { + "include": "#template_isolated_definition" + }, + { + "include": "#template_definition" + }, + { + "include": "#access_control_keywords" + }, + { + "include": "#block" + }, + { + "include": "#static_assert" + }, + { + "include": "#assembly" + }, + { + "include": "#function_pointer" + }, + { + "include": "#evaluation_context" } ], "repository": { - "decltype_specifier": { - "contentName": "meta.arguments.decltype.cpp", - "begin": "((?(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/))", + "captures": { "1": { - "name": "keyword.operator.functionlike.cpp keyword.other.decltype.cpp storage.type.decltype.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "2": { - "name": "punctuation.section.arguments.begin.bracket.round.decltype.cpp" - } - }, - "end": "(\\))", - "endCaptures": { - "1": { - "name": "punctuation.section.arguments.end.bracket.round.decltype.cpp" - } - }, - "patterns": [ - { - "include": "#evaluation_context" - } - ] - }, - "sizeof_operator": { - "contentName": "meta.arguments.operator.sizeof.cpp", - "begin": "((?[#;\\/=*C~]+)(?![#;\\/=*C~]))\\s*.+\\s*\\8\\s*(?:\\n|$)))|(^\\s*((\\/\\*)\\s*?((?>[#;\\/=*C~]+)(?![#;\\/=*C~]))\\s*.+\\s*\\8\\s*\\*\\/)))", + "captures": { + "1": { + "name": "meta.toc-list.banner.double-slash.cpp" + }, + "2": { + "name": "comment.line.double-slash.cpp" + }, + "3": { + "name": "punctuation.definition.comment.cpp" + }, + "4": { + "name": "meta.banner.character.cpp" + }, + "5": { + "name": "meta.toc-list.banner.block.cpp" + }, + "6": { + "name": "comment.line.block.cpp" + }, + "7": { + "name": "punctuation.definition.comment.cpp" + }, + "8": { + "name": "meta.banner.character.cpp" + } + } + }, + "comments": { + "patterns": [ + { + "include": "#emacs_file_banner" + }, + { + "include": "#block_comment" + }, + { + "include": "#line_comment" } ] }, "number_literal": { "begin": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", "beginCaptures": { "1": { "name": "keyword.operator.functionlike.cpp keyword.other.decltype.cpp storage.type.decltype.cpp" }, "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { "name": "punctuation.section.arguments.begin.bracket.round.decltype.cpp" } }, @@ -954,6 +898,120 @@ } ] }, + "decltype": { + "contentName": "meta.arguments.decltype.cpp", + "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", + "beginCaptures": { + "1": { + "name": "keyword.operator.functionlike.cpp keyword.other.decltype.cpp storage.type.decltype.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.section.arguments.begin.bracket.round.decltype.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.arguments.end.bracket.round.decltype.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "pthread_types": { + "match": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(((?:private|protected|public))\\s*(:))", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "storage.type.modifier.access.control.$6.cpp" + }, + "7": { + "name": "punctuation.separator.colon.access.control.cpp" + } + } + }, + "exception_keywords": { + "match": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(delete)\\s*(\\[\\])|(delete))|(new))(?!\\w))", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "keyword.operator.wordlike.cpp" + }, + "6": { + "name": "keyword.operator.delete.array.cpp" + }, + "7": { + "name": "keyword.operator.delete.array.bracket.cpp" + }, + "8": { + "name": "keyword.operator.delete.cpp" + }, + "9": { "name": "keyword.operator.new.cpp" } - }, - "name": "keyword.operator.wordlike.cpp memory.cpp" + } }, "control_flow_keywords": { - "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)", + "captures": { + "1": { + "name": "keyword.control.goto.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "entity.name.label.call.cpp" + } + } + }, + "label": { + "match": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "entity.name.label.cpp" + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "10": { + "name": "punctuation.separator.label.cpp" + } + } }, "default_statement": { "name": "meta.conditional.case.cpp", - "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", "beginCaptures": { "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { "name": "punctuation.section.parens.begin.bracket.round.conditional.switch.cpp" } }, @@ -1077,18 +1570,46 @@ }, "patterns": [ { - "include": "#conditional_context" + "include": "#evaluation_context" + }, + { + "include": "#c_conditional_context" } ] }, "switch_statement": { "name": "meta.block.switch.cpp", - "begin": "(((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?]*|[^>]*+<[^>]*+>)++>\\s*", @@ -1438,7 +1955,7 @@ ] }, "template_isolated_definition": { - "match": "(?\\s*$)", + "match": "(?\\s*$)", "captures": { "1": { "name": "storage.type.template.cpp" @@ -1502,7 +2019,7 @@ ] }, "template_argument_defaulted": { - "match": "(?<=<|,)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s+)*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*([=])", + "match": "(?<=<|,)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s+)*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*([=])", "captures": { "1": { "name": "storage.type.template.cpp" @@ -1516,33 +2033,63 @@ } }, "template_definition_argument": { - "match": "(?:(?:\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)|((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s+)+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*))|((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(\\.\\.\\.)\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*))\\s*(?:(,)|(?=>|$))", + "match": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)|((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s+)+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))|((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*(\\.\\.\\.)\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*(?:(,)|(?=>|$))", "captures": { "1": { - "name": "storage.type.template.argument.$1.cpp" + "patterns": [ + { + "include": "#inline_comment" + } + ] }, "2": { - "name": "storage.type.template.argument.$2.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { - "name": "entity.name.type.template.cpp" + "name": "comment.block.cpp" }, "4": { - "name": "storage.type.template.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "5": { - "name": "ellipses.cpp punctuation.vararg-ellipses.template.definition.cpp" + "name": "storage.type.template.argument.$5.cpp" }, "6": { - "name": "entity.name.type.template.cpp" + "patterns": [ + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", + "name": "storage.type.template.argument.$0.cpp" + } + ] }, "7": { - "name": "comma.cpp punctuation.separator.template.argument.cpp" + "name": "entity.name.type.template.cpp" + }, + "8": { + "name": "storage.type.template.cpp" + }, + "9": { + "name": "ellipses.cpp punctuation.vararg-ellipses.template.definition.cpp" + }, + "10": { + "name": "entity.name.type.template.cpp" + }, + "11": { + "name": "punctuation.separator.delimiter.comma.template.argument.cpp" } } }, "scope_resolution": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*", + "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -1554,7 +2101,7 @@ } }, "scope_resolution_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)", + "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -1580,7 +2127,7 @@ } }, "scope_resolution_template_call": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*", + "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -1592,7 +2139,7 @@ } }, "scope_resolution_template_call_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)", + "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -1618,7 +2165,7 @@ } }, "scope_resolution_template_definition": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*", + "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -1630,7 +2177,7 @@ } }, "scope_resolution_template_definition_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)", + "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -1656,7 +2203,7 @@ } }, "scope_resolution_function_call": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*", + "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -1668,7 +2215,7 @@ } }, "scope_resolution_function_call_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)", + "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -1694,7 +2241,7 @@ } }, "scope_resolution_function_definition": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*", + "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -1706,7 +2253,7 @@ } }, "scope_resolution_function_definition_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)", + "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -1732,7 +2279,7 @@ } }, "scope_resolution_namespace_alias": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*", + "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -1744,7 +2291,7 @@ } }, "scope_resolution_namespace_alias_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)", + "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -1770,7 +2317,7 @@ } }, "scope_resolution_namespace_using": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*", + "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -1782,7 +2329,7 @@ } }, "scope_resolution_namespace_using_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)", + "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -1808,7 +2355,7 @@ } }, "scope_resolution_namespace_block": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*", + "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -1820,7 +2367,7 @@ } }, "scope_resolution_namespace_block_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)", + "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -1845,8 +2392,46 @@ } } }, + "scope_resolution_parameter": { + "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", + "captures": { + "0": { + "patterns": [ + { + "include": "#scope_resolution_parameter_inner_generated" + } + ] + } + } + }, + "scope_resolution_parameter_inner_generated": { + "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", + "captures": { + "1": { + "patterns": [ + { + "include": "#scope_resolution_parameter_inner_generated" + } + ] + }, + "2": { + "name": "entity.name.scope-resolution.parameter.cpp" + }, + "3": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "4": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.parameter.cpp" + } + } + }, "scope_resolution_function_definition_operator_overload": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*", + "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -1858,7 +2443,7 @@ } }, "scope_resolution_function_definition_operator_overload_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)", + "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -1884,7 +2469,7 @@ } }, "qualified_type": { - "match": "\\s*(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)))?\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.])", + "match": "\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])", "captures": { "0": { "name": "meta.qualified_type.cpp", @@ -1893,6 +2478,9 @@ "match": "(?:class|struct|union|enum)", "name": "storage.type.$0.cpp" }, + { + "include": "#attributes_context" + }, { "include": "#function_type" }, @@ -1915,7 +2503,7 @@ "include": "#template_call_range" }, { - "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*", + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] @@ -1930,17 +2518,67 @@ } ] }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { "patterns": [ { "include": "#scope_resolution_inner_generated" } ] }, - "4": { + "12": { "name": "entity.name.scope-resolution.cpp" }, - "5": { + "13": { "name": "meta.template.call.cpp", "patterns": [ { @@ -1948,16 +2586,285 @@ } ] }, - "6": { + "14": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, - "7": { + "15": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "16": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "17": { + "name": "comment.block.cpp" + }, + "18": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "19": { "name": "entity.name.type.cpp" } } }, + "simple_type": { + "match": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?", + "captures": { + "1": { + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?:class|struct|union|enum)", + "name": "storage.type.$0.cpp" + }, + { + "include": "#attributes_context" + }, + { + "include": "#function_type" + }, + { + "include": "#storage_types" + }, + { + "include": "#number_literal" + }, + { + "include": "#string_context_c" + }, + { + "include": "#comma" + }, + { + "include": "#scope_resolution_inner_generated" + }, + { + "include": "#template_call_range" + }, + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", + "name": "entity.name.type.cpp" + } + ] + }, + "2": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "3": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "4": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "5": { + "name": "comment.block.cpp" + }, + "6": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#scope_resolution_inner_generated" + } + ] + }, + "13": { + "name": "entity.name.scope-resolution.cpp" + }, + "14": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "15": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "name": "entity.name.type.cpp" + }, + "21": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "22": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "23": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "24": { + "name": "comment.block.cpp" + }, + "25": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "26": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "27": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "28": { + "name": "comment.block.cpp" + }, + "29": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, "type_alias": { - "match": "(using)\\s*(?!namespace)(\\s*(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)))?\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.]))\\s*(\\=)\\s*(typename)?\\s*((?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)))?\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.]))|(.+(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))\\s*(\\=)\\s*((?:typename)?)\\s*((?:(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))|(.*(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:(\\[)(\\w*)(\\])\\s*)?\\s*(?:(;)|\\n)", "captures": { "1": { "name": "keyword.other.using.directive.cpp" @@ -1969,6 +2876,9 @@ "match": "(?:class|struct|union|enum)", "name": "storage.type.$0.cpp" }, + { + "include": "#attributes_context" + }, { "include": "#function_type" }, @@ -1991,7 +2901,7 @@ "include": "#template_call_range" }, { - "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*", + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] @@ -2006,17 +2916,67 @@ } ] }, + "4": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "5": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "6": { + "name": "comment.block.cpp" + }, + "7": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "8": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "9": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "10": { + "name": "comment.block.cpp" + }, + "11": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { "patterns": [ { "include": "#scope_resolution_inner_generated" } ] }, - "6": { + "14": { "name": "entity.name.scope-resolution.cpp" }, - "7": { + "15": { "name": "meta.template.call.cpp", "patterns": [ { @@ -2024,32 +2984,60 @@ } ] }, - "8": { + "16": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, - "9": { + "17": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "18": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "19": { + "name": "comment.block.cpp" + }, + "20": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "21": { "name": "entity.name.type.cpp" }, - "10": { + "22": { "name": "keyword.operator.assignment.cpp" }, - "11": { + "23": { "name": "keyword.other.typename.cpp" }, - "12": { + "24": { "patterns": [ { "include": "#storage_specifiers" } ] }, - "13": { + "25": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "(?:class|struct|union|enum)", "name": "storage.type.$0.cpp" }, + { + "include": "#attributes_context" + }, { "include": "#function_type" }, @@ -2072,12 +3060,12 @@ "include": "#template_call_range" }, { - "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*", + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, - "14": { + "26": { "patterns": [ { "include": "#attributes_context" @@ -2087,17 +3075,67 @@ } ] }, - "16": { + "27": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "28": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "29": { + "name": "comment.block.cpp" + }, + "30": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "31": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "32": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "33": { + "name": "comment.block.cpp" + }, + "34": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "36": { "patterns": [ { "include": "#scope_resolution_inner_generated" } ] }, - "17": { + "37": { "name": "entity.name.scope-resolution.cpp" }, - "18": { + "38": { "name": "meta.template.call.cpp", "patterns": [ { @@ -2105,13 +3143,38 @@ } ] }, - "19": { + "39": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, - "20": { + "40": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "41": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "42": { + "name": "comment.block.cpp" + }, + "43": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "44": { "name": "entity.name.type.cpp" }, - "21": { + "45": { "name": "meta.declaration.type.alias.value.unknown.cpp", "patterns": [ { @@ -2119,417 +3182,209 @@ } ] }, - "23": { - "name": "storage.modifier.pointer.cpp" + "46": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] }, - "24": { - "name": "storage.modifier.reference.cpp" + "47": { + "patterns": [ + { + "include": "#inline_comment" + } + ] }, - "25": { + "48": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "49": { + "name": "comment.block.cpp" + }, + "50": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "51": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "52": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "53": { + "name": "comment.block.cpp" + }, + "54": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "55": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "56": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "57": { + "name": "comment.block.cpp" + }, + "58": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "59": { "name": "punctuation.definition.begin.bracket.square.cpp" }, - "26": { + "60": { "patterns": [ { "include": "#evaluation_context" } ] }, - "27": { + "61": { "name": "punctuation.definition.end.bracket.square.cpp" }, - "28": { + "62": { "name": "punctuation.terminator.statement.cpp" } }, "name": "meta.declaration.type.alias.cpp" }, - "struct_declare": { - "match": "(struct)\\s+((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))", "captures": { "1": { - "name": "storage.type.struct.declare.cpp" + "name": "storage.modifier.cpp" }, "2": { - "name": "entity.name.type.struct.cpp" - }, - "4": { - "name": "storage.modifier.pointer.cpp" - }, - "5": { - "name": "storage.modifier.reference.cpp" - }, - "6": { - "name": "variable.other.object.declare.cpp" - } - } - }, - "parameter_struct": { - "match": "(struct)\\s+((?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)))?\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.]))(?:\\s+|(\\s*((?:\\*\\s*)*)((?:&\\s*){0,2})\\s*))((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)(?|\\?\\?>)|(?=[;>\\[\\]=]))", - "patterns": [ - { - "name": "meta.head.function.definition.cpp", - "begin": "\\G ?", - "end": "((?:\\{|<%|\\?\\?<|(?=;)))", - "endCaptures": { - "1": { - "name": "punctuation.section.block.begin.bracket.curly.function.definition.cpp" - } - }, - "patterns": [ - { - "contentName": "meta.function.definition.parameters.cpp", - "begin": "(\\()", - "beginCaptures": { - "1": { - "name": "punctuation.section.parameters.begin.bracket.round.cpp" - } - }, - "end": "(\\))", - "endCaptures": { - "1": { - "name": "punctuation.section.parameters.end.bracket.round.cpp" - } - }, - "patterns": [ - { - "include": "#function_parameter_context" - }, - { - "include": "#function_call_context" - } - ] + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" }, { - "include": "#comments_context" - }, - { - "include": "#root_context" + "match": "\\*", + "name": "comment.block.cpp" } ] }, - { - "name": "meta.body.function.definition.cpp", - "begin": "(?<=\\{|<%|\\?\\?<)", - "end": "(\\}|%>|\\?\\?>)", - "endCaptures": { - "1": { - "name": "punctuation.section.block.end.bracket.curly.function.definition.cpp" - } - }, - "patterns": [ - { - "include": "#function_body_context" - } - ] - }, - { - "name": "meta.tail.function.definition.cpp", - "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", - "end": "[\\s\\n]*(?=;)", - "patterns": [ - { - "include": "#root_context" - } - ] - } - ] - }, - "static_assert": { - "begin": "(static_assert|_Static_assert)\\s*(\\()", - "beginCaptures": { - "1": { - "name": "keyword.other.static_assert.cpp" - }, - "2": { - "name": "punctuation.section.arguments.begin.bracket.round.cpp" - } - }, - "end": "(\\))", - "endCaptures": { - "1": { - "name": "punctuation.section.arguments.end.bracket.round.cpp" - } - }, - "patterns": [ - { - "name": "meta.static_assert.message.cpp", - "begin": "(,)\\s*(?=(?:L|u8|u|U\\s*\\\")?)", - "beginCaptures": { - "1": { - "name": "comma.cpp punctuation.separator.delimiter.cpp" - } - }, - "end": "(?=\\))", - "patterns": [ - { - "include": "#string_context" - }, - { - "include": "#string_context_c" - } - ] - }, - { - "include": "#function_call_context" - } - ] - }, - "function_call": { - "begin": "(?!\\s)(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(\\()", - "beginCaptures": { - "1": { - "patterns": [ - { - "include": "#scope_resolution_function_call_inner_generated" - } - ] - }, - "2": { - "name": "entity.name.function.call.cpp" - }, - "3": { - "name": "meta.template.call.cpp", - "patterns": [ - { - "include": "#template_call_range" - } - ] - }, - "4": { - "name": "punctuation.section.arguments.begin.bracket.round.function.call.cpp" - } - }, - "end": "(\\))", - "endCaptures": { - "1": { - "name": "punctuation.section.arguments.end.bracket.round.function.call.cpp" - } - }, - "patterns": [ - { - "include": "#function_call_context" - } - ] - }, - "operators": { - "patterns": [ - { - "include": "#sizeof_operator" - }, - { - "include": "#alignof_operator" - }, - { - "include": "#alignas_operator" - }, - { - "include": "#typeid_operator" - }, - { - "include": "#method_access" - }, - { - "include": "#member_access" - }, - { - "match": "(?>=|\\|=", - "name": "keyword.operator.assignment.compound.bitwise.cpp" - }, - { - "match": "<<|>>", - "name": "keyword.operator.bitwise.shift.cpp" - }, - { - "match": "!=|<=|>=|==|<|>", - "name": "keyword.operator.comparison.cpp" - }, - { - "match": "&&|!|\\|\\|", - "name": "keyword.operator.logical.cpp" - }, - { - "match": "&|\\||\\^|~", - "name": "keyword.operator.cpp" - }, - { - "include": "#assignment_operator" - }, - { - "match": "%|\\*|/|-|\\+", - "name": "keyword.operator.cpp" - }, - { - "begin": "\\?", - "beginCaptures": { - "0": { - "name": "keyword.operator.ternary.cpp" - } - }, - "end": ":", - "applyEndPatternLast": true, - "endCaptures": { - "0": { - "name": "keyword.operator.ternary.cpp" - } - }, - "patterns": [ - { - "include": "#method_access" - }, - { - "include": "#member_access" - }, - { - "include": "#function_call_c" - }, - { - "include": "#root_context" - } - ] - } - ] - }, - "function_pointer": { - "begin": "(\\s*(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)))?\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.]))\\s*(\\s*((?:\\*\\s*)*)((?:&\\s*){0,2})\\s*)(\\()(\\*)\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)?\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", - "beginCaptures": { - "1": { + "10": { "name": "meta.qualified_type.cpp", "patterns": [ { "match": "(?:class|struct|union|enum)", "name": "storage.type.$0.cpp" }, + { + "include": "#attributes_context" + }, { "include": "#function_type" }, @@ -2552,12 +3407,12 @@ "include": "#template_call_range" }, { - "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*", + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", "name": "entity.name.type.cpp" } ] }, - "2": { + "11": { "patterns": [ { "include": "#attributes_context" @@ -2567,485 +3422,107 @@ } ] }, - "4": { - "patterns": [ - { - "include": "#scope_resolution_inner_generated" - } - ] - }, - "5": { - "name": "entity.name.scope-resolution.cpp" - }, - "6": { - "name": "meta.template.call.cpp", - "patterns": [ - { - "include": "#template_call_range" - } - ] - }, - "7": { - "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" - }, - "8": { - "name": "entity.name.type.cpp" - }, - "10": { - "name": "storage.modifier.pointer.cpp" - }, - "11": { - "name": "storage.modifier.reference.cpp" - }, "12": { - "name": "punctuation.section.parens.begin.bracket.round.function.pointer.cpp" + "patterns": [ + { + "include": "#inline_comment" + } + ] }, "13": { - "name": "punctuation.definition.function.pointer.dereference.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "14": { - "name": "variable.other.definition.pointer.function.cpp" + "name": "comment.block.cpp" }, "15": { - "name": "punctuation.definition.begin.bracket.square.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "16": { "patterns": [ { - "include": "#evaluation_context" + "include": "#inline_comment" } ] }, "17": { - "name": "punctuation.definition.end.bracket.square.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "18": { - "name": "punctuation.section.parens.end.bracket.round.function.pointer.cpp" + "name": "comment.block.cpp" }, "19": { - "name": "punctuation.section.parameters.begin.bracket.round.function.pointer.cpp" - } - }, - "end": "(\\))\\s*(?=[{=,);]|\\n)(?!\\()", - "endCaptures": { - "1": { - "name": "punctuation.section.parameters.end.bracket.round.function.pointer.cpp" - } - }, - "patterns": [ - { - "include": "#function_parameter_context" - } - ] - }, - "probably_a_parameter": { - "match": "(?:((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?==))|((?<=\\w |\\*\\/|[&*>\\]\\)]|\\.\\.\\.)\\s*(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?=(?:\\[\\]\\s*)?(?:,|\\)))))", - "captures": { - "1": { - "name": "variable.parameter.defaulted.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, - "2": { - "name": "variable.parameter.cpp" + "21": { + "patterns": [ + { + "include": "#scope_resolution_inner_generated" + } + ] + }, + "22": { + "name": "entity.name.scope-resolution.cpp" + }, + "23": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "24": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" + }, + "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "29": { + "name": "entity.name.type.cpp" } } }, - "operator_overload": { - "name": "meta.function.definition.parameters.operator-overload.cpp", - "begin": "(operator)((?:\\s*(?:\\+\\+|\\-\\-|\\(\\)|\\[\\]|\\->|\\+\\+|\\-\\-|\\+|\\-|!|~|\\*|&|\\->\\*|\\*|\\/|%|\\+|\\-|<<|>>|<=>|<|<=|>|>=|==|!=|&|\\^|\\||&&|\\|\\||=|\\+=|\\-=|\\*=|\\/=|%=|<<=|>>=|&=|\\^=|\\|=|,)|\\s+(?:(?:new|new\\[\\]|delete|delete\\[\\])|(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:&)?)))\\s*(\\()", - "beginCaptures": { - "1": { - "name": "keyword.other.operator.overload.cpp" - }, - "2": { - "name": "entity.name.operator.overloadee.cpp", - "patterns": [ - { - "include": "#scope_resolution_function_definition_operator_overload_inner_generated" - } - ] - }, - "3": { - "name": "punctuation.section.parameters.begin.bracket.round.operator-overload.cpp" - } - }, - "end": "(\\))", - "endCaptures": { - "1": { - "name": "punctuation.section.parameters.end.bracket.round.operator-overload.cpp" - } - }, - "patterns": [ - { - "include": "#function_parameter_context" - } - ] - }, - "member_access": { - "match": "(?:((?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?-mix:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*(\\b(?!auto[^(?-mix:\\w)]|void[^(?-mix:\\w)]|char[^(?-mix:\\w)]|short[^(?-mix:\\w)]|int[^(?-mix:\\w)]|signed[^(?-mix:\\w)]|unsigned[^(?-mix:\\w)]|long[^(?-mix:\\w)]|float[^(?-mix:\\w)]|double[^(?-mix:\\w)]|bool[^(?-mix:\\w)]|wchar_t[^(?-mix:\\w)]|u_char[^(?-mix:\\w)]|u_short[^(?-mix:\\w)]|u_int[^(?-mix:\\w)]|u_long[^(?-mix:\\w)]|ushort[^(?-mix:\\w)]|uint[^(?-mix:\\w)]|u_quad_t[^(?-mix:\\w)]|quad_t[^(?-mix:\\w)]|qaddr_t[^(?-mix:\\w)]|caddr_t[^(?-mix:\\w)]|daddr_t[^(?-mix:\\w)]|div_t[^(?-mix:\\w)]|dev_t[^(?-mix:\\w)]|fixpt_t[^(?-mix:\\w)]|blkcnt_t[^(?-mix:\\w)]|blksize_t[^(?-mix:\\w)]|gid_t[^(?-mix:\\w)]|in_addr_t[^(?-mix:\\w)]|in_port_t[^(?-mix:\\w)]|ino_t[^(?-mix:\\w)]|key_t[^(?-mix:\\w)]|mode_t[^(?-mix:\\w)]|nlink_t[^(?-mix:\\w)]|id_t[^(?-mix:\\w)]|pid_t[^(?-mix:\\w)]|off_t[^(?-mix:\\w)]|segsz_t[^(?-mix:\\w)]|swblk_t[^(?-mix:\\w)]|uid_t[^(?-mix:\\w)]|id_t[^(?-mix:\\w)]|clock_t[^(?-mix:\\w)]|size_t[^(?-mix:\\w)]|ssize_t[^(?-mix:\\w)]|time_t[^(?-mix:\\w)]|useconds_t[^(?-mix:\\w)]|suseconds_t[^(?-mix:\\w)]|int8_t[^(?-mix:\\w)]|int16_t[^(?-mix:\\w)]|int32_t[^(?-mix:\\w)]|int64_t[^(?-mix:\\w)]|uint8_t[^(?-mix:\\w)]|uint16_t[^(?-mix:\\w)]|uint32_t[^(?-mix:\\w)]|uint64_t[^(?-mix:\\w)]|int_least8_t[^(?-mix:\\w)]|int_least16_t[^(?-mix:\\w)]|int_least32_t[^(?-mix:\\w)]|int_least64_t[^(?-mix:\\w)]|uint_least8_t[^(?-mix:\\w)]|uint_least16_t[^(?-mix:\\w)]|uint_least32_t[^(?-mix:\\w)]|uint_least64_t[^(?-mix:\\w)]|int_fast8_t[^(?-mix:\\w)]|int_fast16_t[^(?-mix:\\w)]|int_fast32_t[^(?-mix:\\w)]|int_fast64_t[^(?-mix:\\w)]|uint_fast8_t[^(?-mix:\\w)]|uint_fast16_t[^(?-mix:\\w)]|uint_fast32_t[^(?-mix:\\w)]|uint_fast64_t[^(?-mix:\\w)]|intptr_t[^(?-mix:\\w)]|uintptr_t[^(?-mix:\\w)]|intmax_t[^(?-mix:\\w)]|intmax_t[^(?-mix:\\w)]|uintmax_t[^(?-mix:\\w)]|uintmax_t[^(?-mix:\\w)])(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\b(?!\\())", - "captures": { - "1": { - "name": "variable.language.this.cpp" - }, - "2": { - "name": "variable.other.object.access.cpp" - }, - "3": { - "name": "punctuation.separator.dot-access.cpp" - }, - "4": { - "name": "punctuation.separator.pointer-access.cpp" - }, - "5": { - "patterns": [ - { - "match": "(?<=(?:\\.\\*|\\.|->|->\\*))\\s*(?:((?\\*|->)))", - "captures": { - "1": { - "name": "variable.language.this.cpp" - }, - "2": { - "name": "variable.other.object.property.cpp" - }, - "3": { - "name": "punctuation.separator.dot-access.cpp" - }, - "4": { - "name": "punctuation.separator.pointer-access.cpp" - } - } - }, - { - "match": "(?:((?\\*|->)))", - "captures": { - "1": { - "name": "variable.language.this.cpp" - }, - "2": { - "name": "variable.other.object.access.cpp" - }, - "3": { - "name": "punctuation.separator.dot-access.cpp" - }, - "4": { - "name": "punctuation.separator.pointer-access.cpp" - } - } - }, - { - "include": "#member_access" - }, - { - "include": "#method_access" - } - ] - }, - "6": { - "name": "variable.other.property.cpp" - } - } - }, - "method_access": { - "begin": "(?:((?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?-mix:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(\\()", - "beginCaptures": { - "1": { - "name": "variable.language.this.cpp" - }, - "2": { - "name": "variable.other.object.access.cpp" - }, - "3": { - "name": "punctuation.separator.dot-access.cpp" - }, - "4": { - "name": "punctuation.separator.pointer-access.cpp" - }, - "5": { - "patterns": [ - { - "match": "(?<=(?:\\.\\*|\\.|->|->\\*))\\s*(?:((?\\*|->)))", - "captures": { - "1": { - "name": "variable.language.this.cpp" - }, - "2": { - "name": "variable.other.object.property.cpp" - }, - "3": { - "name": "punctuation.separator.dot-access.cpp" - }, - "4": { - "name": "punctuation.separator.pointer-access.cpp" - } - } - }, - { - "match": "(?:((?\\*|->)))", - "captures": { - "1": { - "name": "variable.language.this.cpp" - }, - "2": { - "name": "variable.other.object.access.cpp" - }, - "3": { - "name": "punctuation.separator.dot-access.cpp" - }, - "4": { - "name": "punctuation.separator.pointer-access.cpp" - } - } - }, - { - "include": "#member_access" - }, - { - "include": "#method_access" - } - ] - }, - "6": { - "name": "entity.name.function.member.cpp" - }, - "7": { - "name": "punctuation.section.arguments.begin.bracket.round.function.member.cpp" - } - }, - "end": "(\\))", - "endCaptures": { - "1": { - "name": "punctuation.section.arguments.end.bracket.round.function.member.cpp" - } - }, - "patterns": [ - { - "include": "#function_call_context" - } - ] - }, - "using_namespace": { - "name": "meta.using-namespace.cpp", - "begin": "(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*))?((?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)\\s*((?|\\?\\?>)|(?=[;>\\[\\]=]))", - "patterns": [ - { - "name": "meta.head.namespace.cpp", - "begin": "\\G ?", - "end": "((?:\\{|<%|\\?\\?<|(?=;)))", - "endCaptures": { - "1": { - "name": "punctuation.section.block.begin.bracket.curly.namespace.cpp" - } - }, - "patterns": [ - { - "include": "#attributes_context" - }, - { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*\\s*(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)\\s*((?|\\?\\?>)", - "endCaptures": { - "1": { - "name": "punctuation.section.block.end.bracket.curly.namespace.cpp" - } - }, - "patterns": [ - { - "include": "#root_context" - } - ] - }, - { - "name": "meta.tail.namespace.cpp", - "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", - "end": "[\\s\\n]*(?=;)", - "patterns": [ - { - "include": "#root_context" - } - ] - } - ] - }, - "macro_argument": { - "match": "##(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*(?!\\w)", - "name": "variable.other.macro.argument.cpp" - }, - "lambdas": { - "begin": "((?:(?<=[^\\s]|^)(?])|(?<=\\Wreturn|^return))\\s*(\\[(?!\\[))((?:.*\\[.*?\\].*?)*.*?)(\\]))", - "beginCaptures": { - "2": { - "name": "punctuation.definition.capture.begin.lambda.cpp" - }, - "3": { - "name": "meta.lambda.capture.cpp", - "patterns": [ - { - "include": "#function_parameter_context" - } - ] - }, - "4": { - "name": "punctuation.definition.capture.end.lambda.cpp" - } - }, - "end": "(?<=})", - "patterns": [ - { - "name": "meta.function.definition.parameters.lambda.cpp", - "begin": "(\\()", - "beginCaptures": { - "1": { - "name": "punctuation.definition.parameters.begin.lambda.cpp" - } - }, - "end": "(\\))", - "endCaptures": { - "1": { - "name": "punctuation.definition.parameters.end.lambda.cpp" - } - }, - "patterns": [ - { - "include": "#function_parameter_context" - } - ] - }, - { - "match": "(?)(.+?(?=\\{|$))?", - "captures": { - "1": { - "name": "punctuation.definition.lambda.return-type.cpp" - }, - "2": { - "name": "storage.type.return-type.lambda.cpp" - } - } - }, - { - "name": "meta.function.definition.body.lambda.cpp", - "begin": "(\\{)", - "beginCaptures": { - "1": { - "name": "punctuation.section.block.begin.bracket.curly.lambda.cpp" - } - }, - "end": "(\\})", - "endCaptures": { - "1": { - "name": "punctuation.section.block.end.bracket.curly.lambda.cpp" - } - }, - "patterns": [ - { - "include": "#root_context" - } - ] - } - ] - }, - "pthread_types": { - "match": "(?))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\())", + "beginCaptures": { + "1": { + "name": "meta.head.function.definition.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "storage.type.template.cpp" + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "name": "storage.modifier.$11.cpp" + }, + "12": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "13": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "14": { + "name": "comment.block.cpp" + }, + "15": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "16": { + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?:class|struct|union|enum)", + "name": "storage.type.$0.cpp" + }, + { + "include": "#attributes_context" + }, + { + "include": "#function_type" + }, + { + "include": "#storage_types" + }, + { + "include": "#number_literal" + }, + { + "include": "#string_context_c" + }, + { + "include": "#comma" + }, + { + "include": "#scope_resolution_inner_generated" + }, + { + "include": "#template_call_range" + }, + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", + "name": "entity.name.type.cpp" + } + ] + }, + "17": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "18": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "19": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "20": { + "name": "comment.block.cpp" + }, + "21": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "22": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "23": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "24": { + "name": "comment.block.cpp" + }, + "25": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "27": { + "patterns": [ + { + "include": "#scope_resolution_inner_generated" + } + ] + }, + "28": { + "name": "entity.name.scope-resolution.cpp" + }, + "29": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "30": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" + }, + "31": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "32": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "33": { + "name": "comment.block.cpp" + }, + "34": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "35": { + "name": "entity.name.type.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "37": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "38": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "39": { + "name": "comment.block.cpp" + }, + "40": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "41": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "42": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "43": { + "name": "comment.block.cpp" + }, + "44": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "45": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "46": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "47": { + "name": "comment.block.cpp" + }, + "48": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "49": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "50": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "51": { + "name": "comment.block.cpp" + }, + "52": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "53": { + "name": "storage.type.modifier.calling-convention.cpp" + }, + "54": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "55": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "56": { + "name": "comment.block.cpp" + }, + "57": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "58": { + "patterns": [ + { + "include": "#scope_resolution_function_definition_inner_generated" + } + ] + }, + "59": { + "name": "entity.name.function.definition.cpp" + }, + "60": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "61": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "62": { + "name": "comment.block.cpp" + }, + "63": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "end": "(?:(?<=\\}|%>|\\?\\?>)|(?=[;>\\[\\]=]))", + "patterns": [ + { + "name": "meta.head.function.definition.cpp", + "begin": "\\G ?", + "end": "((?:\\{|<%|\\?\\?<|(?=;)))", + "endCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.function.definition.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "contentName": "meta.function.definition.parameters.cpp", + "begin": "(\\()", + "beginCaptures": { + "1": { + "name": "punctuation.section.parameters.begin.bracket.round.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.parameters.end.bracket.round.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "include": "#parameter_or_maybe_value" + }, + { + "include": "#comma" + }, + { + "include": "#evaluation_context" + } + ] + }, + { + "include": "$base" + } + ] + }, + { + "name": "meta.body.function.definition.cpp", + "begin": "(?<=\\{|<%|\\?\\?<)", + "end": "(\\}|%>|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.function.definition.cpp" + } + }, + "patterns": [ + { + "include": "#function_body_context" + } + ] + }, + { + "name": "meta.tail.function.definition.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "operator_overload": { + "name": "meta.function.definition.special.operator-overload.cpp", + "begin": "((?:(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(operator)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(?:(?:((?:\\+\\+|\\-\\-|\\(\\)|\\[\\]|\\->|\\+\\+|\\-\\-|\\+|\\-|!|~|\\*|&|new|new\\[\\]|delete|delete\\[\\]|\\->\\*|\\*|\\/|%|\\+|\\-|<<|>>|<=>|<|<=|>|>=|==|!=|&|\\^|\\||&&|\\|\\||=|\\+=|\\-=|\\*=|\\/=|%=|<<=|>>=|&=|\\^=|\\|=|,))|((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:\\[\\])?)))|(\"\")((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\<|\\())", + "beginCaptures": { + "1": { + "name": "meta.head.function.definition.special.operator-overload.cpp" + }, + "2": { + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?:class|struct|union|enum)", + "name": "storage.type.$0.cpp" + }, + { + "include": "#attributes_context" + }, + { + "include": "#function_type" + }, + { + "include": "#storage_types" + }, + { + "include": "#number_literal" + }, + { + "include": "#string_context_c" + }, + { + "include": "#comma" + }, + { + "include": "#scope_resolution_inner_generated" + }, + { + "include": "#template_call_range" + }, + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", + "name": "entity.name.type.cpp" + } + ] + }, + "3": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "4": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "5": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "6": { + "name": "comment.block.cpp" + }, + "7": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "8": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "9": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "10": { + "name": "comment.block.cpp" + }, + "11": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "patterns": [ + { + "include": "#scope_resolution_inner_generated" + } + ] + }, + "14": { + "name": "entity.name.scope-resolution.cpp" + }, + "15": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "16": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" + }, + "17": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "18": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "19": { + "name": "comment.block.cpp" + }, + "20": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "21": { + "name": "entity.name.type.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "23": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "24": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "25": { + "name": "comment.block.cpp" + }, + "26": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "27": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "28": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "29": { + "name": "comment.block.cpp" + }, + "30": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "31": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "32": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "33": { + "name": "comment.block.cpp" + }, + "34": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "35": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "36": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "37": { + "name": "comment.block.cpp" + }, + "38": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "39": { + "name": "storage.type.modifier.calling-convention.cpp" + }, + "40": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "41": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "42": { + "name": "comment.block.cpp" + }, + "43": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "44": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "45": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "46": { + "name": "comment.block.cpp" + }, + "47": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "48": { + "patterns": [ + { + "match": "::", + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.operator.cpp" + }, + { + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "entity.name.operator.type.reference.cpp" + } + ] + }, + "58": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "59": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "60": { + "name": "comment.block.cpp" + }, + "61": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "62": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "63": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "64": { + "name": "comment.block.cpp" + }, + "65": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "66": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "67": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "68": { + "name": "comment.block.cpp" + }, + "69": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "70": { + "name": "entity.name.operator.type.array.cpp" + }, + "71": { + "name": "entity.name.operator.custom-literal.cpp" + }, + "72": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "73": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "74": { + "name": "comment.block.cpp" + }, + "75": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "76": { + "name": "entity.name.operator.custom-literal.cpp" + }, + "77": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "78": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "79": { + "name": "comment.block.cpp" + }, + "80": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "end": "(?:(?<=\\}|%>|\\?\\?>)|(?=[;>\\[\\]=]))", + "patterns": [ + { + "name": "meta.head.function.definition.special.operator-overload.cpp", + "begin": "\\G ?", + "end": "((?:\\{|<%|\\?\\?<|(?=;)))", + "endCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.function.definition.special.operator-overload.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "include": "#template_call_range" + }, + { + "contentName": "meta.function.definition.parameters.special.operator-overload.cpp", + "begin": "(\\()", + "beginCaptures": { + "1": { + "name": "punctuation.section.parameters.begin.bracket.round.special.operator-overload.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.parameters.end.bracket.round.special.operator-overload.cpp" + } + }, + "patterns": [ + { + "include": "#function_parameter_context" + }, + { + "include": "#evaluation_context" + } + ] + }, + { + "include": "$base" + } + ] + }, + { + "name": "meta.body.function.definition.special.operator-overload.cpp", + "begin": "(?<=\\{|<%|\\?\\?<)", + "end": "(\\}|%>|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.function.definition.special.operator-overload.cpp" + } + }, + "patterns": [ + { + "include": "#function_body_context" + } + ] + }, + { + "name": "meta.tail.function.definition.special.operator-overload.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "static_assert": { + "begin": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", + "beginCaptures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "keyword.other.static_assert.cpp" + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "10": { + "name": "punctuation.section.arguments.begin.bracket.round.static_assert.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.arguments.end.bracket.round.static_assert.cpp" + } + }, + "patterns": [ + { + "name": "meta.static_assert.message.cpp", + "begin": "(,)\\s*(?=(?:L|u8|u|U\\s*\\\")?)", + "beginCaptures": { + "1": { + "name": "punctuation.separator.delimiter.comma.cpp" + } + }, + "end": "(?=\\))", + "patterns": [ + { + "include": "#string_context" + }, + { + "include": "#string_context_c" + } + ] + }, + { + "include": "#evaluation_context" + } + ] + }, + "function_call": { + "begin": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?]*|[^>]*+<[^>]*+>)++>\\s*)?(\\()", + "beginCaptures": { + "1": { + "patterns": [ + { + "include": "#scope_resolution_function_call_inner_generated" + } + ] + }, + "2": { + "name": "entity.name.function.call.cpp" + }, + "3": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "4": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "5": { + "name": "comment.block.cpp" + }, + "6": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "7": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "8": { + "name": "punctuation.section.arguments.begin.bracket.round.function.call.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.arguments.end.bracket.round.function.call.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "curly_initializer": { + "name": "meta.initialization.cpp", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\{)", + "beginCaptures": { + "1": { + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?:class|struct|union|enum)", + "name": "storage.type.$0.cpp" + }, + { + "include": "#attributes_context" + }, + { + "include": "#function_type" + }, + { + "include": "#storage_types" + }, + { + "include": "#number_literal" + }, + { + "include": "#string_context_c" + }, + { + "include": "#comma" + }, + { + "include": "#scope_resolution_inner_generated" + }, + { + "include": "#template_call_range" + }, + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", + "name": "entity.name.type.cpp" + } + ] + }, + "2": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "3": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "4": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "5": { + "name": "comment.block.cpp" + }, + "6": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#scope_resolution_inner_generated" + } + ] + }, + "13": { + "name": "entity.name.scope-resolution.cpp" + }, + "14": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "15": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "name": "entity.name.type.cpp" + }, + "21": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "22": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "23": { + "name": "comment.block.cpp" + }, + "24": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "25": { + "name": "punctuation.section.arguments.begin.bracket.curly.initializer.cpp" + } + }, + "end": "(\\})", + "endCaptures": { + "1": { + "name": "punctuation.section.arguments.end.bracket.curly.initializer.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + }, + { + "include": "#comma" + } + ] + }, + "builtin_storage_type_initilizer": { + "begin": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", + "beginCaptures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "storage.type.primitive.cpp storage.type.built-in.primitive.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { + "name": "storage.type.cpp storage.type.built-in.cpp" + }, + "15": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "16": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "17": { + "name": "comment.block.cpp" + }, + "18": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "19": { + "name": "support.type.posix-reserved.pthread.cpp support.type.built-in.posix-reserved.pthread.cpp" + }, + "20": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "21": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "22": { + "name": "comment.block.cpp" + }, + "23": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "24": { + "name": "support.type.posix-reserved.cpp support.type.built-in.posix-reserved.cpp" + }, + "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "29": { + "name": "punctuation.section.arguments.begin.bracket.round.initializer.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.arguments.end.bracket.round.initializer.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "constructor_inline": { + "name": "meta.function.definition.special.constructor.cpp", + "begin": "(^((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:inline|constexpr|mutable|friend|explicit|virtual)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?|\\?\\?>)|(?=[;>\\[\\]=]))", + "patterns": [ + { + "name": "meta.head.function.definition.special.constructor.cpp", + "begin": "\\G ?", + "end": "((?:\\{|<%|\\?\\?<|(?=;)))", + "endCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.function.definition.special.constructor.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "patterns": [ + { + "match": "(\\=)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(default)|(delete))", + "captures": { + "1": { + "name": "keyword.operator.assignment.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "keyword.other.default.constructor.cpp" + }, + "7": { + "name": "keyword.other.delete.constructor.cpp" + } + } + } + ] + }, + { + "include": "#functional_specifiers_pre_parameters" + }, + { + "begin": "(:)", + "beginCaptures": { + "1": { + "name": "punctuation.separator.initializers.cpp" + } + }, + "end": "(?=\\{)", + "patterns": [ + { + "contentName": "meta.parameter.initialization.cpp", + "begin": "((?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.function.definition.special.constructor.cpp" + } + }, + "patterns": [ + { + "include": "#function_body_context" + } + ] + }, + { + "name": "meta.tail.function.definition.special.constructor.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "constructor_root": { + "name": "meta.function.definition.special.constructor.cpp", + "begin": "(\\s*+((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\13((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", + "beginCaptures": { + "1": { + "name": "meta.head.function.definition.special.constructor.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "storage.type.modifier.calling-convention.cpp" + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "patterns": [ + { + "match": "::", + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.constructor.cpp" + }, + { + "match": "(?|\\?\\?>)|(?=[;>\\[\\]=]))", + "patterns": [ + { + "name": "meta.head.function.definition.special.constructor.cpp", + "begin": "\\G ?", + "end": "((?:\\{|<%|\\?\\?<|(?=;)))", + "endCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.function.definition.special.constructor.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "patterns": [ + { + "match": "(\\=)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(default)|(delete))", + "captures": { + "1": { + "name": "keyword.operator.assignment.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "keyword.other.default.constructor.cpp" + }, + "7": { + "name": "keyword.other.delete.constructor.cpp" + } + } + } + ] + }, + { + "include": "#functional_specifiers_pre_parameters" + }, + { + "begin": "(:)", + "beginCaptures": { + "1": { + "name": "punctuation.separator.initializers.cpp" + } + }, + "end": "(?=\\{)", + "patterns": [ + { + "contentName": "meta.parameter.initialization.cpp", + "begin": "((?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.function.definition.special.constructor.cpp" + } + }, + "patterns": [ + { + "include": "#function_body_context" + } + ] + }, + { + "name": "meta.tail.function.definition.special.constructor.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "destructor_inline": { + "name": "meta.function.definition.special.member.destructor.cpp", + "begin": "(^((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:inline|constexpr|mutable|friend|explicit|virtual)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*)(~(?|\\?\\?>)|(?=[;>\\[\\]=]))", + "patterns": [ + { + "name": "meta.head.function.definition.special.member.destructor.cpp", + "begin": "\\G ?", + "end": "((?:\\{|<%|\\?\\?<|(?=;)))", + "endCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.function.definition.special.member.destructor.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "patterns": [ + { + "match": "(\\=)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(default)|(delete))", + "captures": { + "1": { + "name": "keyword.operator.assignment.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "keyword.other.default.constructor.cpp" + }, + "7": { + "name": "keyword.other.delete.constructor.cpp" + } + } + } + ] + }, + { + "contentName": "meta.function.definition.parameters.special.member.destructor.cpp", + "begin": "(\\()", + "beginCaptures": { + "1": { + "name": "punctuation.section.parameters.begin.bracket.round.special.member.destructor.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.parameters.end.bracket.round.special.member.destructor.cpp" + } + } + }, + { + "include": "$base" + } + ] + }, + { + "name": "meta.body.function.definition.special.member.destructor.cpp", + "begin": "(?<=\\{|<%|\\?\\?<)", + "end": "(\\}|%>|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.function.definition.special.member.destructor.cpp" + } + }, + "patterns": [ + { + "include": "#function_body_context" + } + ] + }, + { + "name": "meta.tail.function.definition.special.member.destructor.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "destructor_root": { + "name": "meta.function.definition.special.member.destructor.cpp", + "begin": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))~\\13((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", + "beginCaptures": { + "1": { + "name": "meta.head.function.definition.special.member.destructor.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "storage.type.modifier.calling-convention.cpp" + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "patterns": [ + { + "match": "::", + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.destructor.cpp" + }, + { + "match": "(?|\\?\\?>)|(?=[;>\\[\\]=]))", + "patterns": [ + { + "name": "meta.head.function.definition.special.member.destructor.cpp", + "begin": "\\G ?", + "end": "((?:\\{|<%|\\?\\?<|(?=;)))", + "endCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.function.definition.special.member.destructor.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "patterns": [ + { + "match": "(\\=)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(default)|(delete))", + "captures": { + "1": { + "name": "keyword.operator.assignment.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "keyword.other.default.constructor.cpp" + }, + "7": { + "name": "keyword.other.delete.constructor.cpp" + } + } + } + ] + }, + { + "contentName": "meta.function.definition.parameters.special.member.destructor.cpp", + "begin": "(\\()", + "beginCaptures": { + "1": { + "name": "punctuation.section.parameters.begin.bracket.round.special.member.destructor.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.parameters.end.bracket.round.special.member.destructor.cpp" + } + } + }, + { + "include": "$base" + } + ] + }, + { + "name": "meta.body.function.definition.special.member.destructor.cpp", + "begin": "(?<=\\{|<%|\\?\\?<)", + "end": "(\\}|%>|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.function.definition.special.member.destructor.cpp" + } + }, + "patterns": [ + { + "include": "#function_body_context" + } + ] + }, + { + "name": "meta.tail.function.definition.special.member.destructor.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "operators": { + "patterns": [ + { + "include": "#sizeof_operator" + }, + { + "include": "#alignof_operator" + }, + { + "include": "#alignas_operator" + }, + { + "include": "#typeid_operator" + }, + { + "include": "#noexcept_operator" + }, + { + "match": "--", + "name": "keyword.operator.decrement.cpp" + }, + { + "match": "\\+\\+", + "name": "keyword.operator.increment.cpp" + }, + { + "match": "%=|\\+=|-=|\\*=|(?>=|\\|=", + "name": "keyword.operator.assignment.compound.bitwise.cpp" + }, + { + "match": "<<|>>", + "name": "keyword.operator.bitwise.shift.cpp" + }, + { + "match": "!=|<=|>=|==|<|>", + "name": "keyword.operator.comparison.cpp" + }, + { + "match": "&&|!|\\|\\|", + "name": "keyword.operator.logical.cpp" + }, + { + "match": "&|\\||\\^|~", + "name": "keyword.operator.cpp" + }, + { + "include": "#assignment_operator" + }, + { + "match": "%|\\*|\\/|-|\\+", + "name": "keyword.operator.cpp" + }, + { + "include": "#ternary_operator" + } + ] + }, + "wordlike_operators": { + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", + "beginCaptures": { + "1": { + "name": "keyword.operator.functionlike.cpp keyword.operator.sizeof.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.section.arguments.begin.bracket.round.operator.sizeof.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.arguments.end.bracket.round.operator.sizeof.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "alignof_operator": { + "contentName": "meta.arguments.operator.alignof.cpp", + "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", + "beginCaptures": { + "1": { + "name": "keyword.operator.functionlike.cpp keyword.operator.alignof.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.section.arguments.begin.bracket.round.operator.alignof.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.arguments.end.bracket.round.operator.alignof.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "alignas_operator": { + "contentName": "meta.arguments.operator.alignas.cpp", + "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", + "beginCaptures": { + "1": { + "name": "keyword.operator.functionlike.cpp keyword.operator.alignas.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.section.arguments.begin.bracket.round.operator.alignas.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.arguments.end.bracket.round.operator.alignas.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "typeid_operator": { + "contentName": "meta.arguments.operator.typeid.cpp", + "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", + "beginCaptures": { + "1": { + "name": "keyword.operator.functionlike.cpp keyword.operator.typeid.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.section.arguments.begin.bracket.round.operator.typeid.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.arguments.end.bracket.round.operator.typeid.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "noexcept_operator": { + "contentName": "meta.arguments.operator.noexcept.cpp", + "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", + "beginCaptures": { + "1": { + "name": "keyword.operator.functionlike.cpp keyword.operator.noexcept.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.section.arguments.begin.bracket.round.operator.noexcept.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.arguments.end.bracket.round.operator.noexcept.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "ternary_operator": { + "applyEndPatternLast": true, + "begin": "(\\?)", + "beginCaptures": { + "1": { + "name": "keyword.operator.ternary.cpp" + } + }, + "end": "(:)", + "endCaptures": { + "1": { + "name": "keyword.operator.ternary.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "include": "#string_context" + }, + { + "include": "#number_literal" + }, + { + "include": "#string_context_c" + }, + { + "include": "#method_access" + }, + { + "include": "#member_access" + }, + { + "include": "#predefined_macros" + }, + { + "include": "#operators" + }, + { + "include": "#memory_operators" + }, + { + "include": "#wordlike_operators" + }, + { + "include": "#type_casting_operators" + }, + { + "include": "#control_flow_keywords" + }, + { + "include": "#exception_keywords" + }, + { + "include": "#the_this_keyword" + }, + { + "include": "#language_constants" + }, + { + "include": "#builtin_storage_type_initilizer" + }, + { + "include": "#qualifiers_and_specifiers_post_parameters" + }, + { + "include": "#functional_specifiers_pre_parameters" + }, + { + "include": "#storage_types" + }, + { + "include": "#misc_storage_modifiers" + }, + { + "include": "#lambdas" + }, + { + "include": "#attributes_context" + }, + { + "include": "#parentheses" + }, + { + "include": "#function_call" + }, + { + "include": "#scope_resolution_inner_generated" + }, + { + "include": "#square_brackets" + }, + { + "include": "#empty_square_brackets" + }, + { + "include": "#semicolon" + }, + { + "include": "#comma" + } + ] + }, + "function_pointer": { + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", + "beginCaptures": { + "1": { + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?:class|struct|union|enum)", + "name": "storage.type.$0.cpp" + }, + { + "include": "#attributes_context" + }, + { + "include": "#function_type" + }, + { + "include": "#storage_types" + }, + { + "include": "#number_literal" + }, + { + "include": "#string_context_c" + }, + { + "include": "#comma" + }, + { + "include": "#scope_resolution_inner_generated" + }, + { + "include": "#template_call_range" + }, + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", + "name": "entity.name.type.cpp" + } + ] + }, + "2": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "3": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "4": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "5": { + "name": "comment.block.cpp" + }, + "6": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#scope_resolution_inner_generated" + } + ] + }, + "13": { + "name": "entity.name.scope-resolution.cpp" + }, + "14": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "15": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "name": "entity.name.type.cpp" + }, + "21": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "22": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "23": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "24": { + "name": "comment.block.cpp" + }, + "25": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "26": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "27": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "28": { + "name": "comment.block.cpp" + }, + "29": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "30": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "31": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "32": { + "name": "comment.block.cpp" + }, + "33": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "34": { + "name": "punctuation.section.parens.begin.bracket.round.function.pointer.cpp" + }, + "35": { + "name": "punctuation.definition.function.pointer.dereference.cpp" + }, + "36": { + "name": "variable.other.definition.pointer.function.cpp" + }, + "37": { + "name": "punctuation.definition.begin.bracket.square.cpp" + }, + "38": { + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "39": { + "name": "punctuation.definition.end.bracket.square.cpp" + }, + "40": { + "name": "punctuation.section.parens.end.bracket.round.function.pointer.cpp" + }, + "41": { + "name": "punctuation.section.parameters.begin.bracket.round.function.pointer.cpp" + } + }, + "end": "(\\))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=[{=,);]|\\n)(?!\\()", + "endCaptures": { + "1": { + "name": "punctuation.section.parameters.end.bracket.round.function.pointer.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "patterns": [ + { + "include": "#function_parameter_context" + } + ] + }, + "function_pointer_parameter": { + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", + "beginCaptures": { + "1": { + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?:class|struct|union|enum)", + "name": "storage.type.$0.cpp" + }, + { + "include": "#attributes_context" + }, + { + "include": "#function_type" + }, + { + "include": "#storage_types" + }, + { + "include": "#number_literal" + }, + { + "include": "#string_context_c" + }, + { + "include": "#comma" + }, + { + "include": "#scope_resolution_inner_generated" + }, + { + "include": "#template_call_range" + }, + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", + "name": "entity.name.type.cpp" + } + ] + }, + "2": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "3": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "4": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "5": { + "name": "comment.block.cpp" + }, + "6": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#scope_resolution_inner_generated" + } + ] + }, + "13": { + "name": "entity.name.scope-resolution.cpp" + }, + "14": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "15": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "name": "entity.name.type.cpp" + }, + "21": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "22": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "23": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "24": { + "name": "comment.block.cpp" + }, + "25": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "26": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "27": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "28": { + "name": "comment.block.cpp" + }, + "29": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "30": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "31": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "32": { + "name": "comment.block.cpp" + }, + "33": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "34": { + "name": "punctuation.section.parens.begin.bracket.round.function.pointer.cpp" + }, + "35": { + "name": "punctuation.definition.function.pointer.dereference.cpp" + }, + "36": { + "name": "variable.parameter.pointer.function.cpp" + }, + "37": { + "name": "punctuation.definition.begin.bracket.square.cpp" + }, + "38": { + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "39": { + "name": "punctuation.definition.end.bracket.square.cpp" + }, + "40": { + "name": "punctuation.section.parens.end.bracket.round.function.pointer.cpp" + }, + "41": { + "name": "punctuation.section.parameters.begin.bracket.round.function.pointer.cpp" + } + }, + "end": "(\\))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=[{=,);]|\\n)(?!\\()", + "endCaptures": { + "1": { + "name": "punctuation.section.parameters.end.bracket.round.function.pointer.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "patterns": [ + { + "include": "#function_parameter_context" + } + ] + }, + "parameter_or_maybe_value": { + "name": "meta.parameter.cpp", + "begin": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\w)", + "beginCaptures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "end": "(?:(?=\\))|(,))", + "endCaptures": { + "1": { + "name": "punctuation.separator.delimiter.comma.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "include": "#memory_operators" + }, + { + "include": "#builtin_storage_type_initilizer" + }, + { + "include": "#curly_initializer" + }, + { + "include": "#function_pointer_parameter" + }, + { + "include": "#decltype" + }, + { + "include": "#vararg_ellipses" + }, + { + "match": "((?:((?:const|static|volatile|register|restrict|extern))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))+)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=,|\\)|=)", + "captures": { + "1": { + "patterns": [ + { + "include": "#storage_types" + } + ] + }, + "2": { + "name": "storage.modifier.specifier.parameter.cpp" + }, + "3": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "4": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "5": { + "name": "comment.block.cpp" + }, + "6": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "12": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "13": { + "name": "comment.block.cpp" + }, + "14": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "15": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "16": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "17": { + "name": "comment.block.cpp" + }, + "18": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "19": { + "name": "storage.type.primitive.cpp storage.type.built-in.primitive.cpp" + }, + "20": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "21": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "22": { + "name": "comment.block.cpp" + }, + "23": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "24": { + "name": "storage.type.cpp storage.type.built-in.cpp" + }, + "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "29": { + "name": "support.type.posix-reserved.pthread.cpp support.type.built-in.posix-reserved.pthread.cpp" + }, + "30": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "31": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "32": { + "name": "comment.block.cpp" + }, + "33": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "34": { + "name": "support.type.posix-reserved.cpp support.type.built-in.posix-reserved.cpp" + }, + "35": { + "name": "entity.name.type.parameter.cpp" + }, + "36": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "37": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "38": { + "name": "comment.block.cpp" + }, + "39": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + { + "include": "#storage_types" + }, + { + "include": "#function_call" + }, + { + "include": "#scope_resolution_parameter_inner_generated" + }, + { + "match": "(?:class|struct|union|enum)", + "name": "storage.type.$0.cpp" + }, + { + "begin": "(?<==)", + "end": "(?:(?=\\))|(,))", + "endCaptures": { + "1": { + "name": "punctuation.separator.delimiter.comma.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + { + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\)|,|\\[|=|\\n)", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "variable.parameter.cpp" + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + { + "include": "#attributes_context" + }, + { + "name": "meta.bracket.square.array.cpp", + "begin": "(\\[)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.begin.bracket.square.array.type.cpp" + } + }, + "end": "(\\])", + "endCaptures": { + "1": { + "name": "punctuation.definition.end.bracket.square.array.type.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*)", + "captures": { + "0": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + { + "include": "#evaluation_context" + } + ] + }, + "parameter": { + "name": "meta.parameter.cpp", + "begin": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\w)", + "beginCaptures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "end": "(?:(?=\\))|(,))", + "endCaptures": { + "1": { + "name": "punctuation.separator.delimiter.comma.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "include": "#function_pointer_parameter" + }, + { + "include": "#decltype" + }, + { + "include": "#vararg_ellipses" + }, + { + "match": "((?:((?:const|static|volatile|register|restrict|extern))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))+)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=,|\\)|=)", + "captures": { + "1": { + "patterns": [ + { + "include": "#storage_types" + } + ] + }, + "2": { + "name": "storage.modifier.specifier.parameter.cpp" + }, + "3": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "4": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "5": { + "name": "comment.block.cpp" + }, + "6": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "12": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "13": { + "name": "comment.block.cpp" + }, + "14": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "15": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "16": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "17": { + "name": "comment.block.cpp" + }, + "18": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "19": { + "name": "storage.type.primitive.cpp storage.type.built-in.primitive.cpp" + }, + "20": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "21": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "22": { + "name": "comment.block.cpp" + }, + "23": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "24": { + "name": "storage.type.cpp storage.type.built-in.cpp" + }, + "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "29": { + "name": "support.type.posix-reserved.pthread.cpp support.type.built-in.posix-reserved.pthread.cpp" + }, + "30": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "31": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "32": { + "name": "comment.block.cpp" + }, + "33": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "34": { + "name": "support.type.posix-reserved.cpp support.type.built-in.posix-reserved.cpp" + }, + "35": { + "name": "entity.name.type.parameter.cpp" + }, + "36": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "37": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "38": { + "name": "comment.block.cpp" + }, + "39": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + { + "include": "#storage_types" + }, + { + "include": "#scope_resolution_parameter_inner_generated" + }, + { + "match": "(?:class|struct|union|enum)", + "name": "storage.type.$0.cpp" + }, + { + "begin": "(?<==)", + "end": "(?:(?=\\))|(,))", + "endCaptures": { + "1": { + "name": "punctuation.separator.delimiter.comma.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + { + "include": "#assignment_operator" + }, + { + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\)|,|\\[|=|\\n)", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "variable.parameter.cpp" + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + { + "include": "#attributes_context" + }, + { + "name": "meta.bracket.square.array.cpp", + "begin": "(\\[)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.begin.bracket.square.array.type.cpp" + } + }, + "end": "(\\])", + "endCaptures": { + "1": { + "name": "punctuation.definition.end.bracket.square.array.type.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*)", + "captures": { + "0": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + } + ] + }, + "member_access": { + "match": "(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*(?:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*(\\b(?!auto[^(?-mix:\\w)]|void[^(?-mix:\\w)]|char[^(?-mix:\\w)]|short[^(?-mix:\\w)]|int[^(?-mix:\\w)]|signed[^(?-mix:\\w)]|unsigned[^(?-mix:\\w)]|long[^(?-mix:\\w)]|float[^(?-mix:\\w)]|double[^(?-mix:\\w)]|bool[^(?-mix:\\w)]|wchar_t[^(?-mix:\\w)]|u_char[^(?-mix:\\w)]|u_short[^(?-mix:\\w)]|u_int[^(?-mix:\\w)]|u_long[^(?-mix:\\w)]|ushort[^(?-mix:\\w)]|uint[^(?-mix:\\w)]|u_quad_t[^(?-mix:\\w)]|quad_t[^(?-mix:\\w)]|qaddr_t[^(?-mix:\\w)]|caddr_t[^(?-mix:\\w)]|daddr_t[^(?-mix:\\w)]|div_t[^(?-mix:\\w)]|dev_t[^(?-mix:\\w)]|fixpt_t[^(?-mix:\\w)]|blkcnt_t[^(?-mix:\\w)]|blksize_t[^(?-mix:\\w)]|gid_t[^(?-mix:\\w)]|in_addr_t[^(?-mix:\\w)]|in_port_t[^(?-mix:\\w)]|ino_t[^(?-mix:\\w)]|key_t[^(?-mix:\\w)]|mode_t[^(?-mix:\\w)]|nlink_t[^(?-mix:\\w)]|id_t[^(?-mix:\\w)]|pid_t[^(?-mix:\\w)]|off_t[^(?-mix:\\w)]|segsz_t[^(?-mix:\\w)]|swblk_t[^(?-mix:\\w)]|uid_t[^(?-mix:\\w)]|id_t[^(?-mix:\\w)]|clock_t[^(?-mix:\\w)]|size_t[^(?-mix:\\w)]|ssize_t[^(?-mix:\\w)]|time_t[^(?-mix:\\w)]|useconds_t[^(?-mix:\\w)]|suseconds_t[^(?-mix:\\w)]|int8_t[^(?-mix:\\w)]|int16_t[^(?-mix:\\w)]|int32_t[^(?-mix:\\w)]|int64_t[^(?-mix:\\w)]|uint8_t[^(?-mix:\\w)]|uint16_t[^(?-mix:\\w)]|uint32_t[^(?-mix:\\w)]|uint64_t[^(?-mix:\\w)]|int_least8_t[^(?-mix:\\w)]|int_least16_t[^(?-mix:\\w)]|int_least32_t[^(?-mix:\\w)]|int_least64_t[^(?-mix:\\w)]|uint_least8_t[^(?-mix:\\w)]|uint_least16_t[^(?-mix:\\w)]|uint_least32_t[^(?-mix:\\w)]|uint_least64_t[^(?-mix:\\w)]|int_fast8_t[^(?-mix:\\w)]|int_fast16_t[^(?-mix:\\w)]|int_fast32_t[^(?-mix:\\w)]|int_fast64_t[^(?-mix:\\w)]|uint_fast8_t[^(?-mix:\\w)]|uint_fast16_t[^(?-mix:\\w)]|uint_fast32_t[^(?-mix:\\w)]|uint_fast64_t[^(?-mix:\\w)]|intptr_t[^(?-mix:\\w)]|uintptr_t[^(?-mix:\\w)]|intmax_t[^(?-mix:\\w)]|intmax_t[^(?-mix:\\w)]|uintmax_t[^(?-mix:\\w)]|uintmax_t[^(?-mix:\\w)])(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\b(?!\\())", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "variable.language.this.cpp" + }, + "6": { + "name": "variable.other.object.access.cpp" + }, + "7": { + "name": "punctuation.separator.dot-access.cpp" + }, + "8": { + "name": "punctuation.separator.pointer-access.cpp" + }, + "9": { + "patterns": [ + { + "match": "(?<=(?:\\.\\*|\\.|->|->\\*))\\s*(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\*|->)))", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "variable.language.this.cpp" + }, + "6": { + "name": "variable.other.object.property.cpp" + }, + "7": { + "name": "punctuation.separator.dot-access.cpp" + }, + "8": { + "name": "punctuation.separator.pointer-access.cpp" + } + } + }, + { + "match": "(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\*|->)))", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "variable.language.this.cpp" + }, + "6": { + "name": "variable.other.object.access.cpp" + }, + "7": { + "name": "punctuation.separator.dot-access.cpp" + }, + "8": { + "name": "punctuation.separator.pointer-access.cpp" + } + } + }, + { + "include": "#member_access" + }, + { + "include": "#method_access" + } + ] + }, + "10": { + "name": "variable.other.property.cpp" + } + } + }, + "method_access": { + "begin": "(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\*|->)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*(?:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*(~?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*(\\()", + "beginCaptures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "variable.language.this.cpp" + }, + "6": { + "name": "variable.other.object.access.cpp" + }, + "7": { + "name": "punctuation.separator.dot-access.cpp" + }, + "8": { + "name": "punctuation.separator.pointer-access.cpp" + }, + "9": { + "patterns": [ + { + "match": "(?<=(?:\\.\\*|\\.|->|->\\*))\\s*(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\*|->)))", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "variable.language.this.cpp" + }, + "6": { + "name": "variable.other.object.property.cpp" + }, + "7": { + "name": "punctuation.separator.dot-access.cpp" + }, + "8": { + "name": "punctuation.separator.pointer-access.cpp" + } + } + }, + { + "match": "(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\*|->)))", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "variable.language.this.cpp" + }, + "6": { + "name": "variable.other.object.access.cpp" + }, + "7": { + "name": "punctuation.separator.dot-access.cpp" + }, + "8": { + "name": "punctuation.separator.pointer-access.cpp" + } + } + }, + { + "include": "#member_access" + }, + { + "include": "#method_access" + } + ] + }, + "10": { + "name": "entity.name.function.member.cpp" + }, + "11": { + "name": "punctuation.section.arguments.begin.bracket.round.function.member.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.arguments.end.bracket.round.function.member.cpp" + } + }, + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "using_namespace": { + "name": "meta.using-namespace.cpp", + "begin": "(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)?((?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)\\s*((?|\\?\\?>)|(?=[;>\\[\\]=]))", + "patterns": [ + { + "name": "meta.head.namespace.cpp", + "begin": "\\G ?", + "end": "((?:\\{|<%|\\?\\?<|(?=;)))", + "endCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.namespace.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "include": "#attributes_context" + }, + { + "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)\\s*((?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.namespace.cpp" + } + }, + "patterns": [ + { + "include": "$base" + } + ] + }, + { + "name": "meta.tail.namespace.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "macro_argument": { + "match": "##?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w)", + "name": "variable.other.macro.argument.cpp" + }, + "lambdas": { + "begin": "((?:(?<=[^\\s]|^)(?])|(?<=\\Wreturn|^return))\\s*(\\[(?!\\[))((?:[^\\]\\[]*\\[.*?\\](?!\\s*\\[)[^\\]\\[]*?)*[^\\]\\[]*?)(\\](?!\\[)))", + "beginCaptures": { + "2": { + "name": "punctuation.definition.capture.begin.lambda.cpp" + }, + "3": { + "name": "meta.lambda.capture.cpp", + "patterns": [ + { + "include": "#the_this_keyword" + }, + { + "match": "((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?=\\]|\\z|$)|(,))|(\\=))", + "captures": { + "1": { + "name": "variable.parameter.capture.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.separator.delimiter.comma.cpp" + }, + "7": { + "name": "keyword.operator.assignment.cpp" + } + } + }, + { + "include": "#evaluation_context" + } + ] + }, + "4": { + "name": "punctuation.definition.capture.end.lambda.cpp" + } + }, + "end": "(?<=})", + "patterns": [ + { + "name": "meta.function.definition.parameters.lambda.cpp", + "begin": "(\\()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.parameters.begin.lambda.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.definition.parameters.end.lambda.cpp" + } + }, + "patterns": [ + { + "include": "#function_parameter_context" + } + ] + }, + { + "match": "(?)((?:.+?(?=\\{|$))?)", + "captures": { + "1": { + "name": "punctuation.definition.lambda.return-type.cpp" + }, + "2": { + "name": "storage.type.return-type.lambda.cpp" + } + } + }, + { + "name": "meta.function.definition.body.lambda.cpp", + "begin": "(\\{)", + "beginCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.lambda.cpp" + } + }, + "end": "(\\})", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.lambda.cpp" + } + }, + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, "enumerator_list": { - "match": "((?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:((?]*|[^>]*+<[^>]*+>)++>\\s*))?(::)))?\\s*((?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?\\s*((?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*))?(?:::)))?\\s*(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.]))))", + "match": "(?<=virtual|private|protected|public|,|:)\\s*(?!(?:(?:private|protected|public)|virtual))((?:\\s*+(?:(?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))", "captures": { "1": { "name": "entity.name.type.inherited.cpp" @@ -4246,7 +10197,7 @@ }, "class_block": { "name": "meta.block.class.cpp", - "begin": "((((?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*))?(?:::)))?\\s*(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.]))))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.class.cpp" @@ -4265,6 +10216,59 @@ ] }, "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { "patterns": [ { "include": "#attributes_context" @@ -4274,19 +10278,19 @@ } ] }, - "6": { + "15": { "name": "entity.name.type.$3.cpp" }, - "7": { + "16": { "name": "storage.type.modifier.final.cpp" }, - "8": { - "name": "colon.cpp punctuation.separator.inhertance.cpp" + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" }, - "9": { + "18": { "patterns": [ { - "include": "#inhertance_context" + "include": "#inheritance_context" } ] } @@ -4312,16 +10316,13 @@ }, "patterns": [ { - "include": "#preprocessor_context" + "include": "#ever_present_context" }, { - "include": "#inhertance_context" + "include": "#inheritance_context" }, { "include": "#template_call_range" - }, - { - "include": "#comments_context" } ] }, @@ -4339,10 +10340,16 @@ "include": "#function_pointer" }, { - "include": "#constructor_context" + "include": "#static_assert" }, { - "include": "#root_context" + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" } ] }, @@ -4352,7 +10359,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "#root_context" + "include": "$base" } ] } @@ -4360,7 +10367,7 @@ }, "struct_block": { "name": "meta.block.struct.cpp", - "begin": "((((?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*))?(?:::)))?\\s*(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.]))))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.struct.cpp" @@ -4379,6 +10386,59 @@ ] }, "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { "patterns": [ { "include": "#attributes_context" @@ -4388,19 +10448,19 @@ } ] }, - "6": { + "15": { "name": "entity.name.type.$3.cpp" }, - "7": { + "16": { "name": "storage.type.modifier.final.cpp" }, - "8": { - "name": "colon.cpp punctuation.separator.inhertance.cpp" + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" }, - "9": { + "18": { "patterns": [ { - "include": "#inhertance_context" + "include": "#inheritance_context" } ] } @@ -4426,16 +10486,13 @@ }, "patterns": [ { - "include": "#preprocessor_context" + "include": "#ever_present_context" }, { - "include": "#inhertance_context" + "include": "#inheritance_context" }, { "include": "#template_call_range" - }, - { - "include": "#comments_context" } ] }, @@ -4453,10 +10510,16 @@ "include": "#function_pointer" }, { - "include": "#constructor_context" + "include": "#static_assert" }, { - "include": "#root_context" + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" } ] }, @@ -4466,7 +10529,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "#root_context" + "include": "$base" } ] } @@ -4474,7 +10537,7 @@ }, "union_block": { "name": "meta.block.union.cpp", - "begin": "((((?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*))?(?:::)))?\\s*(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.]))))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.union.cpp" @@ -4493,6 +10556,59 @@ ] }, "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { "patterns": [ { "include": "#attributes_context" @@ -4502,19 +10618,19 @@ } ] }, - "6": { + "15": { "name": "entity.name.type.$3.cpp" }, - "7": { + "16": { "name": "storage.type.modifier.final.cpp" }, - "8": { - "name": "colon.cpp punctuation.separator.inhertance.cpp" + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" }, - "9": { + "18": { "patterns": [ { - "include": "#inhertance_context" + "include": "#inheritance_context" } ] } @@ -4540,16 +10656,13 @@ }, "patterns": [ { - "include": "#preprocessor_context" + "include": "#ever_present_context" }, { - "include": "#inhertance_context" + "include": "#inheritance_context" }, { "include": "#template_call_range" - }, - { - "include": "#comments_context" } ] }, @@ -4567,10 +10680,16 @@ "include": "#function_pointer" }, { - "include": "#constructor_context" + "include": "#static_assert" }, { - "include": "#root_context" + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" } ] }, @@ -4580,7 +10699,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "#root_context" + "include": "$base" } ] } @@ -4588,12 +10707,37 @@ }, "extern_block": { "name": "meta.block.extern.cpp", - "begin": "((\\bextern)(?=\\s*\\\"))", + "begin": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(extern)(?=\\s*\\\"))", "beginCaptures": { "1": { "name": "meta.head.extern.cpp" }, "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { "name": "storage.type.extern.cpp" } }, @@ -4618,7 +10762,7 @@ }, "patterns": [ { - "include": "#root_context" + "include": "$base" } ] }, @@ -4633,7 +10777,7 @@ }, "patterns": [ { - "include": "#root_context" + "include": "$base" } ] }, @@ -4643,12 +10787,12 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "#root_context" + "include": "$base" } ] }, { - "include": "#root_context" + "include": "$base" } ] }, @@ -4663,7 +10807,7 @@ "patterns": [ { "name": "meta.block.class.cpp", - "begin": "((((?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*))?(?:::)))?\\s*(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.]))))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.class.cpp" @@ -4682,6 +10826,59 @@ ] }, "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { "patterns": [ { "include": "#attributes_context" @@ -4691,19 +10888,19 @@ } ] }, - "6": { + "15": { "name": "entity.name.type.$3.cpp" }, - "7": { + "16": { "name": "storage.type.modifier.final.cpp" }, - "8": { - "name": "colon.cpp punctuation.separator.inhertance.cpp" + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" }, - "9": { + "18": { "patterns": [ { - "include": "#inhertance_context" + "include": "#inheritance_context" } ] } @@ -4729,16 +10926,13 @@ }, "patterns": [ { - "include": "#preprocessor_context" + "include": "#ever_present_context" }, { - "include": "#inhertance_context" + "include": "#inheritance_context" }, { "include": "#template_call_range" - }, - { - "include": "#comments_context" } ] }, @@ -4756,10 +10950,16 @@ "include": "#function_pointer" }, { - "include": "#constructor_context" + "include": "#static_assert" }, { - "include": "#root_context" + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" } ] }, @@ -4769,15 +10969,127 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "match": "(\\s*((?:\\*\\s*)*)((?:&\\s*){0,2})\\s*)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, "2": { - "name": "storage.modifier.pointer.cpp" + "patterns": [ + { + "include": "#inline_comment" + } + ] }, "3": { - "name": "storage.modifier.reference.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { "name": "entity.name.type.alias.cpp" } } @@ -4802,7 +11114,7 @@ "patterns": [ { "name": "meta.block.struct.cpp", - "begin": "((((?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*))?(?:::)))?\\s*(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.]))))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.struct.cpp" @@ -4821,6 +11133,59 @@ ] }, "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { "patterns": [ { "include": "#attributes_context" @@ -4830,19 +11195,19 @@ } ] }, - "6": { + "15": { "name": "entity.name.type.$3.cpp" }, - "7": { + "16": { "name": "storage.type.modifier.final.cpp" }, - "8": { - "name": "colon.cpp punctuation.separator.inhertance.cpp" + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" }, - "9": { + "18": { "patterns": [ { - "include": "#inhertance_context" + "include": "#inheritance_context" } ] } @@ -4868,16 +11233,13 @@ }, "patterns": [ { - "include": "#preprocessor_context" + "include": "#ever_present_context" }, { - "include": "#inhertance_context" + "include": "#inheritance_context" }, { "include": "#template_call_range" - }, - { - "include": "#comments_context" } ] }, @@ -4895,10 +11257,16 @@ "include": "#function_pointer" }, { - "include": "#constructor_context" + "include": "#static_assert" }, { - "include": "#root_context" + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" } ] }, @@ -4908,15 +11276,127 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "match": "(\\s*((?:\\*\\s*)*)((?:&\\s*){0,2})\\s*)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, "2": { - "name": "storage.modifier.pointer.cpp" + "patterns": [ + { + "include": "#inline_comment" + } + ] }, "3": { - "name": "storage.modifier.reference.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { "name": "entity.name.type.alias.cpp" } } @@ -4941,7 +11421,7 @@ "patterns": [ { "name": "meta.block.union.cpp", - "begin": "((((?]*|[^>]*+<[^>]*+>)++>\\s*)))?::)*\\s*)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)\\s*(?:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*))?(?:::)))?\\s*(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)(?:(?-mix:(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)))?(?![\\w<:.]))))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.union.cpp" @@ -4960,6 +11440,59 @@ ] }, "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { "patterns": [ { "include": "#attributes_context" @@ -4969,19 +11502,19 @@ } ] }, - "6": { + "15": { "name": "entity.name.type.$3.cpp" }, - "7": { + "16": { "name": "storage.type.modifier.final.cpp" }, - "8": { - "name": "colon.cpp punctuation.separator.inhertance.cpp" + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" }, - "9": { + "18": { "patterns": [ { - "include": "#inhertance_context" + "include": "#inheritance_context" } ] } @@ -5007,16 +11540,13 @@ }, "patterns": [ { - "include": "#preprocessor_context" + "include": "#ever_present_context" }, { - "include": "#inhertance_context" + "include": "#inheritance_context" }, { "include": "#template_call_range" - }, - { - "include": "#comments_context" } ] }, @@ -5034,10 +11564,16 @@ "include": "#function_pointer" }, { - "include": "#constructor_context" + "include": "#static_assert" }, { - "include": "#root_context" + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" } ] }, @@ -5047,15 +11583,127 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "match": "(\\s*((?:\\*\\s*)*)((?:&\\s*){0,2})\\s*)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, "2": { - "name": "storage.modifier.pointer.cpp" + "patterns": [ + { + "include": "#inline_comment" + } + ] }, "3": { - "name": "storage.modifier.reference.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { "name": "entity.name.type.alias.cpp" } } @@ -5069,10 +11717,1948 @@ } ] }, + "struct_declare": { + "match": "(struct)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!final\\W|final\\$|override\\W|override\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?!:)", + "captures": { + "1": { + "name": "storage.type.struct.declare.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "entity.name.type.struct.cpp" + }, + "7": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "8": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "9": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "10": { + "name": "comment.block.cpp" + }, + "11": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "13": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "14": { + "name": "comment.block.cpp" + }, + "15": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "name": "variable.other.object.declare.cpp" + }, + "21": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "22": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "23": { + "name": "comment.block.cpp" + }, + "24": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + "union_declare": { + "match": "(union)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!final\\W|final\\$|override\\W|override\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?!:)", + "captures": { + "1": { + "name": "storage.type.union.declare.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "entity.name.type.union.cpp" + }, + "7": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "8": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "9": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "10": { + "name": "comment.block.cpp" + }, + "11": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "13": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "14": { + "name": "comment.block.cpp" + }, + "15": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "name": "variable.other.object.declare.cpp" + }, + "21": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "22": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "23": { + "name": "comment.block.cpp" + }, + "24": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + "enum_declare": { + "match": "(enum)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!final\\W|final\\$|override\\W|override\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?!:)", + "captures": { + "1": { + "name": "storage.type.enum.declare.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "entity.name.type.enum.cpp" + }, + "7": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "8": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "9": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "10": { + "name": "comment.block.cpp" + }, + "11": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "13": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "14": { + "name": "comment.block.cpp" + }, + "15": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "name": "variable.other.object.declare.cpp" + }, + "21": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "22": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "23": { + "name": "comment.block.cpp" + }, + "24": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + "class_declare": { + "match": "(class)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!final\\W|final\\$|override\\W|override\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?!:)", + "captures": { + "1": { + "name": "storage.type.class.declare.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "entity.name.type.class.cpp" + }, + "7": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "8": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "9": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "10": { + "name": "comment.block.cpp" + }, + "11": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "13": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "14": { + "name": "comment.block.cpp" + }, + "15": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "name": "variable.other.object.declare.cpp" + }, + "21": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "22": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "23": { + "name": "comment.block.cpp" + }, + "24": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + "standard_declares": { + "patterns": [ + { + "include": "#struct_declare" + }, + { + "include": "#union_declare" + }, + { + "include": "#enum_declare" + }, + { + "include": "#class_declare" + } + ] + }, + "parameter_struct": { + "match": "(struct)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:\\[((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\]((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?=,|\\)|\\n)", + "captures": { + "1": { + "name": "storage.type.struct.parameter.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "entity.name.type.struct.parameter.cpp" + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "13": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "14": { + "name": "comment.block.cpp" + }, + "15": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "21": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "22": { + "name": "comment.block.cpp" + }, + "23": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "24": { + "name": "variable.other.object.declare.cpp" + }, + "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + "parameter_enum": { + "match": "(enum)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:\\[((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\]((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?=,|\\)|\\n)", + "captures": { + "1": { + "name": "storage.type.enum.parameter.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "entity.name.type.enum.parameter.cpp" + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "13": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "14": { + "name": "comment.block.cpp" + }, + "15": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "21": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "22": { + "name": "comment.block.cpp" + }, + "23": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "24": { + "name": "variable.other.object.declare.cpp" + }, + "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + "parameter_union": { + "match": "(union)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:\\[((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\]((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?=,|\\)|\\n)", + "captures": { + "1": { + "name": "storage.type.union.parameter.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "entity.name.type.union.parameter.cpp" + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "13": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "14": { + "name": "comment.block.cpp" + }, + "15": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "21": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "22": { + "name": "comment.block.cpp" + }, + "23": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "24": { + "name": "variable.other.object.declare.cpp" + }, + "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + "parameter_class": { + "match": "(class)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:\\[((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\]((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?=,|\\)|\\n)", + "captures": { + "1": { + "name": "storage.type.class.parameter.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "entity.name.type.class.parameter.cpp" + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "13": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "14": { + "name": "comment.block.cpp" + }, + "15": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "21": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "22": { + "name": "comment.block.cpp" + }, + "23": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "24": { + "name": "variable.other.object.declare.cpp" + }, + "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + } + }, + "over_qualified_types": { + "patterns": [ + { + "include": "#parameter_struct" + }, + { + "include": "#parameter_enum" + }, + { + "include": "#parameter_union" + }, + { + "include": "#parameter_class" + } + ] + }, "hacky_fix_for_stray_directive": { "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))#define.*(?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*))\\s*::\\s*~\\2|~(?>(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8})))*)))\\s*(\\()\\s*(\\))", - "captures": { - "1": { - "name": "entity.name.function.destructor.cpp entity.name.function.special.destructor.cpp" - }, - "3": { - "name": "punctuation.definition.parameters.begin.destructor.cpp" - }, - "4": { - "name": "punctuation.definition.parameters.end.destructor.cpp" - } - }, - "name": "meta.function.destructor.cpp" + "misc_storage_modifiers": { + "match": "\\b(?:export|mutable|typename|thread_local|register|restrict|static|volatile|inline)\\b", + "name": "storage.modifier.$0.cpp" }, "meta_preprocessor_macro": { "name": "meta.preprocessor.macro.cpp", @@ -5156,7 +13719,7 @@ "end": "(?=(?://|/\\*))|(?=+!]+ | \\(\\) | \\[\\]))\n)\n\\s*(\\() # opening bracket", - "beginCaptures": { - "1": { - "name": "variable.other.cpp" - }, - "2": { - "name": "punctuation.section.parens.begin.bracket.round.initialization.cpp" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.parens.end.bracket.round.initialization.cpp" - } - }, - "patterns": [ - { - "include": "#function_call_context" - } - ] - }, - { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.block.begin.bracket.curly.cpp" - } - }, - "end": "}|(?=\\s*#\\s*(?:elif|else|endif)\\b)", - "endCaptures": { - "0": { - "name": "punctuation.section.block.end.bracket.curly.cpp" - } - }, - "patterns": [ - { - "include": "#block_context" - } - ] - }, - { - "include": "#parentheses_block" - }, - { - "include": "#root_context" - } - ] - }, - "comments_context": { - "patterns": [ - { - "captures": { - "1": { - "name": "meta.toc-list.banner.block.cpp" - } - }, - "match": "^/\\* =(\\s*.*?)\\s*= \\*/$\\n?", - "name": "comment.block.cpp" - }, - { - "begin": "/\\*", - "beginCaptures": { - "0": { - "name": "punctuation.definition.comment.begin.cpp" - } - }, - "end": "\\*/", - "endCaptures": { - "0": { - "name": "punctuation.definition.comment.end.cpp" - } - }, - "name": "comment.block.cpp" - }, - { - "captures": { - "1": { - "name": "meta.toc-list.banner.line.cpp" - } - }, - "match": "^// =(\\s*.*?)\\s*=\\s*$\\n?", - "name": "comment.line.banner.cpp" - }, - { - "begin": "(^[ \\t]+)?(?=//)", - "beginCaptures": { - "1": { - "name": "punctuation.whitespace.comment.leading.cpp" - } - }, - "end": "(?!\\G)", - "patterns": [ - { - "begin": "//", - "beginCaptures": { - "0": { - "name": "punctuation.definition.comment.cpp" - } - }, - "end": "(?=\\n)", - "name": "comment.line.double-slash.cpp", - "patterns": [ - { - "include": "#line_continuation_character" - } - ] - } - ] + "include": "#function_body_context" } ] }, @@ -5663,45 +14048,28 @@ }, "parentheses": { "name": "meta.parens.cpp", - "begin": "\\(", + "begin": "(\\()", "beginCaptures": { - "0": { + "1": { "name": "punctuation.section.parens.begin.bracket.round.cpp" } }, - "end": "\\)", + "end": "(\\))", "endCaptures": { - "0": { + "1": { "name": "punctuation.section.parens.end.bracket.round.cpp" } }, "patterns": [ { - "include": "#root_context" - } - ] - }, - "parentheses_block": { - "name": "meta.parens.block.cpp", - "begin": "\\(", - "beginCaptures": { - "0": { - "name": "punctuation.section.parens.begin.bracket.round.cpp" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.section.parens.end.bracket.round.cpp" - } - }, - "patterns": [ - { - "include": "#block_context" + "include": "#over_qualified_types" }, { - "match": "(?-mix:(?=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", + "begin": "(?x)\n(?=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", "end": "(?<=\\))(?!\\w)|(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\13((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", + "beginCaptures": { + "1": { + "name": "meta.head.function.definition.special.constructor.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "storage.type.modifier.calling-convention.cpp" + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "patterns": [ + { + "match": "::", + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.constructor.cpp" + }, + { + "match": "(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(default)|(delete))", + "captures": { + "1": { + "name": "keyword.operator.assignment.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "keyword.other.default.constructor.cpp" + }, + "7": { + "name": "keyword.other.delete.constructor.cpp" + } + } + } + ] + }, + { + "include": "#functional_specifiers_pre_parameters" + }, + { + "begin": "(:)", + "beginCaptures": { + "1": { + "name": "punctuation.separator.initializers.cpp" + } + }, + "end": "(?=\\{)", + "patterns": [ + { + "contentName": "meta.parameter.initialization.cpp", + "begin": "((?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.function.definition.special.constructor.cpp" + } + }, + "patterns": [ + { + "include": "#function_body_context" + } + ] }, { - "include": "#functional_specifiers_pre_parameters" + "name": "meta.tail.function.definition.special.constructor.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "macro_safe_destructor_root": { + "name": "meta.function.definition.special.member.destructor.cpp", + "begin": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))~\\13((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", + "beginCaptures": { + "1": { + "name": "meta.head.function.definition.special.member.destructor.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "storage.type.modifier.calling-convention.cpp" + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "patterns": [ + { + "match": "::", + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.destructor.cpp" + }, + { + "match": "(?|\\?\\?>)|(?=[;>\\[\\]=]))|(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(default)|(delete))", + "captures": { + "1": { + "name": "keyword.operator.assignment.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "keyword.other.default.constructor.cpp" + }, + "7": { + "name": "keyword.other.delete.constructor.cpp" + } + } + } + ] + }, + { + "contentName": "meta.function.definition.parameters.special.member.destructor.cpp", + "begin": "(\\()", + "beginCaptures": { + "1": { + "name": "punctuation.section.parameters.begin.bracket.round.special.member.destructor.cpp" + } + }, + "end": "(\\))", + "endCaptures": { + "1": { + "name": "punctuation.section.parameters.end.bracket.round.special.member.destructor.cpp" + } + } + }, + { + "include": "$base" + } + ] }, { - "include": "#qualifiers_and_specifiers_post_parameters" + "name": "meta.body.function.definition.special.member.destructor.cpp", + "begin": "(?<=\\{|<%|\\?\\?<)", + "end": "(\\}|%>|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.function.definition.special.member.destructor.cpp" + } + }, + "patterns": [ + { + "include": "#function_body_context" + } + ] }, { - "include": "#storage_specifiers" + "name": "meta.tail.function.definition.special.member.destructor.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "macro_safe_function_definition": { + "name": "meta.function.definition.cpp", + "begin": "((?:(?:^|\\G|(?<=;|\\}))|(?<=>))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\())", + "beginCaptures": { + "1": { + "name": "meta.head.function.definition.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "storage.type.template.cpp" + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "11": { + "name": "storage.modifier.$11.cpp" + }, + "12": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "13": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "14": { + "name": "comment.block.cpp" + }, + "15": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "16": { + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?:class|struct|union|enum)", + "name": "storage.type.$0.cpp" + }, + { + "include": "#attributes_context" + }, + { + "include": "#function_type" + }, + { + "include": "#storage_types" + }, + { + "include": "#number_literal" + }, + { + "include": "#string_context_c" + }, + { + "include": "#comma" + }, + { + "include": "#scope_resolution_inner_generated" + }, + { + "include": "#template_call_range" + }, + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", + "name": "entity.name.type.cpp" + } + ] + }, + "17": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "18": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "19": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "20": { + "name": "comment.block.cpp" + }, + "21": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "22": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "23": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "24": { + "name": "comment.block.cpp" + }, + "25": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "27": { + "patterns": [ + { + "include": "#scope_resolution_inner_generated" + } + ] + }, + "28": { + "name": "entity.name.scope-resolution.cpp" + }, + "29": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "30": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" + }, + "31": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "32": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "33": { + "name": "comment.block.cpp" + }, + "34": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "35": { + "name": "entity.name.type.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "37": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "38": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "39": { + "name": "comment.block.cpp" + }, + "40": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "41": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "42": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "43": { + "name": "comment.block.cpp" + }, + "44": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "45": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "46": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "47": { + "name": "comment.block.cpp" + }, + "48": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "49": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "50": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "51": { + "name": "comment.block.cpp" + }, + "52": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "53": { + "name": "storage.type.modifier.calling-convention.cpp" + }, + "54": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "55": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "56": { + "name": "comment.block.cpp" + }, + "57": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "58": { + "patterns": [ + { + "include": "#scope_resolution_function_definition_inner_generated" + } + ] + }, + "59": { + "name": "entity.name.function.definition.cpp" + }, + "60": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "61": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "62": { + "name": "comment.block.cpp" + }, + "63": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "end": "(?:(?<=\\}|%>|\\?\\?>)|(?=[;>\\[\\]=]))|(?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.function.definition.cpp" + } + }, + "patterns": [ + { + "include": "#function_body_context" + } + ] }, { - "include": "#exception_keywords" + "name": "meta.tail.function.definition.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "macro_safe_operator_overload": { + "name": "meta.function.definition.special.operator-overload.cpp", + "begin": "((?:(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(operator)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(?:(?:((?:\\+\\+|\\-\\-|\\(\\)|\\[\\]|\\->|\\+\\+|\\-\\-|\\+|\\-|!|~|\\*|&|new|new\\[\\]|delete|delete\\[\\]|\\->\\*|\\*|\\/|%|\\+|\\-|<<|>>|<=>|<|<=|>|>=|==|!=|&|\\^|\\||&&|\\|\\||=|\\+=|\\-=|\\*=|\\/=|%=|<<=|>>=|&=|\\^=|\\|=|,))|((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:\\[\\])?)))|(\"\")((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\<|\\())", + "beginCaptures": { + "1": { + "name": "meta.head.function.definition.special.operator-overload.cpp" + }, + "2": { + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?:class|struct|union|enum)", + "name": "storage.type.$0.cpp" + }, + { + "include": "#attributes_context" + }, + { + "include": "#function_type" + }, + { + "include": "#storage_types" + }, + { + "include": "#number_literal" + }, + { + "include": "#string_context_c" + }, + { + "include": "#comma" + }, + { + "include": "#scope_resolution_inner_generated" + }, + { + "include": "#template_call_range" + }, + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", + "name": "entity.name.type.cpp" + } + ] + }, + "3": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "4": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "5": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "6": { + "name": "comment.block.cpp" + }, + "7": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "8": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "9": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "10": { + "name": "comment.block.cpp" + }, + "11": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "patterns": [ + { + "include": "#scope_resolution_inner_generated" + } + ] + }, + "14": { + "name": "entity.name.scope-resolution.cpp" + }, + "15": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "16": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" + }, + "17": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "18": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "19": { + "name": "comment.block.cpp" + }, + "20": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "21": { + "name": "entity.name.type.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "23": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "24": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "25": { + "name": "comment.block.cpp" + }, + "26": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "27": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "28": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "29": { + "name": "comment.block.cpp" + }, + "30": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "31": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "32": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "33": { + "name": "comment.block.cpp" + }, + "34": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "35": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "36": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "37": { + "name": "comment.block.cpp" + }, + "38": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "39": { + "name": "storage.type.modifier.calling-convention.cpp" + }, + "40": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "41": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "42": { + "name": "comment.block.cpp" + }, + "43": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "44": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "45": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "46": { + "name": "comment.block.cpp" + }, + "47": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "48": { + "patterns": [ + { + "match": "::", + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.operator.cpp" + }, + { + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "entity.name.operator.type.reference.cpp" + } + ] + }, + "58": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "59": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "60": { + "name": "comment.block.cpp" + }, + "61": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "62": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "63": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "64": { + "name": "comment.block.cpp" + }, + "65": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "66": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "67": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "68": { + "name": "comment.block.cpp" + }, + "69": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "70": { + "name": "entity.name.operator.type.array.cpp" + }, + "71": { + "name": "entity.name.operator.custom-literal.cpp" + }, + "72": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "73": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "74": { + "name": "comment.block.cpp" + }, + "75": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "76": { + "name": "entity.name.operator.custom-literal.cpp" + }, + "77": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "78": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "79": { + "name": "comment.block.cpp" + }, + "80": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "end": "(?:(?<=\\}|%>|\\?\\?>)|(?=[;>\\[\\]=]))|(?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.function.definition.special.operator-overload.cpp" + } + }, + "patterns": [ + { + "include": "#function_body_context" + } + ] }, { - "include": "#other_keywords" + "name": "meta.tail.function.definition.special.operator-overload.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "macro_safe_using_namespace": { + "name": "meta.using-namespace.cpp", + "begin": "(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)?((?|\\?\\?>)|(?=[;>\\[\\]=]))|(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)\\s*((?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.namespace.cpp" + } + }, + "patterns": [ + { + "include": "$base" + } + ] }, { - "include": "#the_this_keyword" + "name": "meta.tail.namespace.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "macro_safe_extern_block": { + "name": "meta.block.extern.cpp", + "begin": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(extern)(?=\\s*\\\"))", + "beginCaptures": { + "1": { + "name": "meta.head.extern.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "storage.type.extern.cpp" + } + }, + "end": "(?:(?:(?<=\\}|%>|\\?\\?>)\\s*(;)|(;))|(?=[;>\\[\\]=]))|(?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.extern.cpp" + } + }, + "patterns": [ + { + "include": "$base" + } + ] }, { - "include": "#misc_storage_modifiers_1" + "name": "meta.tail.extern.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] }, { - "include": "#lambdas" + "include": "$base" + } + ] + }, + "macro_safe_typedef_class": { + "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "beginCaptures": { + "1": { + "name": "meta.head.class.cpp" + }, + "3": { + "name": "storage.type.$3.cpp" + }, + "4": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "15": { + "name": "entity.name.type.$3.cpp" + }, + "16": { + "name": "storage.type.modifier.final.cpp" + }, + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "18": { + "patterns": [ + { + "include": "#inheritance_context" + } + ] + } + }, + "end": "(?:(?:(?<=\\}|%>|\\?\\?>)\\s*(;)|(;))|(?=[;>\\[\\]=]))", + "endCaptures": { + "1": { + "name": "punctuation.terminator.statement.cpp" + }, + "2": { + "name": "punctuation.terminator.statement.cpp" + } + }, + "patterns": [ + { + "name": "meta.head.class.cpp", + "begin": "\\G ?", + "end": "((?:\\{|<%|\\?\\?<|(?=;)))", + "endCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.class.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "include": "#inheritance_context" + }, + { + "include": "#template_call_range" + } + ] + }, + { + "name": "meta.body.class.cpp", + "begin": "(?<=\\{|<%|\\?\\?<)", + "end": "(\\}|%>|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.class.cpp" + } + }, + "patterns": [ + { + "include": "#function_pointer" + }, + { + "include": "#static_assert" + }, + { + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" + } + ] + }, + { + "name": "meta.tail.class.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "match": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { + "name": "entity.name.type.alias.cpp" + } + } + }, + { + "match": "," + } + ] + } + ] + } + ] + }, + "macro_safe_typedef_struct": { + "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "beginCaptures": { + "1": { + "name": "meta.head.struct.cpp" + }, + "3": { + "name": "storage.type.$3.cpp" + }, + "4": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "15": { + "name": "entity.name.type.$3.cpp" + }, + "16": { + "name": "storage.type.modifier.final.cpp" + }, + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "18": { + "patterns": [ + { + "include": "#inheritance_context" + } + ] + } + }, + "end": "(?:(?:(?<=\\}|%>|\\?\\?>)\\s*(;)|(;))|(?=[;>\\[\\]=]))", + "endCaptures": { + "1": { + "name": "punctuation.terminator.statement.cpp" + }, + "2": { + "name": "punctuation.terminator.statement.cpp" + } + }, + "patterns": [ + { + "name": "meta.head.struct.cpp", + "begin": "\\G ?", + "end": "((?:\\{|<%|\\?\\?<|(?=;)))", + "endCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.struct.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "include": "#inheritance_context" + }, + { + "include": "#template_call_range" + } + ] + }, + { + "name": "meta.body.struct.cpp", + "begin": "(?<=\\{|<%|\\?\\?<)", + "end": "(\\}|%>|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.struct.cpp" + } + }, + "patterns": [ + { + "include": "#function_pointer" + }, + { + "include": "#static_assert" + }, + { + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" + } + ] + }, + { + "name": "meta.tail.struct.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "match": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { + "name": "entity.name.type.alias.cpp" + } + } + }, + { + "match": "," + } + ] + } + ] + } + ] + }, + "macro_safe_typedef_union": { + "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "beginCaptures": { + "1": { + "name": "meta.head.union.cpp" + }, + "3": { + "name": "storage.type.$3.cpp" + }, + "4": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "15": { + "name": "entity.name.type.$3.cpp" + }, + "16": { + "name": "storage.type.modifier.final.cpp" + }, + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "18": { + "patterns": [ + { + "include": "#inheritance_context" + } + ] + } + }, + "end": "(?:(?:(?<=\\}|%>|\\?\\?>)\\s*(;)|(;))|(?=[;>\\[\\]=]))", + "endCaptures": { + "1": { + "name": "punctuation.terminator.statement.cpp" + }, + "2": { + "name": "punctuation.terminator.statement.cpp" + } + }, + "patterns": [ + { + "name": "meta.head.union.cpp", + "begin": "\\G ?", + "end": "((?:\\{|<%|\\?\\?<|(?=;)))", + "endCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.union.cpp" + } + }, + "patterns": [ + { + "include": "#ever_present_context" + }, + { + "include": "#inheritance_context" + }, + { + "include": "#template_call_range" + } + ] + }, + { + "name": "meta.body.union.cpp", + "begin": "(?<=\\{|<%|\\?\\?<)", + "end": "(\\}|%>|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.union.cpp" + } + }, + "patterns": [ + { + "include": "#function_pointer" + }, + { + "include": "#static_assert" + }, + { + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" + } + ] + }, + { + "name": "meta.tail.union.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "match": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { + "name": "entity.name.type.alias.cpp" + } + } + }, + { + "match": "," + } + ] + } + ] + } + ] + }, + "macro_safe_class_block": { + "name": "meta.block.class.cpp", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "beginCaptures": { + "1": { + "name": "meta.head.class.cpp" + }, + "3": { + "name": "storage.type.$3.cpp" + }, + "4": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "15": { + "name": "entity.name.type.$3.cpp" + }, + "16": { + "name": "storage.type.modifier.final.cpp" + }, + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "18": { + "patterns": [ + { + "include": "#inheritance_context" + } + ] + } + }, + "end": "(?:(?:(?<=\\}|%>|\\?\\?>)\\s*(;)|(;))|(?=[;>\\[\\]=]))|(?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.class.cpp" + } + }, + "patterns": [ + { + "include": "#function_pointer" + }, + { + "include": "#static_assert" + }, + { + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" + } + ] + }, + { + "name": "meta.tail.class.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "macro_safe_struct_block": { + "name": "meta.block.struct.cpp", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "beginCaptures": { + "1": { + "name": "meta.head.struct.cpp" + }, + "3": { + "name": "storage.type.$3.cpp" + }, + "4": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "15": { + "name": "entity.name.type.$3.cpp" + }, + "16": { + "name": "storage.type.modifier.final.cpp" + }, + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "18": { + "patterns": [ + { + "include": "#inheritance_context" + } + ] + } + }, + "end": "(?:(?:(?<=\\}|%>|\\?\\?>)\\s*(;)|(;))|(?=[;>\\[\\]=]))|(?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.struct.cpp" + } + }, + "patterns": [ + { + "include": "#function_pointer" + }, + { + "include": "#static_assert" + }, + { + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" + } + ] + }, + { + "name": "meta.tail.struct.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "macro_safe_union_block": { + "name": "meta.block.union.cpp", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "beginCaptures": { + "1": { + "name": "meta.head.union.cpp" + }, + "3": { + "name": "storage.type.$3.cpp" + }, + "4": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "5": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "6": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "7": { + "name": "comment.block.cpp" + }, + "8": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "9": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "10": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "11": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "12": { + "name": "comment.block.cpp" + }, + "13": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "14": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "15": { + "name": "entity.name.type.$3.cpp" + }, + "16": { + "name": "storage.type.modifier.final.cpp" + }, + "17": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "18": { + "patterns": [ + { + "include": "#inheritance_context" + } + ] + } + }, + "end": "(?:(?:(?<=\\}|%>|\\?\\?>)\\s*(;)|(;))|(?=[;>\\[\\]=]))|(?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.union.cpp" + } + }, + "patterns": [ + { + "include": "#function_pointer" + }, + { + "include": "#static_assert" + }, + { + "include": "#constructor_inline" + }, + { + "include": "#destructor_inline" + }, + { + "include": "$base" + } + ] + }, + { + "name": "meta.tail.union.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "macro_safe_enum_block": { + "name": "meta.block.enum.cpp", + "begin": "(((?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?\\s*((?|\\?\\?>)\\s*(;)|(;))|(?=[;>\\[\\]=]))|(?|\\?\\?>)", + "endCaptures": { + "1": { + "name": "punctuation.section.block.end.bracket.curly.enum.cpp" + } + }, + "patterns": [ + { + "include": "#enumerator_list" + }, + { + "include": "#comments" + }, + { + "include": "#comma" + }, + { + "include": "#semicolon" + } + ] + }, + { + "name": "meta.tail.enum.cpp", + "begin": "(?<=\\}|%>|\\?\\?>)[\\s\\n]*", + "end": "[\\s\\n]*(?=;)", + "patterns": [ + { + "include": "$base" + } + ] + } + ] + }, + "macro_safe_template_definition": { + "name": "meta.template.definition.cpp", + "begin": "(?)|(?)", + "endCaptures": { + "1": { + "name": "punctuation.section.angle-brackets.begin.template.call.cpp" + } + }, + "patterns": [ + { + "include": "#template_call_context" + } + ] + }, + { + "include": "#template_definition_context" + } + ] + }, + "macro_safe_block": { + "name": "meta.block.cpp", + "begin": "({)", + "beginCaptures": { + "1": { + "name": "punctuation.section.block.begin.bracket.curly.cpp" + } + }, + "end": "(}|(?=\\s*#\\s*(?:elif|else|endif)\\b))|(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()", + "beginCaptures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "keyword.other.static_assert.cpp" + }, + "6": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "7": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "8": { + "name": "comment.block.cpp" + }, + "9": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "10": { + "name": "punctuation.section.arguments.begin.bracket.round.static_assert.cpp" + } + }, + "end": "(\\))|(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", + "beginCaptures": { + "1": { + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?:class|struct|union|enum)", + "name": "storage.type.$0.cpp" + }, + { + "include": "#attributes_context" + }, + { + "include": "#function_type" + }, + { + "include": "#storage_types" + }, + { + "include": "#number_literal" + }, + { + "include": "#string_context_c" + }, + { + "include": "#comma" + }, + { + "include": "#scope_resolution_inner_generated" + }, + { + "include": "#template_call_range" + }, + { + "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*", + "name": "entity.name.type.cpp" + } + ] + }, + "2": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "3": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "4": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "5": { + "name": "comment.block.cpp" + }, + "6": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "7": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "8": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "9": { + "name": "comment.block.cpp" + }, + "10": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "12": { + "patterns": [ + { + "include": "#scope_resolution_inner_generated" + } + ] + }, + "13": { + "name": "entity.name.scope-resolution.cpp" + }, + "14": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "15": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" + }, + "16": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "17": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "18": { + "name": "comment.block.cpp" + }, + "19": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "20": { + "name": "entity.name.type.cpp" + }, + "21": { + "patterns": [ + { + "match": "\\*", + "name": "storage.modifier.pointer.cpp" + }, + { + "match": "(?:\\&((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "22": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "23": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "24": { + "name": "comment.block.cpp" + }, + "25": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "26": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "27": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "28": { + "name": "comment.block.cpp" + }, + "29": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "30": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "31": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "32": { + "name": "comment.block.cpp" + }, + "33": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "34": { + "name": "punctuation.section.parens.begin.bracket.round.function.pointer.cpp" + }, + "35": { + "name": "punctuation.definition.function.pointer.dereference.cpp" + }, + "36": { + "name": "variable.other.definition.pointer.function.cpp" + }, + "37": { + "name": "punctuation.definition.begin.bracket.square.cpp" + }, + "38": { + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "39": { + "name": "punctuation.definition.end.bracket.square.cpp" + }, + "40": { + "name": "punctuation.section.parens.end.bracket.round.function.pointer.cpp" + }, + "41": { + "name": "punctuation.section.parameters.begin.bracket.round.function.pointer.cpp" + } + }, + "end": "(\\))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=[{=,);]|\\n)(?!\\()|(? using namespace std; +#define EXTERN_C extern "C" + class Rectangle { int width, height; public: @@ -18,5 +20,8 @@ int main () { Rectangle rect; rect.set_values (3,4); cout << "area: " << rect.area(); + Task::links_to; + int t = 2; + if (t > 0) puts("\n*************************************************"); return 0; } \ No newline at end of file diff --git a/extensions/cpp/test/colorize-results/test-23630_cpp.json b/extensions/cpp/test/colorize-results/test-23630_cpp.json index 55aec19d2cb..a58961ae945 100644 --- a/extensions/cpp/test/colorize-results/test-23630_cpp.json +++ b/extensions/cpp/test/colorize-results/test-23630_cpp.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -12,7 +12,7 @@ }, { "c": "ifndef", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -23,7 +23,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.preprocessor.cpp", + "t": "source.cpp meta.preprocessor.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -34,7 +34,7 @@ }, { "c": "_UCRT", - "t": "source.cpp source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", + "t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -45,7 +45,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.preprocessor.macro.cpp", + "t": "source.cpp meta.preprocessor.macro.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -56,7 +56,7 @@ }, { "c": "#", - "t": "source.cpp source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp punctuation.definition.directive.cpp", + "t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -67,7 +67,7 @@ }, { "c": "define", - "t": "source.cpp source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp", + "t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -78,7 +78,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.preprocessor.macro.cpp", + "t": "source.cpp meta.preprocessor.macro.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -89,7 +89,7 @@ }, { "c": "_UCRT", - "t": "source.cpp source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp", + "t": "source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -100,7 +100,7 @@ }, { "c": "#", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -111,7 +111,7 @@ }, { "c": "endif", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", diff --git a/extensions/cpp/test/colorize-results/test-23850_cpp.json b/extensions/cpp/test/colorize-results/test-23850_cpp.json index dfcdfd6787a..924bbc78243 100644 --- a/extensions/cpp/test/colorize-results/test-23850_cpp.json +++ b/extensions/cpp/test/colorize-results/test-23850_cpp.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -12,7 +12,7 @@ }, { "c": "ifndef", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -23,7 +23,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.preprocessor.cpp", + "t": "source.cpp meta.preprocessor.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -34,7 +34,7 @@ }, { "c": "_UCRT", - "t": "source.cpp source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", + "t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -45,7 +45,7 @@ }, { "c": "#", - "t": "source.cpp source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp punctuation.definition.directive.cpp", + "t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -56,7 +56,7 @@ }, { "c": "define", - "t": "source.cpp source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp", + "t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -67,7 +67,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.preprocessor.macro.cpp", + "t": "source.cpp meta.preprocessor.macro.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -78,7 +78,7 @@ }, { "c": "_UCRT", - "t": "source.cpp source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp", + "t": "source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -89,7 +89,7 @@ }, { "c": "#", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -100,7 +100,7 @@ }, { "c": "endif", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", diff --git a/extensions/cpp/test/colorize-results/test_cc.json b/extensions/cpp/test/colorize-results/test_cc.json index c96d57f2373..4567285df23 100644 --- a/extensions/cpp/test/colorize-results/test_cc.json +++ b/extensions/cpp/test/colorize-results/test_cc.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -12,7 +12,7 @@ }, { "c": "if", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -23,7 +23,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.preprocessor.cpp", + "t": "source.cpp meta.preprocessor.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -34,7 +34,7 @@ }, { "c": "B4G_DEBUG_CHECK", - "t": "source.cpp source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", + "t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -45,7 +45,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp", + "t": "source.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -56,7 +56,7 @@ }, { "c": "fprintf", - "t": "source.cpp source.cpp entity.name.function.call.cpp", + "t": "source.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -67,7 +67,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", + "t": "source.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -78,7 +78,7 @@ }, { "c": "stderr", - "t": "source.cpp source.cpp", + "t": "source.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -89,7 +89,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp comma.cpp punctuation.separator.delimiter.cpp", + "t": "source.cpp punctuation.separator.delimiter.comma.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -100,7 +100,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -111,7 +111,7 @@ }, { "c": "num_candidate_ret=", - "t": "source.cpp source.cpp string.quoted.double.cpp", + "t": "source.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -122,7 +122,7 @@ }, { "c": "%d", - "t": "source.cpp source.cpp string.quoted.double.cpp constant.other.placeholder.cpp", + "t": "source.cpp string.quoted.double.cpp constant.other.placeholder.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -133,7 +133,7 @@ }, { "c": ":", - "t": "source.cpp source.cpp string.quoted.double.cpp", + "t": "source.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -144,7 +144,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -155,7 +155,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp comma.cpp punctuation.separator.delimiter.cpp", + "t": "source.cpp punctuation.separator.delimiter.comma.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -166,7 +166,7 @@ }, { "c": " num_candidate", - "t": "source.cpp source.cpp", + "t": "source.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -177,7 +177,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", + "t": "source.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -188,7 +188,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -199,7 +199,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp", + "t": "source.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -210,7 +210,7 @@ }, { "c": "for", - "t": "source.cpp source.cpp keyword.control.for.cpp", + "t": "source.cpp keyword.control.for.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -221,7 +221,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.parens.cpp punctuation.section.parens.begin.bracket.round.cpp", + "t": "source.cpp meta.parens.cpp punctuation.section.parens.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -232,7 +232,7 @@ }, { "c": "int", - "t": "source.cpp source.cpp meta.parens.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.parens.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -243,7 +243,7 @@ }, { "c": " i", - "t": "source.cpp source.cpp meta.parens.cpp", + "t": "source.cpp meta.parens.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -254,7 +254,7 @@ }, { "c": "=", - "t": "source.cpp source.cpp meta.parens.cpp keyword.operator.assignment.cpp", + "t": "source.cpp meta.parens.cpp keyword.operator.assignment.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -265,7 +265,7 @@ }, { "c": "0", - "t": "source.cpp source.cpp meta.parens.cpp constant.numeric.decimal.cpp", + "t": "source.cpp meta.parens.cpp constant.numeric.decimal.cpp", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -276,7 +276,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.parens.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.parens.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -287,7 +287,7 @@ }, { "c": "i", - "t": "source.cpp source.cpp meta.parens.cpp", + "t": "source.cpp meta.parens.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -298,7 +298,7 @@ }, { "c": "<", - "t": "source.cpp source.cpp meta.parens.cpp keyword.operator.comparison.cpp", + "t": "source.cpp meta.parens.cpp keyword.operator.comparison.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -309,7 +309,7 @@ }, { "c": "num_candidate", - "t": "source.cpp source.cpp meta.parens.cpp", + "t": "source.cpp meta.parens.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -320,7 +320,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.parens.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.parens.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -331,7 +331,7 @@ }, { "c": "++", - "t": "source.cpp source.cpp meta.parens.cpp keyword.operator.increment.cpp", + "t": "source.cpp meta.parens.cpp keyword.operator.increment.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -342,7 +342,7 @@ }, { "c": "i", - "t": "source.cpp source.cpp meta.parens.cpp", + "t": "source.cpp meta.parens.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -353,7 +353,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.parens.cpp punctuation.section.parens.end.bracket.round.cpp", + "t": "source.cpp meta.parens.cpp punctuation.section.parens.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -364,7 +364,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp", + "t": "source.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -375,7 +375,7 @@ }, { "c": "fprintf", - "t": "source.cpp source.cpp entity.name.function.call.cpp", + "t": "source.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -386,7 +386,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", + "t": "source.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -397,7 +397,7 @@ }, { "c": "stderr", - "t": "source.cpp source.cpp", + "t": "source.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -408,7 +408,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp comma.cpp punctuation.separator.delimiter.cpp", + "t": "source.cpp punctuation.separator.delimiter.comma.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -419,7 +419,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -430,7 +430,7 @@ }, { "c": "%d", - "t": "source.cpp source.cpp string.quoted.double.cpp constant.other.placeholder.cpp", + "t": "source.cpp string.quoted.double.cpp constant.other.placeholder.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -441,7 +441,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp string.quoted.double.cpp", + "t": "source.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -452,7 +452,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -463,7 +463,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp comma.cpp punctuation.separator.delimiter.cpp", + "t": "source.cpp punctuation.separator.delimiter.comma.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -474,7 +474,7 @@ }, { "c": "user_candidate", - "t": "source.cpp source.cpp meta.bracket.square.access.cpp variable.other.object.cpp", + "t": "source.cpp meta.bracket.square.access.cpp variable.other.object.cpp", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -485,7 +485,7 @@ }, { "c": "[", - "t": "source.cpp source.cpp meta.bracket.square.access.cpp punctuation.definition.begin.bracket.square.cpp", + "t": "source.cpp meta.bracket.square.access.cpp punctuation.definition.begin.bracket.square.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -496,7 +496,7 @@ }, { "c": "i", - "t": "source.cpp source.cpp meta.bracket.square.access.cpp", + "t": "source.cpp meta.bracket.square.access.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -507,7 +507,7 @@ }, { "c": "]", - "t": "source.cpp source.cpp meta.bracket.square.access.cpp punctuation.definition.end.bracket.square.cpp", + "t": "source.cpp meta.bracket.square.access.cpp punctuation.definition.end.bracket.square.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -518,7 +518,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", + "t": "source.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -529,7 +529,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -540,7 +540,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp", + "t": "source.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -551,7 +551,7 @@ }, { "c": "fprintf", - "t": "source.cpp source.cpp entity.name.function.call.cpp", + "t": "source.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -562,7 +562,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", + "t": "source.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -573,7 +573,7 @@ }, { "c": "stderr", - "t": "source.cpp source.cpp", + "t": "source.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -584,7 +584,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp comma.cpp punctuation.separator.delimiter.cpp", + "t": "source.cpp punctuation.separator.delimiter.comma.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -595,7 +595,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -606,7 +606,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp string.quoted.double.cpp", + "t": "source.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -617,7 +617,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -628,7 +628,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", + "t": "source.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -639,7 +639,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -650,7 +650,7 @@ }, { "c": "#", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -661,7 +661,7 @@ }, { "c": "endif", - "t": "source.cpp source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -672,7 +672,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp", + "t": "source.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -683,7 +683,7 @@ }, { "c": "void", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -694,7 +694,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -705,7 +705,7 @@ }, { "c": "main", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -716,7 +716,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -726,8 +726,19 @@ } }, { - "c": "O ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp", + "c": "O", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp entity.name.type.parameter.cpp", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": " ", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -738,7 +749,7 @@ }, { "c": "obj", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp variable.parameter.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp variable.parameter.cpp", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -749,7 +760,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -760,7 +771,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -771,7 +782,7 @@ }, { "c": "{", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.block.begin.bracket.curly.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.block.begin.bracket.curly.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -782,7 +793,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -793,7 +804,7 @@ }, { "c": "LOG_INFO", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -804,7 +815,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -815,7 +826,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -826,7 +837,7 @@ }, { "c": "not hilighted as string", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -837,7 +848,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -848,7 +859,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -859,7 +870,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -870,7 +881,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -881,7 +892,7 @@ }, { "c": "LOG_INFO", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -892,7 +903,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -903,7 +914,7 @@ }, { "c": "obj ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -914,7 +925,7 @@ }, { "c": "<<", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.bitwise.shift.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.bitwise.shift.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -925,7 +936,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -936,7 +947,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -947,7 +958,7 @@ }, { "c": ", even worse; ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -958,7 +969,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -969,7 +980,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -980,7 +991,7 @@ }, { "c": "<<", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.bitwise.shift.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.bitwise.shift.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -991,7 +1002,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1002,7 +1013,7 @@ }, { "c": "obj", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp variable.other.object.access.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp variable.other.object.access.cpp", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1013,7 +1024,7 @@ }, { "c": ".", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.dot-access.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.dot-access.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1024,7 +1035,7 @@ }, { "c": "x", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp variable.other.property.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp variable.other.property.cpp", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1035,7 +1046,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1046,7 +1057,7 @@ }, { "c": "<<", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.bitwise.shift.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.bitwise.shift.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1057,7 +1068,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1068,7 +1079,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1079,7 +1090,7 @@ }, { "c": " check this out.", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1090,7 +1101,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1101,7 +1112,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1112,7 +1123,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1123,18 +1134,18 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.whitespace.comment.leading.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" } }, { "c": "//", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1145,7 +1156,7 @@ }, { "c": " everything from this point on is interpeted as a string literal...", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1156,7 +1167,7 @@ }, { "c": " O x", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1167,7 +1178,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1178,7 +1189,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1189,7 +1200,7 @@ }, { "c": "std", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.scope-resolution.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.scope-resolution.cpp", "r": { "dark_plus": "entity.name.scope-resolution: #4EC9B0", "light_plus": "entity.name.scope-resolution: #267F99", @@ -1200,7 +1211,7 @@ }, { "c": "::", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1211,7 +1222,7 @@ }, { "c": "unique_ptr", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1222,7 +1233,7 @@ }, { "c": "<", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.comparison.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.comparison.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1233,7 +1244,7 @@ }, { "c": "O", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1244,7 +1255,7 @@ }, { "c": ">", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.comparison.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.comparison.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1255,7 +1266,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1266,7 +1277,7 @@ }, { "c": "o", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -1277,7 +1288,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1288,7 +1299,7 @@ }, { "c": "new", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.wordlike.cpp memory.cpp keyword.operator.new.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.wordlike.cpp keyword.operator.new.cpp", "r": { "dark_plus": "source.cpp keyword.operator.new: #C586C0", "light_plus": "source.cpp keyword.operator.new: #AF00DB", @@ -1299,7 +1310,7 @@ }, { "c": " O", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1310,7 +1321,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1321,7 +1332,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1332,18 +1343,18 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.whitespace.comment.leading.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" } }, { "c": "//", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1354,7 +1365,7 @@ }, { "c": " sadness.", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1365,7 +1376,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1376,7 +1387,7 @@ }, { "c": "sprintf", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -1387,7 +1398,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1398,7 +1409,7 @@ }, { "c": "options", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1409,7 +1420,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comma.cpp punctuation.separator.delimiter.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.delimiter.comma.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1420,7 +1431,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1431,7 +1442,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1442,7 +1453,7 @@ }, { "c": "STYLE=Keramik;TITLE=", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1453,7 +1464,7 @@ }, { "c": "%s", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp constant.other.placeholder.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp constant.other.placeholder.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1464,7 +1475,7 @@ }, { "c": ";THEME=", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1475,7 +1486,7 @@ }, { "c": "%s", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp constant.other.placeholder.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp constant.other.placeholder.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1486,7 +1497,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1497,7 +1508,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comma.cpp punctuation.separator.delimiter.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.delimiter.comma.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1507,19 +1518,8 @@ } }, { - "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "...", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.vararg-ellipses.cpp", + "c": " ...", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1530,7 +1530,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1541,7 +1541,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1552,7 +1552,7 @@ }, { "c": "}", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.block.end.bracket.curly.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.block.end.bracket.curly.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1563,7 +1563,7 @@ }, { "c": "int", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -1574,7 +1574,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1585,7 +1585,7 @@ }, { "c": "main2", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -1596,7 +1596,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1607,7 +1607,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1618,7 +1618,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1629,7 +1629,7 @@ }, { "c": "{", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.block.begin.bracket.curly.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.block.begin.bracket.curly.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1640,7 +1640,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1651,7 +1651,7 @@ }, { "c": "printf", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -1662,7 +1662,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1673,7 +1673,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1684,7 +1684,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1695,7 +1695,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1706,7 +1706,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1717,7 +1717,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1728,18 +1728,18 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.whitespace.comment.leading.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" } }, { "c": "//", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1750,7 +1750,7 @@ }, { "c": " the rest of", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1761,7 +1761,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1772,7 +1772,7 @@ }, { "c": "asm", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp storage.type.asm.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp storage.type.asm.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -1783,7 +1783,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp punctuation.section.parens.begin.bracket.round.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp punctuation.section.parens.begin.bracket.round.assembly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1794,7 +1794,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp string.quoted.double.cpp punctuation.definition.string.begin.assembly.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1804,63 +1804,19 @@ } }, { - "c": "movw $0x38, ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp string.quoted.double.cpp", + "c": "movw $0x38, %ax; ltr %ax", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp string.quoted.double.cpp meta.embedded.assembly.cpp", "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "%a", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp string.quoted.double.cpp constant.other.placeholder.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "x; ltr ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp string.quoted.double.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "%a", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp string.quoted.double.cpp constant.other.placeholder.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "x", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp string.quoted.double.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" + "dark_plus": "meta.embedded: #D4D4D4", + "light_plus": "meta.embedded: #000000", + "dark_vs": "meta.embedded: #D4D4D4", + "light_vs": "meta.embedded: #000000", + "hc_black": "meta.embedded: #FFFFFF" } }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp string.quoted.double.cpp punctuation.definition.string.end.assembly.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1871,7 +1827,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp punctuation.section.parens.end.bracket.round.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp punctuation.section.parens.end.bracket.round.assembly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1882,7 +1838,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1893,7 +1849,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1904,7 +1860,7 @@ }, { "c": "fn", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -1915,7 +1871,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1926,7 +1882,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1937,7 +1893,7 @@ }, { "c": "{};", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1948,7 +1904,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1959,7 +1915,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1970,7 +1926,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1981,18 +1937,18 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.whitespace.comment.leading.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" } }, { "c": "//", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -2003,7 +1959,7 @@ }, { "c": " the rest of", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -2014,7 +1970,7 @@ }, { "c": "}", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.block.end.bracket.curly.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.block.end.bracket.curly.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", diff --git a/extensions/cpp/test/colorize-results/test_cpp.json b/extensions/cpp/test/colorize-results/test_cpp.json index 8d651f04f42..025f668b4c9 100644 --- a/extensions/cpp/test/colorize-results/test_cpp.json +++ b/extensions/cpp/test/colorize-results/test_cpp.json @@ -1,7 +1,7 @@ [ { "c": "//", - "t": "source.cpp source.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", + "t": "source.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -12,7 +12,7 @@ }, { "c": " classes example", - "t": "source.cpp source.cpp comment.line.double-slash.cpp", + "t": "source.cpp comment.line.double-slash.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -23,7 +23,7 @@ }, { "c": "#", - "t": "source.cpp source.cpp meta.preprocessor.include.cpp keyword.control.directive.include.cpp punctuation.definition.directive.cpp", + "t": "source.cpp meta.preprocessor.include.cpp keyword.control.directive.include.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -34,7 +34,7 @@ }, { "c": "include", - "t": "source.cpp source.cpp meta.preprocessor.include.cpp keyword.control.directive.include.cpp", + "t": "source.cpp meta.preprocessor.include.cpp keyword.control.directive.include.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -45,7 +45,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.preprocessor.include.cpp", + "t": "source.cpp meta.preprocessor.include.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -56,7 +56,7 @@ }, { "c": "<", - "t": "source.cpp source.cpp meta.preprocessor.include.cpp string.quoted.other.lt-gt.include.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.preprocessor.include.cpp string.quoted.other.lt-gt.include.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -67,7 +67,7 @@ }, { "c": "iostream", - "t": "source.cpp source.cpp meta.preprocessor.include.cpp string.quoted.other.lt-gt.include.cpp", + "t": "source.cpp meta.preprocessor.include.cpp string.quoted.other.lt-gt.include.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -78,7 +78,7 @@ }, { "c": ">", - "t": "source.cpp source.cpp meta.preprocessor.include.cpp string.quoted.other.lt-gt.include.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.preprocessor.include.cpp string.quoted.other.lt-gt.include.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -89,7 +89,7 @@ }, { "c": "using", - "t": "source.cpp source.cpp meta.using-namespace.cpp keyword.other.using.directive.cpp", + "t": "source.cpp meta.using-namespace.cpp keyword.other.using.directive.cpp", "r": { "dark_plus": "keyword.other.using: #C586C0", "light_plus": "keyword.other.using: #AF00DB", @@ -100,7 +100,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.using-namespace.cpp", + "t": "source.cpp meta.using-namespace.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -111,7 +111,7 @@ }, { "c": "namespace", - "t": "source.cpp source.cpp meta.using-namespace.cpp keyword.other.namespace.directive.cpp storage.type.namespace.directive.cpp", + "t": "source.cpp meta.using-namespace.cpp keyword.other.namespace.directive.cpp storage.type.namespace.directive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -122,7 +122,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.using-namespace.cpp", + "t": "source.cpp meta.using-namespace.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -133,7 +133,7 @@ }, { "c": "std", - "t": "source.cpp source.cpp meta.using-namespace.cpp entity.name.namespace.cpp", + "t": "source.cpp meta.using-namespace.cpp entity.name.namespace.cpp", "r": { "dark_plus": "entity.name.namespace: #4EC9B0", "light_plus": "entity.name.namespace: #267F99", @@ -144,7 +144,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.using-namespace.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.using-namespace.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -154,8 +154,63 @@ } }, { - "c": "class", - "t": "source.cpp source.cpp meta.block.class.cpp meta.head.class.cpp storage.type.class.cpp", + "c": "#", + "t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp punctuation.definition.directive.cpp", + "r": { + "dark_plus": "keyword.control: #C586C0", + "light_plus": "keyword.control: #AF00DB", + "dark_vs": "keyword.control: #569CD6", + "light_vs": "keyword.control: #0000FF", + "hc_black": "keyword.control: #C586C0" + } + }, + { + "c": "define", + "t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp", + "r": { + "dark_plus": "keyword.control: #C586C0", + "light_plus": "keyword.control: #AF00DB", + "dark_vs": "keyword.control: #569CD6", + "light_vs": "keyword.control: #0000FF", + "hc_black": "keyword.control: #C586C0" + } + }, + { + "c": " ", + "t": "source.cpp meta.preprocessor.macro.cpp", + "r": { + "dark_plus": "meta.preprocessor: #569CD6", + "light_plus": "meta.preprocessor: #0000FF", + "dark_vs": "meta.preprocessor: #569CD6", + "light_vs": "meta.preprocessor: #0000FF", + "hc_black": "meta.preprocessor: #569CD6" + } + }, + { + "c": "EXTERN_C", + "t": "source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp", + "r": { + "dark_plus": "entity.name.function: #DCDCAA", + "light_plus": "entity.name.function: #795E26", + "dark_vs": "meta.preprocessor: #569CD6", + "light_vs": "meta.preprocessor: #0000FF", + "hc_black": "entity.name.function: #DCDCAA" + } + }, + { + "c": " ", + "t": "source.cpp meta.preprocessor.macro.cpp meta.block.extern.cpp", + "r": { + "dark_plus": "meta.preprocessor: #569CD6", + "light_plus": "meta.preprocessor: #0000FF", + "dark_vs": "meta.preprocessor: #569CD6", + "light_vs": "meta.preprocessor: #0000FF", + "hc_black": "meta.preprocessor: #569CD6" + } + }, + { + "c": "extern", + "t": "source.cpp meta.preprocessor.macro.cpp meta.block.extern.cpp meta.head.extern.cpp storage.type.extern.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -166,7 +221,62 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.block.class.cpp meta.head.class.cpp", + "t": "source.cpp meta.preprocessor.macro.cpp meta.block.extern.cpp meta.head.extern.cpp", + "r": { + "dark_plus": "meta.preprocessor: #569CD6", + "light_plus": "meta.preprocessor: #0000FF", + "dark_vs": "meta.preprocessor: #569CD6", + "light_vs": "meta.preprocessor: #0000FF", + "hc_black": "meta.preprocessor: #569CD6" + } + }, + { + "c": "\"", + "t": "source.cpp meta.preprocessor.macro.cpp meta.block.extern.cpp meta.head.extern.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "C", + "t": "source.cpp meta.preprocessor.macro.cpp meta.block.extern.cpp meta.head.extern.cpp string.quoted.double.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "\"", + "t": "source.cpp meta.preprocessor.macro.cpp meta.block.extern.cpp meta.head.extern.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "class", + "t": "source.cpp meta.block.class.cpp meta.head.class.cpp storage.type.class.cpp", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": " ", + "t": "source.cpp meta.block.class.cpp meta.head.class.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -177,7 +287,7 @@ }, { "c": "Rectangle", - "t": "source.cpp source.cpp meta.block.class.cpp meta.head.class.cpp entity.name.type.class.cpp", + "t": "source.cpp meta.block.class.cpp meta.head.class.cpp entity.name.type.class.cpp", "r": { "dark_plus": "entity.name.type: #4EC9B0", "light_plus": "entity.name.type: #267F99", @@ -188,7 +298,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.block.class.cpp meta.head.class.cpp", + "t": "source.cpp meta.block.class.cpp meta.head.class.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -199,7 +309,7 @@ }, { "c": "{", - "t": "source.cpp source.cpp meta.block.class.cpp meta.head.class.cpp punctuation.section.block.begin.bracket.curly.class.cpp", + "t": "source.cpp meta.block.class.cpp meta.head.class.cpp punctuation.section.block.begin.bracket.curly.class.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -210,7 +320,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -221,7 +331,7 @@ }, { "c": "int", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -232,7 +342,7 @@ }, { "c": " width", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -243,7 +353,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp comma.cpp punctuation.separator.delimiter.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp punctuation.separator.delimiter.comma.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -254,7 +364,7 @@ }, { "c": " height", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -265,7 +375,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -276,7 +386,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -287,7 +397,7 @@ }, { "c": "public", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp storage.type.modifier.access.control.public.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp storage.type.modifier.access.control.public.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -298,7 +408,7 @@ }, { "c": ":", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp storage.type.modifier.access.control.public.cpp colon.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp storage.type.modifier.access.control.public.cpp punctuation.separator.colon.access.control.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -309,7 +419,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.qualified_type.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -320,7 +430,7 @@ }, { "c": "void", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -331,7 +441,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -342,7 +452,7 @@ }, { "c": "set_values", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -353,7 +463,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -364,7 +474,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -375,7 +485,7 @@ }, { "c": "int", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -386,7 +496,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp comma.cpp punctuation.separator.delimiter.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp punctuation.separator.delimiter.comma.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -397,7 +507,7 @@ }, { "c": "int", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -408,7 +518,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -419,7 +529,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -430,7 +540,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.qualified_type.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -441,7 +551,7 @@ }, { "c": "int", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -452,7 +562,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -463,7 +573,7 @@ }, { "c": "area", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -474,7 +584,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -485,7 +595,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -496,7 +606,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -507,7 +617,7 @@ }, { "c": "{", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.block.begin.bracket.curly.function.definition.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.block.begin.bracket.curly.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -518,7 +628,7 @@ }, { "c": "return", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.control.return.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.control.return.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -529,7 +639,7 @@ }, { "c": " width", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -540,7 +650,7 @@ }, { "c": "*", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -551,7 +661,7 @@ }, { "c": "height", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -562,7 +672,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -573,7 +683,7 @@ }, { "c": "}", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.block.end.bracket.curly.function.definition.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.block.end.bracket.curly.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -584,7 +694,7 @@ }, { "c": "}", - "t": "source.cpp source.cpp meta.block.class.cpp meta.body.class.cpp punctuation.section.block.end.bracket.curly.class.cpp", + "t": "source.cpp meta.block.class.cpp meta.body.class.cpp punctuation.section.block.end.bracket.curly.class.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -595,7 +705,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.block.class.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.block.class.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -606,7 +716,7 @@ }, { "c": "void", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -617,7 +727,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -628,7 +738,7 @@ }, { "c": "Rectangle", - "t": "source.cpp source.cpp meta.function.definition.cpp entity.name.scope-resolution.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp entity.name.scope-resolution.function.definition.cpp", "r": { "dark_plus": "entity.name.scope-resolution: #4EC9B0", "light_plus": "entity.name.scope-resolution: #267F99", @@ -639,7 +749,7 @@ }, { "c": "::", - "t": "source.cpp source.cpp meta.function.definition.cpp punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -650,7 +760,7 @@ }, { "c": "set_values", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -661,7 +771,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -672,7 +782,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -683,7 +793,7 @@ }, { "c": "int", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -694,7 +804,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -705,7 +815,7 @@ }, { "c": "x", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp variable.parameter.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp variable.parameter.cpp", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -716,7 +826,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp comma.cpp punctuation.separator.delimiter.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp punctuation.separator.delimiter.comma.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -727,7 +837,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -738,7 +848,7 @@ }, { "c": "int", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -749,7 +859,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -760,7 +870,7 @@ }, { "c": "y", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp variable.parameter.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp meta.function.definition.parameters.cpp meta.parameter.cpp variable.parameter.cpp", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -771,7 +881,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -782,7 +892,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -793,7 +903,7 @@ }, { "c": "{", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.block.begin.bracket.curly.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.block.begin.bracket.curly.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -804,7 +914,7 @@ }, { "c": " width ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -815,7 +925,7 @@ }, { "c": "=", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.assignment.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.assignment.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -826,7 +936,7 @@ }, { "c": " x", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -837,7 +947,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -848,7 +958,7 @@ }, { "c": " height ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -859,7 +969,7 @@ }, { "c": "=", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.assignment.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.assignment.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -870,7 +980,7 @@ }, { "c": " y", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -881,7 +991,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -892,7 +1002,7 @@ }, { "c": "}", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.block.end.bracket.curly.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.block.end.bracket.curly.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -903,7 +1013,7 @@ }, { "c": "int", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "t": "source.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -914,7 +1024,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -925,7 +1035,7 @@ }, { "c": "main", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp entity.name.function.definition.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -936,7 +1046,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -947,7 +1057,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -958,7 +1068,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -969,7 +1079,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -980,7 +1090,7 @@ }, { "c": "{", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.block.begin.bracket.curly.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.head.function.definition.cpp punctuation.section.block.begin.bracket.curly.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -991,7 +1101,7 @@ }, { "c": " Rectangle rect", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1002,7 +1112,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1013,7 +1123,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1024,7 +1134,7 @@ }, { "c": "rect", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp variable.other.object.access.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp variable.other.object.access.cpp", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1035,7 +1145,7 @@ }, { "c": ".", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.dot-access.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.dot-access.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1046,7 +1156,7 @@ }, { "c": "set_values", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.member.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.member.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -1057,7 +1167,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1068,7 +1178,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.member.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.member.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1079,7 +1189,7 @@ }, { "c": "3", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.cpp", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -1090,7 +1200,7 @@ }, { "c": ",", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comma.cpp punctuation.separator.delimiter.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.delimiter.comma.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1101,7 +1211,7 @@ }, { "c": "4", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.cpp", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -1112,7 +1222,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.member.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.member.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1123,7 +1233,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1134,7 +1244,7 @@ }, { "c": " cout ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1145,7 +1255,7 @@ }, { "c": "<<", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.bitwise.shift.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.bitwise.shift.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1156,7 +1266,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1167,7 +1277,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1178,7 +1288,7 @@ }, { "c": "area: ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1189,7 +1299,7 @@ }, { "c": "\"", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1200,7 +1310,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1211,7 +1321,7 @@ }, { "c": "<<", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.bitwise.shift.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.bitwise.shift.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1222,7 +1332,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1233,7 +1343,7 @@ }, { "c": "rect", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp variable.other.object.access.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp variable.other.object.access.cpp", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1244,7 +1354,7 @@ }, { "c": ".", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.dot-access.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.dot-access.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1255,7 +1365,7 @@ }, { "c": "area", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.member.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.member.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -1266,7 +1376,7 @@ }, { "c": "(", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.member.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.member.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1277,7 +1387,7 @@ }, { "c": ")", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.member.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.member.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1288,7 +1398,7 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1299,7 +1409,7 @@ }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1309,19 +1419,52 @@ } }, { - "c": "return", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.control.return.cpp", + "c": "Task", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.scope-resolution.cpp", "r": { - "dark_plus": "keyword.control: #C586C0", - "light_plus": "keyword.control: #AF00DB", - "dark_vs": "keyword.control: #569CD6", - "light_vs": "keyword.control: #0000FF", - "hc_black": "keyword.control: #C586C0" + "dark_plus": "entity.name.scope-resolution: #4EC9B0", + "light_plus": "entity.name.scope-resolution: #267F99", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "entity.name.scope-resolution: #4EC9B0" + } + }, + { + "c": "<", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.template.call.cpp meta.template.call.cpp punctuation.section.angle-brackets.begin.template.call.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "ANY_OUTPUT_TYPE", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.template.call.cpp meta.template.call.cpp meta.qualified_type.cpp entity.name.type.cpp", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": ",", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.template.call.cpp meta.template.call.cpp punctuation.separator.delimiter.comma.template.argument.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" } }, { "c": " ", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.template.call.cpp meta.template.call.cpp meta.qualified_type.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1331,8 +1474,118 @@ } }, { - "c": "0", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.cpp", + "c": "ANY_INPUT_TYPE", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.template.call.cpp meta.template.call.cpp meta.qualified_type.cpp entity.name.type.cpp", + "r": { + "dark_plus": "entity.name.type: #4EC9B0", + "light_plus": "entity.name.type: #267F99", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "entity.name.type: #4EC9B0" + } + }, + { + "c": ">", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.template.call.cpp meta.template.call.cpp punctuation.section.angle-brackets.end.template.call.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "::", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "links_to", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ";", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "int", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": " t ", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "=", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.operator.assignment.cpp", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4" + } + }, + { + "c": " ", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "2", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.cpp", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -1343,7 +1596,260 @@ }, { "c": ";", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "if", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.control.if.cpp", + "r": { + "dark_plus": "keyword.control: #C586C0", + "light_plus": "keyword.control: #AF00DB", + "dark_vs": "keyword.control: #569CD6", + "light_vs": "keyword.control: #0000FF", + "hc_black": "keyword.control: #C586C0" + } + }, + { + "c": " ", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "(", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp punctuation.section.parens.begin.bracket.round.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "t ", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ">", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp keyword.operator.comparison.cpp", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4" + } + }, + { + "c": " ", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "0", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp constant.numeric.decimal.cpp", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #09885A", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #09885A", + "hc_black": "constant.numeric: #B5CEA8" + } + }, + { + "c": ")", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.parens.cpp punctuation.section.parens.end.bracket.round.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "puts", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp", + "r": { + "dark_plus": "entity.name.function: #DCDCAA", + "light_plus": "entity.name.function: #795E26", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "entity.name.function: #DCDCAA" + } + }, + { + "c": "(", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "\"", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "\\n", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp constant.character.escape.cpp", + "r": { + "dark_plus": "constant.character.escape: #D7BA7D", + "light_plus": "constant.character.escape: #FF0000", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "constant.character: #569CD6" + } + }, + { + "c": "*************************************************", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "\"", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": ")", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ";", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "return", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.control.return.cpp", + "r": { + "dark_plus": "keyword.control: #C586C0", + "light_plus": "keyword.control: #AF00DB", + "dark_vs": "keyword.control: #569CD6", + "light_vs": "keyword.control: #0000FF", + "hc_black": "keyword.control: #C586C0" + } + }, + { + "c": " ", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "0", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.cpp", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #09885A", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #09885A", + "hc_black": "constant.numeric: #B5CEA8" + } + }, + { + "c": ";", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1354,7 +1860,7 @@ }, { "c": "}", - "t": "source.cpp source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.block.end.bracket.curly.function.definition.cpp", + "t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.block.end.bracket.curly.function.definition.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", diff --git a/extensions/css-language-features/package.json b/extensions/css-language-features/package.json index ae3e28751a8..a435a4e16b8 100644 --- a/extensions/css-language-features/package.json +++ b/extensions/css-language-features/package.json @@ -733,8 +733,8 @@ ] }, "dependencies": { - "vscode-languageclient": "^5.2.1", - "vscode-nls": "^4.0.0" + "vscode-languageclient": "^5.3.0-next.6", + "vscode-nls": "^4.1.1" }, "devDependencies": { "@types/node": "^10.14.8", diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json index 05d800740ed..6f2e734a109 100644 --- a/extensions/css-language-features/server/package.json +++ b/extensions/css-language-features/server/package.json @@ -9,15 +9,15 @@ }, "main": "./out/cssServerMain", "dependencies": { - "vscode-css-languageservice": "^4.0.2-next.4", - "vscode-languageserver": "^5.3.0-next.2" + "vscode-css-languageservice": "^4.0.2", + "vscode-languageserver": "^5.3.0-next.8" }, "devDependencies": { "@types/mocha": "2.2.33", "@types/node": "^10.14.8", - "glob": "^7.1.2", - "mocha": "^5.2.0", - "mocha-junit-reporter": "^1.17.0", + "glob": "^7.1.4", + "mocha": "^6.1.4", + "mocha-junit-reporter": "^1.23.0", "mocha-multi-reporters": "^1.1.7" }, "scripts": { diff --git a/extensions/css-language-features/server/src/cssServerMain.ts b/extensions/css-language-features/server/src/cssServerMain.ts index e1c78b158c1..cf539df1e1d 100644 --- a/extensions/css-language-features/server/src/cssServerMain.ts +++ b/extensions/css-language-features/server/src/cssServerMain.ts @@ -32,8 +32,7 @@ process.on('unhandledRejection', (e: any) => { connection.console.error(formatError(`Unhandled exception`, e)); }); -// Create a simple text document manager. The text document manager -// supports full document sync only +// Create a text document manager. const documents: TextDocuments = new TextDocuments(); // Make the text document manager listen on the connection // for open, change and close text document events diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock index d8f2b53b982..c5bfa63c869 100644 --- a/extensions/css-language-features/server/yarn.lock +++ b/extensions/css-language-features/server/yarn.lock @@ -12,11 +12,40 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9" integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw== +ansi-colors@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -35,32 +64,78 @@ browser-stdout@1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +chalk@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= -commander@2.15.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + crypt@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= -debug@3.1.0, debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== +debug@3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== dependencies: - ms "2.0.0" + ms "^2.1.1" debug@^2.2.0: version "2.6.9" @@ -69,25 +144,143 @@ debug@^2.2.0: dependencies: ms "2.0.0" +debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + diff@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== -escape-string-regexp@1.0.5: +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +es-abstract@^1.5.1: + version "1.13.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" + integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-keys "^1.0.12" + +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +find-up@3.0.0, find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +flat@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" + integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== + dependencies: + is-buffer "~2.0.3" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -glob@7.1.2, glob@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +glob@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -106,10 +299,22 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= -he@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" - integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== inflight@^1.0.4: version "1.0.6" @@ -124,16 +329,114 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-buffer@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" + integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + +is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +js-yaml@3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + lodash@^4.16.4: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" integrity sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg== +lodash@^4.17.11: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +log-symbols@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + md5@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" @@ -143,6 +446,20 @@ md5@^2.1.0: crypt "~0.0.1" is-buffer "~1.1.1" +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -162,10 +479,10 @@ mkdirp@0.5.1, mkdirp@~0.5.1: dependencies: minimist "0.0.8" -mocha-junit-reporter@^1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-1.17.0.tgz#2e5149ed40fc5d2e3ca71e42db5ab1fec9c6d85c" - integrity sha1-LlFJ7UD8XS48px5C21qx/snG2Fw= +mocha-junit-reporter@^1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-1.23.0.tgz#c5ad7f10b5aa9a7cc6e169b6bf15baf2700266ca" + integrity sha512-pmpnEO4iDTmLfrT2RKqPsc5relG4crnDSGmXPuGogdda27A7kLujDNJV4EbTbXlVBCZXggN9rQYPEWMkOv4AAA== dependencies: debug "^2.2.0" md5 "^2.1.0" @@ -181,40 +498,251 @@ mocha-multi-reporters@^1.1.7: debug "^3.1.0" lodash "^4.16.4" -mocha@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" - integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== +mocha@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.1.4.tgz#e35fada242d5434a7e163d555c705f6875951640" + integrity sha512-PN8CIy4RXsIoxoFJzS4QNnCH4psUCPWc4/rPrst/ecSJJbLBkubMiyGCP2Kj/9YnWbotFqAoeXyXMucj7gwCFg== dependencies: + ansi-colors "3.2.3" browser-stdout "1.3.1" - commander "2.15.1" - debug "3.1.0" + debug "3.2.6" diff "3.5.0" escape-string-regexp "1.0.5" - glob "7.1.2" + find-up "3.0.0" + glob "7.1.3" growl "1.10.5" - he "1.1.1" + he "1.2.0" + js-yaml "3.13.1" + log-symbols "2.2.0" minimatch "3.0.4" mkdirp "0.5.1" - supports-color "5.4.0" + ms "2.1.1" + node-environment-flags "1.0.5" + object.assign "4.1.0" + strip-json-comments "2.0.1" + supports-color "6.0.0" + which "1.3.1" + wide-align "1.1.3" + yargs "13.2.2" + yargs-parser "13.0.0" + yargs-unparser "1.5.0" ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -once@^1.3.0: +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-environment-flags@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" + integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== + dependencies: + object.getownpropertydescriptors "^2.0.3" + semver "^5.7.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +object-keys@^1.0.11, object-keys@^1.0.12: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" +os-locale@^3.0.0, os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" + integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +semver@^5.5.0, semver@^5.7.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -222,57 +750,114 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -supports-color@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== +strip-ansi@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-json-comments@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +supports-color@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" + integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== dependencies: has-flag "^3.0.0" -vscode-css-languageservice@^4.0.2-next.4: - version "4.0.2-next.4" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.2-next.4.tgz#84930967c4b3f63206491ededb18112227eb64a3" - integrity sha512-k8sRcmzu58Muusx0IkIYWuFaG4VBQsxy6nM+Cken0sY/bemS5cvX2l4g5zRIJTzUHr85sxqkLmUk0n6Ef/asFA== +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: - vscode-languageserver-types "^3.14.0" - vscode-nls "^4.0.0" + has-flag "^3.0.0" -vscode-jsonrpc@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9" - integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg== - -vscode-languageserver-protocol@3.15.0-next.1: - version "3.15.0-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.1.tgz#1e45e224d7eef8c79b4bed75b9dcb1930d2ab8ed" - integrity sha512-LXF0d9s3vxFBxVQ4aKl/XghdEMAncGt3dh4urIYa9Is43g3MfIQL9fC44YZtP+XXOrI2rpZU8lRNN01U1V6CDg== +vscode-css-languageservice@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.2.tgz#7496e538b0c151feac16d5888cc0b1b104f4c736" + integrity sha512-pTnfXbsME3pl+yDfhUp/mtvPyIJk0Le4zqJxDn56s9GY9LqY0RmkSEh0oHH6D0HXR3Ni6wKosIaqu8a2G0+jdw== dependencies: - vscode-jsonrpc "^4.0.0" - vscode-languageserver-types "3.14.0" + vscode-languageserver-types "^3.15.0-next.2" + vscode-nls "^4.1.1" -vscode-languageserver-types@3.14.0, vscode-languageserver-types@^3.14.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" - integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== +vscode-jsonrpc@^4.1.0-next.2: + version "4.1.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.1.0-next.2.tgz#3bd318910a48e631742b290975386e3dae685be3" + integrity sha512-GsBLjP9DxQ42yl1mW9GEIlnSc0+R8mfzhaebwmmTPEJjezD5SPoAo3DFrIAFZha9yvQ1nzZfZlhtVpGQmgxtXg== -vscode-languageserver@^5.3.0-next.2: - version "5.3.0-next.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-5.3.0-next.2.tgz#31ce4c34d68b517b400ca9e211e43f8d868b8dcc" - integrity sha512-n5onRw9naMrRHp2jnOn+ZwN1n+tTfzftWLPonjp1FWf/iCZWIlnw2TyF/Hn+SDGhLoVtoghmxhwEQaxEAfLHvw== +vscode-languageserver-protocol@^3.15.0-next.6: + version "3.15.0-next.6" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.6.tgz#a8aeb7e7dd65da8216b386db59494cdfd3215d92" + integrity sha512-/yDpYlWyNs26mM23mT73xmOFsh1iRfgZfBdHmfAxwDKwpQKLoOSqVidtYfxlK/pD3IEKGcAVnT4WXTsguxxAMQ== dependencies: - vscode-languageserver-protocol "3.15.0-next.1" + vscode-jsonrpc "^4.1.0-next.2" + vscode-languageserver-types "^3.15.0-next.2" + +vscode-languageserver-types@^3.15.0-next.2: + version "3.15.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.2.tgz#a0601332cdaafac21931f497bb080cfb8d73f254" + integrity sha512-2JkrMWWUi2rlVLSo9OFR2PIGUzdiowEM8NgNYiwLKnXTjpwpjjIrJbNNxDik7Rv4oo9KtikcFQZKXbrKilL/MQ== + +vscode-languageserver@^5.3.0-next.8: + version "5.3.0-next.8" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-5.3.0-next.8.tgz#12a4adf60374dbb93e153e08bdca5525f9b2029f" + integrity sha512-6vUb96wsRfrFqndril3gct/FBCSc24OxFZ2iz7kuEuXvLaIcEVOcSZIqQK8oFN7PdbAIaa9nnIpKSy4Yd15cIw== + dependencies: + vscode-languageserver-protocol "^3.15.0-next.6" + vscode-textbuffer "^1.0.0" vscode-uri "^1.0.6" -vscode-nls@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002" - integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw== +vscode-nls@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c" + integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A== + +vscode-textbuffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vscode-textbuffer/-/vscode-textbuffer-1.0.0.tgz#1faee638c8e0e4131c8d5c353993a1874acda086" + integrity sha512-zPaHo4urgpwsm+PrJWfNakolRpryNja18SUip/qIIsfhuEqEIPEXMxHOlFPjvDC4JgTaimkncNW7UMXRJTY6ow== vscode-uri@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.6.tgz#6b8f141b0bbc44ad7b07e94f82f168ac7608ad4d" integrity sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww== +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@1.3.1, which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -282,3 +867,76 @@ xml@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yargs-parser@13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.0.0.tgz#3fc44f3e76a8bdb1cc3602e860108602e5ccde8b" + integrity sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^13.0.0: + version "13.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" + integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-unparser@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.5.0.tgz#f2bb2a7e83cbc87bb95c8e572828a06c9add6e0d" + integrity sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw== + dependencies: + flat "^4.1.0" + lodash "^4.17.11" + yargs "^12.0.5" + +yargs@13.2.2: + version "13.2.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993" + integrity sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA== + dependencies: + cliui "^4.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.0.0" + +yargs@^12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" diff --git a/extensions/css-language-features/yarn.lock b/extensions/css-language-features/yarn.lock index 6c3b551509a..48f16a42fe5 100644 --- a/extensions/css-language-features/yarn.lock +++ b/extensions/css-language-features/yarn.lock @@ -162,36 +162,36 @@ supports-color@5.4.0: dependencies: has-flag "^3.0.0" -vscode-jsonrpc@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9" - integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg== +vscode-jsonrpc@^4.1.0-next.2: + version "4.1.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.1.0-next.2.tgz#3bd318910a48e631742b290975386e3dae685be3" + integrity sha512-GsBLjP9DxQ42yl1mW9GEIlnSc0+R8mfzhaebwmmTPEJjezD5SPoAo3DFrIAFZha9yvQ1nzZfZlhtVpGQmgxtXg== -vscode-languageclient@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz#7cfc83a294c409f58cfa2b910a8cfeaad0397193" - integrity sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q== +vscode-languageclient@^5.3.0-next.6: + version "5.3.0-next.6" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-5.3.0-next.6.tgz#35e74882781158e8b111911c0953869d3df08777" + integrity sha512-DxT8+gkenjCjJV6ArcP75/AQfx6HP6m6kHIbacPCpffMeoE1YMLKj6ZixA9J87yr0fMtBmqumLmDeGe7MIF2bw== dependencies: semver "^5.5.0" - vscode-languageserver-protocol "3.14.1" + vscode-languageserver-protocol "^3.15.0-next.6" -vscode-languageserver-protocol@3.14.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz#b8aab6afae2849c84a8983d39a1cf742417afe2f" - integrity sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g== +vscode-languageserver-protocol@^3.15.0-next.6: + version "3.15.0-next.6" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.6.tgz#a8aeb7e7dd65da8216b386db59494cdfd3215d92" + integrity sha512-/yDpYlWyNs26mM23mT73xmOFsh1iRfgZfBdHmfAxwDKwpQKLoOSqVidtYfxlK/pD3IEKGcAVnT4WXTsguxxAMQ== dependencies: - vscode-jsonrpc "^4.0.0" - vscode-languageserver-types "3.14.0" + vscode-jsonrpc "^4.1.0-next.2" + vscode-languageserver-types "^3.15.0-next.2" -vscode-languageserver-types@3.14.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" - integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== +vscode-languageserver-types@^3.15.0-next.2: + version "3.15.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.2.tgz#a0601332cdaafac21931f497bb080cfb8d73f254" + integrity sha512-2JkrMWWUi2rlVLSo9OFR2PIGUzdiowEM8NgNYiwLKnXTjpwpjjIrJbNNxDik7Rv4oo9KtikcFQZKXbrKilL/MQ== -vscode-nls@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002" - integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw== +vscode-nls@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c" + integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A== wrappy@1: version "1.0.2" diff --git a/extensions/git/cgmanifest.json b/extensions/git/cgmanifest.json index d0bdb9ac443..e8081d6472e 100644 --- a/extensions/git/cgmanifest.json +++ b/extensions/git/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "textmate/git.tmbundle", "repositoryUrl": "https://github.com/textmate/git.tmbundle", - "commitHash": "3f6ad2138200db14b57a090ecb2d2e733275ca3e" + "commitHash": "5870cf3f8abad3a6637bdf69250b5d2ded427dc4" } }, "licenseDetail": [ diff --git a/extensions/git/package.json b/extensions/git/package.json index 2debe889d38..814f53020aa 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -82,8 +82,8 @@ "title": "%command.openFile%", "category": "Git", "icon": { - "light": "resources/icons/light/open-file-mono.svg", - "dark": "resources/icons/dark/open-file-mono.svg" + "light": "resources/icons/light/open-file.svg", + "dark": "resources/icons/dark/open-file.svg" } }, { @@ -319,12 +319,12 @@ }, { "command": "git.pushWithTags", - "title": "%command.pushWithTags%", + "title": "%command.pushFollowTags%", "category": "Git" }, { "command": "git.pushWithTagsForce", - "title": "%command.pushWithTagsForce%", + "title": "%command.pushFollowTagsForce%", "category": "Git" }, { diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 90f3d824999..adff0134ed9 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -47,8 +47,8 @@ "command.pushForce": "Push (Force)", "command.pushTo": "Push to...", "command.pushToForce": "Push to... (Force)", - "command.pushWithTags": "Push With Tags", - "command.pushWithTagsForce": "Push With Tags (Force)", + "command.pushFollowTags": "Push (Follow Tags)", + "command.pushFollowTagsForce": "Push (Follow Tags, Force)", "command.addRemote": "Add Remote", "command.removeRemote": "Remove Remote", "command.sync": "Sync", diff --git a/extensions/git/resources/icons/dark/check.svg b/extensions/git/resources/icons/dark/check.svg index c225b2f597f..865cc83c347 100644 --- a/extensions/git/resources/icons/dark/check.svg +++ b/extensions/git/resources/icons/dark/check.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/dark/clean.svg b/extensions/git/resources/icons/dark/clean.svg index 3770d63d5f9..de85d6ba679 100644 --- a/extensions/git/resources/icons/dark/clean.svg +++ b/extensions/git/resources/icons/dark/clean.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/dark/git.svg b/extensions/git/resources/icons/dark/git.svg index c08b1c2e403..4d9389336b9 100644 --- a/extensions/git/resources/icons/dark/git.svg +++ b/extensions/git/resources/icons/dark/git.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/dark/open-change.svg b/extensions/git/resources/icons/dark/open-change.svg index 6f785c26a5e..41ebc85a8c8 100644 --- a/extensions/git/resources/icons/dark/open-change.svg +++ b/extensions/git/resources/icons/dark/open-change.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/dark/open-file-mono.svg b/extensions/git/resources/icons/dark/open-file-mono.svg deleted file mode 100644 index 830727e70b3..00000000000 --- a/extensions/git/resources/icons/dark/open-file-mono.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/extensions/git/resources/icons/dark/open-file.svg b/extensions/git/resources/icons/dark/open-file.svg index f6302185aa4..ed302ae1398 100644 --- a/extensions/git/resources/icons/dark/open-file.svg +++ b/extensions/git/resources/icons/dark/open-file.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/dark/refresh.svg b/extensions/git/resources/icons/dark/refresh.svg index d79fdaa4e8e..e1f05aadeeb 100644 --- a/extensions/git/resources/icons/dark/refresh.svg +++ b/extensions/git/resources/icons/dark/refresh.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + + diff --git a/extensions/git/resources/icons/dark/stage.svg b/extensions/git/resources/icons/dark/stage.svg index 3475c1e1963..4d9389336b9 100644 --- a/extensions/git/resources/icons/dark/stage.svg +++ b/extensions/git/resources/icons/dark/stage.svg @@ -1 +1,3 @@ -Layer 1 \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/dark/unstage.svg b/extensions/git/resources/icons/dark/unstage.svg index 2de46fcf5b5..4c5a9c1e3a5 100644 --- a/extensions/git/resources/icons/dark/unstage.svg +++ b/extensions/git/resources/icons/dark/unstage.svg @@ -1 +1,3 @@ -Layer 1 \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/light/check.svg b/extensions/git/resources/icons/light/check.svg index 3f365c4800e..e1a546660ed 100644 --- a/extensions/git/resources/icons/light/check.svg +++ b/extensions/git/resources/icons/light/check.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/light/clean.svg b/extensions/git/resources/icons/light/clean.svg index f86ec7d627d..b70626957d0 100644 --- a/extensions/git/resources/icons/light/clean.svg +++ b/extensions/git/resources/icons/light/clean.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/light/git.svg b/extensions/git/resources/icons/light/git.svg index d1049a44d0d..01a9de7d5ab 100644 --- a/extensions/git/resources/icons/light/git.svg +++ b/extensions/git/resources/icons/light/git.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/light/open-change.svg b/extensions/git/resources/icons/light/open-change.svg index 873b93d8106..772c3c198fc 100644 --- a/extensions/git/resources/icons/light/open-change.svg +++ b/extensions/git/resources/icons/light/open-change.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/light/open-file-mono.svg b/extensions/git/resources/icons/light/open-file-mono.svg deleted file mode 100644 index fa3f245b755..00000000000 --- a/extensions/git/resources/icons/light/open-file-mono.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/extensions/git/resources/icons/light/open-file.svg b/extensions/git/resources/icons/light/open-file.svg index d23a23c6b5f..392a840c5ef 100644 --- a/extensions/git/resources/icons/light/open-file.svg +++ b/extensions/git/resources/icons/light/open-file.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/light/refresh.svg b/extensions/git/resources/icons/light/refresh.svg index e0345748192..9b1d9108409 100644 --- a/extensions/git/resources/icons/light/refresh.svg +++ b/extensions/git/resources/icons/light/refresh.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + + diff --git a/extensions/git/resources/icons/light/stage.svg b/extensions/git/resources/icons/light/stage.svg index bdecdb0e45b..01a9de7d5ab 100644 --- a/extensions/git/resources/icons/light/stage.svg +++ b/extensions/git/resources/icons/light/stage.svg @@ -1 +1,3 @@ -Layer 1 \ No newline at end of file + + + diff --git a/extensions/git/resources/icons/light/unstage.svg b/extensions/git/resources/icons/light/unstage.svg index f5d128b2df8..d12a8ee3135 100644 --- a/extensions/git/resources/icons/light/unstage.svg +++ b/extensions/git/resources/icons/light/unstage.svg @@ -1 +1,3 @@ -Layer 1 \ No newline at end of file + + + diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 336c45589ea..a9b53103702 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -202,7 +202,7 @@ function createCheckoutItems(repository: Repository): CheckoutItem[] { enum PushType { Push, PushTo, - PushTags, + PushFollowTags, } interface PushOptions { @@ -487,10 +487,10 @@ export class CommandCenter { (_, token) => this.git.clone(url!, parentPath, token) ); - const choices = []; let message = localize('proposeopen', "Would you like to open the cloned repository?"); - const open = localize('openrepo', "Open Repository"); - choices.push(open); + const open = localize('openrepo', "Open"); + const openNewWindow = localize('openreponew', "Open in New Window"); + const choices = [open, openNewWindow]; const addToWorkspace = localize('add', "Add to Workspace"); if (workspace.workspaceFolders) { @@ -515,6 +515,8 @@ export class CommandCenter { commands.executeCommand('vscode.openFolder', uri); } else if (result === addToWorkspace) { workspace.updateWorkspaceFolders(workspace.workspaceFolders!.length, 0, { uri }); + } else if (result === openNewWindow) { + commands.executeCommand('vscode.openFolder', uri, true); } } catch (err) { if (/already exists and is not an empty directory/.test(err && err.stderr || '')) { @@ -599,10 +601,10 @@ export class CommandCenter { await this.git.init(repositoryPath); - const choices = []; let message = localize('proposeopen init', "Would you like to open the initialized repository?"); - const open = localize('openrepo', "Open Repository"); - choices.push(open); + const open = localize('openrepo', "Open"); + const openNewWindow = localize('openreponew', "Open in New Window"); + const choices = [open, openNewWindow]; if (!askToOpen) { return; @@ -621,6 +623,8 @@ export class CommandCenter { commands.executeCommand('vscode.openFolder', uri); } else if (result === addToWorkspace) { workspace.updateWorkspaceFolders(workspace.workspaceFolders!.length, 0, { uri }); + } else if (result === openNewWindow) { + commands.executeCommand('vscode.openFolder', uri, true); } else { await this.model.openRepository(repositoryPath); } @@ -669,7 +673,6 @@ export class CommandCenter { if (!(resource instanceof Resource)) { // can happen when called from a keybinding - console.log('WHAT'); resource = this.getSCMResource(); } @@ -734,6 +737,8 @@ export class CommandCenter { } const HEAD = await this.getLeftResource(resource); + const basename = path.basename(resource.resourceUri.fsPath); + const title = `${basename} (HEAD)`; if (!HEAD) { window.showWarningMessage(localize('HEAD not available', "HEAD version of '{0}' is not available.", path.basename(resource.resourceUri.fsPath))); @@ -744,7 +749,7 @@ export class CommandCenter { preview }; - return await commands.executeCommand('vscode.open', HEAD, opts); + return await commands.executeCommand('vscode.open', HEAD, opts, title); } @command('git.openChange') @@ -1566,8 +1571,11 @@ export class CommandCenter { @command('git.renameBranch', { repository: true }) async renameBranch(repository: Repository): Promise { - const placeHolder = localize('provide branch name', "Please provide a branch name"); - const name = await window.showInputBox({ placeHolder }); + const name = await window.showInputBox({ + placeHolder: localize('branch name', "Branch name"), + prompt: localize('provide branch name', "Please provide a branch name"), + value: repository.HEAD && repository.HEAD.name + }); if (!name || name.trim().length === 0) { return; @@ -1759,10 +1767,8 @@ export class CommandCenter { } } - if (pushOptions.pushType === PushType.PushTags) { - await repository.pushTags(undefined, forcePushMode); - - window.showInformationMessage(localize('push with tags success', "Successfully pushed with tags.")); + if (pushOptions.pushType === PushType.PushFollowTags) { + await repository.pushFollowTags(undefined, forcePushMode); return; } @@ -1819,13 +1825,13 @@ export class CommandCenter { } @command('git.pushWithTags', { repository: true }) - async pushWithTags(repository: Repository): Promise { - await this._push(repository, { pushType: PushType.PushTags }); + async pushFollowTags(repository: Repository): Promise { + await this._push(repository, { pushType: PushType.PushFollowTags }); } @command('git.pushWithTagsForce', { repository: true }) - async pushWithTagsForce(repository: Repository): Promise { - await this._push(repository, { pushType: PushType.PushTags, forcePush: true }); + async pushFollowTagsForce(repository: Repository): Promise { + await this._push(repository, { pushType: PushType.PushFollowTags, forcePush: true }); } @command('git.pushTo', { repository: true }) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index ea3e22eec82..30348608dd0 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -329,8 +329,8 @@ export class Git { this.env = options.env || {}; } - open(repository: string): Repository { - return new Repository(this, repository); + open(repository: string, dotGit: string): Repository { + return new Repository(this, repository, dotGit); } async init(repository: string): Promise { @@ -339,7 +339,7 @@ export class Git { } async clone(url: string, parentPath: string, cancellationToken?: CancellationToken): Promise { - let baseFolderName = decodeURI(url).replace(/^.*\//, '').replace(/\.git$/, '') || 'repository'; + let baseFolderName = decodeURI(url).replace(/[\/]+$/, '').replace(/^.*\//, '').replace(/\.git$/, '') || 'repository'; let folderName = baseFolderName; let folderPath = path.join(parentPath, folderName); let count = 1; @@ -370,6 +370,17 @@ export class Git { return path.normalize(result.stdout.trim()); } + async getRepositoryDotGit(repositoryPath: string): Promise { + const result = await this.exec(repositoryPath, ['rev-parse', '--git-dir']); + let dotGitPath = result.stdout.trim(); + + if (!path.isAbsolute(dotGitPath)) { + dotGitPath = path.join(repositoryPath, dotGitPath); + } + + return path.normalize(dotGitPath); + } + async exec(cwd: string, args: string[], options: SpawnOptions = {}): Promise> { options = assign({ cwd }, options || {}); return await this._exec(args, options); @@ -649,7 +660,8 @@ export class Repository { constructor( private _git: Git, - private repositoryRoot: string + private repositoryRoot: string, + readonly dotGit: string ) { } get git(): Git { @@ -1419,7 +1431,7 @@ export class Repository { } if (tags) { - args.push('--tags'); + args.push('--follow-tags'); } if (remote) { diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts index 22c690a5dfd..a04dc33c8be 100644 --- a/extensions/git/src/model.ts +++ b/extensions/git/src/model.ts @@ -78,7 +78,7 @@ export class Model { this.disposables.push(fsWatcher); const onWorkspaceChange = anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete); - const onGitRepositoryChange = filterEvent(onWorkspaceChange, uri => /\/\.git\//.test(uri.path)); + const onGitRepositoryChange = filterEvent(onWorkspaceChange, uri => /\/\.git/.test(uri.path)); const onPossibleGitRepositoryChange = filterEvent(onGitRepositoryChange, uri => !this.getRepository(uri)); onPossibleGitRepositoryChange(this.onPossibleGitRepositoryChange, this, this.disposables); @@ -232,7 +232,8 @@ export class Model { return; } - const repository = new Repository(this.git.open(repositoryRoot), this.globalState); + const dotGit = await this.git.getRepositoryDotGit(repositoryRoot); + const repository = new Repository(this.git.open(repositoryRoot, dotGit), this.globalState, this.outputChannel); this.open(repository); } catch (err) { diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 33106400301..a581f9f5fd4 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -3,9 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento, SourceControlInputBoxValidationType } from 'vscode'; +import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento, SourceControlInputBoxValidationType, OutputChannel, LogLevel, env } from 'vscode'; import { Repository as BaseRepository, Commit, Stash, GitError, Submodule, CommitOptions, ForcePushMode } from './git'; -import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent } from './util'; +import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, combinedDisposable, watch, IFileWatcher } from './util'; import { memoize, throttle, debounce } from './decorators'; import { toGitUri } from './uri'; import { AutoFetcher } from './autofetch'; @@ -447,6 +447,91 @@ class ProgressManager { } } +class FileEventLogger { + + private eventDisposable: IDisposable = EmptyDisposable; + private logLevelDisposable: IDisposable = EmptyDisposable; + + constructor( + private onWorkspaceWorkingTreeFileChange: Event, + private onDotGitFileChange: Event, + private outputChannel: OutputChannel + ) { + this.logLevelDisposable = env.onDidChangeLogLevel(this.onDidChangeLogLevel, this); + this.onDidChangeLogLevel(env.logLevel); + } + + private onDidChangeLogLevel(level: LogLevel): void { + this.eventDisposable.dispose(); + + if (level > LogLevel.Debug) { + return; + } + + this.eventDisposable = combinedDisposable([ + this.onWorkspaceWorkingTreeFileChange(uri => this.outputChannel.appendLine(`[debug] [wt] Change: ${uri.fsPath}`)), + this.onDotGitFileChange(uri => this.outputChannel.appendLine(`[debug] [.git] Change: ${uri.fsPath}`)) + ]); + } + + dispose(): void { + this.eventDisposable.dispose(); + this.logLevelDisposable.dispose(); + } +} + +class DotGitWatcher implements IFileWatcher { + + readonly event: Event; + + private emitter = new EventEmitter(); + private transientDisposables: IDisposable[] = []; + private disposables: IDisposable[] = []; + + constructor( + private repository: Repository, + private outputChannel: OutputChannel + ) { + const rootWatcher = watch(repository.dotGit); + this.disposables.push(rootWatcher); + + const filteredRootWatcher = filterEvent(rootWatcher.event, uri => !/\/\.git(\/index\.lock)?$/.test(uri.path)); + this.event = anyEvent(filteredRootWatcher, this.emitter.event); + + repository.onDidRunGitStatus(this.updateTransientWatchers, this, this.disposables); + this.updateTransientWatchers(); + } + + private updateTransientWatchers() { + this.transientDisposables = dispose(this.transientDisposables); + + if (!this.repository.HEAD || !this.repository.HEAD.upstream) { + return; + } + + this.transientDisposables = dispose(this.transientDisposables); + + const { name, remote } = this.repository.HEAD.upstream; + const upstreamPath = path.join(this.repository.dotGit, 'refs', 'remotes', remote, name); + + try { + const upstreamWatcher = watch(upstreamPath); + this.transientDisposables.push(upstreamWatcher); + upstreamWatcher.event(this.emitter.fire, this.emitter, this.transientDisposables); + } catch (err) { + if (env.logLevel <= LogLevel.Info) { + this.outputChannel.appendLine(`Failed to watch ref '${upstreamPath}'. Ref is most likely packed.`); + } + } + } + + dispose() { + this.emitter.dispose(); + this.transientDisposables = dispose(this.transientDisposables); + this.disposables = dispose(this.disposables); + } +} + export class Repository implements Disposable { private _onDidChangeRepository = new EventEmitter(); @@ -544,36 +629,41 @@ export class Repository implements Disposable { return this.repository.root; } + get dotGit(): string { + return this.repository.dotGit; + } + private isRepositoryHuge = false; private didWarnAboutLimit = false; private isFreshRepository: boolean | undefined = undefined; + private disposables: Disposable[] = []; constructor( private readonly repository: BaseRepository, - globalState: Memento + globalState: Memento, + outputChannel: OutputChannel ) { - const fsWatcher = workspace.createFileSystemWatcher('**'); - this.disposables.push(fsWatcher); + const workspaceWatcher = workspace.createFileSystemWatcher('**'); + this.disposables.push(workspaceWatcher); - const workspaceFilter = (uri: Uri) => isDescendant(repository.root, uri.fsPath); - const onWorkspaceDelete = filterEvent(fsWatcher.onDidDelete, workspaceFilter); - const onWorkspaceChange = filterEvent(anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate), workspaceFilter); - const onRepositoryDotGitDelete = filterEvent(onWorkspaceDelete, uri => /\/\.git$/.test(uri.path)); - const onRepositoryChange = anyEvent(onWorkspaceDelete, onWorkspaceChange); + const onWorkspaceFileChange = anyEvent(workspaceWatcher.onDidChange, workspaceWatcher.onDidCreate, workspaceWatcher.onDidDelete); + const onWorkspaceRepositoryFileChange = filterEvent(onWorkspaceFileChange, uri => isDescendant(repository.root, uri.fsPath)); + const onWorkspaceWorkingTreeFileChange = filterEvent(onWorkspaceRepositoryFileChange, uri => !/\/\.git($|\/)/.test(uri.path)); - // relevant repository changes are: - // - DELETE .git folder - // - ANY CHANGE within .git folder except .git itself and .git/index.lock - const onRelevantRepositoryChange = anyEvent( - onRepositoryDotGitDelete, - filterEvent(onRepositoryChange, uri => !/\/\.git(\/index\.lock)?$/.test(uri.path)) - ); + const dotGitFileWatcher = new DotGitWatcher(this, outputChannel); + this.disposables.push(dotGitFileWatcher); - onRelevantRepositoryChange(this.onFSChange, this, this.disposables); + // FS changes should trigger `git status`: + // - any change inside the repository working tree + // - any change whithin the first level of the `.git` folder, except the folder itself and `index.lock` + const onFileChange = anyEvent(onWorkspaceWorkingTreeFileChange, dotGitFileWatcher.event); + onFileChange(this.onFileChange, this, this.disposables); - const onRelevantGitChange = filterEvent(onRelevantRepositoryChange, uri => /\/\.git\//.test(uri.path)); - onRelevantGitChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables); + // Relevate repository changes should trigger virtual document change events + dotGitFileWatcher.event(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables); + + this.disposables.push(new FileEventLogger(onWorkspaceWorkingTreeFileChange, dotGitFileWatcher.event, outputChannel)); const root = Uri.file(repository.root); this._sourceControl = scm.createSourceControl('git', 'Git', root); @@ -583,9 +673,9 @@ export class Repository implements Disposable { this._sourceControl.inputBox.validateInput = this.validateInput.bind(this); this.disposables.push(this._sourceControl); - this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "Merge Changes")); - this._indexGroup = this._sourceControl.createResourceGroup('index', localize('staged changes', "Staged Changes")); - this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', localize('changes', "Changes")); + this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "MERGE CHANGES")); + this._indexGroup = this._sourceControl.createResourceGroup('index', localize('staged changes', "STAGED CHANGES")); + this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', localize('changes', "CHANGES")); const updateIndexGroupVisibility = () => { const config = workspace.getConfiguration('git', root); @@ -1012,7 +1102,7 @@ export class Repository implements Disposable { await this.run(Operation.Push, () => this.repository.push(remote, name, setUpstream, undefined, forcePushMode)); } - async pushTags(remote?: string, forcePushMode?: ForcePushMode): Promise { + async pushFollowTags(remote?: string, forcePushMode?: ForcePushMode): Promise { await this.run(Operation.Push, () => this.repository.push(remote, undefined, false, true, forcePushMode)); } @@ -1453,7 +1543,7 @@ export class Repository implements Disposable { return result; } - private onFSChange(_uri: Uri): void { + private onFileChange(_uri: Uri): void { const config = workspace.getConfiguration('git'); const autorefresh = config.get('autorefresh'); diff --git a/extensions/git/src/util.ts b/extensions/git/src/util.ts index 7bf81adccd9..c4e93850619 100644 --- a/extensions/git/src/util.ts +++ b/extensions/git/src/util.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Event } from 'vscode'; -import { dirname, sep } from 'path'; +import { Event, EventEmitter, Uri } from 'vscode'; +import { dirname, sep, join } from 'path'; import { Readable } from 'stream'; import * as fs from 'fs'; import * as byline from 'byline'; @@ -343,4 +343,20 @@ export function pathEquals(a: string, b: string): boolean { } return a === b; -} \ No newline at end of file +} + +export interface IFileWatcher extends IDisposable { + readonly event: Event; +} + +export function watch(location: string): IFileWatcher { + const dotGitWatcher = fs.watch(location); + const onDotGitFileChangeEmitter = new EventEmitter(); + dotGitWatcher.on('change', (_, e) => onDotGitFileChangeEmitter.fire(Uri.file(join(location, e as string)))); + dotGitWatcher.on('error', err => console.error(err)); + + return new class implements IFileWatcher { + event = onDotGitFileChangeEmitter.event; + dispose() { dotGitWatcher.close(); } + }; +} diff --git a/extensions/git/syntaxes/git-rebase.tmLanguage.json b/extensions/git/syntaxes/git-rebase.tmLanguage.json index a2c116bd09b..0238d8a6f29 100644 --- a/extensions/git/syntaxes/git-rebase.tmLanguage.json +++ b/extensions/git/syntaxes/git-rebase.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/textmate/git.tmbundle/commit/3f6ad2138200db14b57a090ecb2d2e733275ca3e", + "version": "https://github.com/textmate/git.tmbundle/commit/5870cf3f8abad3a6637bdf69250b5d2ded427dc4", "name": "Git Rebase Message", "scopeName": "text.git-rebase", "patterns": [ @@ -47,6 +47,15 @@ }, "match": "^\\s*(exec|x)\\s+(.*)$", "name": "meta.commit-command.git-rebase" + }, + { + "captures": { + "1": { + "name": "support.function.git-rebase" + } + }, + "match": "^\\s*(break|b)\\s*$", + "name": "meta.commit-command.git-rebase" } ] } \ No newline at end of file diff --git a/extensions/grunt/src/main.ts b/extensions/grunt/src/main.ts index 09a812ac06f..deec1587cc2 100644 --- a/extensions/grunt/src/main.ts +++ b/extensions/grunt/src/main.ts @@ -54,14 +54,14 @@ function isTestTask(name: string): boolean { let _channel: vscode.OutputChannel; function getOutputChannel(): vscode.OutputChannel { if (!_channel) { - _channel = vscode.window.createOutputChannel('Gulp Auto Detection'); + _channel = vscode.window.createOutputChannel('Grunt Auto Detection'); } return _channel; } function showError() { - vscode.window.showWarningMessage(localize('gulpTaskDetectError', 'Problem finding jake tasks. See the output for more information.'), - localize('jakeShowOutput', 'Go to output')).then(() => { + vscode.window.showWarningMessage(localize('gruntTaskDetectError', 'Problem finding grunt tasks. See the output for more information.'), + localize('gruntShowOutput', 'Go to output')).then(() => { getOutputChannel().show(true); }); } @@ -230,7 +230,7 @@ class TaskDetector { this.detectors.clear(); } - private updateWorkspaceFolders(added: vscode.WorkspaceFolder[], removed: vscode.WorkspaceFolder[]): void { + private updateWorkspaceFolders(added: readonly vscode.WorkspaceFolder[], removed: readonly vscode.WorkspaceFolder[]): void { for (let remove of removed) { let detector = this.detectors.get(remove.uri.toString()); if (detector) { @@ -272,7 +272,7 @@ class TaskDetector { private updateProvider(): void { if (!this.taskProvider && this.detectors.size > 0) { - this.taskProvider = vscode.workspace.registerTaskProvider('gulp', { + this.taskProvider = vscode.workspace.registerTaskProvider('grunt', { provideTasks: () => { return this.getTasks(); }, diff --git a/extensions/gulp/src/main.ts b/extensions/gulp/src/main.ts index 19beae3499a..ddc07a2f5c5 100644 --- a/extensions/gulp/src/main.ts +++ b/extensions/gulp/src/main.ts @@ -67,6 +67,24 @@ function showError() { }); } +async function findGulpCommand(rootPath: string): Promise { + let gulpCommand: string; + let platform = process.platform; + if (platform === 'win32' && await exists(path.join(rootPath, 'node_modules', '.bin', 'gulp.cmd'))) { + const globalGulp = path.join(process.env.APPDATA ? process.env.APPDATA : '', 'npm', 'gulp.cmd'); + if (await exists(globalGulp)) { + gulpCommand = '"' + globalGulp + '"'; + } else { + gulpCommand = path.join('.', 'node_modules', '.bin', 'gulp.cmd'); + } + } else if ((platform === 'linux' || platform === 'darwin') && await exists(path.join(rootPath, 'node_modules', '.bin', 'gulp'))) { + gulpCommand = path.join('.', 'node_modules', '.bin', 'gulp'); + } else { + gulpCommand = 'gulp'; + } + return gulpCommand; +} + interface GulpTaskDefinition extends vscode.TaskDefinition { task: string; file?: string; @@ -77,7 +95,9 @@ class FolderDetector { private fileWatcher: vscode.FileSystemWatcher | undefined; private promise: Thenable | undefined; - constructor(private _workspaceFolder: vscode.WorkspaceFolder) { + constructor( + private _workspaceFolder: vscode.WorkspaceFolder, + private _gulpCommand: Promise) { } public get workspaceFolder(): vscode.WorkspaceFolder { @@ -97,10 +117,28 @@ class FolderDetector { } public async getTasks(): Promise { - if (!this.promise) { - this.promise = this.computeTasks(); + if (this.isEnabled()) { + if (!this.promise) { + this.promise = this.computeTasks(); + } + return this.promise; + } else { + return []; } - return this.promise; + } + + public async getTask(_task: vscode.Task): Promise { + const gulpTask = (_task.definition).task; + if (gulpTask) { + let kind: GulpTaskDefinition = { + type: 'gulp', + task: gulpTask + }; + let options: vscode.ShellExecutionOptions = { cwd: this.workspaceFolder.uri.fsPath }; + let task = new vscode.Task(kind, this.workspaceFolder, gulpTask, 'gulp', new vscode.ShellExecution(await this._gulpCommand, [gulpTask], options)); + return task; + } + return undefined; } private async computeTasks(): Promise { @@ -117,22 +155,7 @@ class FolderDetector { } } - let gulpCommand: string; - let platform = process.platform; - if (platform === 'win32' && await exists(path.join(rootPath!, 'node_modules', '.bin', 'gulp.cmd'))) { - const globalGulp = path.join(process.env.APPDATA ? process.env.APPDATA : '', 'npm', 'gulp.cmd'); - if (await exists(globalGulp)) { - gulpCommand = '"' + globalGulp + '"'; - } else { - gulpCommand = path.join('.', 'node_modules', '.bin', 'gulp.cmd'); - } - } else if ((platform === 'linux' || platform === 'darwin') && await exists(path.join(rootPath!, 'node_modules', '.bin', 'gulp'))) { - gulpCommand = path.join('.', 'node_modules', '.bin', 'gulp'); - } else { - gulpCommand = 'gulp'; - } - - let commandLine = `${gulpCommand} --tasks-simple --no-color`; + let commandLine = `${await this._gulpCommand} --tasks-simple --no-color`; try { let { stdout, stderr } = await exec(commandLine, { cwd: rootPath }); if (stderr && stderr.length > 0) { @@ -151,7 +174,7 @@ class FolderDetector { task: line }; let options: vscode.ShellExecutionOptions = { cwd: this.workspaceFolder.uri.fsPath }; - let task = new vscode.Task(kind, this.workspaceFolder, line, 'gulp', new vscode.ShellExecution(gulpCommand, [line], options)); + let task = new vscode.Task(kind, this.workspaceFolder, line, 'gulp', new vscode.ShellExecution(await this._gulpCommand, [line], options)); result.push(task); let lowerCaseLine = line.toLowerCase(); if (isBuildTask(lowerCaseLine)) { @@ -209,7 +232,7 @@ class TaskDetector { this.detectors.clear(); } - private updateWorkspaceFolders(added: vscode.WorkspaceFolder[], removed: vscode.WorkspaceFolder[]): void { + private updateWorkspaceFolders(added: readonly vscode.WorkspaceFolder[], removed: readonly vscode.WorkspaceFolder[]): void { for (let remove of removed) { let detector = this.detectors.get(remove.uri.toString()); if (detector) { @@ -218,9 +241,9 @@ class TaskDetector { } } for (let add of added) { - let detector = new FolderDetector(add); + let detector = new FolderDetector(add, findGulpCommand(add.uri.fsPath)); + this.detectors.set(add.uri.toString(), detector); if (detector.isEnabled()) { - this.detectors.set(add.uri.toString(), detector); detector.start(); } } @@ -229,18 +252,16 @@ class TaskDetector { private updateConfiguration(): void { for (let detector of this.detectors.values()) { - if (!detector.isEnabled()) { - detector.dispose(); - this.detectors.delete(detector.workspaceFolder.uri.toString()); - } + detector.dispose(); + this.detectors.delete(detector.workspaceFolder.uri.toString()); } let folders = vscode.workspace.workspaceFolders; if (folders) { for (let folder of folders) { if (!this.detectors.has(folder.uri.toString())) { - let detector = new FolderDetector(folder); + let detector = new FolderDetector(folder, findGulpCommand(folder.uri.fsPath)); + this.detectors.set(folder.uri.toString(), detector); if (detector.isEnabled()) { - this.detectors.set(folder.uri.toString(), detector); detector.start(); } } @@ -251,12 +272,13 @@ class TaskDetector { private updateProvider(): void { if (!this.taskProvider && this.detectors.size > 0) { + const thisCapture = this; this.taskProvider = vscode.workspace.registerTaskProvider('gulp', { - provideTasks: () => { - return this.getTasks(); + provideTasks(): Promise { + return thisCapture.getTasks(); }, - resolveTask(_task: vscode.Task): vscode.Task | undefined { - return undefined; + resolveTask(_task: vscode.Task): Promise { + return thisCapture.getTask(_task); } }); } @@ -291,6 +313,25 @@ class TaskDetector { }); } } + + public async getTask(task: vscode.Task): Promise { + if (this.detectors.size === 0) { + return undefined; + } else if (this.detectors.size === 1) { + return this.detectors.values().next().value.getTask(task); + } else { + if ((task.scope === vscode.TaskScope.Workspace) || (task.scope === vscode.TaskScope.Global)) { + // Not supported, we don't have enough info to create the task. + return undefined; + } else if (task.scope) { + const detector = this.detectors.get(task.scope.uri.toString()); + if (detector) { + return detector.getTask(task); + } + } + return undefined; + } + } } let detector: TaskDetector; diff --git a/extensions/html-language-features/client/src/tagClosing.ts b/extensions/html-language-features/client/src/tagClosing.ts index 35511e63f43..298edcdaa0a 100644 --- a/extensions/html-language-features/client/src/tagClosing.ts +++ b/extensions/html-language-features/client/src/tagClosing.ts @@ -32,7 +32,7 @@ export function activateTagClosing(tagProvider: (document: TextDocument, positio isEnabled = true; } - function onDidChangeTextDocument(document: TextDocument, changes: TextDocumentContentChangeEvent[]) { + function onDidChangeTextDocument(document: TextDocument, changes: readonly TextDocumentContentChangeEvent[]) { if (!isEnabled) { return; } diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index 6689bb75a5e..e2d06c20860 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -177,8 +177,8 @@ }, "dependencies": { "vscode-extension-telemetry": "0.1.1", - "vscode-languageclient": "^5.2.1", - "vscode-nls": "^4.0.0" + "vscode-languageclient": "^5.3.0-next.6", + "vscode-nls": "^4.1.1" }, "devDependencies": { "@types/node": "^10.14.8" diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json index dd930a80bb2..e97a42ab0a6 100644 --- a/extensions/html-language-features/server/package.json +++ b/extensions/html-language-features/server/package.json @@ -9,12 +9,12 @@ }, "main": "./out/htmlServerMain", "dependencies": { - "vscode-css-languageservice": "^4.0.2-next.3", - "vscode-html-languageservice": "^3.0.0-next.7", - "vscode-languageserver": "^5.3.0-next.2", - "vscode-languageserver-types": "^3.14.0", - "vscode-nls": "^4.0.0", - "vscode-uri": "^1.0.6" + "vscode-css-languageservice": "^4.0.2", + "vscode-html-languageservice": "^3.0.0", + "vscode-languageserver": "^5.3.0-next.8", + "vscode-languageserver-types": "3.15.0-next.2", + "vscode-nls": "^4.1.1", + "vscode-uri": "^2.0.1" }, "devDependencies": { "@types/mocha": "2.2.33", diff --git a/extensions/html-language-features/server/src/htmlServerMain.ts b/extensions/html-language-features/server/src/htmlServerMain.ts index 7974284bd77..e3e62991aca 100644 --- a/extensions/html-language-features/server/src/htmlServerMain.ts +++ b/extensions/html-language-features/server/src/htmlServerMain.ts @@ -15,7 +15,7 @@ import { getLanguageModes, LanguageModes, Settings } from './modes/languageModes import { format } from './modes/formatting'; import { pushAll } from './utils/arrays'; import { getDocumentContext } from './utils/documentContext'; -import uri from 'vscode-uri'; +import { URI } from 'vscode-uri'; import { formatError, runSafe, runSafeAsync } from './utils/runner'; import { getFoldingRanges } from './modes/htmlFolding'; @@ -38,8 +38,7 @@ process.on('uncaughtException', (e: any) => { console.error(formatError(`Unhandled exception`, e)); }); -// Create a simple text document manager. The text document manager -// supports full document sync only +// Create a text document manager. const documents: TextDocuments = new TextDocuments(); // Make the text document manager listen on the connection // for open, change and close text document events @@ -85,7 +84,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => { if (!Array.isArray(workspaceFolders)) { workspaceFolders = []; if (params.rootPath) { - workspaceFolders.push({ name: '', uri: uri.file(params.rootPath).toString() }); + workspaceFolders.push({ name: '', uri: URI.file(params.rootPath).toString() }); } } diff --git a/extensions/html-language-features/server/src/modes/htmlMode.ts b/extensions/html-language-features/server/src/modes/htmlMode.ts index 09efb996f6e..57249a65b8a 100644 --- a/extensions/html-language-features/server/src/modes/htmlMode.ts +++ b/extensions/html-language-features/server/src/modes/htmlMode.ts @@ -15,7 +15,7 @@ export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace: getId() { return 'html'; }, - getSelectionRanges(document: TextDocument, positions: Position[]): SelectionRange[][] { + getSelectionRanges(document: TextDocument, positions: Position[]): SelectionRange[] { return htmlLanguageService.getSelectionRanges(document, positions); }, doComplete(document: TextDocument, position: Position, settings = workspace.settings) { diff --git a/extensions/html-language-features/server/src/modes/languageModes.ts b/extensions/html-language-features/server/src/modes/languageModes.ts index 94c0b04a293..b44b2442420 100644 --- a/extensions/html-language-features/server/src/modes/languageModes.ts +++ b/extensions/html-language-features/server/src/modes/languageModes.ts @@ -31,7 +31,7 @@ export interface Workspace { export interface LanguageMode { getId(): string; - getSelectionRanges?: (document: TextDocument, positions: Position[]) => SelectionRange[][]; + getSelectionRanges?: (document: TextDocument, positions: Position[]) => SelectionRange[]; doValidation?: (document: TextDocument, settings?: Settings) => Diagnostic[]; doComplete?: (document: TextDocument, position: Position, settings?: Settings) => CompletionList; doResolve?: (document: TextDocument, item: CompletionItem) => CompletionItem; diff --git a/extensions/html-language-features/server/src/modes/pathCompletion.ts b/extensions/html-language-features/server/src/modes/pathCompletion.ts index f73acdcbcc8..7451fee1d93 100644 --- a/extensions/html-language-features/server/src/modes/pathCompletion.ts +++ b/extensions/html-language-features/server/src/modes/pathCompletion.ts @@ -7,7 +7,7 @@ import { TextDocument, CompletionItemKind, CompletionItem, TextEdit, Range, Posi import { WorkspaceFolder } from 'vscode-languageserver'; import * as path from 'path'; import * as fs from 'fs'; -import URI from 'vscode-uri'; +import { URI } from 'vscode-uri'; import { ICompletionParticipant } from 'vscode-html-languageservice'; import { startsWith } from '../utils/strings'; import { contains } from '../utils/arrays'; diff --git a/extensions/html-language-features/server/src/test/completions.test.ts b/extensions/html-language-features/server/src/test/completions.test.ts index c28daf9f0c2..de056ed3c1e 100644 --- a/extensions/html-language-features/server/src/test/completions.test.ts +++ b/extensions/html-language-features/server/src/test/completions.test.ts @@ -5,7 +5,7 @@ import 'mocha'; import * as assert from 'assert'; import * as path from 'path'; -import Uri from 'vscode-uri'; +import { URI } from 'vscode-uri'; import { TextDocument, CompletionList, CompletionItemKind } from 'vscode-languageserver-types'; import { getLanguageModes } from '../modes/languageModes'; import { WorkspaceFolder } from 'vscode-languageserver'; @@ -58,8 +58,8 @@ export function testCompletionFor(value: string, expected: { count?: number, ite let document = TextDocument.create(uri, 'html', 0, value); let position = document.positionAt(offset); - var languageModes = getLanguageModes({ css: true, javascript: true }, workspace); - var mode = languageModes.getModeAtPosition(document, position)!; + const languageModes = getLanguageModes({ css: true, javascript: true }, workspace); + const mode = languageModes.getModeAtPosition(document, position)!; let list = mode.doComplete!(document, position); @@ -95,9 +95,9 @@ suite('HTML Path Completion', () => { }; const fixtureRoot = path.resolve(__dirname, '../../src/test/pathCompletionFixtures'); - const fixtureWorkspace = { name: 'fixture', uri: Uri.file(fixtureRoot).toString() }; - const indexHtmlUri = Uri.file(path.resolve(fixtureRoot, 'index.html')).toString(); - const aboutHtmlUri = Uri.file(path.resolve(fixtureRoot, 'about/about.html')).toString(); + const fixtureWorkspace = { name: 'fixture', uri: URI.file(fixtureRoot).toString() }; + const indexHtmlUri = URI.file(path.resolve(fixtureRoot, 'index.html')).toString(); + const aboutHtmlUri = URI.file(path.resolve(fixtureRoot, 'about/about.html')).toString(); test('Basics - Correct label/kind/result/command', () => { testCompletionFor(' - ${this.getStyles(sourceUri, nonce, config, state)} - + + ${this.getStyles(resourceProvider, sourceUri, config, state)} + ${body}
- ${this.getScripts(nonce)} + ${this.getScripts(resourceProvider, nonce)} `; } @@ -107,13 +109,13 @@ export class MarkdownContentProvider { `; } - private extensionResourcePath(mediaFile: string): string { - return vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile))) - .with({ scheme: 'vscode-resource' }) - .toString(); + private extensionResourcePath(resourceProvider: WebviewResourceProvider, mediaFile: string): string { + const webviewResource = resourceProvider.toWebviewResource( + vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile)))); + return webviewResource.toString(); } - private fixHref(resource: vscode.Uri, href: string): string { + private fixHref(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, href: string): string { if (!href) { return href; } @@ -124,42 +126,36 @@ export class MarkdownContentProvider { // Assume it must be a local file if (path.isAbsolute(href)) { - return vscode.Uri.file(href) - .with({ scheme: 'vscode-resource' }) - .toString(); + return resourceProvider.toWebviewResource(vscode.Uri.file(href)).toString(); } // Use a workspace relative path if there is a workspace const root = vscode.workspace.getWorkspaceFolder(resource); if (root) { - return vscode.Uri.file(path.join(root.uri.fsPath, href)) - .with({ scheme: 'vscode-resource' }) - .toString(); + return resourceProvider.toWebviewResource(vscode.Uri.file(path.join(root.uri.fsPath, href))).toString(); } // Otherwise look relative to the markdown file - return vscode.Uri.file(path.join(path.dirname(resource.fsPath), href)) - .with({ scheme: 'vscode-resource' }) - .toString(); + return resourceProvider.toWebviewResource(vscode.Uri.file(path.join(path.dirname(resource.fsPath), href))).toString(); } - private computeCustomStyleSheetIncludes(resource: vscode.Uri, config: MarkdownPreviewConfiguration): string { - if (Array.isArray(config.styles)) { - return config.styles.map(style => { - return ``; - }).join('\n'); + private computeCustomStyleSheetIncludes(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration): string { + if (!Array.isArray(config.styles)) { + return ''; } - return ''; + const out: string[] = []; + for (const style of config.styles) { + out.push(``); + } + return out.join('\n'); } - private getSettingsOverrideStyles(nonce: string, config: MarkdownPreviewConfiguration): string { - return ``; + private getSettingsOverrideStyles(config: MarkdownPreviewConfiguration): string { + return [ + config.fontFamily ? `--vscode-markdown-font-family: ${config.fontFamily};` : '', + isNaN(config.fontSize) ? '' : `--vscode-markdown-font-size: ${config.fontSize}px;`, + isNaN(config.lineHeight) ? '' : `--vscode-markdown-line-height: ${config.lineHeight};`, + ].join(' '); } private getImageStabilizerStyles(state?: any) { @@ -177,37 +173,47 @@ export class MarkdownContentProvider { return ret; } - private getStyles(resource: vscode.Uri, nonce: string, config: MarkdownPreviewConfiguration, state?: any): string { - const baseStyles = this.contributionProvider.contributions.previewStyles - .map(resource => ``) - .join('\n'); + private getStyles(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration, state?: any): string { + const baseStyles: string[] = []; + for (const resource of this.contributionProvider.contributions.previewStyles) { + baseStyles.push(``); + } - return `${baseStyles} - ${this.getSettingsOverrideStyles(nonce, config)} - ${this.computeCustomStyleSheetIncludes(resource, config)} + return `${baseStyles.join('\n')} + ${this.computeCustomStyleSheetIncludes(resourceProvider, resource, config)} ${this.getImageStabilizerStyles(state)}`; } - private getScripts(nonce: string): string { - return this.contributionProvider.contributions.previewScripts - .map(resource => ``) - .join('\n'); + private getScripts(resourceProvider: WebviewResourceProvider, nonce: string): string { + const out: string[] = []; + for (const resource of this.contributionProvider.contributions.previewScripts) { + out.push(``); + } + return out.join('\n'); } - private getCspForResource(resource: vscode.Uri, nonce: string): string { + private getCsp( + provider: WebviewResourceProvider, + resource: vscode.Uri, + nonce: string + ): string { + const rule = provider.cspSource; switch (this.cspArbiter.getSecurityLevelForResource(resource)) { case MarkdownPreviewSecurityLevel.AllowInsecureContent: - return ``; + return ``; case MarkdownPreviewSecurityLevel.AllowInsecureLocalContent: - return ``; + return ``; case MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent: return ''; case MarkdownPreviewSecurityLevel.Strict: default: - return ``; + return ``; } } } diff --git a/extensions/markdown-language-features/src/markdownEngine.ts b/extensions/markdown-language-features/src/markdownEngine.ts index 0c10f5540fa..0cc75bfe823 100644 --- a/extensions/markdown-language-features/src/markdownEngine.ts +++ b/extensions/markdown-language-features/src/markdownEngine.ts @@ -225,7 +225,6 @@ export class MarkdownEngine { return normalizeLink(externalSchemeUri.toString(true)); } - // Assume it must be an relative or absolute file path // Use a fake scheme to avoid parse warnings let uri = vscode.Uri.parse(`vscode-resource:${link}`); @@ -262,7 +261,7 @@ export class MarkdownEngine { const validateLink = md.validateLink; md.validateLink = (link: string) => { // support file:// links - return validateLink(link) || link.indexOf('file:') === 0; + return validateLink(link) || link.startsWith('file:') || /^data:image\/.*?;/.test(link); }; } diff --git a/extensions/markdown-language-features/src/markdownExtensions.ts b/extensions/markdown-language-features/src/markdownExtensions.ts index 65899874f5a..b03c5df80bd 100644 --- a/extensions/markdown-language-features/src/markdownExtensions.ts +++ b/extensions/markdown-language-features/src/markdownExtensions.ts @@ -9,8 +9,7 @@ import { Disposable } from './util/dispose'; import * as arrays from './util/arrays'; const resolveExtensionResource = (extension: vscode.Extension, resourcePath: string): vscode.Uri => { - return vscode.Uri.file(path.join(extension.extensionPath, resourcePath)) - .with({ scheme: 'vscode-resource' }); + return vscode.Uri.file(path.join(extension.extensionPath, resourcePath)); }; const resolveExtensionResources = (extension: vscode.Extension, resourcePaths: unknown): vscode.Uri[] => { diff --git a/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts b/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts index f6309a027d3..ba6cfa2567f 100644 --- a/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts +++ b/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts @@ -72,6 +72,14 @@ suite('markdown.DocumentLinkProvider', () => { assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 25)); }); + // #35245 + test('Should handle links with escaped characters in name', () => { + const links = getLinksForFile('a [b\\]](./file)'); + assert.strictEqual(links.length, 1); + const [link] = links; + assertRangeEqual(link.range, new vscode.Range(0, 8, 0, 14)); + }); + test('Should handle links with balanced parens', () => { { diff --git a/extensions/markdown-language-features/src/util/resources.ts b/extensions/markdown-language-features/src/util/resources.ts new file mode 100644 index 00000000000..1def7adcce0 --- /dev/null +++ b/extensions/markdown-language-features/src/util/resources.ts @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; + +export interface WebviewResourceProvider { + toWebviewResource(resource: vscode.Uri): vscode.Uri; + + readonly cspSource: string; +} + +export function normalizeResource( + base: vscode.Uri, + resource: vscode.Uri +): vscode.Uri { + // If we have a windows path and are loading a workspace with an authority, + // make sure we use a unc path with an explicit localhost authority. + // + // Otherwise, the `` rule will insert the authority into the resolved resource + // URI incorrectly. + if (base.authority && !resource.authority) { + const driveMatch = resource.path.match(/^\/(\w):\//); + if (driveMatch) { + return vscode.Uri.file(`\\\\localhost\\${driveMatch[1]}$\\${resource.fsPath.replace(/^\w:\\/, '')}`).with({ + fragment: resource.fragment, + query: resource.query + }); + } + } + return resource; +} \ No newline at end of file diff --git a/extensions/merge-conflict/src/commandHandler.ts b/extensions/merge-conflict/src/commandHandler.ts index c4a59721065..f79c6650af0 100644 --- a/extensions/merge-conflict/src/commandHandler.ts +++ b/extensions/merge-conflict/src/commandHandler.ts @@ -34,8 +34,8 @@ export default class CommandHandler implements vscode.Disposable { this.registerTextEditorCommand('merge-conflict.accept.incoming', this.acceptIncoming), this.registerTextEditorCommand('merge-conflict.accept.selection', this.acceptSelection), this.registerTextEditorCommand('merge-conflict.accept.both', this.acceptBoth), - this.registerTextEditorCommand('merge-conflict.accept.all-current', this.acceptAllCurrent), - this.registerTextEditorCommand('merge-conflict.accept.all-incoming', this.acceptAllIncoming), + this.registerTextEditorCommand('merge-conflict.accept.all-current', this.acceptAllCurrent, this.acceptAllCurrentResources), + this.registerTextEditorCommand('merge-conflict.accept.all-incoming', this.acceptAllIncoming, this.acceptAllIncomingResources), this.registerTextEditorCommand('merge-conflict.accept.all-both', this.acceptAllBoth), this.registerTextEditorCommand('merge-conflict.next', this.navigateNext), this.registerTextEditorCommand('merge-conflict.previous', this.navigatePrevious), @@ -43,8 +43,11 @@ export default class CommandHandler implements vscode.Disposable { ); } - private registerTextEditorCommand(command: string, cb: (editor: vscode.TextEditor, ...args: any[]) => Promise) { + private registerTextEditorCommand(command: string, cb: (editor: vscode.TextEditor, ...args: any[]) => Promise, resourceCB?: (uris: vscode.Uri[]) => Promise) { return vscode.commands.registerCommand(command, (...args) => { + if (resourceCB && args.length && args.every(arg => arg && arg.resourceUri)) { + return resourceCB.call(this, args.map(arg => arg.resourceUri)); + } const editor = vscode.window.activeTextEditor; return editor && cb.call(this, editor, ...args); }); @@ -70,6 +73,14 @@ export default class CommandHandler implements vscode.Disposable { return this.acceptAll(interfaces.CommitType.Incoming, editor); } + acceptAllCurrentResources(resources: vscode.Uri[]): Promise { + return this.acceptAllResources(interfaces.CommitType.Current, resources); + } + + acceptAllIncomingResources(resources: vscode.Uri[]): Promise { + return this.acceptAllResources(interfaces.CommitType.Incoming, resources); + } + acceptAllBoth(editor: vscode.TextEditor): Promise { return this.acceptAll(interfaces.CommitType.Both, editor); } @@ -259,10 +270,31 @@ export default class CommandHandler implements vscode.Disposable { // Apply all changes as one edit await editor.edit((edit) => conflicts.forEach(conflict => { - conflict.applyEdit(type, editor, edit); + conflict.applyEdit(type, editor.document, edit); })); } + private async acceptAllResources(type: interfaces.CommitType, resources: vscode.Uri[]): Promise { + const documents = await Promise.all(resources.map(resource => vscode.workspace.openTextDocument(resource))); + const edit = new vscode.WorkspaceEdit(); + for (const document of documents) { + const conflicts = await this.tracker.getConflicts(document); + + if (!conflicts || conflicts.length === 0) { + continue; + } + + // For get the current state of the document, as we know we are doing to do a large edit + this.tracker.forget(document); + + // Apply all changes as one edit + conflicts.forEach(conflict => { + conflict.applyEdit(type, document, { replace: (range, newText) => edit.replace(document.uri, range, newText) }); + }); + } + vscode.workspace.applyEdit(edit); + } + private async findConflictContainingSelection(editor: vscode.TextEditor, conflicts?: interfaces.IDocumentMergeConflict[]): Promise { if (!conflicts) { diff --git a/extensions/merge-conflict/src/documentMergeConflict.ts b/extensions/merge-conflict/src/documentMergeConflict.ts index 3bf94a16ea7..560c7ed8c72 100644 --- a/extensions/merge-conflict/src/documentMergeConflict.ts +++ b/extensions/merge-conflict/src/documentMergeConflict.ts @@ -25,14 +25,14 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict if (edit) { - this.applyEdit(type, editor, edit); + this.applyEdit(type, editor.document, edit); return Promise.resolve(true); } - return editor.edit((edit) => this.applyEdit(type, editor, edit)); + return editor.edit((edit) => this.applyEdit(type, editor.document, edit)); } - public applyEdit(type: interfaces.CommitType, editor: vscode.TextEditor, edit: vscode.TextEditorEdit): void { + public applyEdit(type: interfaces.CommitType, document: vscode.TextDocument, edit: { replace(range: vscode.Range, newText: string): void; }): void { // Each conflict is a set of ranges as follows, note placements or newlines // which may not in in spans @@ -45,24 +45,24 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict // ] if (type === interfaces.CommitType.Current) { // Replace [ Conflict Range ] with [ Current Content ] - let content = editor.document.getText(this.current.content); + let content = document.getText(this.current.content); this.replaceRangeWithContent(content, edit); } else if (type === interfaces.CommitType.Incoming) { - let content = editor.document.getText(this.incoming.content); + let content = document.getText(this.incoming.content); this.replaceRangeWithContent(content, edit); } else if (type === interfaces.CommitType.Both) { // Replace [ Conflict Range ] with [ Current Content ] + \n + [ Incoming Content ] - const currentContent = editor.document.getText(this.current.content); - const incomingContent = editor.document.getText(this.incoming.content); + const currentContent = document.getText(this.current.content); + const incomingContent = document.getText(this.incoming.content); edit.replace(this.range, currentContent.concat(incomingContent)); } } - private replaceRangeWithContent(content: string, edit: vscode.TextEditorEdit) { + private replaceRangeWithContent(content: string, edit: { replace(range: vscode.Range, newText: string): void; }) { if (this.isNewlineOnly(content)) { edit.replace(this.range, ''); return; diff --git a/extensions/merge-conflict/src/interfaces.ts b/extensions/merge-conflict/src/interfaces.ts index bab96d13318..836bb5baa5a 100644 --- a/extensions/merge-conflict/src/interfaces.ts +++ b/extensions/merge-conflict/src/interfaces.ts @@ -25,7 +25,7 @@ export interface IExtensionConfiguration { export interface IDocumentMergeConflict extends IDocumentMergeConflictDescriptor { commitEdit(type: CommitType, editor: vscode.TextEditor, edit?: vscode.TextEditorEdit): Thenable; - applyEdit(type: CommitType, editor: vscode.TextEditor, edit: vscode.TextEditorEdit): void; + applyEdit(type: CommitType, document: vscode.TextDocument, edit: { replace(range: vscode.Range, newText: string): void; }): void; } export interface IDocumentMergeConflictDescriptor { diff --git a/extensions/npm/src/features/packageJSONContribution.ts b/extensions/npm/src/features/packageJSONContribution.ts index 88cf753425c..17e194cad32 100644 --- a/extensions/npm/src/features/packageJSONContribution.ts +++ b/extensions/npm/src/features/packageJSONContribution.ts @@ -9,6 +9,7 @@ import { XHRRequest } from 'request-light'; import { Location } from 'jsonc-parser'; import { textToMarkedString } from './markedTextUtil'; +import * as cp from 'child_process'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); @@ -73,11 +74,25 @@ export class PackageJSONContribution implements IJSONContribution { let queryUrl: string; if (currentWord.length > 0) { if (currentWord[0] === '@') { - return this.collectScopedPackages(currentWord, addValue, isLast, collector); + if (currentWord.indexOf('/') !== -1) { + return this.collectScopedPackages(currentWord, addValue, isLast, collector); + } + for (let scope of this.knownScopes) { + const proposal = new CompletionItem(scope); + proposal.kind = CompletionItemKind.Property; + proposal.insertText = new SnippetString().appendText(`"${scope}/`).appendTabstop().appendText('"'); + proposal.filterText = JSON.stringify(scope); + proposal.documentation = ''; + proposal.command = { + title: '', + command: 'editor.action.triggerSuggest' + }; + collector.add(proposal); + } + collector.setAsIncomplete(); } - queryUrl = 'https://skimdb.npmjs.com/registry/_design/app/_view/browseAll?group_level=2&limit=' + LIMIT + '&start_key=%5B%22' + encodeURIComponent(currentWord) + '%22%5D&end_key=%5B%22' + encodeURIComponent(currentWord + 'z') + '%22,%7B%7D%5D'; - + queryUrl = `https://api.npms.io/v2/search/suggestions?size=${LIMIT}&q=${encodeURIComponent(currentWord)}`; return this.xhr({ url: queryUrl, agent: USER_AGENT @@ -85,26 +100,10 @@ export class PackageJSONContribution implements IJSONContribution { if (success.status === 200) { try { const obj = JSON.parse(success.responseText); - if (obj && Array.isArray(obj.rows)) { - const results = <{ key: string[]; }[]>obj.rows; + if (obj && Array.isArray(obj)) { + const results = <{ package: SearchPackageInfo; }[]>obj; for (const result of results) { - const keys = result.key; - if (Array.isArray(keys) && keys.length > 0) { - const name = keys[0]; - const insertText = new SnippetString().appendText(JSON.stringify(name)); - if (addValue) { - insertText.appendText(': "').appendTabstop().appendText('"'); - if (!isLast) { - insertText.appendText(','); - } - } - const proposal = new CompletionItem(name); - proposal.kind = CompletionItemKind.Property; - proposal.insertText = insertText; - proposal.filterText = JSON.stringify(name); - proposal.documentation = keys[1]; - collector.add(proposal); - } + this.processPackage(result.package, addValue, isLast, collector); } if (results.length === LIMIT) { collector.setAsIncomplete(); @@ -148,20 +147,7 @@ export class PackageJSONContribution implements IJSONContribution { private collectScopedPackages(currentWord: string, addValue: boolean, isLast: boolean, collector: ISuggestionsCollector): Thenable { let segments = currentWord.split('/'); - if (segments.length === 1) { - for (let scope of this.knownScopes) { - const proposal = new CompletionItem(scope); - proposal.kind = CompletionItemKind.Property; - proposal.insertText = new SnippetString().appendText(`"${scope}/`).appendTabstop().appendText('"'); - proposal.filterText = JSON.stringify(scope); - proposal.documentation = ''; - proposal.command = { - title: '', - command: 'editor.action.triggerSuggest' - }; - collector.add(proposal); - } - } else if (segments.length === 2 && segments[0].length > 1) { + if (segments.length === 2 && segments[0].length > 1) { let scope = segments[0].substr(1); let name = segments[1]; if (name.length < 4) { @@ -176,30 +162,9 @@ export class PackageJSONContribution implements IJSONContribution { try { const obj = JSON.parse(success.responseText); if (obj && Array.isArray(obj.results)) { - const objects = <{ package: { name: string; version: string, description: string; } }[]>obj.results; + const objects = <{ package: SearchPackageInfo }[]>obj.results; for (let object of objects) { - if (object.package && object.package.name) { - const name = object.package.name; - const insertText = new SnippetString().appendText(JSON.stringify(name)); - if (addValue) { - insertText.appendText(': "'); - if (object.package.version) { - insertText.appendVariable('version', object.package.version); - } else { - insertText.appendTabstop(); - } - insertText.appendText('"'); - if (!isLast) { - insertText.appendText(','); - } - } - const proposal = new CompletionItem(name); - proposal.kind = CompletionItemKind.Property; - proposal.insertText = insertText; - proposal.filterText = JSON.stringify(name); - proposal.documentation = object.package.description || ''; - collector.add(proposal); - } + this.processPackage(object.package, addValue, isLast, collector); } if (objects.length === SCOPED_LIMIT) { collector.setAsIncomplete(); @@ -229,38 +194,29 @@ export class PackageJSONContribution implements IJSONContribution { if ((location.matches(['dependencies', '*']) || location.matches(['devDependencies', '*']) || location.matches(['optionalDependencies', '*']) || location.matches(['peerDependencies', '*']))) { const currentKey = location.path[location.path.length - 1]; if (typeof currentKey === 'string') { - const queryUrl = 'https://registry.npmjs.org/' + encodeURIComponent(currentKey).replace(/%40/g, '@'); - return this.xhr({ - url: queryUrl, - agent: USER_AGENT - }).then((success) => { - try { - const obj = JSON.parse(success.responseText); - const latest = obj && obj['dist-tags'] && obj['dist-tags']['latest']; - if (latest) { - let name = JSON.stringify(latest); - let proposal = new CompletionItem(name); - proposal.kind = CompletionItemKind.Property; - proposal.insertText = name; - proposal.documentation = localize('json.npm.latestversion', 'The currently latest version of the package'); - result.add(proposal); + return this.npmView(currentKey).then(info => { + const latest = info.distTagsLatest; + if (latest) { + let name = JSON.stringify(latest); + let proposal = new CompletionItem(name); + proposal.kind = CompletionItemKind.Property; + proposal.insertText = name; + proposal.documentation = localize('json.npm.latestversion', 'The currently latest version of the package'); + result.add(proposal); - name = JSON.stringify('^' + latest); - proposal = new CompletionItem(name); - proposal.kind = CompletionItemKind.Property; - proposal.insertText = name; - proposal.documentation = localize('json.npm.majorversion', 'Matches the most recent major version (1.x.x)'); - result.add(proposal); + name = JSON.stringify('^' + latest); + proposal = new CompletionItem(name); + proposal.kind = CompletionItemKind.Property; + proposal.insertText = name; + proposal.documentation = localize('json.npm.majorversion', 'Matches the most recent major version (1.x.x)'); + result.add(proposal); - name = JSON.stringify('~' + latest); - proposal = new CompletionItem(name); - proposal.kind = CompletionItemKind.Property; - proposal.insertText = name; - proposal.documentation = localize('json.npm.minorversion', 'Matches the most recent minor version (1.2.x)'); - result.add(proposal); - } - } catch (e) { - // ignore + name = JSON.stringify('~' + latest); + proposal = new CompletionItem(name); + proposal.kind = CompletionItemKind.Property; + proposal.insertText = name; + proposal.documentation = localize('json.npm.minorversion', 'Matches the most recent minor version (1.2.x)'); + result.add(proposal); } return 0; }, () => { @@ -288,37 +244,38 @@ export class PackageJSONContribution implements IJSONContribution { } private getInfo(pack: string): Thenable { - - const queryUrl = 'https://registry.npmjs.org/' + encodeURIComponent(pack).replace(/%40/g, '@'); - return this.xhr({ - url: queryUrl, - agent: USER_AGENT - }).then((success) => { - try { - const obj = JSON.parse(success.responseText); - if (obj) { - const result: string[] = []; - if (obj.description) { - result.push(obj.description); - } - const latest = obj && obj['dist-tags'] && obj['dist-tags']['latest']; - if (latest) { - result.push(localize('json.npm.version.hover', 'Latest version: {0}', latest)); - } - if (obj.homepage) { - result.push(obj.homepage); - } - return result; - } - } catch (e) { - // ignore - } - return []; + return this.npmView(pack).then(info => { + const result: string[] = []; + result.push(info.description || ''); + result.push(info.distTagsLatest ? localize('json.npm.version.hover', 'Latest version: {0}', info.distTagsLatest) : ''); + result.push(info.homepage || ''); + return result; }, () => { return []; }); } + private npmView(pack: string): Promise { + return new Promise((resolve, reject) => { + const command = 'npm view --json ' + pack + ' description dist-tags.latest homepage'; + cp.exec(command, (error, stdout) => { + if (error) { + return reject(); + } + try { + const content = JSON.parse(stdout); + resolve({ + description: content['description'], + distTagsLatest: content['dist-tags.latest'], + homepage: content['homepage'] + }); + } catch (e) { + reject(); + } + }); + }); + } + public getInfoContribution(_fileName: string, location: Location): Thenable | null { if ((location.matches(['dependencies', '*']) || location.matches(['devDependencies', '*']) || location.matches(['optionalDependencies', '*']) || location.matches(['peerDependencies', '*']))) { const pack = location.path[location.path.length - 1]; @@ -333,4 +290,41 @@ export class PackageJSONContribution implements IJSONContribution { } return null; } + + private processPackage(pack: SearchPackageInfo, addValue: boolean, isLast: boolean, collector: ISuggestionsCollector) { + if (pack && pack.name) { + const name = pack.name; + const insertText = new SnippetString().appendText(JSON.stringify(name)); + if (addValue) { + insertText.appendText(': "'); + if (pack.version) { + insertText.appendVariable('version', pack.version); + } else { + insertText.appendTabstop(); + } + insertText.appendText('"'); + if (!isLast) { + insertText.appendText(','); + } + } + const proposal = new CompletionItem(name); + proposal.kind = CompletionItemKind.Property; + proposal.insertText = insertText; + proposal.filterText = JSON.stringify(name); + proposal.documentation = pack.description || ''; + collector.add(proposal); + } + } } + +interface SearchPackageInfo { + name: string; + description?: string; + version?: string; +} + +interface ViewPackageInfo { + description: string; + distTagsLatest?: string; + homepage?: string; +} \ No newline at end of file diff --git a/extensions/objective-c/build/update-grammars.js b/extensions/objective-c/build/update-grammars.js index 52dd76e06a1..5518bbcb033 100644 --- a/extensions/objective-c/build/update-grammars.js +++ b/extensions/objective-c/build/update-grammars.js @@ -6,6 +6,6 @@ var updateGrammar = require('../../../build/npm/update-grammar'); -updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/objc.tmLanguage.json', './syntaxes/objective-c.tmLanguage.json'); -updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/objcpp.tmLanguage.json', './syntaxes/objective-c++.tmLanguage.json'); +updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/objc.tmLanguage.json', './syntaxes/objective-c.tmLanguage.json', undefined, 'master', 'source/languages/cpp'); +updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/objcpp.tmLanguage.json', './syntaxes/objective-c++.tmLanguage.json', undefined, 'master', 'source/languages/cpp'); diff --git a/extensions/objective-c/cgmanifest.json b/extensions/objective-c/cgmanifest.json index fc610c254ee..f33f55aad69 100644 --- a/extensions/objective-c/cgmanifest.json +++ b/extensions/objective-c/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "jeff-hykin/cpp-textmate-grammar", "repositoryUrl": "https://github.com/jeff-hykin/cpp-textmate-grammar", - "commitHash": "efa8ce61762d0481a1b710fdbc12e284867cdc8f" + "commitHash": "9c4f4b3291538d9f5144f02d3b6af877b84f2cb2" } }, "license": "MIT", - "version": "1.11.0", + "version": "1.12.11", "description": "The files syntaxes/objective-c.tmLanguage.json and syntaxes/objective-c++.tmLanguage.json were derived from the language package https://github.com/jeff-hykin/cpp-textmate-grammar." } ], diff --git a/extensions/objective-c/syntaxes/objective-c++.tmLanguage.json b/extensions/objective-c/syntaxes/objective-c++.tmLanguage.json index 5f5f57ccc7a..d9d1cfa5584 100644 --- a/extensions/objective-c/syntaxes/objective-c++.tmLanguage.json +++ b/extensions/objective-c/syntaxes/objective-c++.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/8d3cf8028835c68e75e42d0bd3192c837847a419", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/9c4f4b3291538d9f5144f02d3b6af877b84f2cb2", "name": "Objective-C++", "scopeName": "source.objcpp", "patterns": [ diff --git a/extensions/objective-c/syntaxes/objective-c.tmLanguage.json b/extensions/objective-c/syntaxes/objective-c.tmLanguage.json index 95a57cee9cc..e08731bb134 100644 --- a/extensions/objective-c/syntaxes/objective-c.tmLanguage.json +++ b/extensions/objective-c/syntaxes/objective-c.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/efa8ce61762d0481a1b710fdbc12e284867cdc8f", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/9c4f4b3291538d9f5144f02d3b6af877b84f2cb2", "name": "Objective-C", "scopeName": "source.objc", "patterns": [ diff --git a/extensions/package.json b/extensions/package.json index b397a2d852e..52ece5e2051 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "3.5.1" + "typescript": "3.5.2" }, "scripts": { "postinstall": "node ./postinstall" diff --git a/extensions/perl/cgmanifest.json b/extensions/perl/cgmanifest.json index 83d91107671..b7c850dd1aa 100644 --- a/extensions/perl/cgmanifest.json +++ b/extensions/perl/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "textmate/perl.tmbundle", "repositoryUrl": "https://github.com/textmate/perl.tmbundle", - "commitHash": "80826abe75250286c2a1a07958e50e8551d3f50c" + "commitHash": "d9841a0878239fa43f88c640f8d458590f97e8f5" } }, "licenseDetail": [ diff --git a/extensions/php-language-features/package.json b/extensions/php-language-features/package.json index c27df6e4e6a..8172c6bece8 100644 --- a/extensions/php-language-features/package.json +++ b/extensions/php-language-features/package.json @@ -38,7 +38,8 @@ "null" ], "default": null, - "description": "%configuration.validate.executablePath%" + "description": "%configuration.validate.executablePath%", + "scope": "machine" }, "php.validate.run": { "type": "string", diff --git a/extensions/php/build/update-grammar.js b/extensions/php/build/update-grammar.js index a6bf6d52721..58b1207a4a2 100644 --- a/extensions/php/build/update-grammar.js +++ b/extensions/php/build/update-grammar.js @@ -23,16 +23,40 @@ function adaptInjectionScope(grammar) { // Workaround for https://github.com/Microsoft/vscode/issues/40279 // and https://github.com/Microsoft/vscode-textmate/issues/59 function fixBadRegex(grammar) { + function fail(msg) { + throw new Error(`fixBadRegex callback couldn't patch ${msg}. It may be obsolete`); + } + const scopeResolution = grammar.repository['scope-resolution']; if (scopeResolution) { const match = scopeResolution.patterns[0].match; if (match === '(?i)([a-z_\\x{7f}-\\x{7fffffff}\\\\][a-z0-9_\\x{7f}-\\x{7fffffff}\\\\]*)(?=\\s*::)') { scopeResolution.patterns[0].match = '([A-Za-z_\\x{7f}-\\x{7fffffff}\\\\][A-Za-z0-9_\\x{7f}-\\x{7fffffff}\\\\]*)(?=\\s*::)'; - return; + } else { + fail('scope-resolution.match'); } + } else { + fail('scope-resolution'); } - throw new Error(`fixBadRegex callback couldn't patch the regex. It may be obsolete`); + const functionCall = grammar.repository['function-call']; + if (functionCall) { + const begin0 = functionCall.patterns[0].begin; + if (begin0 === '(?xi)\n(\n \\\\?(? { if (this.pendingGetErr === getErr) { this.pendingGetErr = undefined; diff --git a/extensions/typescript-language-features/src/features/definitions.ts b/extensions/typescript-language-features/src/features/definitions.ts index 5fe72c2005f..fd3a1f10e79 100644 --- a/extensions/typescript-language-features/src/features/definitions.ts +++ b/extensions/typescript-language-features/src/features/definitions.ts @@ -37,10 +37,18 @@ export default class TypeScriptDefinitionProvider extends DefinitionProviderBase return response.body.definitions .map((location): vscode.DefinitionLink => { const target = typeConverters.Location.fromTextSpan(this.client.toResource(location.file), location); + if ((location as any).contextStart) { + return { + originSelectionRange: span, + targetRange: typeConverters.Range.fromLocations((location as any).contextStart, (location as any).contextEnd), + targetUri: target.uri, + targetSelectionRange: target.range, + }; + } return { originSelectionRange: span, targetRange: target.range, - targetUri: target.uri, + targetUri: target.uri }; }); } diff --git a/extensions/typescript-language-features/src/features/diagnostics.ts b/extensions/typescript-language-features/src/features/diagnostics.ts index d3d40ac97f4..327573e8c18 100644 --- a/extensions/typescript-language-features/src/features/diagnostics.ts +++ b/extensions/typescript-language-features/src/features/diagnostics.ts @@ -208,7 +208,7 @@ export class DiagnosticsManager extends Disposable { public configFileDiagnosticsReceived( file: vscode.Uri, - diagnostics: vscode.Diagnostic[] + diagnostics: ReadonlyArray ): void { this._currentDiagnostics.set(file, diagnostics); } @@ -218,7 +218,7 @@ export class DiagnosticsManager extends Disposable { this._diagnostics.delete(resource); } - public getDiagnostics(file: vscode.Uri): vscode.Diagnostic[] { + public getDiagnostics(file: vscode.Uri): ReadonlyArray { return this._currentDiagnostics.get(file) || []; } diff --git a/extensions/typescript-language-features/src/features/implementationsCodeLens.ts b/extensions/typescript-language-features/src/features/implementationsCodeLens.ts index 63cfc6222d9..c732ade5223 100644 --- a/extensions/typescript-language-features/src/features/implementationsCodeLens.ts +++ b/extensions/typescript-language-features/src/features/implementationsCodeLens.ts @@ -26,7 +26,7 @@ export default class TypeScriptImplementationsCodeLensProvider extends TypeScrip const codeLens = inputCodeLens as ReferencesCodeLens; const args = typeConverters.Position.toFileLocationRequestArgs(codeLens.file, codeLens.range.start); - const response = await this.client.execute('implementation', args, token, /* lowPriority */ true); + const response = await this.client.execute('implementation', args, token, { lowPriority: true }); if (response.type !== 'response' || !response.body) { codeLens.command = response.type === 'cancelled' ? TypeScriptBaseCodeLensProvider.cancelledCommand diff --git a/extensions/typescript-language-features/src/features/referencesCodeLens.ts b/extensions/typescript-language-features/src/features/referencesCodeLens.ts index ff09a9a4346..65c2cd5eb7f 100644 --- a/extensions/typescript-language-features/src/features/referencesCodeLens.ts +++ b/extensions/typescript-language-features/src/features/referencesCodeLens.ts @@ -22,7 +22,7 @@ class TypeScriptReferencesCodeLensProvider extends TypeScriptBaseCodeLensProvide public async resolveCodeLens(inputCodeLens: vscode.CodeLens, token: vscode.CancellationToken): Promise { const codeLens = inputCodeLens as ReferencesCodeLens; const args = typeConverters.Position.toFileLocationRequestArgs(codeLens.file, codeLens.range.start); - const response = await this.client.execute('references', args, token, /* lowPriority */ true); + const response = await this.client.execute('references', args, token, { lowPriority: true }); if (response.type !== 'response' || !response.body) { codeLens.command = response.type === 'cancelled' ? TypeScriptBaseCodeLensProvider.cancelledCommand diff --git a/extensions/typescript-language-features/src/features/tagClosing.ts b/extensions/typescript-language-features/src/features/tagClosing.ts index c8db74597e5..1123b175531 100644 --- a/extensions/typescript-language-features/src/features/tagClosing.ts +++ b/extensions/typescript-language-features/src/features/tagClosing.ts @@ -46,7 +46,7 @@ class TagClosing extends Disposable { private onDidChangeTextDocument( document: vscode.TextDocument, - changes: vscode.TextDocumentContentChangeEvent[] + changes: readonly vscode.TextDocumentContentChangeEvent[] ) { const activeDocument = vscode.window.activeTextEditor && vscode.window.activeTextEditor.document; if (document !== activeDocument || changes.length === 0) { diff --git a/extensions/typescript-language-features/src/features/task.ts b/extensions/typescript-language-features/src/features/task.ts index 8c393ade672..d5fa55ba87a 100644 --- a/extensions/typescript-language-features/src/features/task.ts +++ b/extensions/typescript-language-features/src/features/task.ts @@ -72,6 +72,12 @@ class TscTaskProvider implements vscode.TaskProvider { } public resolveTask(_task: vscode.Task): vscode.Task | undefined { + const definition = _task.definition; + const badTsconfig = '\\tsconfig.json'; + if ((definition.tsconfig.length > badTsconfig.length) && (definition.tsconfig.substring(definition.tsconfig.length - badTsconfig.length, definition.tsconfig.length) === badTsconfig)) { + // Warn that the task has the wrong slash type + vscode.window.showWarningMessage(localize('badTsConfig', "Typescript Task in tasks.json contains \"\\\\\". Typescript tasks must use \"/\"")); + } return undefined; } @@ -234,8 +240,10 @@ class TscTaskProvider implements vscode.TaskProvider { private getLabelForTasks(project: TSConfig): string { if (project.workspaceFolder) { - return path.posix.relative(project.workspaceFolder.uri.path, project.posixPath); + const workspaceNormalizedUri = vscode.Uri.file(path.normalize(project.workspaceFolder.uri.fsPath)); // Make sure the drive letter is lowercase + return path.posix.relative(workspaceNormalizedUri.path, project.posixPath); } + return project.posixPath; } diff --git a/extensions/typescript-language-features/src/test/server.test.ts b/extensions/typescript-language-features/src/test/server.test.ts index bd22203d8d3..651967fc12c 100644 --- a/extensions/typescript-language-features/src/test/server.test.ts +++ b/extensions/typescript-language-features/src/test/server.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import 'mocha'; import * as stream from 'stream'; -import { PipeRequestCanceller, ServerProcess, TypeScriptServer } from '../tsServer/server'; +import { PipeRequestCanceller, TsServerProcess, ProcessBasedTsServer } from '../tsServer/server'; import { nulToken } from '../utils/cancellation'; import Logger from '../utils/logger'; import TelemetryReporter from '../utils/telemetry'; @@ -19,7 +19,7 @@ const NoopTelemetryReporter = new class implements TelemetryReporter { dispose(): void { /* noop */ } }; -class FakeServerProcess implements ServerProcess { +class FakeServerProcess implements TsServerProcess { private readonly _out: stream.PassThrough; private readonly writeListeners = new Set<(data: Buffer) => void>(); @@ -62,7 +62,7 @@ suite('Server', () => { test('should send requests with increasing sequence numbers', async () => { const process = new FakeServerProcess(); - const server = new TypeScriptServer(process, undefined, new PipeRequestCanceller(undefined, tracer), undefined!, NoopTelemetryReporter, tracer); + const server = new ProcessBasedTsServer('semantic', process, undefined, new PipeRequestCanceller('semantic', undefined, tracer), undefined!, NoopTelemetryReporter, tracer); const onWrite1 = process.onWrite(); server.executeImpl('geterr', {}, { isAsync: false, token: nulToken, expectsResult: true }); diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index 10a001d52c2..f10b02abf8e 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -3,248 +3,19 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as child_process from 'child_process'; import * as fs from 'fs'; -import * as path from 'path'; import * as stream from 'stream'; import * as vscode from 'vscode'; import * as Proto from '../protocol'; -import { ServerResponse } from '../typescriptService'; -import API from '../utils/api'; -import { TsServerLogLevel, TypeScriptServiceConfiguration } from '../utils/configuration'; +import { ServerResponse, TypeScriptRequests } from '../typescriptService'; import { Disposable } from '../utils/dispose'; -import * as electron from '../utils/electron'; -import LogDirectoryProvider from '../utils/logDirectoryProvider'; -import Logger from '../utils/logger'; -import { TypeScriptPluginPathsProvider } from '../utils/pluginPathsProvider'; -import { PluginManager } from '../utils/plugins'; -import { escapeRegExp } from '../utils/regexp'; import TelemetryReporter from '../utils/telemetry'; import Tracer from '../utils/tracer'; -import { TypeScriptVersion, TypeScriptVersionProvider } from '../utils/versionProvider'; +import { TypeScriptVersion } from '../utils/versionProvider'; import { Reader } from '../utils/wireProtocol'; import { CallbackMap } from './callbackMap'; import { RequestItem, RequestQueue, RequestQueueingType } from './requestQueue'; - -class TypeScriptServerError extends Error { - - public static create( - version: TypeScriptVersion, - response: Proto.Response, - ): TypeScriptServerError { - const parsedResult = TypeScriptServerError.parseErrorText(version, response); - return new TypeScriptServerError(version, response, - parsedResult ? parsedResult.message : undefined, - parsedResult ? parsedResult.stack : undefined); - } - - constructor( - version: TypeScriptVersion, - private readonly response: Proto.Response, - public readonly serverMessage: string | undefined, - public readonly serverStack: string | undefined, - ) { - super(`TypeScript Server Error (${version.versionString})\n${serverMessage}\n${serverStack}`); - } - - public get serverErrorText() { - return this.response.message; - } - - public get serverCommand() { - return this.response.command; - } - - /** - * Given a `errorText` from a tsserver request indicating failure in handling a request, - * prepares a payload for telemetry-logging. - */ - private static parseErrorText( - version: TypeScriptVersion, - response: Proto.Response, - ) { - const errorText = response.message; - if (errorText) { - const errorPrefix = 'Error processing request. '; - if (errorText.startsWith(errorPrefix)) { - const prefixFreeErrorText = errorText.substr(errorPrefix.length); - const newlineIndex = prefixFreeErrorText.indexOf('\n'); - if (newlineIndex >= 0) { - // Newline expected between message and stack. - return { - message: prefixFreeErrorText.substring(0, newlineIndex), - stack: TypeScriptServerError.normalizeMessageStack(version, prefixFreeErrorText.substring(newlineIndex + 1)) - }; - } - } - } - return undefined; - } - - /** - * Try to replace full TS Server paths with 'tsserver.js' so that we don't have to post process the data as much - */ - private static normalizeMessageStack( - version: TypeScriptVersion, - message: string | undefined, - ) { - if (!message) { - return ''; - } - return message.replace(new RegExp(`${escapeRegExp(version.path)}[/\\\\]tsserver.js:`, 'gi'), 'tsserver.js:'); - } -} - -export class TypeScriptServerSpawner { - public constructor( - private readonly _versionProvider: TypeScriptVersionProvider, - private readonly _logDirectoryProvider: LogDirectoryProvider, - private readonly _pluginPathsProvider: TypeScriptPluginPathsProvider, - private readonly _logger: Logger, - private readonly _telemetryReporter: TelemetryReporter, - private readonly _tracer: Tracer, - ) { } - - public spawn( - version: TypeScriptVersion, - configuration: TypeScriptServiceConfiguration, - pluginManager: PluginManager - ): TypeScriptServer { - const apiVersion = version.version || API.defaultVersion; - - const { args, cancellationPipeName, tsServerLogFile } = this.getTsServerArgs(configuration, version, apiVersion, pluginManager); - - if (TypeScriptServerSpawner.isLoggingEnabled(apiVersion, configuration)) { - if (tsServerLogFile) { - this._logger.info(`TSServer log file: ${tsServerLogFile}`); - } else { - this._logger.error('Could not create TSServer log directory'); - } - } - - this._logger.info('Forking TSServer'); - const childProcess = electron.fork(version.tsServerPath, args, this.getForkOptions()); - this._logger.info('Started TSServer'); - - return new TypeScriptServer( - new ChildServerProcess(childProcess), - tsServerLogFile, - new PipeRequestCanceller(cancellationPipeName, this._tracer), - version, - this._telemetryReporter, - this._tracer); - } - - private getForkOptions() { - const debugPort = TypeScriptServerSpawner.getDebugPort(); - const tsServerForkOptions: electron.ForkOptions = { - execArgv: debugPort ? [`--inspect=${debugPort}`] : [], - }; - return tsServerForkOptions; - } - - private getTsServerArgs( - configuration: TypeScriptServiceConfiguration, - currentVersion: TypeScriptVersion, - apiVersion: API, - pluginManager: PluginManager, - ): { args: string[], cancellationPipeName: string | undefined, tsServerLogFile: string | undefined } { - const args: string[] = []; - let cancellationPipeName: string | undefined; - let tsServerLogFile: string | undefined; - - if (apiVersion.gte(API.v206)) { - if (apiVersion.gte(API.v250)) { - args.push('--useInferredProjectPerProjectRoot'); - } else { - args.push('--useSingleInferredProject'); - } - - if (configuration.disableAutomaticTypeAcquisition) { - args.push('--disableAutomaticTypingAcquisition'); - } - } - - if (apiVersion.gte(API.v208)) { - args.push('--enableTelemetry'); - } - - if (apiVersion.gte(API.v222)) { - cancellationPipeName = electron.getTempFile('tscancellation'); - args.push('--cancellationPipeName', cancellationPipeName + '*'); - } - - if (TypeScriptServerSpawner.isLoggingEnabled(apiVersion, configuration)) { - const logDir = this._logDirectoryProvider.getNewLogDirectory(); - if (logDir) { - tsServerLogFile = path.join(logDir, `tsserver.log`); - args.push('--logVerbosity', TsServerLogLevel.toString(configuration.tsServerLogLevel)); - args.push('--logFile', tsServerLogFile); - } - } - - if (apiVersion.gte(API.v230)) { - const pluginPaths = this._pluginPathsProvider.getPluginPaths(); - - if (pluginManager.plugins.length) { - args.push('--globalPlugins', pluginManager.plugins.map(x => x.name).join(',')); - - const isUsingBundledTypeScriptVersion = currentVersion.path === this._versionProvider.defaultVersion.path; - for (const plugin of pluginManager.plugins) { - if (isUsingBundledTypeScriptVersion || plugin.enableForWorkspaceTypeScriptVersions) { - pluginPaths.push(plugin.path); - } - } - } - - if (pluginPaths.length !== 0) { - args.push('--pluginProbeLocations', pluginPaths.join(',')); - } - } - - if (apiVersion.gte(API.v234)) { - if (configuration.npmLocation) { - args.push('--npmLocation', `"${configuration.npmLocation}"`); - } - } - - if (apiVersion.gte(API.v260)) { - args.push('--locale', TypeScriptServerSpawner.getTsLocale(configuration)); - } - - if (apiVersion.gte(API.v291)) { - args.push('--noGetErrOnBackgroundUpdate'); - } - - if (apiVersion.gte(API.v345)) { - args.push('--validateDefaultNpmLocation'); - } - - return { args, cancellationPipeName, tsServerLogFile }; - } - - private static getDebugPort(): number | undefined { - const value = process.env['TSS_DEBUG']; - if (value) { - const port = parseInt(value); - if (!isNaN(port)) { - return port; - } - } - return undefined; - } - - private static isLoggingEnabled(apiVersion: API, configuration: TypeScriptServiceConfiguration) { - return apiVersion.gte(API.v222) && - configuration.tsServerLogLevel !== TsServerLogLevel.Off; - } - - private static getTsLocale(configuration: TypeScriptServiceConfiguration): string { - return configuration.locale - ? configuration.locale - : vscode.env.language; - } -} +import { TypeScriptServerError } from './serverError'; export interface OngoingRequestCanceller { tryCancelOngoingRequest(seq: number): boolean; @@ -252,6 +23,7 @@ export interface OngoingRequestCanceller { export class PipeRequestCanceller implements OngoingRequestCanceller { public constructor( + private readonly _serverId: string, private readonly _cancellationPipeName: string | undefined, private readonly _tracer: Tracer, ) { } @@ -260,7 +32,7 @@ export class PipeRequestCanceller implements OngoingRequestCanceller { if (!this._cancellationPipeName) { return false; } - this._tracer.logTrace(`TypeScript Server: trying to cancel ongoing request with sequence number ${seq}`); + this._tracer.logTrace(this._serverId, `TypeScript Server: trying to cancel ongoing request with sequence number ${seq}`); try { fs.writeFileSync(this._cancellationPipeName + seq, ''); } catch { @@ -270,7 +42,24 @@ export class PipeRequestCanceller implements OngoingRequestCanceller { } } -export interface ServerProcess { +export interface ITypeScriptServer { + readonly onEvent: vscode.Event; + readonly onExit: vscode.Event; + readonly onError: vscode.Event; + readonly onReaderError: vscode.Event; + + readonly tsServerLogFile: string | undefined; + + kill(): void; + + executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; + executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; + executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined; + + dispose(): void; +} + +export interface TsServerProcess { readonly stdout: stream.Readable; write(serverRequest: Proto.Request): void; @@ -280,37 +69,15 @@ export interface ServerProcess { kill(): void; } -class ChildServerProcess implements ServerProcess { - - public constructor( - private readonly _process: child_process.ChildProcess, - ) { } - - get stdout(): stream.Readable { return this._process.stdout!; } - - write(serverRequest: Proto.Request): void { - this._process.stdin!.write(JSON.stringify(serverRequest) + '\r\n', 'utf8'); - } - - on(name: 'exit', handler: (code: number | null) => void): void; - on(name: 'error', handler: (error: Error) => void): void; - on(name: any, handler: any) { - this._process.on(name, handler); - } - - kill(): void { - this._process.kill(); - } -} - -export class TypeScriptServer extends Disposable { +export class ProcessBasedTsServer extends Disposable implements ITypeScriptServer { private readonly _reader: Reader; private readonly _requestQueue = new RequestQueue(); private readonly _callbacks = new CallbackMap(); private readonly _pendingResponses = new Set(); constructor( - private readonly _process: ServerProcess, + private readonly _serverId: string, + private readonly _process: TsServerProcess, private readonly _tsServerLogFile: string | undefined, private readonly _requestCanceller: OngoingRequestCanceller, private readonly _version: TypeScriptVersion, @@ -371,11 +138,11 @@ export class TypeScriptServer extends Disposable { const seq = (event as Proto.RequestCompletedEvent).body.request_seq; const p = this._callbacks.fetch(seq); if (p) { - this._tracer.traceRequestCompleted('requestCompleted', seq, p.startTime); + this._tracer.traceRequestCompleted(this._serverId, 'requestCompleted', seq, p.startTime); p.onSuccess(undefined); } } else { - this._tracer.traceEvent(event); + this._tracer.traceEvent(this._serverId, event); this._onEvent.fire(event); } break; @@ -391,7 +158,7 @@ export class TypeScriptServer extends Disposable { private tryCancelRequest(seq: number, command: string): boolean { try { if (this._requestQueue.tryDeletePendingRequest(seq)) { - this._tracer.logTrace(`TypeScript Server: canceled request with sequence number ${seq}`); + this.logTrace(`Canceled request with sequence number ${seq}`); return true; } @@ -399,7 +166,7 @@ export class TypeScriptServer extends Disposable { return true; } - this._tracer.logTrace(`TypeScript Server: tried to cancel request with sequence number ${seq}. But request got already delivered.`); + this.logTrace(`Tried to cancel request with sequence number ${seq}. But request got already delivered.`); return false; } finally { const callback = this.fetchCallback(seq); @@ -415,26 +182,26 @@ export class TypeScriptServer extends Disposable { return; } - this._tracer.traceResponse(response, callback.startTime); + this._tracer.traceResponse(this._serverId, response, callback.startTime); if (response.success) { callback.onSuccess(response); } else if (response.message === 'No content available.') { // Special case where response itself is successful but there is not any data to return. callback.onSuccess(ServerResponse.NoContent); } else { - callback.onError(TypeScriptServerError.create(this._version, response)); + callback.onError(TypeScriptServerError.create(this._serverId, this._version, response)); } } - public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; - public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; - public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { const request = this._requestQueue.createRequest(command, args); const requestInfo: RequestItem = { request, expectsResponse: executeInfo.expectsResult, isAsync: executeInfo.isAsync, - queueingType: getQueueingType(command, executeInfo.lowPriority) + queueingType: ProcessBasedTsServer.getQueueingType(command, executeInfo.lowPriority) }; let result: Promise> | undefined; if (executeInfo.expectsResult) { @@ -490,7 +257,7 @@ export class TypeScriptServer extends Disposable { private sendRequest(requestItem: RequestItem): void { const serverRequest = requestItem.request; - this._tracer.traceRequest(serverRequest, requestItem.expectsResponse, this._requestQueue.length); + this._tracer.traceRequest(this._serverId, serverRequest, requestItem.expectsResponse, this._requestQueue.length); if (requestItem.expectsResponse && !requestItem.isAsync) { this._pendingResponses.add(requestItem.request.seq); @@ -515,17 +282,115 @@ export class TypeScriptServer extends Disposable { this._pendingResponses.delete(seq); return callback; } -} -const fenceCommands = new Set(['change', 'close', 'open', 'updateOpen']); - -function getQueueingType( - command: string, - lowPriority?: boolean -): RequestQueueingType { - if (fenceCommands.has(command)) { - return RequestQueueingType.Fence; + private logTrace(message: string) { + this._tracer.logTrace(this._serverId, message); + } + + private static readonly fenceCommands = new Set(['change', 'close', 'open', 'updateOpen']); + + private static getQueueingType( + command: string, + lowPriority?: boolean + ): RequestQueueingType { + if (ProcessBasedTsServer.fenceCommands.has(command)) { + return RequestQueueingType.Fence; + } + return lowPriority ? RequestQueueingType.LowPriority : RequestQueueingType.Normal; } - return lowPriority ? RequestQueueingType.LowPriority : RequestQueueingType.Normal; } + +export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServer { + public constructor( + private readonly syntaxServer: ITypeScriptServer, + private readonly semanticServer: ITypeScriptServer, + ) { + super(); + + this._register(syntaxServer.onEvent(e => this._onEvent.fire(e))); + this._register(semanticServer.onEvent(e => this._onEvent.fire(e))); + + this._register(semanticServer.onExit(e => { + this._onExit.fire(e); + this.syntaxServer.kill(); + })); + this._register(semanticServer.onError(e => this._onError.fire(e))); + } + + private readonly _onEvent = this._register(new vscode.EventEmitter()); + public readonly onEvent = this._onEvent.event; + + private readonly _onExit = this._register(new vscode.EventEmitter()); + public readonly onExit = this._onExit.event; + + private readonly _onError = this._register(new vscode.EventEmitter()); + public readonly onError = this._onError.event; + + public get onReaderError() { return this.semanticServer.onReaderError; } + + public get tsServerLogFile() { return this.semanticServer.tsServerLogFile; } + + public kill(): void { + this.syntaxServer.kill(); + this.semanticServer.kill(); + } + + private static readonly syntaxCommands = new Set([ + 'navtree', + 'getOutliningSpans', + 'jsxClosingTag', + 'selectionRange', + 'format', + 'formatonkey', + 'docCommentTemplate', + ]); + private static readonly sharedCommands = new Set([ + 'change', + 'close', + 'open', + 'updateOpen', + 'configure', + 'configurePlugin', + ]); + + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { + if (SyntaxRoutingTsServer.syntaxCommands.has(command)) { + return this.syntaxServer.executeImpl(command, args, executeInfo); + } else if (SyntaxRoutingTsServer.sharedCommands.has(command)) { + // Dispatch to both server but only return from syntax one + + // Also make sure we never cancel requests to just one server + let hasCompletedSyntax = false; + let hasCompletedSemantic = false; + let token: vscode.CancellationToken | undefined = undefined; + if (executeInfo.token) { + const source = new vscode.CancellationTokenSource(); + executeInfo.token.onCancellationRequested(() => { + if (hasCompletedSyntax && !hasCompletedSemantic || hasCompletedSemantic && !hasCompletedSyntax) { + // Don't cancel. + // One of the servers completed this request so we don't want to leave the other + // in a different state + return; + } + source.cancel(); + }); + token = source.token; + } + + const semanticRequest = this.semanticServer.executeImpl(command, args, { ...executeInfo, token }); + if (semanticRequest) { + semanticRequest.finally(() => { hasCompletedSemantic = true; }); + } + const syntaxRequest = this.syntaxServer.executeImpl(command, args, { ...executeInfo, token }); + if (syntaxRequest) { + syntaxRequest.finally(() => { hasCompletedSyntax = true; }); + } + return syntaxRequest; + } else { + return this.semanticServer.executeImpl(command, args, executeInfo); + } + } +} diff --git a/extensions/typescript-language-features/src/tsServer/serverError.ts b/extensions/typescript-language-features/src/tsServer/serverError.ts new file mode 100644 index 00000000000..cb5cb8035f1 --- /dev/null +++ b/extensions/typescript-language-features/src/tsServer/serverError.ts @@ -0,0 +1,66 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as Proto from '../protocol'; +import { escapeRegExp } from '../utils/regexp'; +import { TypeScriptVersion } from '../utils/versionProvider'; + +export class TypeScriptServerError extends Error { + public static create( + serverId: string, + version: TypeScriptVersion, + response: Proto.Response + ): TypeScriptServerError { + const parsedResult = TypeScriptServerError.parseErrorText(version, response); + return new TypeScriptServerError(serverId, version, response, parsedResult ? parsedResult.message : undefined, parsedResult ? parsedResult.stack : undefined); + } + + private constructor( + serverId: string, + version: TypeScriptVersion, + private readonly response: Proto.Response, + public readonly serverMessage: string | undefined, + public readonly serverStack: string | undefined + ) { + super(`<${serverId}> TypeScript Server Error (${version.versionString})\n${serverMessage}\n${serverStack}`); + } + + public get serverErrorText() { return this.response.message; } + + public get serverCommand() { return this.response.command; } + + /** + * Given a `errorText` from a tsserver request indicating failure in handling a request, + * prepares a payload for telemetry-logging. + */ + private static parseErrorText(version: TypeScriptVersion, response: Proto.Response) { + const errorText = response.message; + if (errorText) { + const errorPrefix = 'Error processing request. '; + if (errorText.startsWith(errorPrefix)) { + const prefixFreeErrorText = errorText.substr(errorPrefix.length); + const newlineIndex = prefixFreeErrorText.indexOf('\n'); + if (newlineIndex >= 0) { + // Newline expected between message and stack. + return { + message: prefixFreeErrorText.substring(0, newlineIndex), + stack: TypeScriptServerError.normalizeMessageStack(version, prefixFreeErrorText.substring(newlineIndex + 1)) + }; + } + } + } + return undefined; + } + + /** + * Try to replace full TS Server paths with 'tsserver.js' so that we don't have to post process the data as much + */ + private static normalizeMessageStack(version: TypeScriptVersion, message: string | undefined) { + if (!message) { + return ''; + } + return message.replace(new RegExp(`${escapeRegExp(version.path)}[/\\\\]tsserver.js:`, 'gi'), 'tsserver.js:'); + } +} diff --git a/extensions/typescript-language-features/src/tsServer/spawner.ts b/extensions/typescript-language-features/src/tsServer/spawner.ts new file mode 100644 index 00000000000..599abe32ca1 --- /dev/null +++ b/extensions/typescript-language-features/src/tsServer/spawner.ts @@ -0,0 +1,229 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as child_process from 'child_process'; +import * as path from 'path'; +import * as stream from 'stream'; +import * as vscode from 'vscode'; +import * as Proto from '../protocol'; +import API from '../utils/api'; +import { TsServerLogLevel, TypeScriptServiceConfiguration } from '../utils/configuration'; +import * as electron from '../utils/electron'; +import LogDirectoryProvider from '../utils/logDirectoryProvider'; +import Logger from '../utils/logger'; +import { TypeScriptPluginPathsProvider } from '../utils/pluginPathsProvider'; +import { PluginManager } from '../utils/plugins'; +import TelemetryReporter from '../utils/telemetry'; +import Tracer from '../utils/tracer'; +import { TypeScriptVersion, TypeScriptVersionProvider } from '../utils/versionProvider'; +import { ITypeScriptServer, PipeRequestCanceller, ProcessBasedTsServer, SyntaxRoutingTsServer, TsServerProcess } from './server'; + +type ServerKind = 'main' | 'syntax' | 'semantic'; + +export class TypeScriptServerSpawner { + public constructor( + private readonly _versionProvider: TypeScriptVersionProvider, + private readonly _logDirectoryProvider: LogDirectoryProvider, + private readonly _pluginPathsProvider: TypeScriptPluginPathsProvider, + private readonly _logger: Logger, + private readonly _telemetryReporter: TelemetryReporter, + private readonly _tracer: Tracer, + ) { } + + public spawn( + version: TypeScriptVersion, + configuration: TypeScriptServiceConfiguration, + pluginManager: PluginManager + ): ITypeScriptServer { + if (this.shouldUseSeparateSyntaxServer(version, configuration)) { + const syntaxServer = this.spawnTsServer('syntax', version, configuration, pluginManager); + const semanticServer = this.spawnTsServer('semantic', version, configuration, pluginManager); + return new SyntaxRoutingTsServer(syntaxServer, semanticServer); + } + + return this.spawnTsServer('main', version, configuration, pluginManager); + } + + private shouldUseSeparateSyntaxServer( + version: TypeScriptVersion, + configuration: TypeScriptServiceConfiguration, + ): boolean { + return configuration.useSeparateSyntaxServer && !!version.apiVersion && version.apiVersion.gte(API.v340); + } + + private spawnTsServer( + kind: ServerKind, + version: TypeScriptVersion, + configuration: TypeScriptServiceConfiguration, + pluginManager: PluginManager, + ): ITypeScriptServer { + const apiVersion = version.apiVersion || API.defaultVersion; + + const { args, cancellationPipeName, tsServerLogFile } = this.getTsServerArgs(kind, configuration, version, apiVersion, pluginManager); + + if (TypeScriptServerSpawner.isLoggingEnabled(apiVersion, configuration)) { + if (tsServerLogFile) { + this._logger.info(`<${kind}> Log file: ${tsServerLogFile}`); + } else { + this._logger.error(`<${kind}> Could not create log directory`); + } + } + + this._logger.info(`<${kind}> Forking...`); + const childProcess = electron.fork(version.tsServerPath, args, this.getForkOptions(kind)); + this._logger.info(`<${kind}> Starting...`); + + return new ProcessBasedTsServer( + kind, + new ChildServerProcess(childProcess), + tsServerLogFile, + new PipeRequestCanceller(kind, cancellationPipeName, this._tracer), + version, + this._telemetryReporter, + this._tracer); + } + + private getForkOptions(kind: ServerKind) { + const debugPort = TypeScriptServerSpawner.getDebugPort(kind); + const tsServerForkOptions: electron.ForkOptions = { + execArgv: debugPort ? [`--inspect=${debugPort}`] : [], + }; + return tsServerForkOptions; + } + + private getTsServerArgs( + kind: ServerKind, + configuration: TypeScriptServiceConfiguration, + currentVersion: TypeScriptVersion, + apiVersion: API, + pluginManager: PluginManager, + ): { args: string[], cancellationPipeName: string | undefined, tsServerLogFile: string | undefined } { + const args: string[] = []; + let cancellationPipeName: string | undefined; + let tsServerLogFile: string | undefined; + + if (kind === 'syntax') { + args.push('--syntaxOnly'); + } + + if (apiVersion.gte(API.v206)) { + if (apiVersion.gte(API.v250)) { + args.push('--useInferredProjectPerProjectRoot'); + } else { + args.push('--useSingleInferredProject'); + } + + if (configuration.disableAutomaticTypeAcquisition || kind === 'syntax') { + args.push('--disableAutomaticTypingAcquisition'); + } + } + + if (apiVersion.gte(API.v208) && kind !== 'syntax') { + args.push('--enableTelemetry'); + } + + if (apiVersion.gte(API.v222)) { + cancellationPipeName = electron.getTempFile('tscancellation'); + args.push('--cancellationPipeName', cancellationPipeName + '*'); + } + + if (TypeScriptServerSpawner.isLoggingEnabled(apiVersion, configuration)) { + const logDir = this._logDirectoryProvider.getNewLogDirectory(); + if (logDir) { + tsServerLogFile = path.join(logDir, `tsserver.log`); + args.push('--logVerbosity', TsServerLogLevel.toString(configuration.tsServerLogLevel)); + args.push('--logFile', tsServerLogFile); + } + } + + if (apiVersion.gte(API.v230)) { + const pluginPaths = this._pluginPathsProvider.getPluginPaths(); + + if (pluginManager.plugins.length) { + args.push('--globalPlugins', pluginManager.plugins.map(x => x.name).join(',')); + + const isUsingBundledTypeScriptVersion = currentVersion.path === this._versionProvider.defaultVersion.path; + for (const plugin of pluginManager.plugins) { + if (isUsingBundledTypeScriptVersion || plugin.enableForWorkspaceTypeScriptVersions) { + pluginPaths.push(plugin.path); + } + } + } + + if (pluginPaths.length !== 0) { + args.push('--pluginProbeLocations', pluginPaths.join(',')); + } + } + + if (apiVersion.gte(API.v234)) { + if (configuration.npmLocation) { + args.push('--npmLocation', `"${configuration.npmLocation}"`); + } + } + + if (apiVersion.gte(API.v260)) { + args.push('--locale', TypeScriptServerSpawner.getTsLocale(configuration)); + } + + if (apiVersion.gte(API.v291)) { + args.push('--noGetErrOnBackgroundUpdate'); + } + + if (apiVersion.gte(API.v345)) { + args.push('--validateDefaultNpmLocation'); + } + + return { args, cancellationPipeName, tsServerLogFile }; + } + + private static getDebugPort(kind: ServerKind): number | undefined { + if (kind === 'syntax') { + // We typically only want to debug the main semantic server + return undefined; + } + const value = process.env['TSS_DEBUG']; + if (value) { + const port = parseInt(value); + if (!isNaN(port)) { + return port; + } + } + return undefined; + } + + private static isLoggingEnabled(apiVersion: API, configuration: TypeScriptServiceConfiguration) { + return apiVersion.gte(API.v222) && + configuration.tsServerLogLevel !== TsServerLogLevel.Off; + } + + private static getTsLocale(configuration: TypeScriptServiceConfiguration): string { + return configuration.locale + ? configuration.locale + : vscode.env.language; + } +} + +class ChildServerProcess implements TsServerProcess { + + public constructor( + private readonly _process: child_process.ChildProcess, + ) { } + + get stdout(): stream.Readable { return this._process.stdout!; } + + write(serverRequest: Proto.Request): void { + this._process.stdin!.write(JSON.stringify(serverRequest) + '\r\n', 'utf8'); + } + + on(name: 'exit', handler: (code: number | null) => void): void; + on(name: 'error', handler: (error: Error) => void): void; + on(name: any, handler: any) { + this._process.on(name, handler); + } + + kill(): void { + this._process.kill(); + } +} \ No newline at end of file diff --git a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts index b11259f22ea..2571d395a5f 100644 --- a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts +++ b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts @@ -24,6 +24,7 @@ import { PluginManager } from './utils/plugins'; import * as typeConverters from './utils/typeConverters'; import TypingsStatus, { AtaProgressReporter } from './utils/typingsStatus'; import VersionStatus from './utils/versionStatus'; +import { flatten } from './utils/arrays'; // Style check diagnostics that can be reported as warnings const styleCheckDiagnostics = [ @@ -68,7 +69,7 @@ export default class TypeScriptServiceClientHost extends Disposable { configFileWatcher.onDidDelete(handleProjectCreateOrDelete, this, this._disposables); configFileWatcher.onDidChange(handleProjectChange, this, this._disposables); - const allModeIds = this.getAllModeIds(descriptions); + const allModeIds = this.getAllModeIds(descriptions, pluginManager); this.client = this._register(new TypeScriptServiceClient( workspaceState, version => this.versionStatus.onDidChangeTypeScriptVersion(version), @@ -138,11 +139,11 @@ export default class TypeScriptServiceClientHost extends Disposable { this.configurationChanged(); } - private getAllModeIds(descriptions: LanguageDescription[]) { - const allModeIds: string[] = []; - for (const description of descriptions) { - allModeIds.push(...description.modeIds); - } + private getAllModeIds(descriptions: LanguageDescription[], pluginManager: PluginManager) { + const allModeIds = flatten([ + ...descriptions.map(x => x.modeIds), + ...pluginManager.plugins.map(x => x.languages) + ]); return allModeIds; } diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index 1156b79d268..ba396ad2fd2 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -26,7 +26,7 @@ export namespace ServerResponse { export type Response = T | Cancelled | typeof NoContent; } -export interface TypeScriptRequestTypes { +interface StandardTsServerRequests { 'applyCodeActionCommand': [Proto.ApplyCodeActionCommandRequestArgs, Proto.ApplyCodeActionCommandResponse]; 'completionEntryDetails': [Proto.CompletionDetailsRequestArgs, Proto.CompletionDetailsResponse]; 'completionInfo': [Proto.CompletionsRequestArgs, Proto.CompletionInfoResponse]; @@ -59,6 +59,26 @@ export interface TypeScriptRequestTypes { 'typeDefinition': [Proto.FileLocationRequestArgs, Proto.TypeDefinitionResponse]; } +interface NoResponseTsServerRequests { + 'open': [Proto.OpenRequestArgs, null]; + 'close': [Proto.FileRequestArgs]; + 'change': [Proto.ChangeRequestArgs, null]; + 'updateOpen': [Proto.UpdateOpenRequestArgs, null]; + 'compilerOptionsForInferredProjects': [Proto.SetCompilerOptionsForInferredProjectsArgs, null]; + 'reloadProjects': [null, null]; + 'configurePlugin': [Proto.ConfigurePluginRequest, Proto.ConfigurePluginResponse]; +} + +interface AsyncTsServerRequests { + 'geterr': [Proto.GeterrRequestArgs, Proto.Response]; +} + +export type TypeScriptRequests = StandardTsServerRequests & NoResponseTsServerRequests & AsyncTsServerRequests; + +export type ExecConfig = { + lowPriority?: boolean; +}; + export interface ITypeScriptServiceClient { /** * Convert a resource (VS Code) to a normalized path (TypeScript). @@ -100,19 +120,17 @@ export interface ITypeScriptServiceClient { readonly logger: Logger; readonly bufferSyncSupport: BufferSyncSupport; - execute( + execute( command: K, - args: TypeScriptRequestTypes[K][0], + args: StandardTsServerRequests[K][0], token: vscode.CancellationToken, - lowPriority?: boolean - ): Promise>; + config?: ExecConfig + ): Promise>; - executeWithoutWaitingForResponse(command: 'open', args: Proto.OpenRequestArgs): void; - executeWithoutWaitingForResponse(command: 'close', args: Proto.FileRequestArgs): void; - executeWithoutWaitingForResponse(command: 'change', args: Proto.ChangeRequestArgs): void; - executeWithoutWaitingForResponse(command: 'updateOpen', args: Proto.UpdateOpenRequestArgs): void; - executeWithoutWaitingForResponse(command: 'compilerOptionsForInferredProjects', args: Proto.SetCompilerOptionsForInferredProjectsArgs): void; - executeWithoutWaitingForResponse(command: 'reloadProjects', args: null): void; + executeWithoutWaitingForResponse( + command: K, + args: NoResponseTsServerRequests[K][0] + ): void; executeAsync(command: 'geterr', args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise>; diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index b478e9ed080..996478d6c22 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -10,8 +10,8 @@ import * as nls from 'vscode-nls'; import BufferSyncSupport from './features/bufferSyncSupport'; import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics'; import * as Proto from './protocol'; -import { TypeScriptServer, TypeScriptServerSpawner } from './tsServer/server'; -import { ITypeScriptServiceClient, ServerResponse } from './typescriptService'; +import { ITypeScriptServer } from './tsServer/server'; +import { ITypeScriptServiceClient, ServerResponse, TypeScriptRequests, ExecConfig } from './typescriptService'; import API from './utils/api'; import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration'; import { Disposable } from './utils/dispose'; @@ -25,6 +25,7 @@ import Tracer from './utils/tracer'; import { inferredProjectConfig } from './utils/tsconfig'; import { TypeScriptVersionPicker } from './utils/versionPicker'; import { TypeScriptVersion, TypeScriptVersionProvider } from './utils/versionProvider'; +import { TypeScriptServerSpawner } from './tsServer/spawner'; const localize = nls.loadMessageBundle(); @@ -46,7 +47,7 @@ namespace ServerState { export class Running { readonly type = Type.Running; constructor( - public readonly server: TypeScriptServer, + public readonly server: ITypeScriptServer, /** * API version obtained from the version picker after checking the corresponding path exists. @@ -284,7 +285,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType currentVersion = this.versionPicker.currentVersion; } - const apiVersion = this.versionPicker.currentVersion.version || API.defaultVersion; + const apiVersion = this.versionPicker.currentVersion.apiVersion || API.defaultVersion; this.onDidChangeTypeScriptVersion(currentVersion); let mytoken = ++this.token; @@ -352,7 +353,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType handle.onEvent(event => this.dispatchEvent(event)); this._onReady!.resolve(); - this._onTsServerStarted.fire(currentVersion.version); + this._onTsServerStarted.fire(currentVersion.apiVersion); if (apiVersion.gte(API.v300)) { this.loadingIndicator.startedLoadingProject(undefined /* projectName */); @@ -606,16 +607,16 @@ export default class TypeScriptServiceClient extends Disposable implements IType return undefined; } - public execute(command: string, args: any, token: vscode.CancellationToken, lowPriority?: boolean): Promise> { + public execute(command: keyof TypeScriptRequests, args: any, token: vscode.CancellationToken, config?: ExecConfig): Promise> { return this.executeImpl(command, args, { isAsync: false, token, expectsResult: true, - lowPriority + lowPriority: config ? config.lowPriority : undefined }); } - public executeWithoutWaitingForResponse(command: string, args: any): void { + public executeWithoutWaitingForResponse(command: keyof TypeScriptRequests, args: any): void { this.executeImpl(command, args, { isAsync: false, token: undefined, @@ -623,7 +624,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType }); } - public executeAsync(command: string, args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise> { + public executeAsync(command: keyof TypeScriptRequests, args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise> { return this.executeImpl(command, args, { isAsync: true, token, @@ -631,9 +632,9 @@ export default class TypeScriptServiceClient extends Disposable implements IType }); } - private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; - private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; - private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { + private executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; + private executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; + private executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { this.bufferSyncSupport.beforeCommand(command); const runningServerState = this.service(); return runningServerState.server.executeImpl(command, args, executeInfo); @@ -768,7 +769,6 @@ export default class TypeScriptServiceClient extends Disposable implements IType this.logTelemetry(telemetryData.telemetryEventName, properties); } - private configurePlugin(pluginName: string, configuration: {}): any { if (this.apiVersion.gte(API.v314)) { this.executeWithoutWaitingForResponse('configurePlugin', { pluginName, configuration }); diff --git a/extensions/typescript-language-features/src/utils/configuration.ts b/extensions/typescript-language-features/src/utils/configuration.ts index 3babc53c91b..f0e602e810a 100644 --- a/extensions/typescript-language-features/src/utils/configuration.ts +++ b/extensions/typescript-language-features/src/utils/configuration.ts @@ -54,6 +54,7 @@ export class TypeScriptServiceConfiguration { public readonly checkJs: boolean; public readonly experimentalDecorators: boolean; public readonly disableAutomaticTypeAcquisition: boolean; + public readonly useSeparateSyntaxServer: boolean; public static loadFromWorkspace(): TypeScriptServiceConfiguration { return new TypeScriptServiceConfiguration(); @@ -71,6 +72,7 @@ export class TypeScriptServiceConfiguration { this.checkJs = TypeScriptServiceConfiguration.readCheckJs(configuration); this.experimentalDecorators = TypeScriptServiceConfiguration.readExperimentalDecorators(configuration); this.disableAutomaticTypeAcquisition = TypeScriptServiceConfiguration.readDisableAutomaticTypeAcquisition(configuration); + this.useSeparateSyntaxServer = TypeScriptServiceConfiguration.readUseSeparateSyntaxServer(configuration); } public isEqualTo(other: TypeScriptServiceConfiguration): boolean { @@ -82,7 +84,8 @@ export class TypeScriptServiceConfiguration { && this.checkJs === other.checkJs && this.experimentalDecorators === other.experimentalDecorators && this.disableAutomaticTypeAcquisition === other.disableAutomaticTypeAcquisition - && arrays.equals(this.tsServerPluginPaths, other.tsServerPluginPaths); + && arrays.equals(this.tsServerPluginPaths, other.tsServerPluginPaths) + && this.useSeparateSyntaxServer === other.useSeparateSyntaxServer; } private static fixPathPrefixes(inspectValue: string): string { @@ -139,4 +142,8 @@ export class TypeScriptServiceConfiguration { private static extractLocale(configuration: vscode.WorkspaceConfiguration): string | null { return configuration.get('typescript.locale', null); } + + private static readUseSeparateSyntaxServer(configuration: vscode.WorkspaceConfiguration): boolean { + return configuration.get('typescript.tsserver.useSeparateSyntaxServer', true); + } } diff --git a/extensions/typescript-language-features/src/utils/electron.ts b/extensions/typescript-language-features/src/utils/electron.ts index 3a1ece8f726..ea16bae4277 100644 --- a/extensions/typescript-language-features/src/utils/electron.ts +++ b/extensions/typescript-language-features/src/utils/electron.ts @@ -7,13 +7,14 @@ import * as temp from './temp'; import path = require('path'); import fs = require('fs'); import cp = require('child_process'); +import process = require('process'); const getRootTempDir = (() => { let dir: string | undefined; return () => { if (!dir) { - dir = temp.getTempFile(`vscode-typescript`); + dir = temp.getTempFile(`vscode-typescript${process.platform !== 'win32' && process.getuid ? process.getuid() : ''}`); } if (!fs.existsSync(dir)) { fs.mkdirSync(dir); diff --git a/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts b/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts index 547660f0649..de6d03cd980 100644 --- a/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts +++ b/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts @@ -9,7 +9,6 @@ import { RelativeWorkspacePathResolver } from './relativePathResolver'; export class TypeScriptPluginPathsProvider { - public readonly relativePathResolver: RelativeWorkspacePathResolver = new RelativeWorkspacePathResolver(); public constructor( private configuration: TypeScriptServiceConfiguration @@ -32,7 +31,7 @@ export class TypeScriptPluginPathsProvider { return [pluginPath]; } - const workspacePath = this.relativePathResolver.asAbsoluteWorkspacePath(pluginPath); + const workspacePath = RelativeWorkspacePathResolver.asAbsoluteWorkspacePath(pluginPath); if (workspacePath !== undefined) { return [workspacePath]; } diff --git a/extensions/typescript-language-features/src/utils/projectStatus.ts b/extensions/typescript-language-features/src/utils/projectStatus.ts index 4eb9b8c7686..15aa72a80d0 100644 --- a/extensions/typescript-language-features/src/utils/projectStatus.ts +++ b/extensions/typescript-language-features/src/utils/projectStatus.ts @@ -23,7 +23,12 @@ class ExcludeHintItem { constructor( private readonly telemetryReporter: TelemetryReporter ) { - this._item = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 98 /* to the right of typescript version status (99) */); + this._item = vscode.window.createStatusBarItem({ + id: 'status.typescript.exclude', + name: localize('statusExclude', "TypeScript: Configure Excludes"), + alignment: vscode.StatusBarAlignment.Right, + priority: 98 /* to the right of typescript version status (99) */ + }); this._item.command = 'js.projectStatus.command'; } diff --git a/extensions/typescript-language-features/src/utils/relativePathResolver.ts b/extensions/typescript-language-features/src/utils/relativePathResolver.ts index 85b72a55d6b..64dff66fb53 100644 --- a/extensions/typescript-language-features/src/utils/relativePathResolver.ts +++ b/extensions/typescript-language-features/src/utils/relativePathResolver.ts @@ -6,7 +6,7 @@ import * as path from 'path'; import * as vscode from 'vscode'; export class RelativeWorkspacePathResolver { - public asAbsoluteWorkspacePath(relativePath: string): string | undefined { + public static asAbsoluteWorkspacePath(relativePath: string): string | undefined { for (const root of vscode.workspace.workspaceFolders || []) { const rootPrefixes = [`./${root.name}/`, `${root.name}/`, `.\\${root.name}\\`, `${root.name}\\`]; for (const rootPrefix of rootPrefixes) { diff --git a/extensions/typescript-language-features/src/utils/tracer.ts b/extensions/typescript-language-features/src/utils/tracer.ts index c80254c79a0..f7ca0d674e3 100644 --- a/extensions/typescript-language-features/src/utils/tracer.ts +++ b/extensions/typescript-language-features/src/utils/tracer.ts @@ -50,7 +50,7 @@ export default class Tracer { return result; } - public traceRequest(request: Proto.Request, responseExpected: boolean, queueLength: number): void { + public traceRequest(serverId: string, request: Proto.Request, responseExpected: boolean, queueLength: number): void { if (this.trace === Trace.Off) { return; } @@ -58,10 +58,10 @@ export default class Tracer { if (this.trace === Trace.Verbose && request.arguments) { data = `Arguments: ${JSON.stringify(request.arguments, null, 4)}`; } - this.logTrace(`Sending request: ${request.command} (${request.seq}). Response expected: ${responseExpected ? 'yes' : 'no'}. Current queue length: ${queueLength}`, data); + this.logTrace(serverId, `Sending request: ${request.command} (${request.seq}). Response expected: ${responseExpected ? 'yes' : 'no'}. Current queue length: ${queueLength}`, data); } - public traceResponse(response: Proto.Response, startTime: number): void { + public traceResponse(serverId: string, response: Proto.Response, startTime: number): void { if (this.trace === Trace.Off) { return; } @@ -69,17 +69,17 @@ export default class Tracer { if (this.trace === Trace.Verbose && response.body) { data = `Result: ${JSON.stringify(response.body, null, 4)}`; } - this.logTrace(`Response received: ${response.command} (${response.request_seq}). Request took ${Date.now() - startTime} ms. Success: ${response.success} ${!response.success ? '. Message: ' + response.message : ''}`, data); + this.logTrace(serverId, `Response received: ${response.command} (${response.request_seq}). Request took ${Date.now() - startTime} ms. Success: ${response.success} ${!response.success ? '. Message: ' + response.message : ''}`, data); } - public traceRequestCompleted(command: string, request_seq: number, startTime: number): any { + public traceRequestCompleted(serverId: string, command: string, request_seq: number, startTime: number): any { if (this.trace === Trace.Off) { return; } - this.logTrace(`Async response received: ${command} (${request_seq}). Request took ${Date.now() - startTime} ms.`); + this.logTrace(serverId, `Async response received: ${command} (${request_seq}). Request took ${Date.now() - startTime} ms.`); } - public traceEvent(event: Proto.Event): void { + public traceEvent(serverId: string, event: Proto.Event): void { if (this.trace === Trace.Off) { return; } @@ -87,12 +87,12 @@ export default class Tracer { if (this.trace === Trace.Verbose && event.body) { data = `Data: ${JSON.stringify(event.body, null, 4)}`; } - this.logTrace(`Event received: ${event.event} (${event.seq}).`, data); + this.logTrace(serverId, `Event received: ${event.event} (${event.seq}).`, data); } - public logTrace(message: string, data?: any): void { + public logTrace(serverId: string, message: string, data?: any): void { if (this.trace !== Trace.Off) { - this.logger.logLevel('Trace', message, data); + this.logger.logLevel('Trace', `<${serverId}> ${message}`, data); } } } \ No newline at end of file diff --git a/extensions/typescript-language-features/src/utils/typeConverters.ts b/extensions/typescript-language-features/src/utils/typeConverters.ts index eaa6a96c860..37947b38810 100644 --- a/extensions/typescript-language-features/src/utils/typeConverters.ts +++ b/extensions/typescript-language-features/src/utils/typeConverters.ts @@ -13,9 +13,12 @@ import { ITypeScriptServiceClient } from '../typescriptService'; export namespace Range { export const fromTextSpan = (span: Proto.TextSpan): vscode.Range => + fromLocations(span.start, span.end); + + export const fromLocations = (start: Proto.Location, end: Proto.Location): vscode.Range => new vscode.Range( - Math.max(0, span.start.line - 1), Math.max(span.start.offset - 1, 0), - Math.max(0, span.end.line - 1), Math.max(0, span.end.offset - 1)); + Math.max(0, start.line - 1), Math.max(start.offset - 1, 0), + Math.max(0, end.line - 1), Math.max(0, end.offset - 1)); export const toFileRangeRequestArgs = (file: string, range: vscode.Range): Proto.FileRangeRequestArgs => ({ file, diff --git a/extensions/typescript-language-features/src/utils/versionPicker.ts b/extensions/typescript-language-features/src/utils/versionPicker.ts index afbda6ef206..d1827002ee3 100644 --- a/extensions/typescript-language-features/src/utils/versionPicker.ts +++ b/extensions/typescript-language-features/src/utils/versionPicker.ts @@ -113,7 +113,7 @@ export class TypeScriptVersionPicker { return { oldVersion: previousVersion, newVersion: shippedVersion }; case MessageAction.learnMore: - vscode.commands.executeCommand('vscode.open', vscode.Uri.parse('https://go.microsoft.com/fwlink/?linkid=839919')); + vscode.env.openExternal(vscode.Uri.parse('https://go.microsoft.com/fwlink/?linkid=839919')); return { oldVersion: this.currentVersion }; default: diff --git a/extensions/typescript-language-features/src/utils/versionProvider.ts b/extensions/typescript-language-features/src/utils/versionProvider.ts index b9cfc16d31d..8e9e9a2a8c6 100644 --- a/extensions/typescript-language-features/src/utils/versionProvider.ts +++ b/extensions/typescript-language-features/src/utils/versionProvider.ts @@ -27,10 +27,10 @@ export class TypeScriptVersion { } public get isValid(): boolean { - return this.version !== undefined; + return this.apiVersion !== undefined; } - public get version(): API | undefined { + public get apiVersion(): API | undefined { const version = this.getTypeScriptVersion(this.tsServerPath); if (version) { return version; @@ -46,7 +46,7 @@ export class TypeScriptVersion { } public get versionString(): string { - const version = this.version; + const version = this.apiVersion; return version ? version.versionString : localize( 'couldNotLoadTsVersion', 'Could not load the TypeScript version at this path'); } @@ -88,7 +88,6 @@ export class TypeScriptVersion { } export class TypeScriptVersionProvider { - private readonly relativePathResolver: RelativeWorkspacePathResolver = new RelativeWorkspacePathResolver(); public constructor( private configuration: TypeScriptServiceConfiguration @@ -155,11 +154,13 @@ export class TypeScriptVersionProvider { private getContributedVersion(extensionId: string, pathToTs: readonly string[]): TypeScriptVersion | undefined { try { - const { extensionPath } = vscode.extensions.getExtension(extensionId)!; - const typescriptPath = path.join(extensionPath, ...pathToTs, 'typescript', 'lib'); - const bundledVersion = new TypeScriptVersion(typescriptPath, ''); - if (bundledVersion.isValid) { - return bundledVersion; + const extension = vscode.extensions.getExtension(extensionId); + if (extension) { + const typescriptPath = path.join(extension.extensionPath, ...pathToTs, 'typescript', 'lib'); + const bundledVersion = new TypeScriptVersion(typescriptPath, ''); + if (bundledVersion.isValid) { + return bundledVersion; + } } } catch { // noop @@ -177,7 +178,7 @@ export class TypeScriptVersionProvider { return [new TypeScriptVersion(tsdkPathSetting)]; } - const workspacePath = this.relativePathResolver.asAbsoluteWorkspacePath(tsdkPathSetting); + const workspacePath = RelativeWorkspacePathResolver.asAbsoluteWorkspacePath(tsdkPathSetting); if (workspacePath !== undefined) { return [new TypeScriptVersion(workspacePath, tsdkPathSetting)]; } diff --git a/extensions/typescript-language-features/src/utils/versionStatus.ts b/extensions/typescript-language-features/src/utils/versionStatus.ts index 0b3e3412617..07bd2e5921a 100644 --- a/extensions/typescript-language-features/src/utils/versionStatus.ts +++ b/extensions/typescript-language-features/src/utils/versionStatus.ts @@ -7,6 +7,9 @@ import * as vscode from 'vscode'; import * as languageModeIds from './languageModeIds'; import { TypeScriptVersion } from './versionProvider'; import { Disposable } from './dispose'; +import * as nls from 'vscode-nls'; + +const localize = nls.loadMessageBundle(); export default class VersionStatus extends Disposable { private readonly _versionBarEntry: vscode.StatusBarItem; @@ -15,7 +18,12 @@ export default class VersionStatus extends Disposable { private readonly _normalizePath: (resource: vscode.Uri) => string | undefined ) { super(); - this._versionBarEntry = this._register(vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 99 /* to the right of editor status (100) */)); + this._versionBarEntry = this._register(vscode.window.createStatusBarItem({ + id: 'status.typescript.version', + name: localize('typescriptVersion', "TypeScript: Version"), + alignment: vscode.StatusBarAlignment.Right, + priority: 99 /* to the right of editor status (100) */ + })); vscode.window.onDidChangeActiveTextEditor(this.showHideStatus, this, this._disposables); } diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/env.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/env.test.ts index 31d6d4ce312..112c76139b7 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/env.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/env.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { env } from 'vscode'; +import { env, extensions, ExtensionKind } from 'vscode'; suite('env-namespace', () => { @@ -14,6 +14,7 @@ suite('env-namespace', () => { assert.equal(typeof env.appName, 'string'); assert.equal(typeof env.machineId, 'string'); assert.equal(typeof env.sessionId, 'string'); + assert.equal(typeof env.shell, 'string'); }); test('env is readonly', function () { @@ -22,6 +23,25 @@ suite('env-namespace', () => { assert.throws(() => (env as any).appName = '234'); assert.throws(() => (env as any).machineId = '234'); assert.throws(() => (env as any).sessionId = '234'); + assert.throws(() => (env as any).shell = '234'); + }); + + test('env.remoteName', function () { + const remoteName = env.remoteName; + const apiTestExtension = extensions.getExtension('vscode.vscode-api-tests'); + const testResolverExtension = extensions.getExtension('vscode.vscode-test-resolver'); + if (typeof remoteName === 'undefined') { + assert.ok(apiTestExtension); + assert.ok(testResolverExtension); + assert.equal(ExtensionKind.UI, apiTestExtension!.extensionKind); + assert.equal(ExtensionKind.UI, testResolverExtension!.extensionKind); + } else if (typeof remoteName === 'string') { + assert.ok(apiTestExtension); + assert.ok(!testResolverExtension); // we currently can only access extensions that run on same host + assert.equal(ExtensionKind.Workspace, apiTestExtension!.extensionKind); + } else { + assert.fail(); + } }); }); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts new file mode 100644 index 00000000000..ad07fc997ad --- /dev/null +++ b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts @@ -0,0 +1,344 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { window, Terminal, TerminalVirtualProcess, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget } from 'vscode'; +import { doesNotThrow, equal, ok } from 'assert'; + +suite('window namespace tests', () => { + suiteSetup(async () => { + // Disable conpty in integration tests because of https://github.com/microsoft/vscode/issues/76548 + await workspace.getConfiguration('terminal.integrated').update('windowsEnableConpty', false, ConfigurationTarget.Global); + }); + suite('Terminal', () => { + test('sendText immediately after createTerminal should not throw', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(terminal, term); + terminal.dispose(); + reg1.dispose(); + const reg2 = window.onDidCloseTerminal(() => { + reg2.dispose(); + done(); + }); + }); + const terminal = window.createTerminal(); + doesNotThrow(terminal.sendText.bind(terminal, 'echo "foo"')); + }); + + test('onDidCloseTerminal event fires when terminal is disposed', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(terminal, term); + terminal.dispose(); + reg1.dispose(); + const reg2 = window.onDidCloseTerminal(() => { + reg2.dispose(); + done(); + }); + }); + const terminal = window.createTerminal(); + }); + + test('processId immediately after createTerminal should fetch the pid', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(terminal, term); + reg1.dispose(); + terminal.processId.then(id => { + ok(id > 0); + terminal.dispose(); + const reg2 = window.onDidCloseTerminal(() => { + reg2.dispose(); + done(); + }); + }); + }); + const terminal = window.createTerminal(); + }); + + test('name in constructor should set terminal.name', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(terminal, term); + terminal.dispose(); + reg1.dispose(); + const reg2 = window.onDidCloseTerminal(() => { + reg2.dispose(); + done(); + }); + }); + const terminal = window.createTerminal('a'); + equal(terminal.name, 'a'); + }); + + test('onDidOpenTerminal should fire when a terminal is created', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(term.name, 'b'); + reg1.dispose(); + const reg2 = window.onDidCloseTerminal(() => { + reg2.dispose(); + done(); + }); + terminal.dispose(); + }); + const terminal = window.createTerminal('b'); + }); + + test('Terminal.sendText should fire Terminal.onInput', (done) => { + const reg1 = window.onDidOpenTerminal(terminal => { + reg1.dispose(); + const reg2 = renderer.onDidAcceptInput(data => { + equal(data, 'bar'); + reg2.dispose(); + const reg3 = window.onDidCloseTerminal(() => { + reg3.dispose(); + done(); + }); + terminal.dispose(); + }); + terminal.sendText('bar', false); + }); + const renderer = window.createTerminalRenderer('foo'); + }); + + // test('onDidChangeActiveTerminal should fire when new terminals are created', (done) => { + // const reg1 = window.onDidChangeActiveTerminal((active: Terminal | undefined) => { + // equal(active, terminal); + // equal(active, window.activeTerminal); + // reg1.dispose(); + // const reg2 = window.onDidChangeActiveTerminal((active: Terminal | undefined) => { + // equal(active, undefined); + // equal(active, window.activeTerminal); + // reg2.dispose(); + // done(); + // }); + // terminal.dispose(); + // }); + // const terminal = window.createTerminal(); + // terminal.show(); + // }); + + // test('onDidChangeTerminalDimensions should fire when new terminals are created', (done) => { + // const reg1 = window.onDidChangeTerminalDimensions(async (event: TerminalDimensionsChangeEvent) => { + // equal(event.terminal, terminal1); + // equal(typeof event.dimensions.columns, 'number'); + // equal(typeof event.dimensions.rows, 'number'); + // ok(event.dimensions.columns > 0); + // ok(event.dimensions.rows > 0); + // reg1.dispose(); + // let terminal2: Terminal; + // const reg2 = window.onDidOpenTerminal((newTerminal) => { + // // This is guarantees to fire before dimensions change event + // if (newTerminal !== terminal1) { + // terminal2 = newTerminal; + // reg2.dispose(); + // } + // }); + // let firstCalled = false; + // let secondCalled = false; + // const reg3 = window.onDidChangeTerminalDimensions((event: TerminalDimensionsChangeEvent) => { + // if (event.terminal === terminal1) { + // // The original terminal should fire dimension change after a split + // firstCalled = true; + // } else if (event.terminal !== terminal1) { + // // The new split terminal should fire dimension change + // secondCalled = true; + // } + // if (firstCalled && secondCalled) { + // let firstDisposed = false; + // let secondDisposed = false; + // const reg4 = window.onDidCloseTerminal(term => { + // if (term === terminal1) { + // firstDisposed = true; + // } + // if (term === terminal2) { + // secondDisposed = true; + // } + // if (firstDisposed && secondDisposed) { + // reg4.dispose(); + // done(); + // } + // }); + // terminal1.dispose(); + // terminal2.dispose(); + // reg3.dispose(); + // } + // }); + // await timeout(500); + // commands.executeCommand('workbench.action.terminal.split'); + // }); + // const terminal1 = window.createTerminal({ name: 'test' }); + // terminal1.show(); + // }); + + suite('hideFromUser', () => { + // test('should fire onDidWriteData correctly', done => { + // const terminal = window.createTerminal({ name: 'bg', hideFromUser: true }); + // let data = ''; + // terminal.onDidWriteData(e => { + // data += e; + // if (data.indexOf('foo') !== -1) { + // const reg3 = window.onDidCloseTerminal(() => { + // reg3.dispose(); + // done(); + // }); + // terminal.dispose(); + // } + // }); + // terminal.sendText('foo'); + // }); + + test('should be available to terminals API', done => { + const terminal = window.createTerminal({ name: 'bg', hideFromUser: true }); + window.onDidOpenTerminal(t => { + equal(t, terminal); + equal(t.name, 'bg'); + ok(window.terminals.indexOf(terminal) !== -1); + const reg3 = window.onDidCloseTerminal(() => { + reg3.dispose(); + done(); + }); + terminal.dispose(); + }); + }); + }); + + suite('Terminal renderers (deprecated)', () => { + test('should fire onDidOpenTerminal and onDidCloseTerminal from createTerminalRenderer terminal', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(term.name, 'c'); + reg1.dispose(); + const reg2 = window.onDidCloseTerminal(() => { + reg2.dispose(); + done(); + }); + term.dispose(); + }); + window.createTerminalRenderer('c'); + }); + + test('should get maximum dimensions set when shown', (done) => { + let terminal: Terminal; + const reg1 = window.onDidOpenTerminal(term => { + reg1.dispose(); + term.show(); + terminal = term; + }); + const renderer = window.createTerminalRenderer('foo'); + const reg2 = renderer.onDidChangeMaximumDimensions(dimensions => { + ok(dimensions.columns > 0); + ok(dimensions.rows > 0); + reg2.dispose(); + const reg3 = window.onDidCloseTerminal(() => { + reg3.dispose(); + done(); + }); + terminal.dispose(); + }); + }); + + test('should fire Terminal.onData on write', (done) => { + const reg1 = window.onDidOpenTerminal(terminal => { + reg1.dispose(); + const reg2 = terminal.onDidWriteData(data => { + equal(data, 'bar'); + reg2.dispose(); + const reg3 = window.onDidCloseTerminal(() => { + reg3.dispose(); + done(); + }); + terminal.dispose(); + }); + renderer.write('bar'); + }); + const renderer = window.createTerminalRenderer('foo'); + }); + }); + + suite('Virtual process terminals', () => { + test('should fire onDidOpenTerminal and onDidCloseTerminal', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(term.name, 'c'); + reg1.dispose(); + const reg2 = window.onDidCloseTerminal(() => { + reg2.dispose(); + done(); + }); + term.dispose(); + }); + const virtualProcess: TerminalVirtualProcess = { + onDidWrite: new EventEmitter().event + }; + window.createTerminal({ name: 'c', virtualProcess }); + }); + + test('should get dimensions event when shown', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + reg1.dispose(); + equal(terminal, term); + term.show(); + }); + const virtualProcess: TerminalVirtualProcess = { + onDidWrite: new EventEmitter().event, + setDimensions: dimensions => { + ok(dimensions.columns > 0); + ok(dimensions.rows > 0); + const reg2 = window.onDidCloseTerminal(() => { + reg2.dispose(); + done(); + }); + terminal.dispose(); + } + }; + const terminal = window.createTerminal({ name: 'foo', virtualProcess }); + }); + + test('should fire Terminal.onData on write', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(terminal, term); + reg1.dispose(); + const reg2 = terminal.onDidWriteData(data => { + equal(data, 'bar'); + reg2.dispose(); + const reg3 = window.onDidCloseTerminal(() => { + reg3.dispose(); + done(); + }); + terminal.dispose(); + }); + writeEmitter.fire('bar'); + }); + const writeEmitter = new EventEmitter(); + const virtualProcess: TerminalVirtualProcess = { + onDidWrite: writeEmitter.event + }; + const terminal = window.createTerminal({ name: 'foo', virtualProcess }); + }); + + test('should respect dimension overrides', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(terminal, term); + reg1.dispose(); + term.show(); + const reg2 = window.onDidChangeTerminalDimensions(e => { + equal(e.dimensions.columns, 10); + equal(e.dimensions.rows, 5); + equal(e.terminal, terminal); + reg2.dispose(); + const reg3 = window.onDidCloseTerminal(() => { + reg3.dispose(); + done(); + }); + terminal.dispose(); + }); + overrideDimensionsEmitter.fire({ columns: 10, rows: 5 }); + }); + const writeEmitter = new EventEmitter(); + const overrideDimensionsEmitter = new EventEmitter(); + const virtualProcess: TerminalVirtualProcess = { + onDidWrite: writeEmitter.event, + onDidOverrideDimensions: overrideDimensionsEmitter.event + }; + const terminal = window.createTerminal({ name: 'foo', virtualProcess }); + }); + }); + }); +}); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts index 3cc1cb3863b..4be0218ab64 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts @@ -251,15 +251,18 @@ suite('Webview tests', () => { }); `); - const workspaceRootUri = vscode.Uri.file(vscode.workspace.rootPath!).with({ scheme: 'vscode-resource' }); + async function toWebviewResource(path: string) { + const root = await webview.webview.toWebviewResource(vscode.Uri.file(vscode.workspace.rootPath!)); + return root.toString() + path; + } { - const imagePath = workspaceRootUri.toString() + '/image.png'; + const imagePath = await toWebviewResource('/image.png'); const response = sendRecieveMessage(webview, { src: imagePath }); assert.strictEqual((await response).value, true); } { - const imagePath = workspaceRootUri.toString() + '/no-such-image.png'; + const imagePath = await toWebviewResource('/no-such-image.png'); const response = sendRecieveMessage(webview, { src: imagePath }); assert.strictEqual((await response).value, false); } diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts index 4218162c24d..c2ec4f13681 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { workspace, window, commands, ViewColumn, TextEditorViewColumnChangeEvent, Uri, Selection, Position, CancellationTokenSource, TextEditorSelectionChangeKind, Terminal, TerminalDimensionsChangeEvent } from 'vscode'; +import { workspace, window, commands, ViewColumn, TextEditorViewColumnChangeEvent, Uri, Selection, Position, CancellationTokenSource, TextEditorSelectionChangeKind } from 'vscode'; import { join } from 'path'; import { closeAllEditors, pathEquals, createRandomFile } from '../utils'; @@ -568,201 +568,4 @@ suite('window namespace tests', () => { }); }); - - suite('Terminal', () => { - test('sendText immediately after createTerminal should not throw', () => { - const terminal = window.createTerminal(); - assert.doesNotThrow(terminal.sendText.bind(terminal, 'echo "foo"')); - terminal.dispose(); - }); - - test('onDidCloseTerminal event fires when terminal is disposed', (done) => { - const terminal = window.createTerminal(); - const reg = window.onDidCloseTerminal((eventTerminal) => { - assert.equal(terminal, eventTerminal); - reg.dispose(); - done(); - }); - terminal.dispose(); - }); - - test('processId immediately after createTerminal should fetch the pid', (done) => { - const terminal = window.createTerminal(); - terminal.processId.then(id => { - assert.ok(id > 0); - terminal.dispose(); - done(); - }); - }); - - test('name in constructor should set terminal.name', () => { - const terminal = window.createTerminal('a'); - assert.equal(terminal.name, 'a'); - terminal.dispose(); - }); - - test('onDidOpenTerminal should fire when a terminal is created', (done) => { - const reg1 = window.onDidOpenTerminal(term => { - assert.equal(term.name, 'b'); - reg1.dispose(); - const reg2 = window.onDidCloseTerminal(() => { - reg2.dispose(); - done(); - }); - terminal.dispose(); - }); - const terminal = window.createTerminal('b'); - }); - - test('createTerminalRenderer should fire onDidOpenTerminal and onDidCloseTerminal', (done) => { - const reg1 = window.onDidOpenTerminal(term => { - assert.equal(term.name, 'c'); - reg1.dispose(); - const reg2 = window.onDidCloseTerminal(() => { - reg2.dispose(); - done(); - }); - term.dispose(); - }); - window.createTerminalRenderer('c'); - }); - - test('terminal renderers should get maximum dimensions set when shown', (done) => { - let terminal: Terminal; - const reg1 = window.onDidOpenTerminal(term => { - reg1.dispose(); - term.show(); - terminal = term; - }); - const renderer = window.createTerminalRenderer('foo'); - const reg2 = renderer.onDidChangeMaximumDimensions(dimensions => { - assert.ok(dimensions.columns > 0); - assert.ok(dimensions.rows > 0); - reg2.dispose(); - const reg3 = window.onDidCloseTerminal(() => { - reg3.dispose(); - done(); - }); - terminal.dispose(); - }); - }); - - test('TerminalRenderer.write should fire Terminal.onData', (done) => { - const reg1 = window.onDidOpenTerminal(terminal => { - reg1.dispose(); - const reg2 = terminal.onDidWriteData(data => { - assert.equal(data, 'bar'); - reg2.dispose(); - const reg3 = window.onDidCloseTerminal(() => { - reg3.dispose(); - done(); - }); - terminal.dispose(); - }); - renderer.write('bar'); - }); - const renderer = window.createTerminalRenderer('foo'); - }); - - test('Terminal.sendText should fire Terminal.onInput', (done) => { - const reg1 = window.onDidOpenTerminal(terminal => { - reg1.dispose(); - const reg2 = renderer.onDidAcceptInput(data => { - assert.equal(data, 'bar'); - reg2.dispose(); - const reg3 = window.onDidCloseTerminal(() => { - reg3.dispose(); - done(); - }); - terminal.dispose(); - }); - terminal.sendText('bar', false); - }); - const renderer = window.createTerminalRenderer('foo'); - }); - - test('onDidChangeActiveTerminal should fire when new terminals are created', (done) => { - const reg1 = window.onDidChangeActiveTerminal((active: Terminal | undefined) => { - assert.equal(active, terminal); - assert.equal(active, window.activeTerminal); - reg1.dispose(); - const reg2 = window.onDidChangeActiveTerminal((active: Terminal | undefined) => { - assert.equal(active, undefined); - assert.equal(active, window.activeTerminal); - reg2.dispose(); - done(); - }); - terminal.dispose(); - }); - const terminal = window.createTerminal(); - terminal.show(); - }); - - test('onDidChangeTerminalDimensions should fire when new terminals are created', (done) => { - const reg1 = window.onDidChangeTerminalDimensions(async (event: TerminalDimensionsChangeEvent) => { - assert.equal(event.terminal, terminal1); - assert.equal(typeof event.dimensions.columns, 'number'); - assert.equal(typeof event.dimensions.rows, 'number'); - assert.ok(event.dimensions.columns > 0); - assert.ok(event.dimensions.rows > 0); - reg1.dispose(); - let terminal2: Terminal; - const reg2 = window.onDidOpenTerminal((newTerminal) => { - // This is guarantees to fire before dimensions change event - if (newTerminal !== terminal1) { - terminal2 = newTerminal; - reg2.dispose(); - } - }); - let firstCalled = false; - let secondCalled = false; - const reg3 = window.onDidChangeTerminalDimensions((event: TerminalDimensionsChangeEvent) => { - if (event.terminal === terminal1) { - // The original terminal should fire dimension change after a split - firstCalled = true; - } else if (event.terminal !== terminal1) { - // The new split terminal should fire dimension change - secondCalled = true; - } - if (firstCalled && secondCalled) { - terminal1.dispose(); - terminal2.dispose(); - reg3.dispose(); - done(); - } - }); - await timeout(500); - commands.executeCommand('workbench.action.terminal.split'); - }); - const terminal1 = window.createTerminal({ name: 'test' }); - terminal1.show(); - }); - - test('runInBackground terminal: onDidWriteData should work', done => { - const terminal = window.createTerminal({ name: 'bg', runInBackground: true }); - let data = ''; - terminal.onDidWriteData(e => { - data += e; - if (data.indexOf('foo') !== -1) { - terminal.dispose(); - done(); - } - }); - terminal.sendText('foo'); - }); - - test('runInBackground terminal: should be available to terminals API', done => { - const terminal = window.createTerminal({ name: 'bg', runInBackground: true }); - window.onDidOpenTerminal(t => { - assert.equal(t, terminal); - assert.equal(t.name, 'bg'); - assert.ok(window.terminals.indexOf(terminal) !== -1); - done(); - }); - }); - }); }); - -async function timeout(ms = 0): Promise { - return new Promise(resolve => setTimeout(() => resolve(), ms)); -} \ No newline at end of file diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts new file mode 100644 index 00000000000..06728e206d9 --- /dev/null +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts @@ -0,0 +1,141 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import * as vscode from 'vscode'; +import { posix } from 'path'; + +suite('workspace-fs', () => { + + let root: vscode.Uri; + + suiteSetup(function () { + root = vscode.workspace.workspaceFolders![0]!.uri; + }); + + test('fs.stat', async function () { + const stat = await vscode.workspace.fs.stat(root); + assert.equal(stat.type, vscode.FileType.Directory); + + assert.equal(typeof stat.size, 'number'); + assert.equal(typeof stat.mtime, 'number'); + assert.equal(typeof stat.ctime, 'number'); + + + const entries = await vscode.workspace.fs.readDirectory(root); + assert.ok(entries.length > 0); + + // find far.js + const tuple = entries.find(tuple => tuple[0] === 'far.js')!; + assert.ok(tuple); + assert.equal(tuple[0], 'far.js'); + assert.equal(tuple[1], vscode.FileType.File); + }); + + test('fs.stat - bad scheme', async function () { + try { + await vscode.workspace.fs.stat(vscode.Uri.parse('foo:/bar/baz/test.txt')); + assert.ok(false); + } catch { + assert.ok(true); + } + }); + + test('fs.stat - missing file', async function () { + try { + await vscode.workspace.fs.stat(root.with({ path: root.path + '.bad' })); + assert.ok(false); + } catch (e) { + assert.ok(true); + } + }); + + test('fs.write/stat/delete', async function () { + + const uri = root.with({ path: posix.join(root.path, 'new.file') }); + await vscode.workspace.fs.writeFile(uri, Buffer.from('HELLO')); + + const stat = await vscode.workspace.fs.stat(uri); + assert.equal(stat.type, vscode.FileType.File); + + await vscode.workspace.fs.delete(uri); + + try { + await vscode.workspace.fs.stat(uri); + assert.ok(false); + } catch { + assert.ok(true); + } + }); + + test('fs.delete folder', async function () { + + const folder = root.with({ path: posix.join(root.path, 'folder') }); + const file = root.with({ path: posix.join(root.path, 'folder/file') }); + + await vscode.workspace.fs.createDirectory(folder); + await vscode.workspace.fs.writeFile(file, Buffer.from('FOO')); + + await vscode.workspace.fs.stat(folder); + await vscode.workspace.fs.stat(file); + + // ensure non empty folder cannot be deleted + try { + await vscode.workspace.fs.delete(folder, { recursive: false, useTrash: false }); + assert.ok(false); + } catch { + await vscode.workspace.fs.stat(folder); + await vscode.workspace.fs.stat(file); + } + + // ensure non empty folder cannot be deleted is DEFAULT + try { + await vscode.workspace.fs.delete(folder); // recursive: false as default + assert.ok(false); + } catch { + await vscode.workspace.fs.stat(folder); + await vscode.workspace.fs.stat(file); + } + + // delete non empty folder with recursive-flag + await vscode.workspace.fs.delete(folder, { recursive: true, useTrash: false }); + + // esnure folder/file are gone + try { + await vscode.workspace.fs.stat(folder); + assert.ok(false); + } catch { + assert.ok(true); + } + try { + await vscode.workspace.fs.stat(file); + assert.ok(false); + } catch { + assert.ok(true); + } + }); + + test('throws FileSystemError', async function () { + + try { + await vscode.workspace.fs.stat(vscode.Uri.file(`/c468bf16-acfd-4591-825e-2bcebba508a3/71b1f274-91cb-4c19-af00-8495eaab4b73/4b60cb48-a6f2-40ea-9085-0936f4a8f59a.tx6`)); + assert.ok(false); + } catch (e) { + assert.ok(e instanceof vscode.FileSystemError); + assert.equal(e.name, vscode.FileSystemError.FileNotFound().name); + } + }); + + test('throws FileSystemError', async function () { + + try { + await vscode.workspace.fs.stat(vscode.Uri.parse('foo:/bar')); + assert.ok(false); + } catch (e) { + assert.ok(e instanceof vscode.FileSystemError); + assert.equal(e.name, vscode.FileSystemError.Unavailable().name); + } + }); +}); diff --git a/extensions/vscode-test-resolver/package.json b/extensions/vscode-test-resolver/package.json index cf87ab6c73b..167df92db2d 100644 --- a/extensions/vscode-test-resolver/package.json +++ b/extensions/vscode-test-resolver/package.json @@ -43,11 +43,6 @@ "category": "Remote-TestResolver", "command": "vscode-testresolver.newWindow" }, - { - "title": "New Window with Error", - "category": "Remote-TestResolver", - "command": "vscode-testresolver.newWindowWithError" - }, { "title": "Show Log", "category": "Remote-TestResolver", @@ -61,11 +56,6 @@ "when": "!remoteAuthority", "group": "9_local_testresolver@2" }, - { - "command": "vscode-testresolver.newWindowWithError", - "when": "!remoteAuthority", - "group": "9_local_testresolver@3" - }, { "command": "vscode-testresolver.showLog", "when": "remoteAuthority =~ /^test\\+.*$/", @@ -75,13 +65,27 @@ "command": "vscode-testresolver.newWindow", "when": "remoteAuthority =~ /^test\\+.*$/", "group": "1_remote_testresolver_open@1" - }, - { - "command": "vscode-testresolver.newWindowWithError", - "when": "remoteAuthority =~ /^test\\+.*$/", - "group": "1_remote_testresolver_open@2" } ] + }, + "configuration": { + "properties": { + "testresolver.startupDelay": { + "description": "If set, the resolver will delay for the given amount of seconds. Use ths setting for testing a slow resolver", + "type": "number", + "default": 0 + }, + "testresolver.startupError": { + "description": "If set, the resolver will fail. Use ths setting for testing the failure of a resolver.", + "type": "boolean", + "default": false + }, + "testresolver.pause": { + "description": "If set, connection is paused", + "type": "boolean", + "default": false + } + } } } diff --git a/extensions/vscode-test-resolver/scripts/terminateProcess.sh b/extensions/vscode-test-resolver/scripts/terminateProcess.sh new file mode 100755 index 00000000000..908a68287fa --- /dev/null +++ b/extensions/vscode-test-resolver/scripts/terminateProcess.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +terminateTree() { + for cpid in $(/usr/bin/pgrep -P $1); do + terminateTree $cpid + done + kill -9 $1 > /dev/null 2>&1 +} + +for pid in $*; do + terminateTree $pid +done \ No newline at end of file diff --git a/extensions/vscode-test-resolver/src/extension.ts b/extensions/vscode-test-resolver/src/extension.ts index 17868c2007f..0520edcff4e 100644 --- a/extensions/vscode-test-resolver/src/extension.ts +++ b/extensions/vscode-test-resolver/src/extension.ts @@ -8,9 +8,10 @@ import * as cp from 'child_process'; import * as path from 'path'; import * as fs from 'fs'; import * as os from 'os'; +import * as net from 'net'; import { downloadAndUnzipVSCodeServer } from './download'; +import { terminateProcess } from './util/processes'; -let startPromise: Thenable | undefined = void 0; let extHostProcess: cp.ChildProcess | undefined; const enum CharCode { Backspace = 8, @@ -22,7 +23,7 @@ let outputChannel: vscode.OutputChannel; export function activate(context: vscode.ExtensionContext) { function doResolve(_authority: string, progress: vscode.Progress<{ message?: string; increment?: number }>): Promise { - return new Promise(async (res, rej) => { + const serverPromise = new Promise(async (res, rej) => { progress.report({ message: 'Starting Test Resolver' }); outputChannel = vscode.window.createOutputChannel('TestResolver'); @@ -60,9 +61,19 @@ export function activate(context: vscode.ExtensionContext) { } } } + const delay = getConfiguration('startupDelay'); + if (typeof delay === 'number') { + let remaining = Math.ceil(delay); + outputChannel.append(`Delaying startup by ${remaining} seconds (configured by "testresolver.startupDelay").`); + while (remaining > 0) { + progress.report({ message: `Delayed resolving: Remaining ${remaining}s` }); + await (sleep(1000)); + remaining--; + } + } - if (_authority === 'test+error' || vscode.workspace.getConfiguration('testresolver').get('error') === true) { - processError('Unable to start the Test Resolver.'); + if (getConfiguration('startupError') === true) { + processError('Test Resolver failed for testing purposes (configured by "testresolver.startupError").'); return; } @@ -88,21 +99,115 @@ export function activate(context: vscode.ExtensionContext) { } extHostProcess.stdout.on('data', (data: Buffer) => processOutput(data.toString())); extHostProcess.stderr.on('data', (data: Buffer) => processOutput(data.toString())); - extHostProcess.on('error', (error: Error) => processError(`server failed with error:\n${error.message}`)); - extHostProcess.on('close', (code: number) => processError(`server closed unexpectedly.\nError code: ${code}`)); + extHostProcess.on('error', (error: Error) => { + processError(`server failed with error:\n${error.message}`); + extHostProcess = undefined; + }); + extHostProcess.on('close', (code: number) => { + processError(`server closed unexpectedly.\nError code: ${code}`); + extHostProcess = undefined; + }); + context.subscriptions.push({ + dispose: () => { + if (extHostProcess) { + terminateProcess(extHostProcess, context.extensionPath); + } + } + }); + }); + return serverPromise.then(serverAddr => { + return new Promise(async (res, _rej) => { + const proxyServer = net.createServer(proxySocket => { + outputChannel.appendLine(`Proxy connection accepted`); + let remoteReady = true, localReady = true; + const remoteSocket = net.createConnection({ port: serverAddr.port }); + + let isDisconnected = getConfiguration('pause') === true; + vscode.workspace.onDidChangeConfiguration(_ => { + let newIsDisconnected = getConfiguration('pause') === true; + if (isDisconnected !== newIsDisconnected) { + outputChannel.appendLine(`Connection state: ${newIsDisconnected ? 'open' : 'paused'}`); + isDisconnected = newIsDisconnected; + if (!isDisconnected) { + outputChannel.appendLine(`Resume remote and proxy sockets.`); + if (remoteSocket.isPaused() && localReady) { + remoteSocket.resume(); + } + if (proxySocket.isPaused() && remoteReady) { + proxySocket.resume(); + } + } else { + outputChannel.appendLine(`Pausing remote and proxy sockets.`); + if (!remoteSocket.isPaused()) { + remoteSocket.pause(); + } + if (!proxySocket.isPaused()) { + proxySocket.pause(); + } + } + } + }); + + proxySocket.on('data', (data) => { + remoteReady = remoteSocket.write(data); + if (!remoteReady) { + proxySocket.pause(); + } + }); + remoteSocket.on('data', (data) => { + localReady = proxySocket.write(data); + if (!localReady) { + remoteSocket.pause(); + } + }); + proxySocket.on('drain', () => { + localReady = true; + if (!isDisconnected) { + remoteSocket.resume(); + } + }); + remoteSocket.on('drain', () => { + remoteReady = true; + if (!isDisconnected) { + proxySocket.resume(); + } + }); + proxySocket.on('close', () => { + outputChannel.appendLine(`Proxy socket closed, closing remote socket.`); + remoteSocket.end(); + }); + remoteSocket.on('close', () => { + outputChannel.appendLine(`Remote socket closed, closing proxy socket.`); + proxySocket.end(); + }); + context.subscriptions.push({ + dispose: () => { + proxySocket.end(); + remoteSocket.end(); + } + }); + }); + proxyServer.listen(0, () => { + const port = (proxyServer.address()).port; + outputChannel.appendLine(`Going through proxy at port ${port}`); + res({ host: '127.0.0.1', port }); + }); + context.subscriptions.push({ + dispose: () => { + proxyServer.close(); + } + }); + }); }); } vscode.workspace.registerRemoteAuthorityResolver('test', { resolve(_authority: string): Thenable { - if (!startPromise) { - startPromise = vscode.window.withProgress({ - location: vscode.ProgressLocation.Notification, - title: 'Open TestResolver Remote ([details](command:remote-testresolver.showLog))', - cancellable: false - }, (progress) => doResolve(_authority, progress)); - } - return startPromise; + return vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: 'Open TestResolver Remote ([details](command:remote-testresolver.showLog))', + cancellable: false + }, (progress) => doResolve(_authority, progress)); } }); @@ -168,8 +273,12 @@ function getNewEnv(): { [x: string]: string | undefined } { return env; } -export function deactivate() { - if (extHostProcess) { - extHostProcess.kill(); - } +function sleep(ms: number): Promise { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); +} + +function getConfiguration(id: string): T | undefined { + return vscode.workspace.getConfiguration('testresolver').get(id); } diff --git a/extensions/vscode-test-resolver/src/util/processes.ts b/extensions/vscode-test-resolver/src/util/processes.ts new file mode 100644 index 00000000000..d5af12566fb --- /dev/null +++ b/extensions/vscode-test-resolver/src/util/processes.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as cp from 'child_process'; +import * as path from 'path'; + +export interface TerminateResponse { + success: boolean; + error?: any; +} + +export function terminateProcess(p: cp.ChildProcess, extensionPath: string): TerminateResponse { + if (process.platform === 'win32') { + try { + const options: any = { + stdio: ['pipe', 'pipe', 'ignore'] + }; + cp.execFileSync('taskkill', ['/T', '/F', '/PID', p.pid.toString()], options); + } catch (err) { + return { success: false, error: err }; + } + } else if (process.platform === 'darwin' || process.platform === 'linux') { + try { + const cmd = path.join(extensionPath, 'scripts', 'terminateProcess.sh'); + const result = cp.spawnSync(cmd, [process.pid.toString()]); + if (result.error) { + return { success: false, error: result.error }; + } + } catch (err) { + return { success: false, error: err }; + } + } else { + p.kill('SIGKILL'); + } + return { success: true }; +} \ No newline at end of file diff --git a/extensions/yarn.lock b/extensions/yarn.lock index fd211376d48..8e552194c13 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -typescript@3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.1.tgz#ba72a6a600b2158139c5dd8850f700e231464202" - integrity sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw== +typescript@3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.2.tgz#a09e1dc69bc9551cadf17dba10ee42cf55e5d56c" + integrity sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA== diff --git a/gulpfile.js b/gulpfile.js index 1d13cff608c..8a5eff502f6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -40,4 +40,4 @@ process.on('unhandledRejection', (reason, p) => { // Load all the gulpfiles only if running tasks other than the editor tasks const build = path.join(__dirname, 'build'); require('glob').sync('gulpfile.*.js', { cwd: build }) - .forEach(f => require(`./build/${f}`)); + .forEach(f => require(`./build/${f}`)); \ No newline at end of file diff --git a/package.json b/package.json index 268ae97ee1f..616ad5fc534 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", - "version": "1.36.0", - "distro": "f582c39004c7c694d7e1461345e456afedd81d67", + "version": "1.37.0", + "distro": "4d4ca170652edf13efd5916e009bdc9c0d4d1103", "author": { "name": "Microsoft Corporation" }, @@ -17,7 +17,7 @@ "watch-client": "gulp watch-client --max_old_space_size=4095", "monaco-editor-test": "mocha --only-monaco-editor", "precommit": "node build/gulpfile.hygiene.js", - "gulp": "gulp --max_old_space_size=4095", + "gulp": "gulp --max_old_space_size=8192", "7z": "7z", "update-grammars": "node build/npm/update-all-grammars.js", "update-localization-extension": "node build/npm/update-localization-extension.js", @@ -25,46 +25,43 @@ "download-builtin-extensions": "node build/lib/builtInExtensions.js", "monaco-compile-check": "tsc -p src/tsconfig.monaco.json --noEmit", "strict-initialization-watch": "tsc --watch -p src/tsconfig.json --noEmit --strictPropertyInitialization", - "web": "node resources/server/bin-dev/code-web.js", - "web-selfhost": "node resources/server/bin-dev/code-web.js --selfhost --folder .", - "install-server": "git fetch distro && git checkout distro/distro -- src/vs/server resources/server && git reset HEAD src/vs/server resources/server" + "update-distro": "node build/npm/update-distro.js" }, "dependencies": { "applicationinsights": "1.0.8", - "gc-signals": "^0.0.2", "getmac": "1.4.1", "graceful-fs": "4.1.11", "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.1", - "iconv-lite": "0.4.23", + "iconv-lite": "0.5.0", "jschardet": "1.6.0", - "keytar": "4.2.1", + "keytar": "^4.11.0", "minimist": "1.2.0", "native-is-elevated": "^0.2.1", - "native-keymap": "1.2.5", + "native-keymap": "2.0.0", "native-watchdog": "1.0.0", - "node-pty": "0.9.0-beta17", + "node-pty": "0.9.0-beta19", + "nsfw": "1.2.5", "onigasm-umd": "^2.2.2", "puppeteer": "^1.17.0", "semver": "^5.5.0", "spdlog": "^0.9.0", - "sudo-prompt": "8.2.0", + "sudo-prompt": "9.0.0", "v8-inspect-profiler": "^0.0.20", - "vscode-chokidar": "1.6.5", - "vscode-nsfw": "1.1.2", + "vscode-chokidar": "2.1.7", "vscode-proxy-agent": "0.4.0", - "vscode-ripgrep": "^1.2.5", - "vscode-sqlite3": "4.0.7", - "vscode-textmate": "^4.1.1", - "xterm": "3.15.0-beta34", - "xterm-addon-search": "0.1.0-beta6", + "vscode-ripgrep": "^1.3.1", + "vscode-sqlite3": "4.0.8", + "vscode-textmate": "^4.2.2", + "xterm": "3.15.0-beta71", + "xterm-addon-search": "0.2.0-beta2", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", "yazl": "^2.4.3" }, "devDependencies": { "7zip": "0.0.6", - "@types/keytar": "^4.0.1", + "@types/keytar": "^4.4.0", "@types/minimist": "^1.2.0", "@types/mocha": "2.2.39", "@types/node": "^10.12.12", @@ -81,7 +78,7 @@ "debounce": "^1.0.0", "documentdb": "^1.5.1", "electron-mksnapshot": "~2.0.0", - "eslint": "^3.4.0", + "eslint": "^4.18.2", "event-stream": "3.3.4", "express": "^4.13.1", "fancy-log": "^1.3.3", @@ -110,7 +107,7 @@ "gulp-vinyl-zip": "^2.1.2", "http-server": "^0.11.1", "husky": "^0.13.1", - "innosetup-compiler": "^5.5.60", + "innosetup": "5.6.1", "is": "^3.1.0", "istanbul": "^0.3.17", "jsdom-no-contextify": "^3.1.0", @@ -133,7 +130,7 @@ "source-map": "^0.4.4", "ts-loader": "^4.4.2", "tslint": "^5.16.0", - "typescript": "3.5.1", + "typescript": "3.5.2", "typescript-formatter": "7.1.0", "uglify-es": "^3.0.18", "underscore": "^1.8.2", @@ -141,7 +138,7 @@ "vinyl-fs": "^3.0.0", "vsce": "1.48.0", "vscode-debugprotocol": "1.35.0", - "vscode-nls-dev": "3.2.5", + "vscode-nls-dev": "^3.3.1", "webpack": "^4.16.5", "webpack-cli": "^3.1.0", "webpack-stream": "^5.1.1" @@ -158,6 +155,6 @@ "vscode-windows-registry": "1.0.1", "windows-foreground-love": "0.1.0", "windows-mutex": "0.2.1", - "windows-process-tree": "0.2.3" + "windows-process-tree": "0.2.4" } } diff --git a/remote/.yarnrc b/remote/.yarnrc index 29c22bc4be4..b28191e6bae 100644 --- a/remote/.yarnrc +++ b/remote/.yarnrc @@ -1,3 +1,3 @@ disturl "http://nodejs.org/dist" -target "10.2.1" +target "10.11.0" runtime "node" diff --git a/remote/package.json b/remote/package.json index da17913e867..6fc6471a2ce 100644 --- a/remote/package.json +++ b/remote/package.json @@ -3,31 +3,31 @@ "version": "0.0.0", "dependencies": { "applicationinsights": "1.0.8", - "getmac": "^1.4.6", + "getmac": "1.4.1", "graceful-fs": "4.1.11", "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.1", - "iconv-lite": "0.4.23", + "iconv-lite": "0.5.0", "jschardet": "1.6.0", - "keytar": "4.2.1", "minimist": "1.2.0", "native-watchdog": "1.0.0", - "node-pty": "0.8.1", + "node-pty": "0.9.0-beta19", + "nsfw": "1.2.5", "onigasm-umd": "^2.2.2", "semver": "^5.5.0", "spdlog": "^0.9.0", - "vscode-chokidar": "1.6.5", - "vscode-nsfw": "1.1.1", + "vscode-chokidar": "2.1.7", "vscode-proxy-agent": "0.4.0", - "vscode-ripgrep": "^1.2.5", - "vscode-textmate": "^4.1.1", + "vscode-ripgrep": "^1.3.1", + "vscode-textmate": "^4.2.2", + "xterm": "3.15.0-beta71", + "xterm-addon-search": "0.2.0-beta2", + "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", - "yazl": "^2.4.3", - "xterm": "3.15.0-beta34", - "xterm-addon-search": "0.1.0-beta6", - "xterm-addon-web-links": "0.1.0-beta10" + "yazl": "^2.4.3" }, "optionalDependencies": { - "vscode-windows-ca-certs": "0.1.0" + "vscode-windows-ca-certs": "0.1.0", + "vscode-windows-registry": "1.0.1" } } diff --git a/remote/yarn.lock b/remote/yarn.lock index 11db8ed16fb..7d522e2901b 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -16,16 +16,6 @@ agent-base@~4.2.0: dependencies: es6-promisify "^5.0.0" -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - applicationinsights@1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.8.tgz#db6e3d983cf9f9405fe1ee5ba30ac6e1914537b5" @@ -35,45 +25,53 @@ applicationinsights@1.0.8: diagnostic-channel-publishers "0.2.1" zone.js "0.7.6" -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= - dependencies: - arr-flatten "^1.0.1" +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -arr-flatten@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" - integrity sha1-5f/lTUXhnzLyFukeuZyM6JK7YEs= +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= - -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - integrity sha1-GdOGodntxufByF04iu28xW0zYC0= - -balanced-match@^1.0.0: +assign-symbols@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" binary-extensions@^1.0.0: version "1.10.0" @@ -87,73 +85,69 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bl@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" - integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" - -brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" - integrity sha1-wHshHHyVLsH479Uad+8NHTmQopI= - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" repeat-element "^1.1.2" - -buffer-alloc-unsafe@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-0.1.1.tgz#ffe1f67551dd055737de253337bfe853dfab1a6a" - integrity sha1-/+H2dVHdBVc33iUzN7/oU9+rGmo= - -buffer-alloc@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.1.0.tgz#05514d33bf1656d3540c684f65b1202e90eca303" - integrity sha1-BVFNM78WVtNUDGhPZbEgLpDsowM= - dependencies: - buffer-alloc-unsafe "^0.1.0" - buffer-fill "^0.1.0" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= -buffer-fill@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-0.1.1.tgz#76d825c4d6e50e06b7a31eb520c04d08cc235071" - integrity sha512-YgBMBzdRLEfgxJIGu2wrvI2E03tMCFU1p7d1KhB4BOoMN0VxmTFjSyN5JtKt9z8Z9JajMHruI6SE25W96wNv7Q== - -chownr@^1.0.1: +cache-base@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" - integrity sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE= + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-util-is@~1.0.0: version "1.0.2" @@ -167,27 +161,39 @@ debug@3.1.0, debug@^3.1.0: dependencies: ms "2.0.0" -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= +debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: - mimic-response "^1.0.0" + ms "2.0.0" -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -delegates@^1.0.0: +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" -detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" diagnostic-channel-publishers@0.2.1: version "0.2.1" @@ -209,12 +215,12 @@ eachr@^3.2.0: editions "^1.1.1" typechecker "^4.3.0" -editions@^1.1.1: +editions@^1.1.1, editions@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" integrity sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg== -editions@^2.0.2, editions@^2.1.0, editions@^2.1.2: +editions@^2.1.0, editions@^2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/editions/-/editions-2.1.3.tgz#727ccf3ec2c7b12dcc652c71000f16c4824d6f7d" integrity sha512-xDZyVm0A4nLgMNWVVLJvcwMjI80ShiH/27RyLiCnW1L273TcJIA25C4pwJ33AWV01OX6UriP35Xu+lH4S7HWQw== @@ -222,13 +228,6 @@ editions@^2.0.2, editions@^2.1.0, editions@^2.1.2: errlop "^1.1.1" semver "^5.6.0" -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" - integrity sha1-epDYM+/abPpurA9JSduw+tOmMgY= - dependencies: - once "^1.4.0" - errlop@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/errlop/-/errlop-1.1.1.tgz#d9ae4c76c3e64956c5d79e6e035d6343bfd62250" @@ -248,31 +247,47 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= dependencies: - is-posix-bracket "^0.1.0" + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= dependencies: - fill-range "^2.1.0" + is-extendable "^0.1.0" -expand-template@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.1.tgz#981f188c0c3a87d2e28f559bc541426ff94f21dd" - integrity sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg== - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= dependencies: - is-extglob "^1.0.0" + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" extract-opts@^3.2.0: version "3.3.1" @@ -295,38 +310,27 @@ file-uri-to-path@1.0.0: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== -filename-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" - integrity sha1-mW4+gEebmLmJfxWopYs9CE6SZ3U= - -fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - integrity sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM= +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^1.1.3" - repeat-element "^1.1.2" - repeat-string "^1.5.2" + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" -for-in@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.5.tgz#007374e2b6d5c67420a1479bdb75a04872b738c4" - integrity sha1-AHN04rbVxnQgoUeb23WgSHK3OMQ= +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -for-own@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.4.tgz#0149b41a39088c7515f51ebe1c1386d45f935072" - integrity sha1-AUm0GjkIjHUV9R6+HBOG1F+TUHI= +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: - for-in "^0.1.5" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + map-cache "^0.2.2" fs-extra@^7.0.0: version "7.0.1" @@ -337,57 +341,67 @@ fs-extra@^7.0.0: jsonfile "^4.0.0" universalify "^0.1.0" -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -getmac@^1.4.6: - version "1.4.6" - resolved "https://registry.yarnpkg.com/getmac/-/getmac-1.4.6.tgz#ffe7db07900e222916939d44e4c7274adbecc662" - integrity sha512-3JPwiIr4P6Sgr6y6SVXX0+l2mrB6pyf4Cdyua7rvEV7SveWQkAp11vrkNym8wvRxzLrBenKRcwe93asdghuwWg== +getmac@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/getmac/-/getmac-1.4.1.tgz#cfefcb3ee7d7a73cba5292129cb100c19afbe17a" + integrity sha512-mQp+8D+grQX0gG8EJn6VfH0PxE56ZKNsTguOMxPShAiVk9lvH8Ey36eXepG705Ac1HCsvaSrQ/6bPHZ0++F/Mg== dependencies: - editions "^2.0.2" + editions "^1.3.4" extract-opts "^3.2.0" -github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" + is-glob "^3.1.0" + path-dirname "^1.0.0" -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= - dependencies: - is-glob "^2.0.0" - -graceful-fs@4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: +graceful-fs@4.1.11, graceful-fs@^4.1.2: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= +graceful-fs@^4.1.11, graceful-fs@^4.1.6: + version "4.2.0" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" + integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" http-proxy-agent@2.1.0, http-proxy-agent@^2.1.0: version "2.1.0" @@ -405,28 +419,42 @@ https-proxy-agent@2.2.1, https-proxy-agent@^2.2.1: agent-base "^4.1.0" debug "^3.1.0" -iconv-lite@0.4.23: - version "0.4.23" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" - integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== +iconv-lite@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.5.0.tgz#59cdde0a2a297cc2aeb0c6445a195ee89f127550" + integrity sha512-NnEhI9hIEKHOzJ4f697DMz9IQEXr/MMJ5w64vN2/4Ai+wRnvV7SBrL0KLoRlwaKVghOc7LQ5YkPLuX146b6Ydw== dependencies: safer-buffer ">= 2.1.2 < 3" -inherits@^2.0.1, inherits@~2.0.3: +inherits@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@~1.3.0: - version "1.3.4" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" - integrity sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4= - ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -439,63 +467,92 @@ is-buffer@^1.0.2: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" integrity sha1-z8hszV3FpS+oBIkRHGkgxFfi2Ys= -is-dotfile@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" - integrity sha1-LBMjg/ORmfjtwmjKAbmwB9IFzE0= +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= dependencies: - is-primitive "^2.0.0" + kind-of "^3.0.2" -is-extendable@^0.1.1: +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: - number-is-nan "^1.0.0" + is-plain-object "^2.0.4" -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= dependencies: - is-extglob "^1.0.0" + is-extglob "^2.1.0" -is-number@^2.0.2, is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= +is-glob@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= dependencies: kind-of "^3.0.2" -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== isarray@1.0.0, isarray@~1.0.0: version "1.0.0" @@ -509,6 +566,11 @@ isobject@^2.0.0: dependencies: isarray "1.0.0" +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + jschardet@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.6.0.tgz#c7d1a71edcff2839db2f9ec30fc5d5ebd3c1a678" @@ -521,14 +583,6 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -keytar@4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/keytar/-/keytar-4.2.1.tgz#8a06a6577fdf6373e0aa6b112277e63dec77fd12" - integrity sha1-igamV3/fY3PgqmsRInfmPex3/RI= - dependencies: - nan "2.8.0" - prebuild-install "^2.4.1" - kind-of@^3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.0.4.tgz#7b8ecf18a4e17f8269d73b501c9f232c96887a74" @@ -536,6 +590,30 @@ kind-of@^3.0.2: dependencies: is-buffer "^1.0.2" +kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + lodash.isinteger@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" @@ -546,47 +624,55 @@ lodash.isundefined@^3.0.1: resolved "https://registry.yarnpkg.com/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz#23ef3d9535565203a66cefd5b830f848911afb48" integrity sha1-I+89lTVWUgOmbO/VuDD4SJEa+0g= -micromatch@^2.1.5: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= -mimic-response@^1.0.0: +map-visit@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" - integrity sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4= - -minimatch@^3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: - brace-expansion "^1.1.7" + object-visit "^1.0.0" + +micromatch@^3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@1.2.0, minimist@^1.2.0: +minimist@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" @@ -599,128 +685,104 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -nan@2.12.1: - version "2.12.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" - integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== - -nan@2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" - integrity sha1-7XFfP+neArV6XmJS2QqWZ14fCFo= - -nan@^2.10.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099" - integrity sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw== - -nan@^2.12.1, nan@^2.14.0: +nan@^2.0.0, nan@^2.12.1, nan@^2.13.2, nan@^2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + native-watchdog@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/native-watchdog/-/native-watchdog-1.0.0.tgz#97344e83cd6815a8c8e6c44a52e7be05832e65ca" integrity sha512-HKQATz5KLUMPyQQ/QaalzgTXaGz2plYPBxjyalaR4ECIu/UznXY8YJD+a9SLkkcvtxnJ8/zHLY3xik06vUZ7uA== -node-abi@^2.2.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.4.1.tgz#7628c4d4ec4e9cd3764ceb3652f36b2e7f8d4923" - integrity sha512-pUlswqpHQ7zGPI9lGjZ4XDNIEUDbHxsltfIRb7dTnYdhgHWHOcB0MLZKLoCz6UMcGzSPG5wGl1HODZVQAUsH6w== - dependencies: - semver "^5.4.1" - node-addon-api@1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.6.2.tgz#d8aad9781a5cfc4132cc2fecdbdd982534265217" integrity sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA== -node-pty@0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.8.1.tgz#94b457bec013e7a09b8d9141f63b0787fa25c23f" - integrity sha512-j+/g0Q5dR+vkELclpJpz32HcS3O/3EdPSGPvDXJZVJQLCvgG0toEbfmymxAEyQyZEpaoKHAcoL+PvKM+4N9nlw== +node-pty@0.9.0-beta19: + version "0.9.0-beta19" + resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.9.0-beta19.tgz#0fd381b2006f4665c4c2ee0509219e591842371a" + integrity sha512-MkKEvBnauGnzgXNr/oaoWQLVXm1gheIKZs4YQp8883ZiETmbEnpSvD0FU3bELcPXG5VFPRqIGsQJ4KUMBLzkPA== dependencies: - nan "2.12.1" + nan "^2.13.2" -noop-logger@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" - integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-path@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= +nsfw@1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/nsfw/-/nsfw-1.2.5.tgz#febe581af616f7b042f89df133abe62416c4c803" + integrity sha512-m3mwZUKXiCR69PDMLfAmKmiNzy0Oe9LhFE0DYZC5cc1htNj5Hyb1sAgglXhuaDkibFy22AVvPC5cCFB3A6mYIw== dependencies: - remove-trailing-separator "^1.0.1" + fs-extra "^7.0.0" + lodash.isinteger "^4.0.4" + lodash.isundefined "^3.0.1" + nan "^2.0.0" -normalize-path@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" - integrity sha1-R4hqwWYnYNQmG32XnSQXCdPOP3o= - -npmlog@^4.0.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" -number-is-nan@^1.0.0: +object-visit@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object.omit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.0.tgz#868597333d54e60662940bb458605dd6ae12fe94" - integrity sha1-hoWXMz1U5gZilAu0WGBd1q4S/pQ= + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= dependencies: - for-own "^0.1.3" - is-extendable "^0.1.1" + isobject "^3.0.0" -once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= dependencies: - wrappy "1" + isobject "^3.0.1" onigasm-umd@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/onigasm-umd/-/onigasm-umd-2.2.2.tgz#b989d762df61f899a3052ac794a50bd93fe20257" integrity sha512-v2eMOJu7iE444L2iJN+U6s6s5S0y7oj/N0DAkrd6wokRtTVoq/v/yaDI1lIqFrTeJbNtqNzYvguDF5yNzW3Rvw== -oniguruma@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/oniguruma/-/oniguruma-7.1.0.tgz#106ddf7eb42507d0442ac68b187c4f7fdf052c83" - integrity sha512-mV+6HcDNQ38vM8HVKM+MJyXO4EtSigwIZhq023A4rA8Am4dMlGhUkPwudDykExYR45oLrssR/Ep7PZCQ1OM3pA== +oniguruma@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/oniguruma/-/oniguruma-7.2.0.tgz#c9a59c1ea7b9fe67e237a02e02139b638856f3af" + integrity sha512-bh+ZLdykY1sdIx8jBp2zpLbVFDBc3XmKH4Ceo2lijNaN1WhEqtnpqFlmtCbRuDB17nJ58RAUStVwfW8e8uEbnA== dependencies: - nan "^2.12.1" + nan "^2.14.0" -os-homedir@^1.0.1: +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-dirname@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= path-is-absolute@^1.0.0: version "1.0.1" @@ -732,76 +794,21 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= -prebuild-install@^2.4.1: - version "2.5.3" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-2.5.3.tgz#9f65f242782d370296353710e9bc843490c19f69" - integrity sha512-/rI36cN2g7vDQnKWN8Uzupi++KjyqS9iS+/fpwG4Ea8d0Pip0PQ5bshUNzVwt+/D2MRfhVAplYMMvWLqWrCF/g== - dependencies: - detect-libc "^1.0.3" - expand-template "^1.0.2" - github-from-package "0.0.0" - minimist "^1.2.0" - mkdirp "^0.5.1" - node-abi "^2.2.0" - noop-logger "^0.1.1" - npmlog "^4.0.1" - os-homedir "^1.0.1" - pump "^2.0.1" - rc "^1.1.6" - simple-get "^2.7.0" - tar-fs "^1.13.0" - tunnel-agent "^0.6.0" - which-pm-runs "^1.0.0" +picomatch@^2.0.4: + version "2.0.7" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" + integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= -process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== - -pump@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" - integrity sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -randomatic@^1.1.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.5.tgz#5e9ef5f2d573c67bd2b8124ae90b5156e457840b" - integrity sha1-Xp718tVzxnvSuBJK6QtRVuRXhAs= - dependencies: - is-number "^2.0.2" - kind-of "^3.0.2" - -rc@^1.1.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - readable-stream@^2.0.2: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" @@ -815,57 +822,55 @@ readable-stream@^2.0.2: string_decoder "~1.0.3" util-deprecate "~1.0.1" -readable-stream@^2.0.6, readable-stream@^2.3.0, readable-stream@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - integrity sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg= - dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" + graceful-fs "^4.1.11" + micromatch "^3.1.10" readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" -regex-cache@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" - integrity sha1-mxpsNdTQ3871cRrmUejp09cRQUU= +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: - is-equal-shallow "^0.1.3" - is-primitive "^2.0.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + extend-shallow "^3.0.2" + safe-regex "^1.1.0" repeat-element@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" integrity sha1-7wiaF40Ug7quTZPrmLT55OEdmQo= -repeat-string@^1.5.2: - version "1.5.4" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.5.4.tgz#64ec0c91e0f4b475f90d5b643651e3e6e5b6c2d5" - integrity sha1-ZOwMkeD0tHX5DVtkNlHj5uW2wtU= +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -876,7 +881,7 @@ semver@^5.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== -semver@^5.4.1, semver@^5.5.0: +semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== @@ -886,40 +891,51 @@ semver@^5.6.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== -set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -simple-concat@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" - integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= - -simple-get@^2.7.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" - integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== dependencies: - decompress-response "^3.3.0" - once "^1.3.1" - simple-concat "^1.0.0" + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" smart-buffer@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.1.tgz#07ea1ca8d4db24eb4cac86537d7d18995221ace3" integrity sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg== +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + socks-proxy-agent@4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz#5936bf8b707a993079c6f37db2091821bffa6473" @@ -936,6 +952,27 @@ socks@~2.2.0: ip "^1.1.5" smart-buffer "^4.0.1" +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + spdlog@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/spdlog/-/spdlog-0.9.0.tgz#c85dd9d0b9cd385f6f3f5b92dc9d2e1691092b5c" @@ -945,22 +982,20 @@ spdlog@^0.9.0: mkdirp "^0.5.1" nan "^2.14.0" -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" + extend-shallow "^3.0.0" -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" + define-property "^0.2.5" + object-copy "^0.1.0" string_decoder@~1.0.3: version "1.0.3" @@ -969,66 +1004,30 @@ string_decoder@~1.0.3: dependencies: safe-buffer "~5.1.0" -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: - safe-buffer "~5.1.0" + kind-of "^3.0.2" -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: - ansi-regex "^2.0.0" + is-number "^3.0.0" + repeat-string "^1.6.1" -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: - ansi-regex "^3.0.0" - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -tar-fs@^1.13.0: - version "1.16.2" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.2.tgz#17e5239747e399f7e77344f5f53365f04af53577" - integrity sha512-LdknWjPEiZC1nOBwhv0JBzfJBGPJar08dZg2rwZe0ZTLQoRGEzgrl7vF3qUEkCHpI/wN9e7RyCuDhMsJUCLPPQ== - dependencies: - chownr "^1.0.1" - mkdirp "^0.5.1" - pump "^1.0.0" - tar-stream "^1.1.2" - -tar-stream@^1.1.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.1.tgz#f84ef1696269d6223ca48f6e1eeede3f7e81f395" - integrity sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA== - dependencies: - bl "^1.0.0" - buffer-alloc "^1.1.0" - end-of-stream "^1.0.0" - fs-constants "^1.0.0" - readable-stream "^2.3.0" - to-buffer "^1.1.0" - xtend "^4.0.0" - -to-buffer@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" - integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" typechecker@^4.3.0: version "4.7.0" @@ -1037,56 +1036,82 @@ typechecker@^4.3.0: dependencies: editions "^2.1.0" +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" + integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -vscode-anymatch@1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/vscode-anymatch/-/vscode-anymatch-1.3.3.tgz#0613d31a949c8025473bbdad848d219f47a44f86" - integrity sha512-LQ4vF4BWb9gwAvbMtN+3HC4HKDxLd+ZyWmAjACOdD05O/ZMcgvvnjO24GseEIQ6cWn8gW+Ft08gHFihnQy1eSw== +vscode-anymatch@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/vscode-anymatch/-/vscode-anymatch-3.0.3.tgz#5a79101e6df7e659a1f070367bc42f190eb4ae76" + integrity sha512-qQgfbzJJ5nNShh4jjC3BBekY4d8emcxHFgnqcXwsB/PUKvJPCg7AZYXM7hqS7EDnKrX9tsIFwFMihZ7yut92Qg== dependencies: - micromatch "^2.1.5" - normalize-path "^2.0.0" + normalize-path "^3.0.0" + picomatch "^2.0.4" -vscode-chokidar@1.6.5: - version "1.6.5" - resolved "https://registry.yarnpkg.com/vscode-chokidar/-/vscode-chokidar-1.6.5.tgz#f38a1f909fa364a5429a4d4d70ecb40a15b54d0b" - integrity sha512-bc5dNF8tW2R+oesYT/Au//qumyd/0HTwSRqVXcg8ADQW1MsWKFwv+IxfSIuCHckaEy4I81GpSDaRWVGQqtsELw== +vscode-chokidar@2.1.7: + version "2.1.7" + resolved "https://registry.yarnpkg.com/vscode-chokidar/-/vscode-chokidar-2.1.7.tgz#c5b31eb87402f4779bb4170915245bdcb6f7854b" + integrity sha512-uSNEQetPjAlgIAHmcF9E6M+KCw0f842rsEnJ64aamUAV6TO7gkXNCvLSzb4MuLsPU7ZQyCa++DrLQFjvciK5dg== dependencies: - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" is-binary-path "^1.0.0" - is-glob "^2.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" path-is-absolute "^1.0.0" - readdirp "^2.0.0" - vscode-anymatch "1.3.3" + readdirp "^2.2.1" + upath "^1.1.1" + vscode-anymatch "3.0.3" optionalDependencies: - vscode-fsevents "0.3.10" + vscode-fsevents "1.2.12" -vscode-fsevents@0.3.10: - version "0.3.10" - resolved "https://registry.yarnpkg.com/vscode-fsevents/-/vscode-fsevents-0.3.10.tgz#65a586c3c6df3080bea20482146963a0f3a2c58d" - integrity sha512-iNlCKNgEB9A2JZkLf4h4sJlOS1u0lbe4QjM0Dr0PHaTmsttkJEfOaQeci2Ja1wUA7hUUAF6sNbei/Qp2DacFLw== +vscode-fsevents@1.2.12: + version "1.2.12" + resolved "https://registry.yarnpkg.com/vscode-fsevents/-/vscode-fsevents-1.2.12.tgz#01a71a01f90ee95ca822c34427aba437a17c03a7" + integrity sha512-bH/jRdDpSesGpqiVLjp6gHLSKUOh7oNvppzZ17JIrdbRYCcDmV7dIWR5gQc27DFy0RD9JDT+t+ixMid94MkM1A== dependencies: - nan "^2.10.0" - -vscode-nsfw@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/vscode-nsfw/-/vscode-nsfw-1.1.1.tgz#7c3febe153677c5850b197a0b64a197cd11e95c7" - integrity sha512-Wg3vzN1U3T6P1uE13LdVVRIhdy7XWnWkwmAXhkLsIkH2QY0E/pvNDRLrwAMMW6GC1Fvvbxm3hzdIrCmr7Hq3FA== - dependencies: - fs-extra "^7.0.0" - lodash.isinteger "^4.0.4" - lodash.isundefined "^3.0.1" - nan "^2.10.0" + nan "^2.14.0" vscode-proxy-agent@0.4.0: version "0.4.0" @@ -1098,17 +1123,17 @@ vscode-proxy-agent@0.4.0: https-proxy-agent "2.2.1" socks-proxy-agent "4.0.1" -vscode-ripgrep@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.2.5.tgz#2093c8f36d52bd2dab9eb45b003dd02533c5499c" - integrity sha512-n5XBm9od5hahpljw9T8wbkuMnAY7LlAG1OyEEtcCZEX9aCHFuBKSP0IcvciGRTbtWRovNuT83A2iRjt6PL3bLg== +vscode-ripgrep@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.3.1.tgz#51fb93debcd0c18a8b90dbc37f84f94333d0c486" + integrity sha512-4WLB/n4ZeWNi5AEzPTkfYrqbKtXlv0SlgmxbRVdulwZzGx/lfWeWPu9Shy32orM27IofQAQDuirbRBOYNJVzBA== -vscode-textmate@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.1.1.tgz#857e836fbc13a376ec624242437e1747d79610a9" - integrity sha512-xBjq9LH6fMhWDhIVkbKlB1JeCu6lT3FI/QKN24Xi4RKPBUm16IhHTqs6Q6SUGewkNsFZGkb1tJdZsuMnlmVpgw== +vscode-textmate@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.2.2.tgz#0b4dabc69a6fba79a065cb6b615f66eac07c8f4c" + integrity sha512-1U4ih0E/KP1zNK/EbpUqyYtI7PY+Ccd2nDGTtiMR/UalLFnmaYkwoWhN1oI7B91ptBN8NdVwWuvyUnvJAulCUw== dependencies: - oniguruma "^7.0.0" + oniguruma "^7.2.0" vscode-windows-ca-certs@0.1.0: version "0.1.0" @@ -1117,42 +1142,27 @@ vscode-windows-ca-certs@0.1.0: dependencies: node-addon-api "1.6.2" -which-pm-runs@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" - integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== +vscode-windows-registry@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vscode-windows-registry/-/vscode-windows-registry-1.0.1.tgz#bc9f765563eb6dc1c9ad9a41f9eaacc84dfadc7c" + integrity sha512-q0aKXi9Py1OBdmXIJJFeJBzpPJMMUxMJNBU9FysWIXEwJyMQGEVevKzM2J3Qz/cHSc5LVqibmoUWzZ7g+97qRg== dependencies: - string-width "^1.0.2 || 2" + nan "^2.12.1" -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -xtend@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= - -xterm-addon-search@0.1.0-beta6: - version "0.1.0-beta6" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.1.0-beta6.tgz#e2a2b441f8f7b0245c63731d0b2af32c7d4e6747" - integrity sha512-XKxdfO48HkCJW2m1wXW0PK/BOk00WEaN+W2LgDQqCBwwUjyBzWc9HaV8gzLXhSCDAYesWvtQa3RfqHfSp9qsbQ== +xterm-addon-search@0.2.0-beta2: + version "0.2.0-beta2" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta2.tgz#c3173f0a6f207ee9f1848849174ee5d6b6ce8262" + integrity sha512-XEcwi2TeFGk2MuIFjiI/OpVXSNO5dGQBvHH3o+9KzqG3ooVqhhDqzwxs092QGNcNCGh8hGn/PWZiczaBBnKm/g== xterm-addon-web-links@0.1.0-beta10: version "0.1.0-beta10" resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta34: - version "3.15.0-beta34" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta34.tgz#32ca9523f842cfc213bf64cbb199bb9adaddcd2d" - integrity sha512-eqq/K002xVCfYXZggbI7v7dRgRKTvJhVFTHqcs6MdMHuiOYl4lwZFkv4aFf896kkbnKQOZZGGzhnBFfa1w1rTA== +xterm@3.15.0-beta71: + version "3.15.0-beta71" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta71.tgz#2728c9800ca3b08423e835e9504bd1f4b5de6253" + integrity sha512-8M/cLaxZ+iDopRxLPdPfKuDGaNNyYTdCeytdxjMSH0N7dZzbx6fbaEygQdCrV5pO9cGnT92MefSjVPGRXRiBLA== yauzl@^2.9.2: version "2.10.0" diff --git a/resources/completions/bash/code b/resources/completions/bash/code index e377c5d24e2..f40963db05c 100644 --- a/resources/completions/bash/code +++ b/resources/completions/bash/code @@ -50,7 +50,7 @@ _code() --uninstall-extension --enable-proposed-api --verbose --log -s --status -p --performance --prof-startup --disable-extensions --disable-extension --inspect-extensions - --inspect-brk-extensions --disable-gpu --upload-logs + --inspect-brk-extensions --disable-gpu --max-memory=' -- "$cur") ) [[ $COMPREPLY == *= ]] && compopt -o nospace return diff --git a/resources/completions/zsh/_code b/resources/completions/zsh/_code index 9579cffb2f6..054ab351e91 100644 --- a/resources/completions/zsh/_code +++ b/resources/completions/zsh/_code @@ -14,6 +14,7 @@ arguments=( '--user-data-dir[specify the directory that user data is kept in]:directory:_directories' '(- *)'{-v,--version}'[print version]' '(- *)'{-h,--help}'[print usage]' + '(- *)'{--telemetry}'[Shows all telemetry events which VS code collects.]' '--extensions-dir[set the root path for extensions]:root path:_directories' '--list-extensions[list the installed extensions]' '--show-versions[show versions of installed extensions, when using --list-extension]' @@ -30,7 +31,6 @@ arguments=( '--inspect-extensions[allow debugging and profiling of extensions]' '--inspect-brk-extensions[allow debugging and profiling of extensions with the extension host being paused after start]' '--disable-gpu[disable GPU hardware acceleration]' - '--upload-logs[upload logs from current session to a secure endpoint]:confirm:(iConfirmLogsUpload)' '--max-memory=[max memory size for a window (in Mbytes)]:size (Mbytes)' '*:file or directory:_files' ) diff --git a/resources/linux/snap/snapcraft.yaml b/resources/linux/snap/snapcraft.yaml index 0a78d41e8fd..28b3e59ad7e 100644 --- a/resources/linux/snap/snapcraft.yaml +++ b/resources/linux/snap/snapcraft.yaml @@ -51,6 +51,7 @@ apps: @@NAME@@: command: electron-launch $SNAP/usr/share/@@NAME@@/bin/@@NAME@@ desktop: usr/share/applications/@@NAME@@.desktop + common-id: @@NAME@@.desktop environment: DISABLE_WAYLAND: 1 GSETTINGS_SCHEMA_DIR: $SNAP/usr/share/glib-2.0/schemas diff --git a/resources/win32/bin/code.sh b/resources/win32/bin/code.sh index b1a0f7e4f3e..5d92383c496 100644 --- a/resources/win32/bin/code.sh +++ b/resources/win32/bin/code.sh @@ -11,8 +11,18 @@ VSCODE_PATH="$(dirname "$(dirname "$(realpath "$0")")")" ELECTRON="$VSCODE_PATH/$NAME.exe" if grep -qi Microsoft /proc/version; then # in a wsl shell - WSL_BUILD=$(uname -r | sed -E 's/^.+-([0-9]+)-[Mm]icrosoft/\1/') - if [ $WSL_BUILD -ge 17063 ] 2> /dev/null; then + if ! [ -z "$WSL_DISTRO_NAME" ]; then + # $WSL_DISTRO_NAME is available since WSL builds 18362, also for WSL2 + WSL_BUILD=18362 + else + WSL_BUILD=$(uname -r | sed -E 's/^.+-([0-9]+)-Microsoft/\1/') + if [ -z "$WSL_BUILD" ]; then + WSL_BUILD=0 + fi + fi + + if [ $WSL_BUILD -ge 17063 ]; then + # $WSL_DISTRO_NAME is available since WSL builds 18362, also for WSL2 # WSLPATH is available since WSL build 17046 # WSLENV is available since WSL build 17063 export WSLENV=ELECTRON_RUN_AS_NODE/w:$WSLENV diff --git a/scripts/env.ps1 b/scripts/env.ps1 deleted file mode 100644 index 72e094d0a6a..00000000000 --- a/scripts/env.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -$env:npm_config_disturl="https://atom.io/download/electron" -$env:npm_config_target=(node -p "require('./build/lib/electron').getElectronVersion();") -$env:npm_config_runtime="electron" diff --git a/scripts/env.sh b/scripts/env.sh deleted file mode 100755 index 8f641759b27..00000000000 --- a/scripts/env.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -export npm_config_disturl=https://atom.io/download/electron -export npm_config_target=$(node -p "require('./build/lib/electron').getElectronVersion();") -export npm_config_runtime=electron -export npm_config_cache="$HOME/.npm-electron" -mkdir -p "$npm_config_cache" diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat index cf8902a2bce..20567bc77cf 100644 --- a/scripts/test-integration.bat +++ b/scripts/test-integration.bat @@ -10,16 +10,16 @@ call .\scripts\test.bat --runGlob **\*.integrationTest.js %* if %errorlevel% neq 0 exit /b %errorlevel% :: Tests in the extension host -call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testWorkspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% +call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testWorkspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests --disable-extensions --disable-inspect --user-data-dir=%VSCODEUSERDATADIR% if %errorlevel% neq 0 exit /b %errorlevel% -call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testworkspace.code-workspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\workspace-tests --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% +call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testworkspace.code-workspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\workspace-tests --disable-extensions --disable-inspect --user-data-dir=%VSCODEUSERDATADIR% if %errorlevel% neq 0 exit /b %errorlevel% -call .\scripts\code.bat %~dp0\..\extensions\vscode-colorize-tests\test --extensionDevelopmentPath=%~dp0\..\extensions\vscode-colorize-tests --extensionTestsPath=%~dp0\..\extensions\vscode-colorize-tests\out --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% +call .\scripts\code.bat %~dp0\..\extensions\vscode-colorize-tests\test --extensionDevelopmentPath=%~dp0\..\extensions\vscode-colorize-tests --extensionTestsPath=%~dp0\..\extensions\vscode-colorize-tests\out --disable-extensions --disable-inspect --user-data-dir=%VSCODEUSERDATADIR% if %errorlevel% neq 0 exit /b %errorlevel% -call .\scripts\code.bat $%~dp0\..\extensions\emmet\test-fixtures --extensionDevelopmentPath=%~dp0\..\extensions\emmet --extensionTestsPath=%~dp0\..\extensions\emmet\out\test --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% . +call .\scripts\code.bat $%~dp0\..\extensions\emmet\test-fixtures --extensionDevelopmentPath=%~dp0\..\extensions\emmet --extensionTestsPath=%~dp0\..\extensions\emmet\out\test --disable-extensions --disable-inspect --user-data-dir=%VSCODEUSERDATADIR% . if %errorlevel% neq 0 exit /b %errorlevel% :: Tests in commonJS (HTML, CSS, JSON language server tests...) diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh index 3d397ed204e..45595a5f0a3 100755 --- a/scripts/test-integration.sh +++ b/scripts/test-integration.sh @@ -16,13 +16,13 @@ cd $ROOT ./scripts/test.sh --runGlob **/*.integrationTest.js "$@" # Tests in the extension host -./scripts/code.sh $ROOT/extensions/vscode-api-tests/testWorkspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started -./scripts/code.sh $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started -./scripts/code.sh $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started -./scripts/code.sh $ROOT/extensions/markdown-language-features/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started +./scripts/code.sh $ROOT/extensions/vscode-api-tests/testWorkspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests --disable-extensions --skip-getting-started --disable-inspect --user-data-dir=$VSCODEUSERDATADIR +./scripts/code.sh $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-extensions --skip-getting-started --disable-inspect --user-data-dir=$VSCODEUSERDATADIR +./scripts/code.sh $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-extensions --skip-getting-started --disable-inspect --user-data-dir=$VSCODEUSERDATADIR +./scripts/code.sh $ROOT/extensions/markdown-language-features/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-extensions --skip-getting-started --disable-inspect --user-data-dir=$VSCODEUSERDATADIR mkdir -p $ROOT/extensions/emmet/test-fixtures -./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started +./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-extensions --skip-getting-started --disable-inspect --user-data-dir=$VSCODEUSERDATADIR rm -rf $ROOT/extensions/emmet/test-fixtures if [ -f ./resources/server/test/test-remote-integration.sh ]; then diff --git a/src/buildfile.js b/src/buildfile.js index a7c0376985e..0c77f1ae5fa 100644 --- a/src/buildfile.js +++ b/src/buildfile.js @@ -11,8 +11,16 @@ exports.base = [{ dest: 'vs/base/worker/workerMain.js' }]; +exports.serviceWorker = [{ + name: 'vs/workbench/contrib/resources/browser/resourceServiceWorker', + // include: ['vs/editor/common/services/editorSimpleWorker'], + prepend: ['vs/loader.js'], + append: ['vs/workbench/contrib/resources/browser/resourceServiceWorkerMain'], + dest: 'vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.js' +}]; + exports.workbench = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.main']); -exports.workbenchWeb = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.web.main']); +exports.workbenchWeb = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.web.api']); exports.code = require('./vs/code/buildfile').collectModules(); diff --git a/src/main.js b/src/main.js index 6d499413c7d..6902f1d6530 100644 --- a/src/main.js +++ b/src/main.js @@ -51,9 +51,11 @@ userDefinedLocale.then(locale => { } }); -// Configure command line switches +// Cached data const nodeCachedDataDir = getNodeCachedDir(); -configureCommandlineSwitches(args, nodeCachedDataDir); + +// Configure command line switches +configureCommandlineSwitches(args); // Load our code once ready app.once('ready', function () { @@ -134,31 +136,25 @@ function onReady() { * @typedef {import('minimist').ParsedArgs} ParsedArgs * * @param {ParsedArgs} cliArgs - * @param {{ jsFlags: () => string }} nodeCachedDataDir */ -function configureCommandlineSwitches(cliArgs, nodeCachedDataDir) { +function configureCommandlineSwitches(cliArgs) { // Force pre-Chrome-60 color profile handling (for https://github.com/Microsoft/vscode/issues/51791) app.commandLine.appendSwitch('disable-color-correct-rendering'); // Support JS Flags - const jsFlags = resolveJSFlags(cliArgs, nodeCachedDataDir.jsFlags()); + const jsFlags = getJSFlags(cliArgs); if (jsFlags) { app.commandLine.appendSwitch('--js-flags', jsFlags); } - - // Disable smooth scrolling for Webviews - if (cliArgs['disable-smooth-scrolling']) { - app.commandLine.appendSwitch('disable-smooth-scrolling'); - } } /** * @param {ParsedArgs} cliArgs - * @param {string[]} jsFlags * @returns {string} */ -function resolveJSFlags(cliArgs, ...jsFlags) { +function getJSFlags(cliArgs) { + const jsFlags = []; // Add any existing JS flags we already got from the command line if (cliArgs['js-flags']) { @@ -253,7 +249,7 @@ function registerListeners() { } /** - * @returns {{ jsFlags: () => string; ensureExists: () => Promise, _compute: () => string; }} + * @returns {{ ensureExists: () => Promise }} */ function getNodeCachedDir() { return new class { @@ -262,11 +258,6 @@ function getNodeCachedDir() { this.value = this._compute(); } - jsFlags() { - // return this.value ? '--nolazy' : undefined; - return undefined; - } - ensureExists() { return bootstrap.mkdirp(this.value).then(() => this.value, () => { /*ignore*/ }); } diff --git a/src/tsconfig.base.json b/src/tsconfig.base.json index 627491de597..cfd4b390a62 100644 --- a/src/tsconfig.base.json +++ b/src/tsconfig.base.json @@ -3,7 +3,6 @@ "module": "amd", "moduleResolution": "node", "noImplicitAny": true, - "suppressImplicitAnyIndexErrors": true, "target": "es5", "experimentalDecorators": true, "noImplicitReturns": true, diff --git a/src/tsconfig.json b/src/tsconfig.json index 25a1f449cc9..7fbb44c3ec5 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -9,7 +9,8 @@ "lib": [ "dom", "es5", - "es2015.iterable" + "es2015.iterable", + "webworker" ] }, "include": [ @@ -19,4 +20,4 @@ "exclude": [ "./typings/require-monaco.d.ts" ] -} \ No newline at end of file +} diff --git a/src/typings/chokidar.d.ts b/src/typings/chokidar.d.ts index 411080c2cc7..7f78ded23d4 100644 --- a/src/typings/chokidar.d.ts +++ b/src/typings/chokidar.d.ts @@ -5,84 +5,196 @@ declare module 'vscode-chokidar' { + // TypeScript Version: 3.0 + + import * as fs from "fs"; + import { EventEmitter } from "events"; + /** - * takes paths to be watched recursively and options + * The object's keys are all the directories (using absolute paths unless the `cwd` option was + * used), and the values are arrays of the names of the items contained in each directory. */ - export function watch(paths: string | string[], options: IOptions): FSWatcher; - - export interface IOptions { - - /** - * (regexp or function) files to be ignored. This function or regexp is tested against the whole path, not just filename. - * If it is a function with two arguments, it gets called twice per path - once with a single argument (the path), second time with two arguments (the path and the fs.Stats object of that path). - */ - ignored?: any; - - /** - * (default: false). Indicates whether the process should continue to run as long as files are being watched. - */ - persistent?: boolean; - - /** - * (default: false). Indicates whether to watch files that don't have read permissions. - */ - ignorePermissionErrors?: boolean; - - /** - * (default: false). Indicates whether chokidar should ignore the initial add events or not. - */ - ignoreInitial?: boolean; - - /** - * (default: 100). Interval of file system polling. - */ - interval?: number; - - /** - * (default: 300). Interval of file system polling for binary files (see extensions in src/is-binary). - */ - binaryInterval?: number; - - /** - * (default: false on Windows, true on Linux and OS X). Whether to use fs.watchFile (backed by polling), or fs.watch. If polling leads to high CPU utilization, consider setting this to false. - */ - usePolling?: boolean; - - /** - * (default: true on OS X). Whether to use the fsevents watching interface if available. When set to true explicitly and fsevents is available this supercedes the usePolling setting. When set to false on OS X, usePolling: true becomes the default. - */ - useFsEvents?: boolean; - - /** - * (default: true). When false, only the symlinks themselves will be watched for changes instead of following the link references and bubbling events through the link's path. - */ - followSymlinks?: boolean; - - /** - * (default: false). If set to true then the strings passed to .watch() and .add() are treated as literal path names, even if they look like globs. - */ - disableGlobbing?: boolean; + export interface WatchedPaths { + [directory: string]: string[]; } - export interface FSWatcher { + export class FSWatcher extends EventEmitter implements fs.FSWatcher { - add(fileDirOrGlob: string): void; - add(filesDirsOrGlobs: Array): void; - - unwatch(fileDirOrGlob: string): void; - unwatch(filesDirsOrGlobs: Array): void; + readonly options?: WatchOptions; /** - * Listen for an FS event. Available events: add, addDir, change, unlink, unlinkDir, error. Additionally all is available which gets emitted for every non-error event. + * Constructs a new FSWatcher instance with optional WatchOptions parameter. */ - on(event: string, clb: (type: string, path: string) => void): void; - on(event: string, clb: (error: Error) => void): void; + constructor(options?: WatchOptions); + + /** + * Add files, directories, or glob patterns for tracking. Takes an array of strings or just one + * string. + */ + add(paths: string | string[]): void; + + /** + * Stop watching files, directories, or glob patterns. Takes an array of strings or just one + * string. + */ + unwatch(paths: string | string[]): void; + + /** + * Returns an object representing all the paths on the file system being watched by this + * `FSWatcher` instance. The object's keys are all the directories (using absolute paths unless + * the `cwd` option was used), and the values are arrays of the names of the items contained in + * each directory. + */ + getWatched(): WatchedPaths; /** * Removes all listeners from watched files. */ close(): void; - options: IOptions; + on(event: 'add' | 'addDir' | 'change', listener: (path: string, stats?: fs.Stats) => void): this; + + on(event: 'all', listener: (eventName: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', path: string, stats?: fs.Stats) => void): this; + + /** + * Error occured + */ + on(event: 'error', listener: (error: Error) => void): this; + + /** + * Exposes the native Node `fs.FSWatcher events` + */ + on(event: 'raw', listener: (eventName: string, path: string, details: any) => void): this; + + /** + * Fires when the initial scan is complete + */ + on(event: 'ready', listener: () => void): this; + + on(event: 'unlink' | 'unlinkDir', listener: (path: string) => void): this; + + on(event: string, listener: (...args: any[]) => void): this; } + + export interface WatchOptions { + /** + * Indicates whether the process should continue to run as long as files are being watched. If + * set to `false` when using `fsevents` to watch, no more events will be emitted after `ready`, + * even if the process continues to run. + */ + persistent?: boolean; + + /** + * ([anymatch](https://github.com/es128/anymatch)-compatible definition) Defines files/paths to + * be ignored. The whole relative or absolute path is tested, not just filename. If a function + * with two arguments is provided, it gets called twice per path - once with a single argument + * (the path), second time with two arguments (the path and the + * [`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) object of that path). + */ + ignored?: any; + + /** + * If set to `false` then `add`/`addDir` events are also emitted for matching paths while + * instantiating the watching as chokidar discovers these file paths (before the `ready` event). + */ + ignoreInitial?: boolean; + + /** + * When `false`, only the symlinks themselves will be watched for changes instead of following + * the link references and bubbling events through the link's path. + */ + followSymlinks?: boolean; + + /** + * The base directory from which watch `paths` are to be derived. Paths emitted with events will + * be relative to this. + */ + cwd?: string; + + /** + * If set to true then the strings passed to .watch() and .add() are treated as literal path + * names, even if they look like globs. Default: false. + */ + disableGlobbing?: boolean; + + /** + * Whether to use fs.watchFile (backed by polling), or fs.watch. If polling leads to high CPU + * utilization, consider setting this to `false`. It is typically necessary to **set this to + * `true` to successfully watch files over a network**, and it may be necessary to successfully + * watch files in other non-standard situations. Setting to `true` explicitly on OS X overrides + * the `useFsEvents` default. + */ + usePolling?: boolean; + + /** + * Whether to use the `fsevents` watching interface if available. When set to `true` explicitly + * and `fsevents` is available this supercedes the `usePolling` setting. When set to `false` on + * OS X, `usePolling: true` becomes the default. + */ + useFsEvents?: boolean; + + /** + * If relying upon the [`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) object that + * may get passed with `add`, `addDir`, and `change` events, set this to `true` to ensure it is + * provided even in cases where it wasn't already available from the underlying watch events. + */ + alwaysStat?: boolean; + + /** + * If set, limits how many levels of subdirectories will be traversed. + */ + depth?: number; + + /** + * Interval of file system polling. + */ + interval?: number; + + /** + * Interval of file system polling for binary files. ([see list of binary extensions](https://gi + * thub.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json)) + */ + binaryInterval?: number; + + /** + * Indicates whether to watch files that don't have read permissions if possible. If watching + * fails due to `EPERM` or `EACCES` with this set to `true`, the errors will be suppressed + * silently. + */ + ignorePermissionErrors?: boolean; + + /** + * `true` if `useFsEvents` and `usePolling` are `false`). Automatically filters out artifacts + * that occur when using editors that use "atomic writes" instead of writing directly to the + * source file. If a file is re-added within 100 ms of being deleted, Chokidar emits a `change` + * event rather than `unlink` then `add`. If the default of 100 ms does not work well for you, + * you can override it by setting `atomic` to a custom value, in milliseconds. + */ + atomic?: boolean | number; + + /** + * can be set to an object in order to adjust timing params: + */ + awaitWriteFinish?: AwaitWriteFinishOptions | boolean; + } + + export interface AwaitWriteFinishOptions { + /** + * Amount of time in milliseconds for a file size to remain constant before emitting its event. + */ + stabilityThreshold?: number; + + /** + * File size polling interval. + */ + pollInterval?: number; + } + + /** + * produces an instance of `FSWatcher`. + */ + export function watch( + paths: string | string[], + options?: WatchOptions + ): FSWatcher; } \ No newline at end of file diff --git a/src/typings/electron.d.ts b/src/typings/electron.d.ts index 59163a017cc..c52a879c36f 100644 --- a/src/typings/electron.d.ts +++ b/src/typings/electron.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Electron 4.2.3 +// Type definitions for Electron 4.2.5 // Project: http://electronjs.org/ // Definitions by: The Electron Team // Definitions: https://github.com/electron/electron-typescript-definitions @@ -1338,16 +1338,21 @@ declare namespace Electron { removeListener(event: 'new-window-for-tab', listener: Function): this; /** * Emitted when the document changed its title, calling event.preventDefault() will - * prevent the native window's title from changing. + * prevent the native window's title from changing. explicitSet is false when title + * is synthesized from file url. */ on(event: 'page-title-updated', listener: (event: Event, - title: string, explicitSet: boolean) => void): this; + title: string, + explicitSet: boolean) => void): this; once(event: 'page-title-updated', listener: (event: Event, - title: string, explicitSet: boolean) => void): this; + title: string, + explicitSet: boolean) => void): this; addListener(event: 'page-title-updated', listener: (event: Event, - title: string, explicitSet: boolean) => void): this; + title: string, + explicitSet: boolean) => void): this; removeListener(event: 'page-title-updated', listener: (event: Event, - title: string, explicitSet: boolean) => void): this; + title: string, + explicitSet: boolean) => void): this; /** * Emitted when the web page has been rendered (while not being shown) and window * can be displayed without a visual flash. @@ -3355,35 +3360,6 @@ declare namespace Electron { type?: ('task' | 'separator' | 'file'); } - interface MemoryInfo { - - // Docs: http://electronjs.org/docs/api/structures/memory-info - - /** - * The maximum amount of memory that has ever been pinned to actual physical RAM. - * On macOS its value will always be 0. - */ - peakWorkingSetSize: number; - /** - * Process id of the process. - */ - pid: number; - /** - * The amount of memory not shared by other processes, such as JS heap or HTML - * content. - */ - privateBytes: number; - /** - * The amount of memory shared between processes, typically memory consumed by the - * Electron code itself - */ - sharedBytes: number; - /** - * The amount of memory currently pinned to actual physical RAM. - */ - workingSetSize: number; - } - interface MemoryUsageDetails { // Docs: http://electronjs.org/docs/api/structures/memory-usage-details @@ -5919,6 +5895,22 @@ declare namespace Electron { * Array of URLs. */ favicons: string[]) => void): this; + /** + * Fired when page title is set during navigation. explicitSet is false when title + * is synthesized from file url. + */ + on(event: 'page-title-updated', listener: (event: Event, + title: string, + explicitSet: boolean) => void): this; + once(event: 'page-title-updated', listener: (event: Event, + title: string, + explicitSet: boolean) => void): this; + addListener(event: 'page-title-updated', listener: (event: Event, + title: string, + explicitSet: boolean) => void): this; + removeListener(event: 'page-title-updated', listener: (event: Event, + title: string, + explicitSet: boolean) => void): this; /** * Emitted when a new frame is generated. Only the dirty area is passed in the * buffer. diff --git a/src/typings/gc-signals.d.ts b/src/typings/gc-signals.d.ts deleted file mode 100644 index 15af0411773..00000000000 --- a/src/typings/gc-signals.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -declare module 'gc-signals' { - export interface GCSignal { - } - /** - * Create a new GC signal. When being garbage collected the passed - * value is stored for later consumption. - */ - export const GCSignal: { - new(id: number): GCSignal; - }; - /** - * Consume ids of garbage collected signals. - */ - export function consumeSignals(): number[]; - export function onDidGarbageCollectSignals(callback: (ids: number[]) => any): { - dispose(): void; - }; - export function trackGarbageCollection(obj: any, id: number): number; -} \ No newline at end of file diff --git a/src/typings/lib.array-ext.d.ts b/src/typings/lib.array-ext.d.ts index 127f64e1fd4..5a77b70a9f2 100644 --- a/src/typings/lib.array-ext.d.ts +++ b/src/typings/lib.array-ext.d.ts @@ -4,6 +4,8 @@ *--------------------------------------------------------------------------------------------*/ interface ArrayConstructor { + isArray(arg: ReadonlyArray | null | undefined): arg is ReadonlyArray; + isArray(arg: Array | null | undefined): arg is Array; isArray(arg: any): arg is Array; isArray(arg: any): arg is Array; } \ No newline at end of file diff --git a/src/typings/vscode-nsfw.d.ts b/src/typings/nsfw.d.ts similarity index 95% rename from src/typings/vscode-nsfw.d.ts rename to src/typings/nsfw.d.ts index 5f70eb30f7b..f8bb423a2f8 100644 --- a/src/typings/vscode-nsfw.d.ts +++ b/src/typings/nsfw.d.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -declare module 'vscode-nsfw' { +declare module 'nsfw' { interface NsfwWatcher { start(): any; stop(): any; @@ -22,6 +22,7 @@ declare module 'vscode-nsfw' { directory: string; file?: string; newFile?: string; + newDirectory?: string; oldFile?: string; } diff --git a/src/typings/vscode-sqlite3.d.ts b/src/typings/vscode-sqlite3.d.ts index 4363d251c46..9a79c4ded1c 100644 --- a/src/typings/vscode-sqlite3.d.ts +++ b/src/typings/vscode-sqlite3.d.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Type definitions for sqlite3 3.1 -// Project: https://github.com/mapbox/node-sqlite3 +// Project: http://github.com/mapbox/node-sqlite3 // Definitions by: Nick Malaguti // Sumant Manne // Behind The Math @@ -18,6 +18,9 @@ declare module 'vscode-sqlite3' { export const OPEN_READONLY: number; export const OPEN_READWRITE: number; export const OPEN_CREATE: number; + export const OPEN_SHAREDCACHE: number; + export const OPEN_PRIVATECACHE: number; + export const OPEN_URI: number; export const cached: { Database(filename: string, callback?: (this: Database, err: Error | null) => void): Database; @@ -100,6 +103,9 @@ declare module 'vscode-sqlite3' { OPEN_READONLY: number; OPEN_READWRITE: number; OPEN_CREATE: number; + OPEN_SHAREDCACHE: number; + OPEN_PRIVATECACHE: number; + OPEN_URI: number; cached: typeof cached; RunResult: RunResult; Statement: typeof Statement; diff --git a/src/typings/vscode-textmate.d.ts b/src/typings/vscode-textmate.d.ts index 224b9100482..835b33008ac 100644 --- a/src/typings/vscode-textmate.d.ts +++ b/src/typings/vscode-textmate.d.ts @@ -30,7 +30,7 @@ declare module "vscode-textmate" { */ export interface RegistryOptions { theme?: IRawTheme; - loadGrammar(scopeName: string): Thenable | null; + loadGrammar(scopeName: string): Thenable; getInjections?(scopeName: string): string[]; getOnigLib?(): Thenable; } @@ -85,7 +85,7 @@ declare module "vscode-textmate" { * Load the grammar for `scopeName` and all referenced included grammars asynchronously. */ loadGrammar(initialScopeName: string): Thenable; - private _loadGrammar(initialScopeName, initialLanguage, embeddedLanguages, tokenTypes); + private _loadGrammar; /** * Adds a rawGrammar. */ @@ -182,7 +182,7 @@ declare module "vscode-textmate" { equals(other: StackElement): boolean; } export const INITIAL: StackElement; - export const parseRawGrammar: (content: string, filePath: string) => IRawGrammar; + export const parseRawGrammar: (content: string, filePath?: string) => IRawGrammar; export interface ILocation { readonly filename: string; readonly line: number; diff --git a/src/typings/xterm.d.ts b/src/typings/xterm.d.ts index 8b16ab82523..b41d12219a9 100644 --- a/src/typings/xterm.d.ts +++ b/src/typings/xterm.d.ts @@ -310,11 +310,6 @@ declare module 'xterm' { * The set of localizable strings. */ export interface ILocalizableStrings { - /** - * Announcement for a blank line when `screenReaderMode` is enabled. - */ - blankLine: string; - /** * The aria label for the underlying input textarea for the terminal. */ diff --git a/src/vs/base/browser/browser.ts b/src/vs/base/browser/browser.ts index 6a0cc217897..b447e0b68ec 100644 --- a/src/vs/base/browser/browser.ts +++ b/src/vs/base/browser/browser.ts @@ -122,6 +122,7 @@ export const isSafari = (!isChrome && (userAgent.indexOf('Safari') >= 0)); export const isWebkitWebView = (!isChrome && !isSafari && isWebKit); export const isIPad = (userAgent.indexOf('iPad') >= 0); export const isEdgeWebView = isEdge && (userAgent.indexOf('WebView/') >= 0); +export const isStandalone = (window.matchMedia('(display-mode: standalone)').matches); export function hasClipboardSupport() { if (isIE) { diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 90183d71270..d7d5621eec4 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -14,6 +14,8 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import { coalesce } from 'vs/base/common/arrays'; +import { URI } from 'vs/base/common/uri'; +import { Schemas } from 'vs/base/common/network'; export function clearNode(node: HTMLElement): void { while (node.firstChild) { @@ -38,12 +40,12 @@ export function isInDOM(node: Node | null): boolean { } interface IDomClassList { - hasClass(node: HTMLElement, className: string): boolean; - addClass(node: HTMLElement, className: string): void; - addClasses(node: HTMLElement, ...classNames: string[]): void; - removeClass(node: HTMLElement, className: string): void; - removeClasses(node: HTMLElement, ...classNames: string[]): void; - toggleClass(node: HTMLElement, className: string, shouldHaveIt?: boolean): void; + hasClass(node: HTMLElement | SVGElement, className: string): boolean; + addClass(node: HTMLElement | SVGElement, className: string): void; + addClasses(node: HTMLElement | SVGElement, ...classNames: string[]): void; + removeClass(node: HTMLElement | SVGElement, className: string): void; + removeClasses(node: HTMLElement | SVGElement, ...classNames: string[]): void; + toggleClass(node: HTMLElement | SVGElement, className: string, shouldHaveIt?: boolean): void; } const _manualClassList = new class implements IDomClassList { @@ -191,12 +193,12 @@ const _nativeClassList = new class implements IDomClassList { // In IE11 there is only partial support for `classList` which makes us keep our // custom implementation. Otherwise use the native implementation, see: http://caniuse.com/#search=classlist const _classList: IDomClassList = browser.isIE ? _manualClassList : _nativeClassList; -export const hasClass: (node: HTMLElement, className: string) => boolean = _classList.hasClass.bind(_classList); -export const addClass: (node: HTMLElement, className: string) => void = _classList.addClass.bind(_classList); -export const addClasses: (node: HTMLElement, ...classNames: string[]) => void = _classList.addClasses.bind(_classList); -export const removeClass: (node: HTMLElement, className: string) => void = _classList.removeClass.bind(_classList); -export const removeClasses: (node: HTMLElement, ...classNames: string[]) => void = _classList.removeClasses.bind(_classList); -export const toggleClass: (node: HTMLElement, className: string, shouldHaveIt?: boolean) => void = _classList.toggleClass.bind(_classList); +export const hasClass: (node: HTMLElement | SVGElement, className: string) => boolean = _classList.hasClass.bind(_classList); +export const addClass: (node: HTMLElement | SVGElement, className: string) => void = _classList.addClass.bind(_classList); +export const addClasses: (node: HTMLElement | SVGElement, ...classNames: string[]) => void = _classList.addClasses.bind(_classList); +export const removeClass: (node: HTMLElement | SVGElement, className: string) => void = _classList.removeClass.bind(_classList); +export const removeClasses: (node: HTMLElement | SVGElement, ...classNames: string[]) => void = _classList.removeClasses.bind(_classList); +export const toggleClass: (node: HTMLElement | SVGElement, className: string, shouldHaveIt?: boolean) => void = _classList.toggleClass.bind(_classList); class DomListener implements IDisposable { @@ -768,6 +770,10 @@ export function findParentWithClass(node: HTMLElement, clazz: string, stopAtClaz return null; } +export function hasParentWithClass(node: HTMLElement, clazz: string, stopAtClazzOrNode?: string | HTMLElement): boolean { + return !!findParentWithClass(node, clazz, stopAtClazzOrNode); +} + export function createStyleSheet(container: HTMLElement = document.getElementsByTagName('head')[0]): HTMLStyleElement { let style = document.createElement('style'); style.type = 'text/css'; @@ -800,8 +806,7 @@ export function createCSSRule(selector: string, cssText: string, style: HTMLStyl if (!style || !cssText) { return; } - - (style.sheet).insertRule(selector + '{' + cssText + '}', 0); + style.textContent = `${selector}{${cssText}}\n${style.textContent}`; } export function removeCSSRulesContainingSelector(ruleName: string, style: HTMLStyleElement = getSharedStyleSheet()): void { @@ -854,6 +859,8 @@ export const EventType = { ERROR: 'error', RESIZE: 'resize', SCROLL: 'scroll', + FULLSCREEN_CHANGE: 'fullscreenchange', + WK_FULLSCREEN_CHANGE: 'webkitfullscreenchange', // Form SELECT: 'select', CHANGE: 'change', @@ -983,14 +990,28 @@ export function prepend(parent: HTMLElement, child: T): T { const SELECTOR_REGEX = /([\w\-]+)?(#([\w\-]+))?((.([\w\-]+))*)/; -export function $(description: string, attrs?: { [key: string]: any; }, ...children: Array): T { +export enum Namespace { + HTML = 'http://www.w3.org/1999/xhtml', + SVG = 'http://www.w3.org/2000/svg' +} + +function _$(namespace: Namespace, description: string, attrs?: { [key: string]: any; }, ...children: Array): T { let match = SELECTOR_REGEX.exec(description); if (!match) { throw new Error('Bad use of emmet'); } - let result = document.createElement(match[1] || 'div'); + attrs = { ...(attrs || {}) }; + + let tagName = match[1] || 'div'; + let result: T; + + if (namespace !== Namespace.HTML) { + result = document.createElementNS(namespace as string, tagName) as T; + } else { + result = document.createElement(tagName) as unknown as T; + } if (match[3]) { result.id = match[3]; @@ -999,7 +1020,6 @@ export function $(description: string, attrs?: { [key: st result.className = match[4].replace(/\./g, ' ').trim(); } - attrs = attrs || {}; Object.keys(attrs).forEach(name => { const value = attrs![name]; if (/^on\w+$/.test(name)) { @@ -1026,6 +1046,14 @@ export function $(description: string, attrs?: { [key: st return result as T; } +export function $(description: string, attrs?: { [key: string]: any; }, ...children: Array): T { + return _$(Namespace.HTML, description, attrs, ...children); +} + +$.SVG = function (description: string, attrs?: { [key: string]: any; }, ...children: Array): T { + return _$(Namespace.SVG, description, attrs, ...children); +}; + export function join(nodes: Node[], separator: Node | string): Node[] { const result: Node[] = []; @@ -1155,3 +1183,23 @@ export function animate(fn: () => void): IDisposable { let stepDisposable = scheduleAtNextAnimationFrame(step); return toDisposable(() => stepDisposable.dispose()); } + + + +const _location = URI.parse(window.location.href); + +export function asDomUri(uri: URI): URI { + if (!uri) { + return uri; + } + if (!platform.isWeb) { + //todo@joh remove this once we have sw in electron going + return uri; + } + if (Schemas.vscodeRemote === uri.scheme) { + // rewrite vscode-remote-uris to uris of the window location + // so that they can be intercepted by the service worker + return _location.with({ path: '/vscode-resources/fetch', query: JSON.stringify({ u: uri.toJSON(), i: 1 }) }); + } + return uri; +} diff --git a/src/vs/base/browser/htmlContentRenderer.ts b/src/vs/base/browser/htmlContentRenderer.ts index a5c2821936d..4506912e178 100644 --- a/src/vs/base/browser/htmlContentRenderer.ts +++ b/src/vs/base/browser/htmlContentRenderer.ts @@ -6,7 +6,7 @@ import * as DOM from 'vs/base/browser/dom'; import { defaultGenerator } from 'vs/base/common/idGenerator'; import { escape } from 'vs/base/common/strings'; -import { removeMarkdownEscapes, IMarkdownString } from 'vs/base/common/htmlContent'; +import { removeMarkdownEscapes, IMarkdownString, parseHrefAndDimensions } from 'vs/base/common/htmlContent'; import * as marked from 'vs/base/common/marked/marked'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { DisposableStore } from 'vs/base/common/lifecycle'; @@ -75,12 +75,15 @@ export function renderMarkdown(markdown: IMarkdownString, options: RenderOptions return encodeURIComponent(JSON.stringify(data)); }; - const _href = function (href: string): string { + const _href = function (href: string, isDomUri: boolean): string { const data = markdown.uris && markdown.uris[href]; if (!data) { return href; } let uri = URI.revive(data); + if (isDomUri) { + uri = DOM.asDomUri(uri); + } if (uri.query) { uri = uri.with({ query: _uriMassage(uri.query) }); } @@ -97,29 +100,11 @@ export function renderMarkdown(markdown: IMarkdownString, options: RenderOptions const renderer = new marked.Renderer(); renderer.image = (href: string, title: string, text: string) => { - href = _href(href); let dimensions: string[] = []; - if (href) { - const splitted = href.split('|').map(s => s.trim()); - href = splitted[0]; - const parameters = splitted[1]; - if (parameters) { - const heightFromParams = /height=(\d+)/.exec(parameters); - const widthFromParams = /width=(\d+)/.exec(parameters); - const height = heightFromParams ? heightFromParams[1] : ''; - const width = widthFromParams ? widthFromParams[1] : ''; - const widthIsFinite = isFinite(parseInt(width)); - const heightIsFinite = isFinite(parseInt(height)); - if (widthIsFinite) { - dimensions.push(`width="${width}"`); - } - if (heightIsFinite) { - dimensions.push(`height="${height}"`); - } - } - } let attributes: string[] = []; if (href) { + ({ href, dimensions } = parseHrefAndDimensions(href)); + href = _href(href, true); attributes.push(`src="${href}"`); } if (text) { @@ -138,7 +123,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: RenderOptions if (href === text) { // raw link case text = removeMarkdownEscapes(text); } - href = _href(href); + href = _href(href, false); title = removeMarkdownEscapes(title); href = removeMarkdownEscapes(href); if ( diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index e76fd3a6bbc..ffef9180cc6 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -259,9 +259,6 @@ export class ActionViewItem extends BaseActionViewItem { this.label.setAttribute('role', 'menuitem'); } else { this.label.setAttribute('role', 'button'); - - // TODO @misolori remove before shipping stable - this.label.setAttribute('data-title', this._action.id); } } diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css index afade1a3413..1e49da134fd 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css @@ -31,12 +31,16 @@ } .monaco-breadcrumbs .monaco-breadcrumb-item:not(:nth-child(2))::before { - background-image: url(./collapsed.svg); + background-image: url(./tree-collapsed-light.svg); opacity: .7; background-size: 16px; background-position: 50% 50%; } .vs-dark .monaco-breadcrumbs .monaco-breadcrumb-item:not(:nth-child(2))::before { - background-image: url(./collpased-dark.svg); + background-image: url(./tree-collapsed-dark.svg); +} + +.hc-black .monaco-breadcrumbs .monaco-breadcrumb-item:not(:nth-child(2))::before { + background-image: url(./tree-collapsed-hc.svg); } diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index bdbce4e9e30..13e4b9c34be 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -57,7 +57,7 @@ export interface IBreadcrumbsItemEvent { export class BreadcrumbsWidget { - private readonly _disposables = new Array(); + private readonly _disposables = new DisposableStore(); private readonly _domNode: HTMLDivElement; private readonly _styleElement: HTMLStyleElement; private readonly _scrollable: DomScrollableElement; @@ -94,26 +94,25 @@ export class BreadcrumbsWidget { useShadows: false, scrollYToX: true }); - this._disposables.push(this._scrollable); - this._disposables.push(dom.addStandardDisposableListener(this._domNode, 'click', e => this._onClick(e))); + this._disposables.add(this._scrollable); + this._disposables.add(dom.addStandardDisposableListener(this._domNode, 'click', e => this._onClick(e))); container.appendChild(this._scrollable.getDomNode()); this._styleElement = dom.createStyleSheet(this._domNode); - let focusTracker = dom.trackFocus(this._domNode); - this._disposables.push(focusTracker); - this._disposables.push(focusTracker.onDidBlur(_ => this._onDidChangeFocus.fire(false))); - this._disposables.push(focusTracker.onDidFocus(_ => this._onDidChangeFocus.fire(true))); + const focusTracker = dom.trackFocus(this._domNode); + this._disposables.add(focusTracker); + this._disposables.add(focusTracker.onDidBlur(_ => this._onDidChangeFocus.fire(false))); + this._disposables.add(focusTracker.onDidFocus(_ => this._onDidChangeFocus.fire(true))); } dispose(): void { - dispose(this._disposables); + this._disposables.dispose(); dispose(this._pendingLayout); this._onDidSelectItem.dispose(); this._onDidFocusItem.dispose(); this._onDidChangeFocus.dispose(); this._domNode.remove(); - this._disposables.length = 0; this._nodes.length = 0; this._freeNodes.length = 0; } diff --git a/src/vs/base/browser/ui/breadcrumbs/collapsed.svg b/src/vs/base/browser/ui/breadcrumbs/collapsed.svg deleted file mode 100755 index 3a63808c358..00000000000 --- a/src/vs/base/browser/ui/breadcrumbs/collapsed.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/breadcrumbs/collpased-dark.svg b/src/vs/base/browser/ui/breadcrumbs/collpased-dark.svg deleted file mode 100755 index cf5c3641aa7..00000000000 --- a/src/vs/base/browser/ui/breadcrumbs/collpased-dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/breadcrumbs/tree-collapsed-dark.svg b/src/vs/base/browser/ui/breadcrumbs/tree-collapsed-dark.svg new file mode 100644 index 00000000000..243be1451cc --- /dev/null +++ b/src/vs/base/browser/ui/breadcrumbs/tree-collapsed-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/breadcrumbs/tree-collapsed-hc.svg b/src/vs/base/browser/ui/breadcrumbs/tree-collapsed-hc.svg new file mode 100644 index 00000000000..40ba72b7086 --- /dev/null +++ b/src/vs/base/browser/ui/breadcrumbs/tree-collapsed-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/breadcrumbs/tree-collapsed-light.svg b/src/vs/base/browser/ui/breadcrumbs/tree-collapsed-light.svg new file mode 100644 index 00000000000..0d746558a4f --- /dev/null +++ b/src/vs/base/browser/ui/breadcrumbs/tree-collapsed-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/countBadge/countBadge.css b/src/vs/base/browser/ui/countBadge/countBadge.css index 7429322f3e6..909fa7c8e78 100644 --- a/src/vs/base/browser/ui/countBadge/countBadge.css +++ b/src/vs/base/browser/ui/countBadge/countBadge.css @@ -4,11 +4,12 @@ *--------------------------------------------------------------------------------------------*/ .monaco-count-badge { - padding: 0.3em 0.5em; - border-radius: 1em; - font-size: 85%; - min-width: 1.6em; - line-height: 1em; + padding: 3px 5px; + border-radius: 11px; + font-size: 11px; + min-width: 18px; + min-height: 18px; + line-height: 11px; font-weight: normal; text-align: center; display: inline-block; diff --git a/src/vs/base/browser/ui/dialog/close-dark.svg b/src/vs/base/browser/ui/dialog/close-dark.svg new file mode 100644 index 00000000000..7305a8f099a --- /dev/null +++ b/src/vs/base/browser/ui/dialog/close-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/dialog/close-inverse.svg b/src/vs/base/browser/ui/dialog/close-inverse.svg deleted file mode 100644 index a174033d912..00000000000 --- a/src/vs/base/browser/ui/dialog/close-inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/dialog/close-light.svg b/src/vs/base/browser/ui/dialog/close-light.svg new file mode 100644 index 00000000000..ecddcd665b5 --- /dev/null +++ b/src/vs/base/browser/ui/dialog/close-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/dialog/close.svg b/src/vs/base/browser/ui/dialog/close.svg deleted file mode 100644 index f4038b8bfa5..00000000000 --- a/src/vs/base/browser/ui/dialog/close.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/dialog/dialog.css b/src/vs/base/browser/ui/dialog/dialog.css index c909dada79e..e05ed90a949 100644 --- a/src/vs/base/browser/ui/dialog/dialog.css +++ b/src/vs/base/browser/ui/dialog/dialog.css @@ -47,12 +47,12 @@ .monaco-workbench .dialog-box .dialog-close-action { - background: url('close.svg') center center no-repeat; + background: url('close-light.svg') center center no-repeat; } .vs-dark .monaco-workbench .dialog-box .dialog-close-action, .hc-black .monaco-workbench .dialog-box .dialog-close-action { - background: url('close-inverse.svg') center center no-repeat; + background: url('close-dark.svg') center center no-repeat; } /** Dialog: Message Row */ @@ -64,12 +64,12 @@ } .monaco-workbench .dialog-box .dialog-message-row .dialog-icon { - flex: 0 0 30px; - height: 30px; - padding-right: 4px; - padding-left: 4px; + flex: 0 0 40px; + height: 40px; + align-self: baseline; background-position: center; background-repeat: no-repeat; + background-size: 40px; } .vs .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-pending { @@ -77,15 +77,15 @@ } .vs .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-info { - background-image: url('info.svg'); + background-image: url('info-light.svg'); } .vs .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-warning { - background-image: url('warning.svg'); + background-image: url('warning-light.svg'); } .vs .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-error { - background-image: url('error.svg'); + background-image: url('error-light.svg'); } .vs-dark .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-pending { @@ -94,17 +94,17 @@ .vs-dark .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-info, .hc-black .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-info { - background-image: url('info-inverse.svg'); + background-image: url('info-dark.svg'); } .vs-dark .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-warning, .hc-black .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-warning { - background-image: url('warning-inverse.svg'); + background-image: url('warning-dark.svg'); } .vs-dark .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-error, .hc-black .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-error { - background-image: url('error-inverse.svg'); + background-image: url('error-dark.svg'); } .hc-black .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-pending { diff --git a/src/vs/workbench/browser/media/images/notifications/error-alt1.svg b/src/vs/base/browser/ui/dialog/error-dark.svg similarity index 95% rename from src/vs/workbench/browser/media/images/notifications/error-alt1.svg rename to src/vs/base/browser/ui/dialog/error-dark.svg index e39bf5e0e4a..efdc5f2ae2d 100644 --- a/src/vs/workbench/browser/media/images/notifications/error-alt1.svg +++ b/src/vs/base/browser/ui/dialog/error-dark.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/base/browser/ui/dialog/error-inverse.svg b/src/vs/base/browser/ui/dialog/error-inverse.svg deleted file mode 100644 index 51e9dc81b99..00000000000 --- a/src/vs/base/browser/ui/dialog/error-inverse.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/src/vs/base/browser/ui/dialog/error-light.svg b/src/vs/base/browser/ui/dialog/error-light.svg new file mode 100644 index 00000000000..d646c72c740 --- /dev/null +++ b/src/vs/base/browser/ui/dialog/error-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/dialog/error.svg b/src/vs/base/browser/ui/dialog/error.svg deleted file mode 100644 index 04b66689011..00000000000 --- a/src/vs/base/browser/ui/dialog/error.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/src/vs/base/browser/ui/dialog/info-dark.svg b/src/vs/base/browser/ui/dialog/info-dark.svg new file mode 100644 index 00000000000..bb851afdfe5 --- /dev/null +++ b/src/vs/base/browser/ui/dialog/info-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/dialog/info-inverse.svg b/src/vs/base/browser/ui/dialog/info-inverse.svg deleted file mode 100644 index 64b801a63be..00000000000 --- a/src/vs/base/browser/ui/dialog/info-inverse.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - diff --git a/src/vs/base/browser/ui/dialog/info-light.svg b/src/vs/base/browser/ui/dialog/info-light.svg new file mode 100644 index 00000000000..6faf670cccc --- /dev/null +++ b/src/vs/base/browser/ui/dialog/info-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/base/browser/ui/dialog/info.svg b/src/vs/base/browser/ui/dialog/info.svg deleted file mode 100644 index 3c603528a74..00000000000 --- a/src/vs/base/browser/ui/dialog/info.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - diff --git a/src/vs/base/browser/ui/dialog/warning-dark.svg b/src/vs/base/browser/ui/dialog/warning-dark.svg new file mode 100644 index 00000000000..a267963e585 --- /dev/null +++ b/src/vs/base/browser/ui/dialog/warning-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/dialog/warning-inverse.svg b/src/vs/base/browser/ui/dialog/warning-inverse.svg deleted file mode 100644 index a7f4afbcc9c..00000000000 --- a/src/vs/base/browser/ui/dialog/warning-inverse.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - -StatusWarning_16x - - - - - diff --git a/src/vs/base/browser/ui/dialog/warning-light.svg b/src/vs/base/browser/ui/dialog/warning-light.svg new file mode 100644 index 00000000000..f2e2aa741e5 --- /dev/null +++ b/src/vs/base/browser/ui/dialog/warning-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/base/browser/ui/dialog/warning.svg b/src/vs/base/browser/ui/dialog/warning.svg deleted file mode 100644 index 6d8cffe913e..00000000000 --- a/src/vs/base/browser/ui/dialog/warning.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - -StatusWarning_16x - - - - - diff --git a/src/vs/base/browser/ui/dropdown/dropdown.ts b/src/vs/base/browser/ui/dropdown/dropdown.ts index ac1557375b5..1f9217cc9dd 100644 --- a/src/vs/base/browser/ui/dropdown/dropdown.ts +++ b/src/vs/base/browser/ui/dropdown/dropdown.ts @@ -108,6 +108,10 @@ export class BaseDropdown extends ActionRunner { this.visible = false; } + isVisible(): boolean { + return this.visible; + } + protected onEvent(e: Event, activeElement: HTMLElement): void { this.hide(); } diff --git a/src/vs/base/browser/ui/findinput/case-sensitive-dark.svg b/src/vs/base/browser/ui/findinput/case-sensitive-dark.svg index ae540172027..40c9ed3262c 100644 --- a/src/vs/base/browser/ui/findinput/case-sensitive-dark.svg +++ b/src/vs/base/browser/ui/findinput/case-sensitive-dark.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/src/vs/base/browser/ui/findinput/case-sensitive-hc.svg b/src/vs/base/browser/ui/findinput/case-sensitive-hc.svg new file mode 100644 index 00000000000..82501418dae --- /dev/null +++ b/src/vs/base/browser/ui/findinput/case-sensitive-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/findinput/case-sensitive-light.svg b/src/vs/base/browser/ui/findinput/case-sensitive-light.svg new file mode 100644 index 00000000000..aa1dbd353e4 --- /dev/null +++ b/src/vs/base/browser/ui/findinput/case-sensitive-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/findinput/case-sensitive.svg b/src/vs/base/browser/ui/findinput/case-sensitive.svg deleted file mode 100644 index 1f3b1a2c57e..00000000000 --- a/src/vs/base/browser/ui/findinput/case-sensitive.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/findinput/findInputCheckboxes.css b/src/vs/base/browser/ui/findinput/findInputCheckboxes.css index 37e890d7f89..50ed9346a6c 100644 --- a/src/vs/base/browser/ui/findinput/findInputCheckboxes.css +++ b/src/vs/base/browser/ui/findinput/findInputCheckboxes.css @@ -4,28 +4,40 @@ *--------------------------------------------------------------------------------------------*/ .vs .monaco-custom-checkbox.monaco-case-sensitive { - background: url('case-sensitive.svg') center center no-repeat; + background: url('case-sensitive-light.svg') center center no-repeat; } -.hc-black .monaco-custom-checkbox.monaco-case-sensitive, -.hc-black .monaco-custom-checkbox.monaco-case-sensitive:hover, + .vs-dark .monaco-custom-checkbox.monaco-case-sensitive { background: url('case-sensitive-dark.svg') center center no-repeat; } -.vs .monaco-custom-checkbox.monaco-whole-word { - background: url('whole-word.svg') center center no-repeat; +.hc-black .monaco-custom-checkbox.monaco-case-sensitive, +.hc-black .monaco-custom-checkbox.monaco-case-sensitive:hover { + background: url('case-sensitive-hc.svg') center center no-repeat; } -.hc-black .monaco-custom-checkbox.monaco-whole-word, -.hc-black .monaco-custom-checkbox.monaco-whole-word:hover, + +.vs .monaco-custom-checkbox.monaco-whole-word { + background: url('whole-word-light.svg') center center no-repeat; +} + .vs-dark .monaco-custom-checkbox.monaco-whole-word { background: url('whole-word-dark.svg') center center no-repeat; } -.vs .monaco-custom-checkbox.monaco-regex { - background: url('regex.svg') center center no-repeat; +.hc-black .monaco-custom-checkbox.monaco-whole-word, +.hc-black .monaco-custom-checkbox.monaco-whole-word:hover { + background: url('whole-word-hc.svg') center center no-repeat; } -.hc-black .monaco-custom-checkbox.monaco-regex, -.hc-black .monaco-custom-checkbox.monaco-regex:hover, + +.vs .monaco-custom-checkbox.monaco-regex { + background: url('regex-light.svg') center center no-repeat; +} + .vs-dark .monaco-custom-checkbox.monaco-regex { background: url('regex-dark.svg') center center no-repeat; } + +.hc-black .monaco-custom-checkbox.monaco-regex, +.hc-black .monaco-custom-checkbox.monaco-regex:hover { + background: url('regex-hc.svg') center center no-repeat; +} \ No newline at end of file diff --git a/src/vs/base/browser/ui/findinput/regex-dark.svg b/src/vs/base/browser/ui/findinput/regex-dark.svg index c303032e6a9..cf43e9d952e 100644 --- a/src/vs/base/browser/ui/findinput/regex-dark.svg +++ b/src/vs/base/browser/ui/findinput/regex-dark.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/src/vs/base/browser/ui/findinput/regex-hc.svg b/src/vs/base/browser/ui/findinput/regex-hc.svg new file mode 100644 index 00000000000..116c547d15f --- /dev/null +++ b/src/vs/base/browser/ui/findinput/regex-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/findinput/regex-light.svg b/src/vs/base/browser/ui/findinput/regex-light.svg new file mode 100644 index 00000000000..b329c104fa2 --- /dev/null +++ b/src/vs/base/browser/ui/findinput/regex-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/findinput/regex.svg b/src/vs/base/browser/ui/findinput/regex.svg deleted file mode 100644 index c677843beef..00000000000 --- a/src/vs/base/browser/ui/findinput/regex.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/findinput/whole-word-dark.svg b/src/vs/base/browser/ui/findinput/whole-word-dark.svg index d18e144f318..6c38eb215d3 100644 --- a/src/vs/base/browser/ui/findinput/whole-word-dark.svg +++ b/src/vs/base/browser/ui/findinput/whole-word-dark.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/src/vs/base/browser/ui/findinput/whole-word-hc.svg b/src/vs/base/browser/ui/findinput/whole-word-hc.svg new file mode 100644 index 00000000000..fc1ff43268b --- /dev/null +++ b/src/vs/base/browser/ui/findinput/whole-word-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/findinput/whole-word-light.svg b/src/vs/base/browser/ui/findinput/whole-word-light.svg new file mode 100644 index 00000000000..345e65b2a5c --- /dev/null +++ b/src/vs/base/browser/ui/findinput/whole-word-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/findinput/whole-word.svg b/src/vs/base/browser/ui/findinput/whole-word.svg deleted file mode 100644 index 8244d95abdf..00000000000 --- a/src/vs/base/browser/ui/findinput/whole-word.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/grid/grid.ts b/src/vs/base/browser/ui/grid/grid.ts index 4178efc9e98..8297b231ced 100644 --- a/src/vs/base/browser/ui/grid/grid.ts +++ b/src/vs/base/browser/ui/grid/grid.ts @@ -7,7 +7,7 @@ import 'vs/css!./gridview'; import { Orientation } from 'vs/base/browser/ui/sash/sash'; import { Disposable } from 'vs/base/common/lifecycle'; import { tail2 as tail, equals } from 'vs/base/common/arrays'; -import { orthogonal, IView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles } from './gridview'; +import { orthogonal, IView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles, IViewSize } from './gridview'; import { Event, Emitter } from 'vs/base/common/event'; import { $ } from 'vs/base/browser/dom'; import { LayoutPriority } from 'vs/base/browser/ui/splitview/splitview'; @@ -117,10 +117,6 @@ function getDirectionOrientation(direction: Direction): Orientation { return direction === Direction.Up || direction === Direction.Down ? Orientation.VERTICAL : Orientation.HORIZONTAL; } -function getSize(dimensions: { width: number; height: number; }, orientation: Orientation) { - return orientation === Orientation.HORIZONTAL ? dimensions.width : dimensions.height; -} - export function getRelativeLocation(rootOrientation: Orientation, location: number[], direction: Direction): number[] { const orientation = getLocationOrientation(rootOrientation, location); const directionOrientation = getDirectionOrientation(direction); @@ -209,8 +205,6 @@ export class Grid extends Disposable { get element(): HTMLElement { return this.gridview.element; } - sashResetSizing: Sizing = Sizing.Distribute; - constructor(view: T, options: IGridOptions = {}) { super(); this.gridview = new GridView(options); @@ -298,15 +292,14 @@ export class Grid extends Disposable { return this.gridview.swapViews(fromLocation, toLocation); } - resizeView(view: T, size: number): void { + resizeView(view: T, size: IViewSize): void { const location = this.getViewLocation(view); return this.gridview.resizeView(location, size); } - getViewSize(view: T): number { + getViewSize(view: T): IViewSize { const location = this.getViewLocation(view); - const viewSize = this.gridview.getViewSize(location); - return getLocationOrientation(this.orientation, location) === Orientation.HORIZONTAL ? viewSize.width : viewSize.height; + return this.gridview.getViewSize(location); } // TODO@joao cleanup @@ -361,18 +354,8 @@ export class Grid extends Disposable { } private doResetViewSize(location: number[]): void { - if (this.sashResetSizing === Sizing.Split) { - const orientation = getLocationOrientation(this.orientation, location); - const firstViewSize = getSize(this.gridview.getViewSize(location), orientation); - const [parentLocation, index] = tail(location); - const secondViewSize = getSize(this.gridview.getViewSize([...parentLocation, index + 1]), orientation); - const totalSize = firstViewSize + secondViewSize; - this.gridview.resizeView(location, Math.floor(totalSize / 2)); - - } else { - const [parentLocation,] = tail(location); - this.gridview.distributeViewSizes(parentLocation); - } + const [parentLocation,] = tail(location); + this.gridview.distributeViewSizes(parentLocation); } } @@ -563,8 +546,11 @@ export class SerializableGrid extends Grid { const childLocation = [...location, i]; if (i < node.children.length - 1) { - const size = orientation === Orientation.VERTICAL ? child.box.height : child.box.width; - this.gridview.resizeView(childLocation, Math.floor(size * scale)); + const size = orientation === Orientation.VERTICAL + ? { height: Math.floor(child.box.height * scale) } + : { width: Math.floor(child.box.width * scale) }; + + this.gridview.resizeView(childLocation, size); } this.restoreViewsSize(childLocation, child, orthogonal(orientation), widthScale, heightScale); diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index e4e6f8909ad..8b1a39d02d9 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -15,13 +15,18 @@ import { Color } from 'vs/base/common/color'; export { Sizing, LayoutPriority } from 'vs/base/browser/ui/splitview/splitview'; export { Orientation } from 'vs/base/browser/ui/sash/sash'; +export interface IViewSize { + readonly width: number; + readonly height: number; +} + export interface IView { readonly element: HTMLElement; readonly minimumWidth: number; readonly maximumWidth: number; readonly minimumHeight: number; readonly maximumHeight: number; - readonly onDidChange: Event<{ width: number; height: number; } | undefined>; + readonly onDidChange: Event; readonly priority?: LayoutPriority; readonly snapSize?: number; layout(width: number, height: number, orientation: Orientation): void; @@ -573,7 +578,7 @@ export class GridView implements IDisposable { get maximumWidth(): number { return this.root.maximumHeight; } get maximumHeight(): number { return this.root.maximumHeight; } - private _onDidChange = new Relay<{ width: number; height: number; } | undefined>(); + private _onDidChange = new Relay(); readonly onDidChange = this._onDidChange.event; constructor(options: IGridViewOptions = {}) { @@ -747,18 +752,33 @@ export class GridView implements IDisposable { } } - resizeView(location: number[], size: number): void { + resizeView(location: number[], { width, height }: Partial): void { const [rest, index] = tail(location); - const [, parent] = this.getNode(rest); + const [pathToParent, parent] = this.getNode(rest); if (!(parent instanceof BranchNode)) { throw new Error('Invalid location'); } - parent.resizeChild(index, size); + if (!width && !height) { + return; + } + + const [parentSize, grandParentSize] = parent.orientation === Orientation.HORIZONTAL ? [width, height] : [height, width]; + + if (typeof grandParentSize === 'number' && pathToParent.length > 0) { + const [, grandParent] = tail(pathToParent); + const [, parentIndex] = tail(rest); + + grandParent.resizeChild(parentIndex, grandParentSize); + } + + if (typeof parentSize === 'number') { + parent.resizeChild(index, parentSize); + } } - getViewSize(location: number[]): { width: number; height: number; } { + getViewSize(location: number[]): IViewSize { const [, node] = this.getNode(location); return { width: node.width, height: node.height }; } diff --git a/src/vs/base/browser/ui/list/list.css b/src/vs/base/browser/ui/list/list.css index 73756ce7811..3aa2e653473 100644 --- a/src/vs/base/browser/ui/list/list.css +++ b/src/vs/base/browser/ui/list/list.css @@ -186,9 +186,9 @@ /* Electron */ .monaco-list-type-filter { - cursor: -webkit-grab; + cursor: grab; } .monaco-list-type-filter.dragging { - cursor: -webkit-grabbing; + cursor: grabbing; } \ No newline at end of file diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index 1a8ac09277c..d42777bec4b 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -41,9 +41,11 @@ export interface IListViewDragAndDrop extends IListDragAndDrop { getDragElements(element: T): T[]; } -export interface IAriaSetProvider { +export interface IAriaProvider { getSetSize(element: T, index: number, listLength: number): number; getPosInSet(element: T, index: number): number; + getRole?(element: T): string; + isChecked?(element: T): boolean; } export interface IListViewOptions { @@ -54,7 +56,7 @@ export interface IListViewOptions { readonly supportDynamicHeights?: boolean; readonly mouseSupport?: boolean; readonly horizontalScrolling?: boolean; - readonly ariaSetProvider?: IAriaSetProvider; + readonly ariaProvider?: IAriaProvider; } const DefaultOptions = { @@ -174,7 +176,7 @@ export class ListView implements ISpliceable, IDisposable { private setRowLineHeight: boolean; private supportDynamicHeights: boolean; private horizontalScrolling: boolean; - private ariaSetProvider: IAriaSetProvider; + private ariaProvider: IAriaProvider; private scrollWidth: number | undefined; private canUseTranslate3d: boolean | undefined = undefined; @@ -227,7 +229,7 @@ export class ListView implements ISpliceable, IDisposable { this.horizontalScrolling = getOrDefault(options, o => o.horizontalScrolling, DefaultOptions.horizontalScrolling); DOM.toggleClass(this.domNode, 'horizontal-scrolling', this.horizontalScrolling); - this.ariaSetProvider = options.ariaSetProvider || { getSetSize: (e, i, length) => length, getPosInSet: (_, index) => index + 1 }; + this.ariaProvider = options.ariaProvider || { getSetSize: (e, i, length) => length, getPosInSet: (_, index) => index + 1 }; this.rowsContainer = document.createElement('div'); this.rowsContainer.className = 'monaco-list-rows'; @@ -566,7 +568,12 @@ export class ListView implements ISpliceable, IDisposable { if (!item.row) { item.row = this.cache.alloc(item.templateId); - item.row!.domNode!.setAttribute('role', 'treeitem'); + const role = this.ariaProvider.getRole ? this.ariaProvider.getRole(item.element) : 'treeitem'; + item.row!.domNode!.setAttribute('role', role); + const checked = this.ariaProvider.isChecked ? this.ariaProvider.isChecked(item.element) : undefined; + if (typeof checked !== 'undefined') { + item.row!.domNode!.setAttribute('aria-checked', String(checked)); + } } if (!item.row.domNode!.parentElement) { @@ -634,8 +641,8 @@ export class ListView implements ISpliceable, IDisposable { item.row!.domNode!.setAttribute('data-index', `${index}`); item.row!.domNode!.setAttribute('data-last-element', index === this.length - 1 ? 'true' : 'false'); - item.row!.domNode!.setAttribute('aria-setsize', String(this.ariaSetProvider.getSetSize(item.element, index, this.length))); - item.row!.domNode!.setAttribute('aria-posinset', String(this.ariaSetProvider.getPosInSet(item.element, index))); + item.row!.domNode!.setAttribute('aria-setsize', String(this.ariaProvider.getSetSize(item.element, index, this.length))); + item.row!.domNode!.setAttribute('aria-posinset', String(this.ariaProvider.getPosInSet(item.element, index))); item.row!.domNode!.setAttribute('id', this.getElementDomId(index)); DOM.toggleClass(item.row!.domNode!, 'drop-target', item.dropTarget); diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index b3cc40b3eee..0e0a4df34bc 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -5,7 +5,7 @@ import 'vs/css!./list'; import { localize } from 'vs/nls'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; import { isNumber } from 'vs/base/common/types'; import { range, firstIndex, binarySearch } from 'vs/base/common/arrays'; import { memoize } from 'vs/base/common/decorators'; @@ -17,7 +17,7 @@ import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardE import { Event, Emitter, EventBufferer } from 'vs/base/common/event'; import { domEvent } from 'vs/base/browser/event'; import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IIdentityProvider, IKeyboardNavigationLabelProvider, IListDragAndDrop, IListDragOverReaction, ListAriaRootRole } from './list'; -import { ListView, IListViewOptions, IListViewDragAndDrop, IAriaSetProvider } from './listView'; +import { ListView, IListViewOptions, IListViewDragAndDrop, IAriaProvider } from './listView'; import { Color } from 'vs/base/common/color'; import { mixin } from 'vs/base/common/objects'; import { ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable'; @@ -228,7 +228,7 @@ function isInputElement(e: HTMLElement): boolean { class KeyboardController implements IDisposable { - private disposables: IDisposable[]; + private readonly disposables = new DisposableStore(); private openController: IOpenController; constructor( @@ -237,7 +237,6 @@ class KeyboardController implements IDisposable { options: IListOptions ) { const multipleSelectionSupport = !(options.multipleSelectionSupport === false); - this.disposables = []; this.openController = options.openController || DefaultOpenController; @@ -314,7 +313,7 @@ class KeyboardController implements IDisposable { } dispose() { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -341,8 +340,8 @@ class TypeLabelController implements IDisposable { private automaticKeyboardNavigation = true; private triggered = false; - private enabledDisposables: IDisposable[] = []; - private disposables: IDisposable[] = []; + private readonly enabledDisposables = new DisposableStore(); + private readonly disposables = new DisposableStore(); constructor( private list: List, @@ -398,7 +397,7 @@ class TypeLabelController implements IDisposable { return; } - this.enabledDisposables = dispose(this.enabledDisposables); + this.enabledDisposables.clear(); this.enabled = false; this.triggered = false; } @@ -430,20 +429,19 @@ class TypeLabelController implements IDisposable { dispose() { this.disable(); - this.disposables = dispose(this.disposables); + this.enabledDisposables.dispose(); + this.disposables.dispose(); } } class DOMFocusController implements IDisposable { - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor( private list: List, private view: ListView ) { - this.disposables = []; - const onKeyDown = Event.chain(domEvent(view.domNode, 'keydown')) .filter(e => !isInputElement(e.target as HTMLElement)) .map(e => new StandardKeyboardEvent(e)); @@ -486,7 +484,7 @@ class DOMFocusController implements IDisposable { } dispose() { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -523,7 +521,7 @@ export class MouseController implements IDisposable { readonly multipleSelectionController: IMultipleSelectionController; private openController: IOpenController; private mouseSupport: boolean; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); constructor(protected list: List) { this.multipleSelectionSupport = !(list.options.multipleSelectionSupport === false); @@ -663,7 +661,7 @@ export class MouseController implements IDisposable { } dispose() { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } @@ -833,7 +831,7 @@ export interface IListOptions extends IListStyles { readonly supportDynamicHeights?: boolean; readonly mouseSupport?: boolean; readonly horizontalScrolling?: boolean; - readonly ariaSetProvider?: IAriaSetProvider; + readonly ariaProvider?: IAriaProvider; } export interface IListStyles { @@ -857,6 +855,7 @@ export interface IListStyles { listFilterWidgetOutline?: Color; listFilterWidgetNoMatchesOutline?: Color; listMatchesShadow?: Color; + treeIndentGuidesStroke?: Color; } const defaultStyles: IListStyles = { @@ -867,7 +866,8 @@ const defaultStyles: IListStyles = { listFocusAndSelectionForeground: Color.fromHex('#FFFFFF'), listInactiveSelectionBackground: Color.fromHex('#3F3F46'), listHoverBackground: Color.fromHex('#2A2D2E'), - listDropBackground: Color.fromHex('#383B3D') + listDropBackground: Color.fromHex('#383B3D'), + treeIndentGuidesStroke: Color.fromHex('#a9a9a9') }; const DefaultOptions = { @@ -1094,7 +1094,7 @@ export class List implements ISpliceable, IDisposable { private styleController: IStyleController; private typeLabelController?: TypeLabelController; - protected disposables: IDisposable[]; + protected readonly disposables = new DisposableStore(); @memoize get onFocusChange(): Event> { return Event.map(this.eventBufferer.wrapEvent(this.focus.onChange), e => this.toListEvent(e)); @@ -1112,6 +1112,7 @@ export class List implements ISpliceable, IDisposable { return Event.map(this._onPin.event, indexes => this.toListEvent({ indexes })); } + get domId(): string { return this.view.domId; } get onDidScroll(): Event { return this.view.onDidScroll; } get onMouseClick(): Event> { return this.view.onMouseClick; } get onMouseDblClick(): Event> { return this.view.onMouseDblClick; } @@ -1207,24 +1208,27 @@ export class List implements ISpliceable, IDisposable { this.view ]); - this.disposables = [this.focus, this.selection, this.view, this._onDidDispose]; + this.disposables.add(this.focus); + this.disposables.add(this.selection); + this.disposables.add(this.view); + this.disposables.add(this._onDidDispose); this.onDidFocus = Event.map(domEvent(this.view.domNode, 'focus', true), () => null!); this.onDidBlur = Event.map(domEvent(this.view.domNode, 'blur', true), () => null!); - this.disposables.push(new DOMFocusController(this, this.view)); + this.disposables.add(new DOMFocusController(this, this.view)); if (typeof _options.keyboardSupport !== 'boolean' || _options.keyboardSupport) { const controller = new KeyboardController(this, this.view, _options); - this.disposables.push(controller); + this.disposables.add(controller); } if (_options.keyboardNavigationLabelProvider) { this.typeLabelController = new TypeLabelController(this, this.view, _options.keyboardNavigationLabelProvider); - this.disposables.push(this.typeLabelController); + this.disposables.add(this.typeLabelController); } - this.disposables.push(this.createMouseController(_options)); + this.disposables.add(this.createMouseController(_options)); this.onFocusChange(this._onFocusChange, this, this.disposables); this.onSelectionChange(this._onSelectionChange, this, this.disposables); @@ -1607,7 +1611,7 @@ export class List implements ISpliceable, IDisposable { dispose(): void { this._onDidDispose.fire(); - this.disposables = dispose(this.disposables); + this.disposables.dispose(); this._onDidOpen.dispose(); this._onPin.dispose(); diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 57268648e33..7913bb42fd5 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -18,7 +18,7 @@ import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableEle import { ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable'; import { Event, Emitter } from 'vs/base/common/event'; import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview'; -import { isLinux } from 'vs/base/common/platform'; +import { isLinux, isMacintosh } from 'vs/base/common/platform'; function createMenuMnemonicRegExp() { try { @@ -91,7 +91,7 @@ export class Menu extends ActionBar { context: options.context, actionRunner: options.actionRunner, ariaLabel: options.ariaLabel, - triggerKeys: { keys: [KeyCode.Enter], keyDown: true } + triggerKeys: { keys: [KeyCode.Enter, ...(isMacintosh ? [KeyCode.Space] : [])], keyDown: true } }); this.menuElement = menuElement; @@ -109,7 +109,7 @@ export class Menu extends ActionBar { // Stop tab navigation of menus if (event.equals(KeyCode.Tab)) { - EventHelper.stop(e, true); + e.preventDefault(); } }); diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index 280c102f541..1ffcb47b9a1 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -14,15 +14,18 @@ import { cleanMnemonic, IMenuOptions, Menu, MENU_ESCAPED_MNEMONIC_REGEX, MENU_MN import { ActionRunner, IAction, IActionRunner } from 'vs/base/common/actions'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Event, Emitter } from 'vs/base/common/event'; -import { KeyCode, ResolvedKeybinding } from 'vs/base/common/keyCodes'; +import { KeyCode, ResolvedKeybinding, KeyMod } from 'vs/base/common/keyCodes'; import { Disposable, dispose, IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { withNullAsUndefined } from 'vs/base/common/types'; import { asArray } from 'vs/base/common/arrays'; +import { ScanCodeUtils, ScanCode } from 'vs/base/common/scanCode'; +import { isMacintosh } from 'vs/base/common/platform'; const $ = DOM.$; export interface IMenuBarOptions { enableMnemonics?: boolean; + disableAltFocus?: boolean; visibility?: string; getKeybinding?: (action: IAction) => ResolvedKeybinding | undefined; alwaysOnMnemonics?: boolean; @@ -114,9 +117,9 @@ export class MenuBar extends Disposable { let eventHandled = true; const key = !!e.key ? e.key.toLocaleLowerCase() : ''; - if (event.equals(KeyCode.LeftArrow)) { + if (event.equals(KeyCode.LeftArrow) || (isMacintosh && event.equals(KeyCode.Tab | KeyMod.Shift))) { this.focusPrevious(); - } else if (event.equals(KeyCode.RightArrow)) { + } else if (event.equals(KeyCode.RightArrow) || (isMacintosh && event.equals(KeyCode.Tab))) { this.focusNext(); } else if (event.equals(KeyCode.Escape) && this.isFocused && !this.isOpen) { this.setUnfocusedState(); @@ -127,6 +130,11 @@ export class MenuBar extends Disposable { eventHandled = false; } + // Never allow default tab behavior + if (event.equals(KeyCode.Tab | KeyMod.Shift) || event.equals(KeyCode.Tab)) { + event.preventDefault(); + } + if (eventHandled) { event.preventDefault(); event.stopPropagation(); @@ -776,6 +784,13 @@ export class MenuBar extends Disposable { return; } + // Prevent alt-key default if the menu is not hidden and we use alt to focus + if (modifierKeyStatus.event && !this.options.disableAltFocus) { + if (ScanCodeUtils.toEnum(modifierKeyStatus.event.code) === ScanCode.AltLeft) { + modifierKeyStatus.event.preventDefault(); + } + } + // Alt key pressed while menu is focused. This should return focus away from the menubar if (this.isFocused && modifierKeyStatus.lastKeyPressed === 'alt' && modifierKeyStatus.altKey) { this.setUnfocusedState(); @@ -786,7 +801,7 @@ export class MenuBar extends Disposable { // Clean alt key press and release if (allModifiersReleased && modifierKeyStatus.lastKeyPressed === 'alt' && modifierKeyStatus.lastKeyReleased === 'alt') { if (!this.awaitingAltRelease) { - if (!this.isFocused) { + if (!this.isFocused && !(this.options.disableAltFocus && this.options.visibility !== 'toggle')) { this.mnemonicsInUse = true; this.focusedMenu = { index: this.numMenusShown > 0 ? 0 : MenuBar.OVERFLOW_INDEX }; this.focusState = MenubarState.FOCUSED; @@ -891,6 +906,7 @@ interface IModifierKeyStatus { ctrlKey: boolean; lastKeyPressed?: ModifierKey; lastKeyReleased?: ModifierKey; + event?: KeyboardEvent; } @@ -929,6 +945,7 @@ class ModifierKeyEmitter extends Emitter { this._keyStatus.shiftKey = e.shiftKey; if (this._keyStatus.lastKeyPressed) { + this._keyStatus.event = e; this.fire(this._keyStatus); } })); @@ -953,6 +970,7 @@ class ModifierKeyEmitter extends Emitter { this._keyStatus.shiftKey = e.shiftKey; if (this._keyStatus.lastKeyReleased) { + this._keyStatus.event = e; this.fire(this._keyStatus); } })); diff --git a/src/vs/base/browser/ui/splitview/arrow-collapse-dark.svg b/src/vs/base/browser/ui/splitview/arrow-collapse-dark.svg deleted file mode 100644 index 6f3abfce784..00000000000 --- a/src/vs/base/browser/ui/splitview/arrow-collapse-dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/splitview/arrow-collapse.svg b/src/vs/base/browser/ui/splitview/arrow-collapse.svg deleted file mode 100644 index 5dcb87c772c..00000000000 --- a/src/vs/base/browser/ui/splitview/arrow-collapse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/splitview/arrow-expand-dark.svg b/src/vs/base/browser/ui/splitview/arrow-expand-dark.svg deleted file mode 100644 index 22dfac04f15..00000000000 --- a/src/vs/base/browser/ui/splitview/arrow-expand-dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/splitview/arrow-expand.svg b/src/vs/base/browser/ui/splitview/arrow-expand.svg deleted file mode 100644 index e55ccd923e5..00000000000 --- a/src/vs/base/browser/ui/splitview/arrow-expand.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/splitview/panelview.css b/src/vs/base/browser/ui/splitview/panelview.css index 4801a2bd3a9..d4def58461f 100644 --- a/src/vs/base/browser/ui/splitview/panelview.css +++ b/src/vs/base/browser/ui/splitview/panelview.css @@ -27,23 +27,31 @@ } .monaco-panel-view .panel > .panel-header { - background-image: url('arrow-collapse.svg'); + background-image: url('tree-collapsed-light.svg'); background-position: 2px center; background-repeat: no-repeat; } .monaco-panel-view .panel > .panel-header.expanded { - background-image: url('arrow-expand.svg'); + background-image: url('tree-expanded-light.svg'); background-position: 2px center; background-repeat: no-repeat; } .vs-dark .monaco-panel-view .panel > .panel-header { - background-image: url('arrow-collapse-dark.svg'); + background-image: url('tree-collapsed-dark.svg'); } .vs-dark .monaco-panel-view .panel > .panel-header.expanded { - background-image: url('arrow-expand-dark.svg'); + background-image: url('tree-expanded-dark.svg'); +} + +.hc-black .monaco-panel-view .panel > .panel-header { + background-image: url('tree-collapsed-hc.svg'); +} + +.hc-black .monaco-panel-view .panel > .panel-header.expanded { + background-image: url('tree-expanded-hc.svg'); } /* TODO: actions should be part of the panel, but they aren't yet */ diff --git a/src/vs/base/browser/ui/splitview/tree-collapsed-dark.svg b/src/vs/base/browser/ui/splitview/tree-collapsed-dark.svg new file mode 100644 index 00000000000..c2c2298dd5c --- /dev/null +++ b/src/vs/base/browser/ui/splitview/tree-collapsed-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/splitview/tree-collapsed-hc.svg b/src/vs/base/browser/ui/splitview/tree-collapsed-hc.svg new file mode 100644 index 00000000000..3732cbc04b8 --- /dev/null +++ b/src/vs/base/browser/ui/splitview/tree-collapsed-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/splitview/tree-collapsed-light.svg b/src/vs/base/browser/ui/splitview/tree-collapsed-light.svg new file mode 100644 index 00000000000..1952ad63f84 --- /dev/null +++ b/src/vs/base/browser/ui/splitview/tree-collapsed-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/splitview/tree-expanded-dark.svg b/src/vs/base/browser/ui/splitview/tree-expanded-dark.svg new file mode 100644 index 00000000000..5570923e175 --- /dev/null +++ b/src/vs/base/browser/ui/splitview/tree-expanded-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/splitview/tree-expanded-hc.svg b/src/vs/base/browser/ui/splitview/tree-expanded-hc.svg new file mode 100644 index 00000000000..b370009330c --- /dev/null +++ b/src/vs/base/browser/ui/splitview/tree-expanded-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/splitview/tree-expanded-light.svg b/src/vs/base/browser/ui/splitview/tree-expanded-light.svg new file mode 100644 index 00000000000..939ebc8b969 --- /dev/null +++ b/src/vs/base/browser/ui/splitview/tree-expanded-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/toolbar/ellipsis-dark.svg b/src/vs/base/browser/ui/toolbar/ellipsis-dark.svg new file mode 100644 index 00000000000..2c52e359f61 --- /dev/null +++ b/src/vs/base/browser/ui/toolbar/ellipsis-dark.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/vs/workbench/browser/media/images/explorer/more-alt1.svg b/src/vs/base/browser/ui/toolbar/ellipsis-hc.svg similarity index 100% rename from src/vs/workbench/browser/media/images/explorer/more-alt1.svg rename to src/vs/base/browser/ui/toolbar/ellipsis-hc.svg diff --git a/src/vs/base/browser/ui/toolbar/ellipsis-inverse.svg b/src/vs/base/browser/ui/toolbar/ellipsis-inverse.svg deleted file mode 100644 index e3337557a23..00000000000 --- a/src/vs/base/browser/ui/toolbar/ellipsis-inverse.svg +++ /dev/null @@ -1 +0,0 @@ -Ellipsis_bold_16x \ No newline at end of file diff --git a/src/vs/base/browser/ui/toolbar/ellipsis-light.svg b/src/vs/base/browser/ui/toolbar/ellipsis-light.svg new file mode 100644 index 00000000000..883d2722ce3 --- /dev/null +++ b/src/vs/base/browser/ui/toolbar/ellipsis-light.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/vs/base/browser/ui/toolbar/ellipsis.svg b/src/vs/base/browser/ui/toolbar/ellipsis.svg deleted file mode 100644 index e3f85623356..00000000000 --- a/src/vs/base/browser/ui/toolbar/ellipsis.svg +++ /dev/null @@ -1 +0,0 @@ -Ellipsis_bold_16x \ No newline at end of file diff --git a/src/vs/base/browser/ui/toolbar/toolbar.css b/src/vs/base/browser/ui/toolbar/toolbar.css index 6738aeb68fd..f1fdad313ab 100644 --- a/src/vs/base/browser/ui/toolbar/toolbar.css +++ b/src/vs/base/browser/ui/toolbar/toolbar.css @@ -9,10 +9,13 @@ } .vs .monaco-toolbar .action-label.toolbar-toggle-more { - background-image: url('ellipsis.svg'); + background-image: url('ellipsis-light.svg'); } -.hc-black .monaco-toolbar .action-label.toolbar-toggle-more, .vs-dark .monaco-toolbar .action-label.toolbar-toggle-more { - background-image: url('ellipsis-inverse.svg'); + background-image: url('ellipsis-dark.svg'); +} + +.hc-black .monaco-toolbar .action-label.toolbar-toggle-more { + background-image: url('ellipsis-dark.svg'); } \ No newline at end of file diff --git a/src/vs/base/browser/ui/toolbar/toolbar.ts b/src/vs/base/browser/ui/toolbar/toolbar.ts index b77753855ab..4aa201e1a68 100644 --- a/src/vs/base/browser/ui/toolbar/toolbar.ts +++ b/src/vs/base/browser/ui/toolbar/toolbar.ts @@ -9,7 +9,7 @@ import { Action, IActionRunner, IAction } from 'vs/base/common/actions'; import { ActionBar, ActionsOrientation, IActionViewItemProvider } from 'vs/base/browser/ui/actionbar/actionbar'; import { IContextMenuProvider, DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdown'; import { ResolvedKeybinding } from 'vs/base/common/keyCodes'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview'; import { withNullAsUndefined } from 'vs/base/common/types'; @@ -32,7 +32,7 @@ export class ToolBar extends Disposable { private options: IToolBarOptions; private actionBar: ActionBar; private toggleMenuAction: ToggleMenuAction; - private toggleMenuActionViewItem?: DropdownMenuActionViewItem; + private toggleMenuActionViewItem = this._register(new MutableDisposable()); private hasSecondaryActions: boolean; private lookupKeybindings: boolean; @@ -42,7 +42,7 @@ export class ToolBar extends Disposable { this.options = options; this.lookupKeybindings = typeof this.options.getKeyBinding === 'function'; - this.toggleMenuAction = this._register(new ToggleMenuAction(() => this.toggleMenuActionViewItem && this.toggleMenuActionViewItem.show(), options.toggleMenuTitle)); + this.toggleMenuAction = this._register(new ToggleMenuAction(() => this.toggleMenuActionViewItem.value && this.toggleMenuActionViewItem.value.show(), options.toggleMenuTitle)); let element = document.createElement('div'); element.className = 'monaco-toolbar'; @@ -57,13 +57,8 @@ export class ToolBar extends Disposable { // Return special action item for the toggle menu action if (action.id === ToggleMenuAction.ID) { - // Dispose old - if (this.toggleMenuActionViewItem) { - this.toggleMenuActionViewItem.dispose(); - } - // Create new - this.toggleMenuActionViewItem = new DropdownMenuActionViewItem( + this.toggleMenuActionViewItem.value = new DropdownMenuActionViewItem( action, (action).menuActions, contextMenuProvider, @@ -73,9 +68,9 @@ export class ToolBar extends Disposable { 'toolbar-toggle-more', this.options.anchorAlignmentProvider ); - this.toggleMenuActionViewItem!.setActionContext(this.actionBar.context); + this.toggleMenuActionViewItem.value.setActionContext(this.actionBar.context); - return this.toggleMenuActionViewItem; + return this.toggleMenuActionViewItem.value; } return options.actionViewItemProvider ? options.actionViewItemProvider(action) : undefined; @@ -93,8 +88,8 @@ export class ToolBar extends Disposable { set context(context: any) { this.actionBar.context = context; - if (this.toggleMenuActionViewItem) { - this.toggleMenuActionViewItem.setActionContext(context); + if (this.toggleMenuActionViewItem.value) { + this.toggleMenuActionViewItem.value.setActionContext(context); } } @@ -154,15 +149,6 @@ export class ToolBar extends Disposable { } }; } - - dispose(): void { - if (this.toggleMenuActionViewItem) { - this.toggleMenuActionViewItem.dispose(); - this.toggleMenuActionViewItem = undefined; - } - - super.dispose(); - } } class ToggleMenuAction extends Action { diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 19feab47a05..a034736f2f5 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./media/tree'; -import { IDisposable, dispose, Disposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IListOptions, List, IListStyles, mightProducePrintableCharacter, MouseController } from 'vs/base/browser/ui/list/listWidget'; import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider } from 'vs/base/browser/ui/list/list'; -import { append, $, toggleClass, getDomNodePagePosition, removeClass, addClass, hasClass } from 'vs/base/browser/dom'; +import { append, $, toggleClass, getDomNodePagePosition, removeClass, addClass, hasClass, hasParentWithClass, createStyleSheet, clearNode } from 'vs/base/browser/dom'; import { Event, Relay, Emitter, EventBufferer } from 'vs/base/common/event'; import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { ITreeModel, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeFilter, ITreeNavigator, ICollapseStateChangeEvent, ITreeDragAndDrop, TreeDragOverBubble, TreeVisibility, TreeFilterResult, ITreeModelSpliceEvent } from 'vs/base/browser/ui/tree/tree'; +import { ITreeModel, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeFilter, ITreeNavigator, ICollapseStateChangeEvent, ITreeDragAndDrop, TreeDragOverBubble, TreeVisibility, TreeFilterResult, ITreeModelSpliceEvent, TreeMouseEventTarget } from 'vs/base/browser/ui/tree/tree'; import { ISpliceable } from 'vs/base/common/sequence'; import { IDragAndDropData, StaticDND, DragAndDropData } from 'vs/base/browser/dnd'; import { range, equals, distinctES6 } from 'vs/base/common/arrays'; @@ -25,6 +25,7 @@ import { isMacintosh } from 'vs/base/common/platform'; import { values } from 'vs/base/common/map'; import { clamp } from 'vs/base/common/numbers'; import { ScrollEvent } from 'vs/base/common/scrollable'; +import { SetMap } from 'vs/base/common/collections'; function asTreeDragAndDropData(data: IDragAndDropData): IDragAndDropData { if (data instanceof ElementsDragAndDropData) { @@ -152,7 +153,7 @@ function asListOptions(modelProvider: () => ITreeModel implements IListV interface ITreeListTemplateData { readonly container: HTMLElement; + readonly indent: HTMLElement; readonly twistie: HTMLElement; + indentGuidesDisposable: IDisposable; readonly templateData: T; } +export enum RenderIndentGuides { + None = 'none', + OnHover = 'onHover', + Always = 'always' +} + interface ITreeRendererOptions { readonly indent?: number; + readonly renderIndentGuides?: RenderIndentGuides; +} + +interface IRenderData { + templateData: ITreeListTemplateData; + height: number; +} + +interface Collection { + readonly elements: T[]; + readonly onDidChange: Event; +} + +class EventCollection implements Collection { + + private disposables = new DisposableStore(); + + get elements(): T[] { + return this._elements; + } + + constructor(readonly onDidChange: Event, private _elements: T[] = []) { + onDidChange(e => this._elements = e, null, this.disposables); + } + + dispose() { + this.disposables.dispose(); + } } class TreeRenderer implements IListRenderer, ITreeListTemplateData> { @@ -202,13 +239,20 @@ class TreeRenderer implements IListRenderer>(); - private renderedNodes = new Map, ITreeListTemplateData>(); + private renderedNodes = new Map, IRenderData>(); private indent: number = TreeRenderer.DefaultIndent; + + private _renderIndentGuides: RenderIndentGuides = RenderIndentGuides.None; + private renderedIndentGuides = new SetMap, HTMLDivElement>(); + private activeParentNodes = new Set>(); + private indentGuidesDisposable: IDisposable = Disposable.None; + private disposables: IDisposable[] = []; constructor( private renderer: ITreeRenderer, onDidChangeCollapseState: Event>, + private activeNodes: Collection>, options: ITreeRendererOptions = {} ) { this.templateId = renderer.templateId; @@ -226,34 +270,57 @@ class TreeRenderer implements IListRenderer { - templateData.twistie.style.marginLeft = `${node.depth * this.indent}px`; - }); + if (typeof options.renderIndentGuides !== 'undefined') { + const renderIndentGuides = options.renderIndentGuides; + + if (renderIndentGuides !== this._renderIndentGuides) { + this._renderIndentGuides = renderIndentGuides; + + if (renderIndentGuides) { + const disposables = new DisposableStore(); + this.activeNodes.onDidChange(this._onDidChangeActiveNodes, this, disposables); + this.indentGuidesDisposable = disposables; + + this._onDidChangeActiveNodes(this.activeNodes.elements); + } else { + this.indentGuidesDisposable.dispose(); + } + } + } } renderTemplate(container: HTMLElement): ITreeListTemplateData { const el = append(container, $('.monaco-tl-row')); + const indent = append(el, $('.monaco-tl-indent')); const twistie = append(el, $('.monaco-tl-twistie')); const contents = append(el, $('.monaco-tl-contents')); const templateData = this.renderer.renderTemplate(contents); - return { container, twistie, templateData }; + return { container, indent, twistie, indentGuidesDisposable: Disposable.None, templateData }; } renderElement(node: ITreeNode, index: number, templateData: ITreeListTemplateData, height: number | undefined): void { if (typeof height === 'number') { - this.renderedNodes.set(node, templateData); + this.renderedNodes.set(node, { templateData, height }); this.renderedElements.set(node.element, node); } const indent = TreeRenderer.DefaultIndent + (node.depth - 1) * this.indent; templateData.twistie.style.marginLeft = `${indent}px`; - this.update(node, templateData); + templateData.indent.style.width = `${indent + this.indent - 16}px`; + + this.renderTwistie(node, templateData); + + if (typeof height === 'number') { + this.renderIndentGuides(node, templateData); + } this.renderer.renderElement(node, index, templateData.templateData, height); } disposeElement(node: ITreeNode, index: number, templateData: ITreeListTemplateData, height: number | undefined): void { + templateData.indentGuidesDisposable.dispose(); + if (this.renderer.disposeElement) { this.renderer.disposeElement(node, index, templateData.templateData, height); } @@ -279,16 +346,17 @@ class TreeRenderer implements IListRenderer): void { - const templateData = this.renderedNodes.get(node); + const data = this.renderedNodes.get(node); - if (!templateData) { + if (!data) { return; } - this.update(node, templateData); + this.renderTwistie(node, data.templateData); + this.renderIndentGuides(node, data.templateData); } - private update(node: ITreeNode, templateData: ITreeListTemplateData) { + private renderTwistie(node: ITreeNode, templateData: ITreeListTemplateData) { if (this.renderer.renderTwistie) { this.renderer.renderTwistie(node.element, templateData.twistie); } @@ -303,9 +371,72 @@ class TreeRenderer implements IListRenderer, templateData: ITreeListTemplateData): void { + clearNode(templateData.indent); + templateData.indentGuidesDisposable.dispose(); + + if (this._renderIndentGuides === RenderIndentGuides.None) { + return; + } + + const disposableStore = new DisposableStore(); + let node = target; + + while (node.parent && node.parent.parent) { + const parent = node.parent; + const guide = $('.indent-guide', { style: `width: ${this.indent}px` }); + + if (this.activeParentNodes.has(parent)) { + addClass(guide, 'active'); + } + + if (templateData.indent.childElementCount === 0) { + templateData.indent.appendChild(guide); + } else { + templateData.indent.insertBefore(guide, templateData.indent.firstElementChild); + } + + this.renderedIndentGuides.add(parent, guide); + disposableStore.add(toDisposable(() => this.renderedIndentGuides.delete(parent, guide))); + + node = parent; + } + + templateData.indentGuidesDisposable = disposableStore; + } + + private _onDidChangeActiveNodes(nodes: ITreeNode[]): void { + if (this._renderIndentGuides === RenderIndentGuides.None) { + return; + } + + const set = new Set>(); + + nodes.forEach(node => { + if (node.parent) { + set.add(node.parent); + } + }); + + this.activeParentNodes.forEach(node => { + if (!set.has(node)) { + this.renderedIndentGuides.forEach(node, line => removeClass(line, 'active')); + } + }); + + set.forEach(node => { + if (!this.activeParentNodes.has(node)) { + this.renderedIndentGuides.forEach(node, line => addClass(line, 'active')); + } + }); + + this.activeParentNodes = set; + } + dispose(): void { this.renderedNodes.clear(); this.renderedElements.clear(); + this.indentGuidesDisposable.dispose(); this.disposables = dispose(this.disposables); } } @@ -722,9 +853,18 @@ function asTreeEvent(event: IListEvent>): ITreeEvent { } function asTreeMouseEvent(event: IListMouseEvent>): ITreeMouseEvent { + let target: TreeMouseEventTarget = TreeMouseEventTarget.Unknown; + + if (hasParentWithClass(event.browserEvent.target as HTMLElement, 'monaco-tl-twistie', 'monaco-tl-row')) { + target = TreeMouseEventTarget.Twistie; + } else if (hasParentWithClass(event.browserEvent.target as HTMLElement, 'monaco-tl-contents', 'monaco-tl-row')) { + target = TreeMouseEventTarget.Element; + } + return { browserEvent: event.browserEvent, - element: event.element ? event.element.element : null + element: event.element ? event.element.element : null, + target }; } @@ -811,6 +951,10 @@ class Trait { return [...this.elements]; } + getNodes(): readonly ITreeNode[] { + return this.nodes; + } + has(node: ITreeNode): boolean { return this.nodeSet.has(node); } @@ -999,6 +1143,7 @@ export abstract class AbstractTree implements IDisposable private eventBufferer = new EventBufferer(); private typeFilterController?: TypeFilterController; private focusNavigationFilter: ((node: ITreeNode) => boolean) | undefined; + private styleElement: HTMLStyleElement; protected disposables: IDisposable[] = []; get onDidScroll(): Event { return this.view.onDidScroll; } @@ -1027,7 +1172,6 @@ export abstract class AbstractTree implements IDisposable get filterOnType(): boolean { return !!this._options.filterOnType; } get onDidChangeTypeFilterPattern(): Event { return this.typeFilterController ? this.typeFilterController.onDidChangePattern : Event.None; } - // Options TODO@joao expose options only, not Optional<> get openOnSingleClick(): boolean { return typeof this._options.openOnSingleClick === 'undefined' ? true : this._options.openOnSingleClick; } get expandOnlyOnTwistieClick(): boolean | ((e: T) => boolean) { return typeof this._options.expandOnlyOnTwistieClick === 'undefined' ? false : this._options.expandOnlyOnTwistieClick; } @@ -1045,7 +1189,11 @@ export abstract class AbstractTree implements IDisposable const treeDelegate = new ComposedTreeDelegate>(delegate); const onDidChangeCollapseStateRelay = new Relay>(); - this.renderers = renderers.map(r => new TreeRenderer(r, onDidChangeCollapseStateRelay.event, _options)); + const onDidChangeActiveNodes = new Relay[]>(); + const activeNodes = new EventCollection(onDidChangeActiveNodes.event); + this.disposables.push(activeNodes); + + this.renderers = renderers.map(r => new TreeRenderer(r, onDidChangeCollapseStateRelay.event, activeNodes, _options)); this.disposables.push(...this.renderers); let filter: TypeFilter | undefined; @@ -1068,6 +1216,8 @@ export abstract class AbstractTree implements IDisposable this.selection.onDidModelSplice(e); }, null, this.disposables); + onDidChangeActiveNodes.input = Event.map(Event.any(this.focus.onDidChange, this.selection.onDidChange, this.model.onDidSplice), () => [...this.focus.getNodes(), ...this.selection.getNodes()]); + if (_options.keyboardSupport !== false) { const onKeyDown = Event.chain(this.view.onKeyDown) .filter(e => !isInputElement(e.target as HTMLElement)) @@ -1083,6 +1233,9 @@ export abstract class AbstractTree implements IDisposable this.focusNavigationFilter = node => this.typeFilterController!.shouldAllowFocus(node); this.disposables.push(this.typeFilterController!); } + + this.styleElement = createStyleSheet(this.view.getHTMLElement()); + toggleClass(this.getHTMLElement(), 'always', this._options.renderIndentGuides === RenderIndentGuides.Always); } updateOptions(optionsUpdate: IAbstractTreeOptionsUpdate = {}): void { @@ -1102,6 +1255,8 @@ export abstract class AbstractTree implements IDisposable } this._onDidUpdateOptions.fire(this._options); + + toggleClass(this.getHTMLElement(), 'always', this._options.renderIndentGuides === RenderIndentGuides.Always); } get options(): IAbstractTreeOptions { @@ -1183,6 +1338,19 @@ export abstract class AbstractTree implements IDisposable } style(styles: IListStyles): void { + const suffix = `.${this.view.domId}`; + const content: string[] = []; + + if (styles.treeIndentGuidesStroke) { + content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > .indent-guide, .monaco-list${suffix}.always .monaco-tl-indent > .indent-guide { border-color: ${styles.treeIndentGuidesStroke.transparent(0.4)}; }`); + content.push(`.monaco-list${suffix} .monaco-tl-indent > .indent-guide.active { border-color: ${styles.treeIndentGuidesStroke}; }`); + } + + const newStyles = content.join('\n'); + if (newStyles !== this.styleElement.innerHTML) { + this.styleElement.innerHTML = newStyles; + } + this.view.style(styles); } diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index d5a9fc72915..e31422edf6a 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -28,6 +28,7 @@ interface IAsyncDataTreeNode { hasChildren: boolean; stale: boolean; slow: boolean; + collapsedByDefault: boolean | undefined; } interface IAsyncDataTreeNodeRequiredProps extends Partial> { @@ -42,7 +43,8 @@ function createAsyncDataTreeNode(props: IAsyncDataTreeNodeRequiredPro children: [], loading: false, stale: true, - slow: false + slow: false, + collapsedByDefault: undefined }; } @@ -133,7 +135,8 @@ function asTreeEvent(e: ITreeEvent>): I function asTreeMouseEvent(e: ITreeMouseEvent>): ITreeMouseEvent { return { browserEvent: e.browserEvent, - element: e.element && e.element.element as T + element: e.element && e.element.element as T, + target: e.target }; } @@ -224,6 +227,7 @@ function asObjectTreeOptions(options?: IAsyncDataTreeOpt } }, keyboardNavigationLabelProvider: options.keyboardNavigationLabelProvider && { + ...options.keyboardNavigationLabelProvider, getKeyboardNavigationLabel(e) { return options.keyboardNavigationLabelProvider!.getKeyboardNavigationLabel(e.element as T); } @@ -234,17 +238,21 @@ function asObjectTreeOptions(options?: IAsyncDataTreeOpt e => (options.expandOnlyOnTwistieClick as ((e: T) => boolean))(e.element as T) ) ), - ariaSetProvider: undefined + ariaProvider: undefined }; } function asTreeElement(node: IAsyncDataTreeNode, viewStateContext?: IAsyncDataTreeViewStateContext): ITreeElement> { let collapsed: boolean | undefined; - if (viewStateContext && viewStateContext.viewState.expanded && node.id) { - collapsed = viewStateContext.viewState.expanded.indexOf(node.id) === -1; + if (viewStateContext && viewStateContext.viewState.expanded && node.id && viewStateContext.viewState.expanded.indexOf(node.id) > -1) { + collapsed = false; + } else { + collapsed = node.collapsedByDefault; } + node.collapsedByDefault = undefined; + return { element: node, children: node.hasChildren ? Iterator.map(Iterator.fromArray(node.children), child => asTreeElement(child, viewStateContext)) : [], @@ -255,10 +263,11 @@ function asTreeElement(node: IAsyncDataTreeNode, viewState export interface IAsyncDataTreeOptionsUpdate extends IAbstractTreeOptionsUpdate { } -export interface IAsyncDataTreeOptions extends IAsyncDataTreeOptionsUpdate, IAbstractTreeOptions { - identityProvider?: IIdentityProvider; - sorter?: ITreeSorter; - autoExpandSingleChildren?: boolean; +export interface IAsyncDataTreeOptions extends IAsyncDataTreeOptionsUpdate, Pick, Exclude, 'collapseByDefault'>> { + readonly collapseByDefault?: { (e: T): boolean; }; + readonly identityProvider?: IIdentityProvider; + readonly sorter?: ITreeSorter; + readonly autoExpandSingleChildren?: boolean; } export interface IAsyncDataTreeViewState { @@ -285,6 +294,7 @@ export class AsyncDataTree implements IDisposable private readonly root: IAsyncDataTreeNode; private readonly nodes = new Map>(); private readonly sorter?: ITreeSorter; + private readonly collapseByDefault?: { (e: T): boolean; }; private readonly subTreeRefreshPromises = new Map, Promise>(); private readonly refreshPromises = new Map, CancelablePromise>(); @@ -310,10 +320,20 @@ export class AsyncDataTree implements IDisposable get onDidFocus(): Event { return this.tree.onDidFocus; } get onDidBlur(): Event { return this.tree.onDidBlur; } + get onDidChangeCollapseState(): Event, TFilterData>> { return this.tree.onDidChangeCollapseState; } + get onDidUpdateOptions(): Event { return this.tree.onDidUpdateOptions; } get filterOnType(): boolean { return this.tree.filterOnType; } get openOnSingleClick(): boolean { return this.tree.openOnSingleClick; } + get expandOnlyOnTwistieClick(): boolean | ((e: T) => boolean) { + if (typeof this.tree.expandOnlyOnTwistieClick === 'boolean') { + return this.tree.expandOnlyOnTwistieClick; + } + + const fn = this.tree.expandOnlyOnTwistieClick; + return element => fn(this.nodes.get((element === this.root.element ? null : element) as T) || null); + } get onDidDispose(): Event { return this.tree.onDidDispose; } @@ -327,6 +347,7 @@ export class AsyncDataTree implements IDisposable this.identityProvider = options.identityProvider; this.autoExpandSingleChildren = typeof options.autoExpandSingleChildren === 'undefined' ? false : options.autoExpandSingleChildren; this.sorter = options.sorter; + this.collapseByDefault = options.collapseByDefault; const objectTreeDelegate = new ComposedTreeDelegate>(delegate); const objectTreeRenderers = renderers.map(r => new DataTreeRenderer(r, this._onDidChangeNodeSlowState.event)); @@ -762,12 +783,17 @@ export class AsyncDataTree implements IDisposable const childrenToRefresh: IAsyncDataTreeNode[] = []; const children = childrenElements.map>(element => { + const hasChildren = !!this.dataSource.hasChildren(element); + if (!this.identityProvider) { - return createAsyncDataTreeNode({ - element, - parent: node, - hasChildren: !!this.dataSource.hasChildren(element) - }); + const asyncDataTreeNode = createAsyncDataTreeNode({ element, parent: node, hasChildren }); + + if (hasChildren && this.collapseByDefault && !this.collapseByDefault(element)) { + asyncDataTreeNode.collapsedByDefault = false; + childrenToRefresh.push(asyncDataTreeNode); + } + + return asyncDataTreeNode; } const id = this.identityProvider.getId(element).toString(); @@ -781,7 +807,7 @@ export class AsyncDataTree implements IDisposable this.nodes.set(element, asyncDataTreeNode); asyncDataTreeNode.element = element; - asyncDataTreeNode.hasChildren = !!this.dataSource.hasChildren(element); + asyncDataTreeNode.hasChildren = hasChildren; if (recursive) { if (childNode.collapsed) { @@ -789,17 +815,15 @@ export class AsyncDataTree implements IDisposable } else { childrenToRefresh.push(asyncDataTreeNode); } + } else if (hasChildren && this.collapseByDefault && !this.collapseByDefault(element)) { + asyncDataTreeNode.collapsedByDefault = false; + childrenToRefresh.push(asyncDataTreeNode); } return asyncDataTreeNode; } - const childAsyncDataTreeNode = createAsyncDataTreeNode({ - element, - parent: node, - id, - hasChildren: !!this.dataSource.hasChildren(element) - }); + const childAsyncDataTreeNode = createAsyncDataTreeNode({ element, parent: node, id, hasChildren }); if (viewStateContext && viewStateContext.viewState.focus && viewStateContext.viewState.focus.indexOf(id) > -1) { viewStateContext.focus.push(childAsyncDataTreeNode); @@ -811,6 +835,9 @@ export class AsyncDataTree implements IDisposable if (viewStateContext && viewStateContext.viewState.expanded && viewStateContext.viewState.expanded.indexOf(id) > -1) { childrenToRefresh.push(childAsyncDataTreeNode); + } else if (hasChildren && this.collapseByDefault && !this.collapseByDefault(element)) { + childAsyncDataTreeNode.collapsedByDefault = false; + childrenToRefresh.push(childAsyncDataTreeNode); } return childAsyncDataTreeNode; diff --git a/src/vs/base/browser/ui/tree/dataTree.ts b/src/vs/base/browser/ui/tree/dataTree.ts index d2342d7e85b..bb93ca31fad 100644 --- a/src/vs/base/browser/ui/tree/dataTree.ts +++ b/src/vs/base/browser/ui/tree/dataTree.ts @@ -18,6 +18,7 @@ export interface IDataTreeViewState { readonly focus: string[]; readonly selection: string[]; readonly expanded: string[]; + readonly scrollTop: number; } export class DataTree extends AbstractTree { @@ -80,6 +81,10 @@ export class DataTree extends AbstractTree extends AbstractTree \ No newline at end of file diff --git a/src/vs/base/browser/ui/tree/media/collapsed-hc.svg b/src/vs/base/browser/ui/tree/media/collapsed-hc.svg deleted file mode 100644 index 145c763338f..00000000000 --- a/src/vs/base/browser/ui/tree/media/collapsed-hc.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/tree/media/collapsed.svg b/src/vs/base/browser/ui/tree/media/collapsed.svg deleted file mode 100755 index 3a63808c358..00000000000 --- a/src/vs/base/browser/ui/tree/media/collapsed.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/tree/media/expanded-dark.svg b/src/vs/base/browser/ui/tree/media/expanded-dark.svg deleted file mode 100755 index 73d41e63990..00000000000 --- a/src/vs/base/browser/ui/tree/media/expanded-dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/tree/media/expanded-hc.svg b/src/vs/base/browser/ui/tree/media/expanded-hc.svg deleted file mode 100644 index d38d4abc89e..00000000000 --- a/src/vs/base/browser/ui/tree/media/expanded-hc.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/tree/media/expanded.svg b/src/vs/base/browser/ui/tree/media/expanded.svg deleted file mode 100755 index 75f73adbb02..00000000000 --- a/src/vs/base/browser/ui/tree/media/expanded.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/browser/ui/tree/media/tree-collapsed-dark.svg b/src/vs/base/browser/ui/tree/media/tree-collapsed-dark.svg new file mode 100644 index 00000000000..c2c2298dd5c --- /dev/null +++ b/src/vs/base/browser/ui/tree/media/tree-collapsed-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/tree/media/tree-collapsed-hc.svg b/src/vs/base/browser/ui/tree/media/tree-collapsed-hc.svg new file mode 100644 index 00000000000..3732cbc04b8 --- /dev/null +++ b/src/vs/base/browser/ui/tree/media/tree-collapsed-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/tree/media/tree-collapsed-light.svg b/src/vs/base/browser/ui/tree/media/tree-collapsed-light.svg new file mode 100644 index 00000000000..1952ad63f84 --- /dev/null +++ b/src/vs/base/browser/ui/tree/media/tree-collapsed-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/tree/media/tree-expanded-dark.svg b/src/vs/base/browser/ui/tree/media/tree-expanded-dark.svg new file mode 100644 index 00000000000..5570923e175 --- /dev/null +++ b/src/vs/base/browser/ui/tree/media/tree-expanded-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/tree/media/tree-expanded-hc.svg b/src/vs/base/browser/ui/tree/media/tree-expanded-hc.svg new file mode 100644 index 00000000000..b370009330c --- /dev/null +++ b/src/vs/base/browser/ui/tree/media/tree-expanded-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/tree/media/tree-expanded-light.svg b/src/vs/base/browser/ui/tree/media/tree-expanded-light.svg new file mode 100644 index 00000000000..939ebc8b969 --- /dev/null +++ b/src/vs/base/browser/ui/tree/media/tree-expanded-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 4f86f971f97..47c1e405b96 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -7,6 +7,30 @@ display: flex; height: 100%; align-items: center; + position: relative; +} + +.monaco-tl-indent { + height: 100%; + position: absolute; + top: 0; + left: 18px; + pointer-events: none; +} + +.hide-arrows .monaco-tl-indent { + left: 12px; +} + +.monaco-tl-indent > .indent-guide { + display: inline-block; + box-sizing: border-box; + height: 100%; + border-left: 1px solid transparent; +} + +.monaco-tl-indent > .indent-guide { + transition: border-color 0.1s linear; } .monaco-tl-twistie, @@ -31,28 +55,28 @@ background-size: 16px; background-position: 3px 50%; background-repeat: no-repeat; - background-image: url("expanded.svg"); + background-image: url("tree-expanded-light.svg"); } .monaco-tl-twistie.collapsible.collapsed:not(.loading) { display: inline-block; - background-image: url("collapsed.svg"); + background-image: url("tree-collapsed-light.svg"); } .vs-dark .monaco-tl-twistie.collapsible:not(.loading) { - background-image: url("expanded-dark.svg"); + background-image: url("tree-expanded-dark.svg"); } .vs-dark .monaco-tl-twistie.collapsible.collapsed:not(.loading) { - background-image: url("collapsed-dark.svg"); + background-image: url("tree-collapsed-dark.svg"); } .hc-black .monaco-tl-twistie.collapsible:not(.loading) { - background-image: url("expanded-hc.svg"); + background-image: url("tree-expanded-hc.svg"); } .hc-black .monaco-tl-twistie.collapsible.collapsed:not(.loading) { - background-image: url("collapsed-hc.svg"); + background-image: url("tree-collapsed-hc.svg"); } .monaco-tl-twistie.loading { @@ -66,4 +90,4 @@ .hc-black .monaco-tl-twistie.loading { background-image: url("loading-hc.svg"); -} \ No newline at end of file +} diff --git a/src/vs/base/browser/ui/tree/objectTree.ts b/src/vs/base/browser/ui/tree/objectTree.ts index 1236b065722..38bca41901c 100644 --- a/src/vs/base/browser/ui/tree/objectTree.ts +++ b/src/vs/base/browser/ui/tree/objectTree.ts @@ -6,9 +6,10 @@ import { Iterator, ISequence } from 'vs/base/common/iterator'; import { AbstractTree, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree'; import { ISpliceable } from 'vs/base/common/sequence'; -import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer, ITreeSorter } from 'vs/base/browser/ui/tree/tree'; +import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer, ITreeSorter, ICollapseStateChangeEvent } from 'vs/base/browser/ui/tree/tree'; import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel'; import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; +import { Event } from 'vs/base/common/event'; export interface IObjectTreeOptions extends IAbstractTreeOptions { sorter?: ITreeSorter; @@ -18,6 +19,8 @@ export class ObjectTree, TFilterData = void> extends protected model: ObjectTreeModel; + get onDidChangeCollapseState(): Event> { return this.model.onDidChangeCollapseState; } + constructor( container: HTMLElement, delegate: IListVirtualDelegate, diff --git a/src/vs/base/browser/ui/tree/objectTreeModel.ts b/src/vs/base/browser/ui/tree/objectTreeModel.ts index 9fc7e00898b..d836e39f116 100644 --- a/src/vs/base/browser/ui/tree/objectTreeModel.ts +++ b/src/vs/base/browser/ui/tree/objectTreeModel.ts @@ -8,9 +8,11 @@ import { Iterator, ISequence, getSequenceIterator } from 'vs/base/common/iterato import { IndexTreeModel, IIndexTreeModelOptions } from 'vs/base/browser/ui/tree/indexTreeModel'; import { Event } from 'vs/base/common/event'; import { ITreeModel, ITreeNode, ITreeElement, ITreeSorter, ICollapseStateChangeEvent, ITreeModelSpliceEvent } from 'vs/base/browser/ui/tree/tree'; +import { IIdentityProvider } from 'vs/base/browser/ui/list/list'; export interface IObjectTreeModelOptions extends IIndexTreeModelOptions { readonly sorter?: ITreeSorter; + readonly identityProvider?: IIdentityProvider; } export class ObjectTreeModel, TFilterData extends NonNullable = void> implements ITreeModel { @@ -19,6 +21,8 @@ export class ObjectTreeModel, TFilterData extends Non private model: IndexTreeModel; private nodes = new Map>(); + private readonly nodesByIdentity = new Map>(); + private readonly identityProvider?: IIdentityProvider; private sorter?: ITreeSorter<{ element: T; }>; readonly onDidSplice: Event>; @@ -40,6 +44,8 @@ export class ObjectTreeModel, TFilterData extends Non } }; } + + this.identityProvider = options.identityProvider; } setChildren( @@ -59,11 +65,18 @@ export class ObjectTreeModel, TFilterData extends Non onDidDeleteNode?: (node: ITreeNode) => void ): Iterator> { const insertedElements = new Set(); + const insertedElementIds = new Set(); const _onDidCreateNode = (node: ITreeNode) => { insertedElements.add(node.element); this.nodes.set(node.element, node); + if (this.identityProvider) { + const id = this.identityProvider.getId(node.element).toString(); + insertedElementIds.add(id); + this.nodesByIdentity.set(id, node); + } + if (onDidCreateNode) { onDidCreateNode(node); } @@ -74,18 +87,27 @@ export class ObjectTreeModel, TFilterData extends Non this.nodes.delete(node.element); } + if (this.identityProvider) { + const id = this.identityProvider.getId(node.element).toString(); + if (!insertedElementIds.has(id)) { + this.nodesByIdentity.delete(id); + } + } + if (onDidDeleteNode) { onDidDeleteNode(node); } }; - return this.model.splice( + const result = this.model.splice( [...location, 0], Number.MAX_VALUE, children, _onDidCreateNode, _onDidDeleteNode ); + + return result; } private preserveCollapseState(elements: ISequence> | undefined): ISequence> { @@ -96,7 +118,12 @@ export class ObjectTreeModel, TFilterData extends Non } return Iterator.map(iterator, treeElement => { - const node = this.nodes.get(treeElement.element); + let node = this.nodes.get(treeElement.element); + + if (!node && this.identityProvider) { + const id = this.identityProvider.getId(treeElement.element).toString(); + node = this.nodesByIdentity.get(id); + } if (!node) { return { diff --git a/src/vs/base/browser/ui/tree/tree.ts b/src/vs/base/browser/ui/tree/tree.ts index cedb6fbd423..80b30fa4c55 100644 --- a/src/vs/base/browser/ui/tree/tree.ts +++ b/src/vs/base/browser/ui/tree/tree.ts @@ -137,9 +137,16 @@ export interface ITreeEvent { browserEvent?: UIEvent; } +export enum TreeMouseEventTarget { + Unknown, + Twistie, + Element +} + export interface ITreeMouseEvent { browserEvent: MouseEvent; element: T | null; + target: TreeMouseEventTarget; } export interface ITreeContextMenuEvent { diff --git a/src/vs/base/browser/ui/tree/treeDefaults.ts b/src/vs/base/browser/ui/tree/treeDefaults.ts new file mode 100644 index 00000000000..03b8665cd64 --- /dev/null +++ b/src/vs/base/browser/ui/tree/treeDefaults.ts @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vs/nls'; +import { Action } from 'vs/base/common/actions'; +import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree'; + +export class CollapseAllAction extends Action { + + constructor(private viewer: AsyncDataTree, enabled: boolean) { + super('vs.tree.collapse', nls.localize('collapse all', "Collapse All"), 'monaco-tree-action collapse-all', enabled); + } + + public run(context?: any): Promise { + this.viewer.collapseAll(); + this.viewer.setSelection([]); + this.viewer.setFocus([]); + this.viewer.domFocus(); + this.viewer.focusFirst(); + + return Promise.resolve(); + } +} \ No newline at end of file diff --git a/src/vs/base/common/actions.ts b/src/vs/base/common/actions.ts index 66e93280309..b0e1b6f161e 100644 --- a/src/vs/base/common/actions.ts +++ b/src/vs/base/common/actions.ts @@ -7,13 +7,23 @@ import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; export interface ITelemetryData { - from?: string; - target?: string; + readonly from?: string; + readonly target?: string; [key: string]: any; } -export interface IAction extends IDisposable { +export type WorkbenchActionExecutedClassification = { + id: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + from: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; +}; + +export type WorkbenchActionExecutedEvent = { id: string; + from: string; +}; + +export interface IAction extends IDisposable { + readonly id: string; label: string; tooltip: string; class: string | undefined; @@ -25,12 +35,12 @@ export interface IAction extends IDisposable { export interface IActionRunner extends IDisposable { run(action: IAction, context?: any): Promise; - onDidRun: Event; - onDidBeforeRun: Event; + readonly onDidRun: Event; + readonly onDidBeforeRun: Event; } export interface IActionViewItem extends IDisposable { - actionRunner: IActionRunner; + readonly actionRunner: IActionRunner; setActionContext(context: any): void; render(element: any /* HTMLElement */): void; isEnabled(): boolean; @@ -39,12 +49,12 @@ export interface IActionViewItem extends IDisposable { } export interface IActionChangeEvent { - label?: string; - tooltip?: string; - class?: string; - enabled?: boolean; - checked?: boolean; - radio?: boolean; + readonly label?: string; + readonly tooltip?: string; + readonly class?: string; + readonly enabled?: boolean; + readonly checked?: boolean; + readonly radio?: boolean; } export class Action extends Disposable implements IAction { @@ -52,14 +62,14 @@ export class Action extends Disposable implements IAction { protected _onDidChange = this._register(new Emitter()); readonly onDidChange: Event = this._onDidChange.event; - protected _id: string; + protected readonly _id: string; protected _label: string; protected _tooltip: string; protected _cssClass: string | undefined; protected _enabled: boolean; protected _checked: boolean; protected _radio: boolean; - protected _actionCallback?: (event?: any) => Promise; + protected readonly _actionCallback?: (event?: any) => Promise; constructor(id: string, label: string = '', cssClass: string = '', enabled: boolean = true, actionCallback?: (event?: any) => Promise) { super(); @@ -82,7 +92,7 @@ export class Action extends Disposable implements IAction { this._setLabel(value); } - protected _setLabel(value: string): void { + private _setLabel(value: string): void { if (this._label !== value) { this._label = value; this._onDidChange.fire({ label: value }); @@ -174,9 +184,9 @@ export class Action extends Disposable implements IAction { } export interface IRunEvent { - action: IAction; - result?: any; - error?: any; + readonly action: IAction; + readonly result?: any; + readonly error?: any; } export class ActionRunner extends Disposable implements IActionRunner { diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index 8a3bb5bdbc0..7aa42597714 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -295,7 +295,7 @@ function topStep(array: ReadonlyArray, compare: (a: T, b: T) => number, re /** * @returns a new array with all falsy values removed. The original array IS NOT modified. */ -export function coalesce(array: Array): T[] { +export function coalesce(array: ReadonlyArray): T[] { if (!array) { return array; } @@ -336,7 +336,9 @@ export function isFalsyOrEmpty(obj: any): boolean { /** * @returns True if the provided object is an array and has at least one element. */ -export function isNonEmptyArray(obj: ReadonlyArray | undefined | null): obj is Array { +export function isNonEmptyArray(obj: T[] | undefined | null): obj is T[]; +export function isNonEmptyArray(obj: readonly T[] | undefined | null): obj is readonly T[]; +export function isNonEmptyArray(obj: T[] | readonly T[] | undefined | null): obj is T[] | readonly T[] { return Array.isArray(obj) && obj.length > 0; } diff --git a/src/vs/base/common/buffer.ts b/src/vs/base/common/buffer.ts index cf34296e74c..05a22bd3d1e 100644 --- a/src/vs/base/common/buffer.ts +++ b/src/vs/base/common/buffer.ts @@ -78,7 +78,10 @@ export class VSBuffer { } slice(start?: number, end?: number): VSBuffer { - return new VSBuffer(this.buffer.slice(start, end)); + // IMPORTANT: use subarray instead of slice because TypedArray#slice + // creates shallow copy and NodeBuffer#slice doesn't. The use of subarray + // ensures the same, performant, behaviour. + return new VSBuffer(this.buffer.subarray(start!/*bad lib.d.ts*/, end)); } set(array: VSBuffer, offset?: number): void { @@ -138,18 +141,13 @@ export interface VSBufferReadable { read(): VSBuffer | null; } -/** - * A buffer readable stream emits data to listeners. The stream - * will only start emitting when the first data listener has - * been added or the resume() method has been called. - */ -export interface VSBufferReadableStream { +export interface ReadableStream { /** * The 'data' event is emitted whenever the stream is * relinquishing ownership of a chunk of data to a consumer. */ - on(event: 'data', callback: (chunk: VSBuffer) => void): void; + on(event: 'data', callback: (chunk: T) => void): void; /** * Emitted when any error occurs. @@ -166,19 +164,34 @@ export interface VSBufferReadableStream { /** * Stops emitting any events until resume() is called. */ - pause(): void; + pause?(): void; /** * Starts emitting events again after pause() was called. */ - resume(): void; + resume?(): void; /** * Destroys the stream and stops emitting any event. */ + destroy?(): void; +} + +/** + * A readable stream that sends data via VSBuffer. + */ +export interface VSBufferReadableStream extends ReadableStream { + pause(): void; + resume(): void; destroy(): void; } +export function isVSBufferReadableStream(obj: any): obj is VSBufferReadableStream { + const candidate: VSBufferReadableStream = obj; + + return candidate && [candidate.on, candidate.pause, candidate.resume, candidate.destroy].every(fn => typeof fn === 'function'); +} + /** * Helper to fully read a VSBuffer readable into a single buffer. */ @@ -236,6 +249,19 @@ export function bufferToStream(buffer: VSBuffer): VSBufferReadableStream { return stream; } +/** + * Helper to create a VSBufferStream from a Uint8Array stream. + */ +export function toVSBufferReadableStream(stream: ReadableStream): VSBufferReadableStream { + const vsbufferStream = writeableBufferStream(); + + stream.on('data', data => vsbufferStream.write(typeof data === 'string' ? VSBuffer.fromString(data) : VSBuffer.wrap(data))); + stream.on('end', () => vsbufferStream.end()); + stream.on('error', error => vsbufferStream.error(error)); + + return vsbufferStream; +} + /** * Helper to create a VSBufferStream that can be pushed * buffers to. Will only start to emit data when a listener @@ -437,4 +463,4 @@ class VSBufferWriteableStreamImpl implements VSBufferWriteableStream { this.listeners.end.length = 0; } } -} \ No newline at end of file +} diff --git a/src/vs/base/common/collections.ts b/src/vs/base/common/collections.ts index f5c5cf5408b..a0f6695e8ae 100644 --- a/src/vs/base/common/collections.ts +++ b/src/vs/base/common/collections.ts @@ -46,9 +46,9 @@ export function size(from: IStringDictionary | INumberDictionary): numb } export function first(from: IStringDictionary | INumberDictionary): T | undefined { - for (let key in from) { + for (const key in from) { if (hasOwnProperty.call(from, key)) { - return from[key]; + return (from as any)[key]; } } return undefined; @@ -96,4 +96,44 @@ export function fromMap(original: Map): IStringDictionary { }); } return result; +} + +export class SetMap { + + private map = new Map>(); + + add(key: K, value: V): void { + let values = this.map.get(key); + + if (!values) { + values = new Set(); + this.map.set(key, values); + } + + values.add(value); + } + + delete(key: K, value: V): void { + const values = this.map.get(key); + + if (!values) { + return; + } + + values.delete(value); + + if (values.size === 0) { + this.map.delete(key); + } + } + + forEach(key: K, fn: (value: V) => void): void { + const values = this.map.get(key); + + if (!values) { + return; + } + + values.forEach(fn); + } } \ No newline at end of file diff --git a/src/vs/base/common/comparers.ts b/src/vs/base/common/comparers.ts index adf5859c794..d6dbb1784f1 100644 --- a/src/vs/base/common/comparers.ts +++ b/src/vs/base/common/comparers.ts @@ -7,28 +7,26 @@ import * as strings from 'vs/base/common/strings'; import { sep } from 'vs/base/common/path'; import { IdleValue } from 'vs/base/common/async'; -let intlFileNameCollator: IdleValue<{ collator: Intl.Collator, collatorIsNumeric: boolean }>; - -export function setFileNameComparer(collator: IdleValue<{ collator: Intl.Collator, collatorIsNumeric: boolean }>): void { - intlFileNameCollator = collator; -} +const intlFileNameCollator: IdleValue<{ collator: Intl.Collator, collatorIsNumeric: boolean }> = new IdleValue(() => { + const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }); + return { + collator: collator, + collatorIsNumeric: collator.resolvedOptions().numeric + }; +}); export function compareFileNames(one: string | null, other: string | null, caseSensitive = false): number { - if (intlFileNameCollator) { - const a = one || ''; - const b = other || ''; - const result = intlFileNameCollator.getValue().collator.compare(a, b); + const a = one || ''; + const b = other || ''; + const result = intlFileNameCollator.getValue().collator.compare(a, b); - // Using the numeric option in the collator will - // make compare(`foo1`, `foo01`) === 0. We must disambiguate. - if (intlFileNameCollator.getValue().collatorIsNumeric && result === 0 && a !== b) { - return a < b ? -1 : 1; - } - - return result; + // Using the numeric option in the collator will + // make compare(`foo1`, `foo01`) === 0. We must disambiguate. + if (intlFileNameCollator.getValue().collatorIsNumeric && result === 0 && a !== b) { + return a < b ? -1 : 1; } - return noIntlCompareFileNames(one, other, caseSensitive); + return result; } const FileNameMatch = /^(.*?)(\.([^.]*))?$/; @@ -54,46 +52,27 @@ export function noIntlCompareFileNames(one: string | null, other: string | null, } export function compareFileExtensions(one: string | null, other: string | null): number { - if (intlFileNameCollator) { - const [oneName, oneExtension] = extractNameAndExtension(one); - const [otherName, otherExtension] = extractNameAndExtension(other); + const [oneName, oneExtension] = extractNameAndExtension(one); + const [otherName, otherExtension] = extractNameAndExtension(other); - let result = intlFileNameCollator.getValue().collator.compare(oneExtension, otherExtension); + let result = intlFileNameCollator.getValue().collator.compare(oneExtension, otherExtension); - if (result === 0) { - // Using the numeric option in the collator will - // make compare(`foo1`, `foo01`) === 0. We must disambiguate. - if (intlFileNameCollator.getValue().collatorIsNumeric && oneExtension !== otherExtension) { - return oneExtension < otherExtension ? -1 : 1; - } - - // Extensions are equal, compare filenames - result = intlFileNameCollator.getValue().collator.compare(oneName, otherName); - - if (intlFileNameCollator.getValue().collatorIsNumeric && result === 0 && oneName !== otherName) { - return oneName < otherName ? -1 : 1; - } + if (result === 0) { + // Using the numeric option in the collator will + // make compare(`foo1`, `foo01`) === 0. We must disambiguate. + if (intlFileNameCollator.getValue().collatorIsNumeric && oneExtension !== otherExtension) { + return oneExtension < otherExtension ? -1 : 1; } - return result; + // Extensions are equal, compare filenames + result = intlFileNameCollator.getValue().collator.compare(oneName, otherName); + + if (intlFileNameCollator.getValue().collatorIsNumeric && result === 0 && oneName !== otherName) { + return oneName < otherName ? -1 : 1; + } } - return noIntlCompareFileExtensions(one, other); -} - -function noIntlCompareFileExtensions(one: string | null, other: string | null): number { - const [oneName, oneExtension] = extractNameAndExtension(one && one.toLowerCase()); - const [otherName, otherExtension] = extractNameAndExtension(other && other.toLowerCase()); - - if (oneExtension !== otherExtension) { - return oneExtension < otherExtension ? -1 : 1; - } - - if (oneName === otherName) { - return 0; - } - - return oneName < otherName ? -1 : 1; + return result; } function extractNameAndExtension(str?: string | null): [string, string] { diff --git a/src/vs/base/common/console.ts b/src/vs/base/common/console.ts index ccd30d07a1e..9b49ff985d4 100644 --- a/src/vs/base/common/console.ts +++ b/src/vs/base/common/console.ts @@ -131,7 +131,10 @@ export function log(entry: IRemoteConsoleLog, label: string): void { } // Log it - console[entry.severity].apply(console, consoleArgs); + if (typeof (console as any)[entry.severity] !== 'function') { + throw new Error('Unknown console method'); + } + (console as any)[entry.severity].apply(console, consoleArgs); } function color(color: string): string { diff --git a/src/vs/base/common/errorMessage.ts b/src/vs/base/common/errorMessage.ts index ddd6976f666..e3fc44bacd3 100644 --- a/src/vs/base/common/errorMessage.ts +++ b/src/vs/base/common/errorMessage.ts @@ -10,7 +10,7 @@ import * as arrays from 'vs/base/common/arrays'; function exceptionToErrorMessage(exception: any, verbose: boolean): string { if (exception.message) { if (verbose && (exception.stack || exception.stacktrace)) { - return nls.localize('stackTrace.format', "{0}: {1}", detectSystemErrorMessage(exception), exception.stack || exception.stacktrace); + return nls.localize('stackTrace.format', "{0}: {1}", detectSystemErrorMessage(exception), stackToString(exception.stack) || stackToString(exception.stacktrace)); } return detectSystemErrorMessage(exception); @@ -19,6 +19,14 @@ function exceptionToErrorMessage(exception: any, verbose: boolean): string { return nls.localize('error.defaultMessage', "An unknown error occurred. Please consult the log for more details."); } +function stackToString(stack: string[] | string | undefined): string | undefined { + if (Array.isArray(stack)) { + return stack.join('\n'); + } + + return stack; +} + function detectSystemErrorMessage(exception: any): string { // See https://nodejs.org/api/errors.html#errors_class_system_error diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index a58170e6b78..8b89e002422 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -49,7 +49,7 @@ export namespace Event { /** * Given an event and a `map` function, returns another event which maps each element - * throught the mapping function. + * through the mapping function. */ export function map(event: Event, map: (i: I) => O): Event { return snapshot((listener, thisArgs = null, disposables?) => event(i => listener.call(thisArgs, map(i)), null, disposables)); @@ -90,7 +90,7 @@ export namespace Event { /** * Given an event and a `merge` function, returns another event which maps each element - * and the cummulative result throught the `merge` function. Similar to `map`, but with memory. + * and the cumulative result through the `merge` function. Similar to `map`, but with memory. */ export function reduce(event: Event, merge: (last: O | undefined, event: I) => O, initial?: O): Event { let output: O | undefined = initial; @@ -271,7 +271,7 @@ export namespace Event { filter(fn: (e: T) => boolean): IChainableEvent; reduce(merge: (last: R | undefined, event: T) => R, initial?: R): IChainableEvent; latch(): IChainableEvent; - on(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[]): IDisposable; + on(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable; once(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[]): IDisposable; } @@ -299,7 +299,7 @@ export namespace Event { return new ChainableEvent(latch(this.event)); } - on(listener: (e: T) => any, thisArgs: any, disposables: IDisposable[]) { + on(listener: (e: T) => any, thisArgs: any, disposables: IDisposable[] | DisposableStore) { return this.event(listener, thisArgs, disposables); } diff --git a/src/vs/base/common/filters.ts b/src/vs/base/common/filters.ts index abafd683093..645937c3375 100644 --- a/src/vs/base/common/filters.ts +++ b/src/vs/base/common/filters.ts @@ -125,7 +125,11 @@ const wordSeparators = new Set(); .forEach(s => wordSeparators.add(s.charCodeAt(0))); function isWordSeparator(code: number): boolean { - return wordSeparators.has(code); + return isWhitespace(code) || wordSeparators.has(code); +} + +function charactersMatch(codeA: number, codeB: number): boolean { + return (codeA === codeB) || (isWordSeparator(codeA) && isWordSeparator(codeB)); } function isAlphanumeric(code: number): boolean { @@ -298,7 +302,7 @@ function _matchesWords(word: string, target: string, i: number, j: number, conti return []; } else if (j === target.length) { return null; - } else if (word[i] !== target[j]) { + } else if (!charactersMatch(word.charCodeAt(i), target.charCodeAt(j))) { return null; } else { let result: IMatch[] | null = null; @@ -316,9 +320,8 @@ function _matchesWords(word: string, target: string, i: number, j: number, conti function nextWord(word: string, start: number): number { for (let i = start; i < word.length; i++) { - const c = word.charCodeAt(i); - if (isWhitespace(c) || (i > 0 && isWhitespace(word.charCodeAt(i - 1))) || - isWordSeparator(c) || (i > 0 && isWordSeparator(word.charCodeAt(i - 1)))) { + if (isWordSeparator(word.charCodeAt(i)) || + (i > 0 && isWordSeparator(word.charCodeAt(i - 1)))) { return i; } } @@ -492,7 +495,7 @@ function isUpperCaseAtPos(pos: number, word: string, wordLow: string): boolean { return word[pos] !== wordLow[pos]; } -function isPatternInWord(patternLow: string, patternPos: number, patternLen: number, wordLow: string, wordPos: number, wordLen: number): boolean { +export function isPatternInWord(patternLow: string, patternPos: number, patternLen: number, wordLow: string, wordPos: number, wordLen: number): boolean { while (patternPos < patternLen && wordPos < wordLen) { if (patternLow[patternPos] === wordLow[wordPos]) { patternPos += 1; diff --git a/src/vs/base/common/htmlContent.ts b/src/vs/base/common/htmlContent.ts index 201e378e11e..ac7c8ed3a91 100644 --- a/src/vs/base/common/htmlContent.ts +++ b/src/vs/base/common/htmlContent.ts @@ -92,3 +92,25 @@ export function removeMarkdownEscapes(text: string): string { } return text.replace(/\\([\\`*_{}[\]()#+\-.!])/g, '$1'); } + +export function parseHrefAndDimensions(href: string): { href: string, dimensions: string[] } { + const dimensions: string[] = []; + const splitted = href.split('|').map(s => s.trim()); + href = splitted[0]; + const parameters = splitted[1]; + if (parameters) { + const heightFromParams = /height=(\d+)/.exec(parameters); + const widthFromParams = /width=(\d+)/.exec(parameters); + const height = heightFromParams ? heightFromParams[1] : ''; + const width = widthFromParams ? widthFromParams[1] : ''; + const widthIsFinite = isFinite(parseInt(width)); + const heightIsFinite = isFinite(parseInt(height)); + if (widthIsFinite) { + dimensions.push(`width="${width}"`); + } + if (heightIsFinite) { + dimensions.push(`height="${height}"`); + } + } + return { href, dimensions }; +} diff --git a/src/vs/base/common/lifecycle.ts b/src/vs/base/common/lifecycle.ts index 426f0ddeb8e..66143bb94b7 100644 --- a/src/vs/base/common/lifecycle.ts +++ b/src/vs/base/common/lifecycle.ts @@ -23,24 +23,25 @@ function markTracked(x: T): void { if (x && x !== Disposable.None) { try { - x[__is_disposable_tracked__] = true; + (x as any)[__is_disposable_tracked__] = true; } catch { // noop } } } -function trackDisposable(x: T): void { +function trackDisposable(x: T): T { if (!TRACK_DISPOSABLES) { - return; + return x; } - const stack = new Error().stack!; + const stack = new Error('Potentially leaked disposable').stack!; setTimeout(() => { - if (!x[__is_disposable_tracked__]) { + if (!(x as any)[__is_disposable_tracked__]) { console.log(stack); } }, 3000); + return x; } export interface IDisposable { @@ -76,11 +77,17 @@ export function dispose(disposables: T | T[] | undefined) export function combinedDisposable(...disposables: IDisposable[]): IDisposable { disposables.forEach(markTracked); - return { dispose: () => dispose(disposables) }; + return trackDisposable({ dispose: () => dispose(disposables) }); } export function toDisposable(fn: () => void): IDisposable { - return { dispose: fn }; + const self = trackDisposable({ + dispose: () => { + markTracked(self); + fn(); + } + }); + return self; } export class DisposableStore implements IDisposable { @@ -93,6 +100,10 @@ export class DisposableStore implements IDisposable { * Any future disposables added to this object will be disposed of on `add`. */ public dispose(): void { + if (this._isDisposed) { + return; + } + markTracked(this); this._isDisposed = true; this.clear(); @@ -110,6 +121,9 @@ export class DisposableStore implements IDisposable { if (!t) { return t; } + if ((t as any as DisposableStore) === this) { + throw new Error('Cannot register a disposable on itself!'); + } markTracked(t); if (this._isDisposed) { @@ -140,6 +154,9 @@ export abstract class Disposable implements IDisposable { } protected _register(t: T): T { + if ((t as any as Disposable) === this) { + throw new Error('Cannot register a disposable on itself!'); + } return this._store.add(t); } } diff --git a/src/vs/base/common/mime.ts b/src/vs/base/common/mime.ts index 83234f40ac5..d9451a64def 100644 --- a/src/vs/base/common/mime.ts +++ b/src/vs/base/common/mime.ts @@ -274,52 +274,54 @@ interface MapExtToMediaMimes { // Known media mimes that we can handle const mapExtToMediaMimes: MapExtToMediaMimes = { + '.aac': 'audio/x-aac', + '.avi': 'video/x-msvideo', '.bmp': 'image/bmp', + '.flv': 'video/x-flv', '.gif': 'image/gif', - '.jpg': 'image/jpg', - '.jpeg': 'image/jpg', - '.jpe': 'image/jpg', - '.png': 'image/png', - '.tiff': 'image/tiff', - '.tif': 'image/tiff', '.ico': 'image/x-icon', - '.tga': 'image/x-tga', - '.psd': 'image/vnd.adobe.photoshop', - '.webp': 'image/webp', + '.jpe': 'image/jpg', + '.jpeg': 'image/jpg', + '.jpg': 'image/jpg', + '.m1v': 'video/mpeg', + '.m2a': 'audio/mpeg', + '.m2v': 'video/mpeg', + '.m3a': 'audio/mpeg', '.mid': 'audio/midi', '.midi': 'audio/midi', - '.mp4a': 'audio/mp4', - '.mpga': 'audio/mpeg', + '.mk3d': 'video/x-matroska', + '.mks': 'video/x-matroska', + '.mkv': 'video/x-matroska', + '.mov': 'video/quicktime', + '.movie': 'video/x-sgi-movie', '.mp2': 'audio/mpeg', '.mp2a': 'audio/mpeg', '.mp3': 'audio/mpeg', - '.m2a': 'audio/mpeg', - '.m3a': 'audio/mpeg', - '.oga': 'audio/ogg', - '.ogg': 'audio/ogg', - '.spx': 'audio/ogg', - '.aac': 'audio/x-aac', - '.wav': 'audio/x-wav', - '.wma': 'audio/x-ms-wma', '.mp4': 'video/mp4', + '.mp4a': 'audio/mp4', '.mp4v': 'video/mp4', - '.mpg4': 'video/mp4', + '.mpe': 'video/mpeg', '.mpeg': 'video/mpeg', '.mpg': 'video/mpeg', - '.mpe': 'video/mpeg', - '.m1v': 'video/mpeg', - '.m2v': 'video/mpeg', + '.mpg4': 'video/mp4', + '.mpga': 'audio/mpeg', + '.oga': 'audio/ogg', + '.ogg': 'audio/ogg', '.ogv': 'video/ogg', + '.png': 'image/png', + '.psd': 'image/vnd.adobe.photoshop', '.qt': 'video/quicktime', - '.mov': 'video/quicktime', + '.spx': 'audio/ogg', + '.svg': 'image/svg+xml', + '.tga': 'image/x-tga', + '.tif': 'image/tiff', + '.tiff': 'image/tiff', + '.wav': 'audio/x-wav', '.webm': 'video/webm', - '.mkv': 'video/x-matroska', - '.mk3d': 'video/x-matroska', - '.mks': 'video/x-matroska', + '.webp': 'image/webp', + '.wma': 'audio/x-ms-wma', '.wmv': 'video/x-ms-wmv', - '.flv': 'video/x-flv', - '.avi': 'video/x-msvideo', - '.movie': 'video/x-sgi-movie' + '.woff': 'application/font-woff', }; export function getMediaMime(path: string): string | undefined { diff --git a/src/vs/base/common/network.ts b/src/vs/base/common/network.ts index a7466e641af..46d2933a05e 100644 --- a/src/vs/base/common/network.ts +++ b/src/vs/base/common/network.ts @@ -46,4 +46,6 @@ export namespace Schemas { export const command: string = 'command'; export const vscodeRemote: string = 'vscode-remote'; + + export const userData: string = 'vscode-userdata'; } diff --git a/src/vs/base/common/objects.ts b/src/vs/base/common/objects.ts index 97c8f9196c0..1475bf4a550 100644 --- a/src/vs/base/common/objects.ts +++ b/src/vs/base/common/objects.ts @@ -14,11 +14,11 @@ export function deepClone(obj: T): T { return obj as any; } const result: any = Array.isArray(obj) ? [] : {}; - Object.keys(obj as any).forEach((key: string) => { - if (obj[key] && typeof obj[key] === 'object') { - result[key] = deepClone(obj[key]); + Object.keys(obj).forEach((key: string) => { + if ((obj)[key] && typeof (obj)[key] === 'object') { + result[key] = deepClone((obj)[key]); } else { - result[key] = obj[key]; + result[key] = (obj)[key]; } }); return result; diff --git a/src/vs/base/common/parsers.ts b/src/vs/base/common/parsers.ts index 748abd4fd47..125b965f5e4 100644 --- a/src/vs/base/common/parsers.ts +++ b/src/vs/base/common/parsers.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as Types from 'vs/base/common/types'; - export const enum ValidationState { OK = 0, Info = 1, @@ -78,25 +76,4 @@ export abstract class Parser { public fatal(message: string): void { this._problemReporter.fatal(message); } - - protected static merge(destination: T, source: T, overwrite: boolean): void { - Object.keys(source).forEach((key: string) => { - const destValue = destination[key]; - const sourceValue = source[key]; - if (Types.isUndefined(sourceValue)) { - return; - } - if (Types.isUndefined(destValue)) { - destination[key] = sourceValue; - } else { - if (overwrite) { - if (Types.isObject(destValue) && Types.isObject(sourceValue)) { - this.merge(destValue, sourceValue, overwrite); - } else { - destination[key] = sourceValue; - } - } - } - }); - } } \ No newline at end of file diff --git a/src/vs/base/common/path.ts b/src/vs/base/common/path.ts index 029bfc01632..c8532347224 100644 --- a/src/vs/base/common/path.ts +++ b/src/vs/base/common/path.ts @@ -212,7 +212,7 @@ export const win32: IPath = { // absolute path, get cwd for that drive, or the process cwd if // the drive cwd is not available. We're sure the device is not // a UNC path at this points, because UNC paths are always absolute. - path = process.env['=' + resolvedDevice] || process.cwd(); + path = (process.env as any)['=' + resolvedDevice] || process.cwd(); // Verify that a cwd was found and that it actually points // to our drive. If not, default to the drive's root. diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 521a02a4b57..8ccc9567737 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -221,7 +221,7 @@ export function addTrailingPathSeparator(resource: URI, sep: string = paths.sep) * Returns a relative path between two URIs. If the URIs don't have the same schema or authority, `undefined` is returned. * The returned relative path always uses forward slashes. */ -export function relativePath(from: URI, to: URI): string | undefined { +export function relativePath(from: URI, to: URI, ignoreCase = hasToIgnoreCase(from)): string | undefined { if (from.scheme !== to.scheme || !isEqualAuthority(from.authority, to.authority)) { return undefined; } @@ -229,7 +229,20 @@ export function relativePath(from: URI, to: URI): string | undefined { const relativePath = paths.relative(from.path, to.path); return isWindows ? extpath.toSlashes(relativePath) : relativePath; } - return paths.posix.relative(from.path || '/', to.path || '/'); + let fromPath = from.path || '/', toPath = to.path || '/'; + if (ignoreCase) { + // make casing of fromPath match toPath + let i = 0; + for (const len = Math.min(fromPath.length, toPath.length); i < len; i++) { + if (fromPath.charCodeAt(i) !== toPath.charCodeAt(i)) { + if (fromPath.charAt(i).toLowerCase() !== toPath.charAt(i).toLowerCase()) { + break; + } + } + } + fromPath = toPath.substr(0, i) + fromPath.substr(i); + } + return paths.posix.relative(fromPath, toPath); } /** diff --git a/src/vs/base/common/types.ts b/src/vs/base/common/types.ts index c3e24cc0a45..56d365091e9 100644 --- a/src/vs/base/common/types.ts +++ b/src/vs/base/common/types.ts @@ -169,6 +169,31 @@ export function getAllPropertyNames(obj: object): string[] { return res; } +export function getAllMethodNames(obj: object): string[] { + const methods: string[] = []; + for (const prop of getAllPropertyNames(obj)) { + if (typeof (obj as any)[prop] === 'function') { + methods.push(prop); + } + } + return methods; +} + +export function createProxyObject(methodNames: string[], invoke: (method: string, args: any[]) => any): T { + const createProxyMethod = (method: string): () => any => { + return function () { + const args = Array.prototype.slice.call(arguments, 0); + return invoke(method, args); + }; + }; + + let result = {} as T; + for (const methodName of methodNames) { + (result)[methodName] = createProxyMethod(methodName); + } + return result; +} + /** * Converts null to undefined, passes all other values through. */ diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 90a7537b3e7..966555e04d0 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -96,16 +96,6 @@ const _empty = ''; const _slash = '/'; const _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/; -function _isQueryStringScheme(scheme: string) { - switch (scheme.toLowerCase()) { - case 'http': - case 'https': - case 'ftp': - return true; - } - return false; -} - /** * Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986. * This class is a simple parser which creates the basic component parts @@ -292,14 +282,14 @@ export class URI implements UriComponents { static parse(value: string, _strict: boolean = false): URI { const match = _regexp.exec(value); if (!match) { - return new _URI(_empty, _empty, _empty, _empty, _empty, _strict); + return new _URI(_empty, _empty, _empty, _empty, _empty); } return new _URI( match[2] || _empty, - decodeURIComponentFast(match[4] || _empty, false, false), - decodeURIComponentFast(match[5] || _empty, true, false), - decodeURIComponentFast(match[7] || _empty, false, _isQueryStringScheme(match[2])), - decodeURIComponentFast(match[9] || _empty, false, false), + decodeURIComponent(match[4] || _empty), + decodeURIComponent(match[5] || _empty), + decodeURIComponent(match[7] || _empty), + decodeURIComponent(match[9] || _empty), _strict ); } @@ -331,7 +321,7 @@ export class URI implements UriComponents { // normalize to fwd-slashes on windows, // on other systems bwd-slashes are valid - // filename character, e.g. /f\oo/ba\r.txt + // filename character, eg /f\oo/ba\r.txt if (isWindows) { path = path.replace(/\\/g, _slash); } @@ -475,84 +465,6 @@ class _URI extends URI { } } -function isHex(value: string, pos: number): boolean { - if (pos >= value.length) { - return false; - } - const code = value.charCodeAt(pos); - return (code >= CharCode.Digit0 && code <= CharCode.Digit9)// 0-9 - || (code >= CharCode.a && code <= CharCode.f) //a-f - || (code >= CharCode.A && code <= CharCode.F); //A-F -} - - -function decodeURIComponentFast(uriComponent: string, isPath: boolean, isQueryString: boolean): string { - - let res: string | undefined; - let nativeDecodePos = -1; - - for (let pos = 0; pos < uriComponent.length; pos++) { - const code = uriComponent.charCodeAt(pos); - - // decoding needed - if (code === CharCode.PercentSign && isHex(uriComponent, pos + 1) && isHex(uriComponent, pos + 2)) { - - const chA = uriComponent.charCodeAt(pos + 1); - const chB = uriComponent.charCodeAt(pos + 2); - - // when in a path -> check and accept %2f and %2F (fwd slash) - // when in a query string -> check and accept %3D, %26, and %3B (equals, ampersand, semi-colon) - if ( - (isPath && chA === CharCode.Digit2 && (chB === CharCode.F || chB === CharCode.f)) - || - (isQueryString && ( - (chA === CharCode.Digit2 && chB === CharCode.Digit6) // %26 - || - (chA === CharCode.Digit3 && (chB === CharCode.B || chB === CharCode.b || chB === CharCode.D || chB === CharCode.d)) // %3D, %3D - )) - ) { - if (nativeDecodePos !== -1) { - res += decodeURIComponent(uriComponent.substring(nativeDecodePos, pos)); - nativeDecodePos = -1; - } - - if (res !== undefined) { - res += uriComponent.substr(pos, 3); - } - - pos += 2; - continue; - } - - if (res === undefined) { - res = uriComponent.substring(0, pos); - } - if (nativeDecodePos === -1) { - nativeDecodePos = pos; - } - - pos += 2; - - } else { - - if (nativeDecodePos !== -1) { - res += decodeURIComponent(uriComponent.substring(nativeDecodePos, pos)); - nativeDecodePos = -1; - } - - if (res !== undefined) { - res += String.fromCharCode(code); - } - } - } - - if (nativeDecodePos !== -1) { - res += decodeURIComponent(uriComponent.substr(nativeDecodePos)); - } - - return res !== undefined ? res : uriComponent; -} - // reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2 const encodeTable: { [ch: number]: string } = { [CharCode.Colon]: '%3A', // gen-delims @@ -578,7 +490,7 @@ const encodeTable: { [ch: number]: string } = { [CharCode.Space]: '%20', }; -function encodeURIComponentFast(uriComponent: string, isPath: boolean, isQueryString: boolean): string { +function encodeURIComponentFast(uriComponent: string, allowSlash: boolean): string { let res: string | undefined = undefined; let nativeEncodePos = -1; @@ -594,8 +506,7 @@ function encodeURIComponentFast(uriComponent: string, isPath: boolean, isQuerySt || code === CharCode.Period || code === CharCode.Underline || code === CharCode.Tilde - || (isPath && code === CharCode.Slash) // path => allow slash AS-IS - || (isQueryString && (code === CharCode.Equals || code === CharCode.Ampersand || code === CharCode.Semicolon)) // query string => allow &=; + || (allowSlash && code === CharCode.Slash) ) { // check if we are delaying native encode if (nativeEncodePos !== -1) { @@ -607,20 +518,6 @@ function encodeURIComponentFast(uriComponent: string, isPath: boolean, isQuerySt res += uriComponent.charAt(pos); } - } else if (code === CharCode.PercentSign && isHex(uriComponent, pos + 1) && isHex(uriComponent, pos + 2)) { - // at percentage encoded value - - // check if we are delaying native encode - if (nativeEncodePos !== -1) { - res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos)); - nativeEncodePos = -1; - } - // check if we write into a new string (by default we try to return the param) - if (res !== undefined) { - res += uriComponent.substr(pos, 3); - } - pos += 2; - } else { // encoding needed, we need to allocate a new string if (res === undefined) { @@ -709,7 +606,6 @@ function _asFormatted(uri: URI, skipEncoding: boolean): string { let res = ''; let { scheme, authority, path, query, fragment } = uri; - if (scheme) { res += scheme; res += ':'; @@ -726,22 +622,22 @@ function _asFormatted(uri: URI, skipEncoding: boolean): string { authority = authority.substr(idx + 1); idx = userinfo.indexOf(':'); if (idx === -1) { - res += encoder(userinfo, false, false); + res += encoder(userinfo, false); } else { // :@ - res += encoder(userinfo.substr(0, idx), false, false); + res += encoder(userinfo.substr(0, idx), false); res += ':'; - res += encoder(userinfo.substr(idx + 1), false, false); + res += encoder(userinfo.substr(idx + 1), false); } res += '@'; } authority = authority.toLowerCase(); idx = authority.indexOf(':'); if (idx === -1) { - res += encoder(authority, false, false); + res += encoder(authority, false); } else { // : - res += encoder(authority.substr(0, idx), false, false); + res += encoder(authority.substr(0, idx), false); res += authority.substr(idx); } } @@ -759,15 +655,15 @@ function _asFormatted(uri: URI, skipEncoding: boolean): string { } } // encode the rest of the path - res += encoder(path, true, false); + res += encoder(path, true); } if (query) { res += '?'; - res += encoder(query, false, _isQueryStringScheme(scheme)); + res += encoder(query, false); } if (fragment) { res += '#'; - res += !skipEncoding ? encodeURIComponentFast(fragment, false, false) : fragment; + res += !skipEncoding ? encodeURIComponentFast(fragment, false) : fragment; } return res; } diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index a0191ea7807..ca6e174ce33 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -6,7 +6,7 @@ import { transformErrorForSerialization } from 'vs/base/common/errors'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { isWeb } from 'vs/base/common/platform'; -import { getAllPropertyNames } from 'vs/base/common/types'; +import * as types from 'vs/base/common/types'; const INITIALIZE = '$initialize'; @@ -173,17 +173,22 @@ class SimpleWorkerProtocol { } } +export interface IWorkerClient { + getProxyObject(): Promise; + dispose(): void; +} + /** * Main thread side */ -export class SimpleWorkerClient extends Disposable { +export class SimpleWorkerClient extends Disposable implements IWorkerClient { - private _worker: IWorker; - private _onModuleLoaded: Promise; - private _protocol: SimpleWorkerProtocol; - private _lazyProxy: Promise; + private readonly _worker: IWorker; + private readonly _onModuleLoaded: Promise; + private readonly _protocol: SimpleWorkerProtocol; + private readonly _lazyProxy: Promise; - constructor(workerFactory: IWorkerFactory, moduleId: string) { + constructor(workerFactory: IWorkerFactory, moduleId: string, host: H) { super(); let lazyProxyReject: ((err: any) => void) | null = null; @@ -207,8 +212,15 @@ export class SimpleWorkerClient extends Disposable { this._worker.postMessage(msg); }, handleMessage: (method: string, args: any[]): Promise => { - // Intentionally not supporting worker -> main requests - return Promise.resolve(null); + if (typeof (host as any)[method] !== 'function') { + return Promise.reject(new Error('Missing method ' + method + ' on main thread host.')); + } + + try { + return Promise.resolve((host as any)[method].apply(host, args)); + } catch (e) { + return Promise.reject(e); + } } }); this._protocol.setWorkerId(this._worker.getId()); @@ -223,41 +235,33 @@ export class SimpleWorkerClient extends Disposable { loaderConfiguration = (self).requirejs.s.contexts._.config; } + const hostMethods = types.getAllMethodNames(host); + // Send initialize message this._onModuleLoaded = this._protocol.sendMessage(INITIALIZE, [ this._worker.getId(), + loaderConfiguration, moduleId, - loaderConfiguration + hostMethods, ]); - this._lazyProxy = new Promise((resolve, reject) => { - lazyProxyReject = reject; - this._onModuleLoaded.then((availableMethods: string[]) => { - let proxy = {}; - for (const methodName of availableMethods) { - (proxy as any)[methodName] = createProxyMethod(methodName, proxyMethodRequest); - } - resolve(proxy); - }, (e) => { - reject(e); - this._onError('Worker failed to load ' + moduleId, e); - }); - }); - // Create proxy to loaded code const proxyMethodRequest = (method: string, args: any[]): Promise => { return this._request(method, args); }; - const createProxyMethod = (method: string, proxyMethodRequest: (method: string, args: any[]) => Promise): () => Promise => { - return function () { - let args = Array.prototype.slice.call(arguments, 0); - return proxyMethodRequest(method, args); - }; - }; + this._lazyProxy = new Promise((resolve, reject) => { + lazyProxyReject = reject; + this._onModuleLoaded.then((availableMethods: string[]) => { + resolve(types.createProxyObject(availableMethods, proxyMethodRequest)); + }, (e) => { + reject(e); + this._onError('Worker failed to load ' + moduleId, e); + }); + }); } - public getProxyObject(): Promise { + public getProxyObject(): Promise { return this._lazyProxy; } @@ -280,16 +284,22 @@ export interface IRequestHandler { [prop: string]: any; } +export interface IRequestHandlerFactory { + (host: H): IRequestHandler; +} + /** * Worker side */ -export class SimpleWorkerServer { +export class SimpleWorkerServer { + private _requestHandlerFactory: IRequestHandlerFactory | null; private _requestHandler: IRequestHandler | null; private _protocol: SimpleWorkerProtocol; - constructor(postSerializedMessage: (msg: string) => void, requestHandler: IRequestHandler | null) { - this._requestHandler = requestHandler; + constructor(postSerializedMessage: (msg: string) => void, requestHandlerFactory: IRequestHandlerFactory | null) { + this._requestHandlerFactory = requestHandlerFactory; + this._requestHandler = null; this._protocol = new SimpleWorkerProtocol({ sendMessage: (msg: string): void => { postSerializedMessage(msg); @@ -304,7 +314,7 @@ export class SimpleWorkerServer { private _handleMessage(method: string, args: any[]): Promise { if (method === INITIALIZE) { - return this.initialize(args[0], args[1], args[2]); + return this.initialize(args[0], args[1], args[2], args[3]); } if (!this._requestHandler || typeof this._requestHandler[method] !== 'function') { @@ -318,18 +328,19 @@ export class SimpleWorkerServer { } } - private initialize(workerId: number, moduleId: string, loaderConfig: any): Promise { + private initialize(workerId: number, loaderConfig: any, moduleId: string, hostMethods: string[]): Promise { this._protocol.setWorkerId(workerId); - if (this._requestHandler) { + const proxyMethodRequest = (method: string, args: any[]): Promise => { + return this._protocol.sendMessage(method, args); + }; + + const hostProxy = types.createProxyObject(hostMethods, proxyMethodRequest); + + if (this._requestHandlerFactory) { // static request handler - let methods: string[] = []; - for (const prop of getAllPropertyNames(this._requestHandler)) { - if (typeof this._requestHandler[prop] === 'function') { - methods.push(prop); - } - } - return Promise.resolve(methods); + this._requestHandler = this._requestHandlerFactory(hostProxy); + return Promise.resolve(types.getAllMethodNames(this._requestHandler)); } if (loaderConfig) { @@ -350,23 +361,15 @@ export class SimpleWorkerServer { return new Promise((resolve, reject) => { // Use the global require to be sure to get the global config - (self).require([moduleId], (...result: any[]) => { - let handlerModule = result[0]; - this._requestHandler = handlerModule.create(); + (self).require([moduleId], (module: { create: IRequestHandlerFactory }) => { + this._requestHandler = module.create(hostProxy); if (!this._requestHandler) { reject(new Error(`No RequestHandler!`)); return; } - let methods: string[] = []; - for (const prop of getAllPropertyNames(this._requestHandler)) { - if (typeof this._requestHandler[prop] === 'function') { - methods.push(prop); - } - } - - resolve(methods); + resolve(types.getAllMethodNames(this._requestHandler)); }, reject); }); } @@ -375,6 +378,6 @@ export class SimpleWorkerServer { /** * Called on the worker side */ -export function create(postMessage: (msg: string) => void): SimpleWorkerServer { +export function create(postMessage: (msg: string) => void): SimpleWorkerServer { return new SimpleWorkerServer(postMessage, null); } diff --git a/src/vs/base/node/encoding.ts b/src/vs/base/node/encoding.ts index 9b04d9f0a96..8e23d0adeb2 100644 --- a/src/vs/base/node/encoding.ts +++ b/src/vs/base/node/encoding.ts @@ -395,7 +395,7 @@ export async function resolveTerminalEncoding(verbose?: boolean): Promise { if (stdout) { - const windowsTerminalEncodingKeys = Object.keys(windowsTerminalEncodings); + const windowsTerminalEncodingKeys = Object.keys(windowsTerminalEncodings) as Array; for (const key of windowsTerminalEncodingKeys) { if (stdout.indexOf(key) >= 0) { return resolve(windowsTerminalEncodings[key]); diff --git a/src/vs/base/node/id.ts b/src/vs/base/node/id.ts index d8f617df434..6f72afeed79 100644 --- a/src/vs/base/node/id.ts +++ b/src/vs/base/node/id.ts @@ -11,7 +11,7 @@ import { TernarySearchTree } from 'vs/base/common/map'; // http://www.techrepublic.com/blog/data-center/mac-address-scorecard-for-common-virtual-machine-platforms/ // VMware ESX 3, Server, Workstation, Player 00-50-56, 00-0C-29, 00-05-69 // Microsoft Hyper-V, Virtual Server, Virtual PC 00-03-FF -// Parallells Desktop, Workstation, Server, Virtuozzo 00-1C-42 +// Parallels Desktop, Workstation, Server, Virtuozzo 00-1C-42 // Virtual Iron 4 00-0F-4B // Red Hat Xen 00-16-3E // Oracle VM 00-16-3E diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index 14dca3d5f49..1af9f028c70 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -138,6 +138,20 @@ export async function readdir(path: string): Promise { return handleDirectoryChildren(await promisify(fs.readdir)(path)); } +export async function readdirWithFileTypes(path: string): Promise { + const children = await promisify(fs.readdir)(path, { withFileTypes: true }); + + // Mac: uses NFD unicode form on disk, but we want NFC + // See also https://github.com/nodejs/node/issues/2165 + if (platform.isMacintosh) { + for (const child of children) { + child.name = normalizeNFC(child.name); + } + } + + return children; +} + export function readdirSync(path: string): string[] { return handleDirectoryChildren(fs.readdirSync(path)); } diff --git a/src/vs/base/node/request.ts b/src/vs/base/node/request.ts deleted file mode 100644 index 17731debc5b..00000000000 --- a/src/vs/base/node/request.ts +++ /dev/null @@ -1,183 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { isBoolean, isNumber } from 'vs/base/common/types'; -import * as https from 'https'; -import * as http from 'http'; -import { Stream } from 'stream'; -import { parse as parseUrl } from 'url'; -import { createWriteStream } from 'fs'; -import { assign } from 'vs/base/common/objects'; -import { createGunzip } from 'zlib'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { canceled } from 'vs/base/common/errors'; - -export type Agent = any; - -export interface IRawRequestFunction { - (options: http.RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; -} - -export interface IRequestOptions { - type?: string; - url?: string; - user?: string; - password?: string; - headers?: any; - timeout?: number; - data?: string | Stream; - agent?: Agent; - followRedirects?: number; - strictSSL?: boolean; - getRawRequest?(options: IRequestOptions): IRawRequestFunction; -} - -export interface IRequestContext { - // req: http.ClientRequest; - // res: http.ClientResponse; - res: { - headers: { [n: string]: string }; - statusCode?: number; - }; - stream: Stream; -} - -export interface IRequestFunction { - (options: IRequestOptions, token: CancellationToken): Promise; -} - -async function getNodeRequest(options: IRequestOptions): Promise { - const endpoint = parseUrl(options.url!); - const module = endpoint.protocol === 'https:' ? await import('https') : await import('http'); - return module.request; -} - -export function request(options: IRequestOptions, token: CancellationToken): Promise { - let req: http.ClientRequest; - - const rawRequestPromise = options.getRawRequest - ? Promise.resolve(options.getRawRequest(options)) - : Promise.resolve(getNodeRequest(options)); - - return rawRequestPromise.then(rawRequest => { - - return new Promise((c, e) => { - const endpoint = parseUrl(options.url!); - - const opts: https.RequestOptions = { - hostname: endpoint.hostname, - port: endpoint.port ? parseInt(endpoint.port) : (endpoint.protocol === 'https:' ? 443 : 80), - protocol: endpoint.protocol, - path: endpoint.path, - method: options.type || 'GET', - headers: options.headers, - agent: options.agent, - rejectUnauthorized: isBoolean(options.strictSSL) ? options.strictSSL : true - }; - - if (options.user && options.password) { - opts.auth = options.user + ':' + options.password; - } - - req = rawRequest(opts, (res: http.IncomingMessage) => { - const followRedirects: number = isNumber(options.followRedirects) ? options.followRedirects : 3; - if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && followRedirects > 0 && res.headers['location']) { - request(assign({}, options, { - url: res.headers['location'], - followRedirects: followRedirects - 1 - }), token).then(c, e); - } else { - let stream: Stream = res; - - if (res.headers['content-encoding'] === 'gzip') { - stream = stream.pipe(createGunzip()); - } - - c({ res, stream } as IRequestContext); - } - }); - - req.on('error', e); - - if (options.timeout) { - req.setTimeout(options.timeout); - } - - if (options.data) { - if (typeof options.data === 'string') { - req.write(options.data); - } else { - options.data.pipe(req); - return; - } - } - - req.end(); - - token.onCancellationRequested(() => { - req.abort(); - e(canceled()); - }); - }); - }); -} - -function isSuccess(context: IRequestContext): boolean { - return (context.res.statusCode && context.res.statusCode >= 200 && context.res.statusCode < 300) || context.res.statusCode === 1223; -} - -function hasNoContent(context: IRequestContext): boolean { - return context.res.statusCode === 204; -} - -export function download(filePath: string, context: IRequestContext): Promise { - return new Promise((c, e) => { - const out = createWriteStream(filePath); - - out.once('finish', () => c(undefined)); - context.stream.once('error', e); - context.stream.pipe(out); - }); -} - -export function asText(context: IRequestContext): Promise { - return new Promise((c, e) => { - if (!isSuccess(context)) { - return e('Server returned ' + context.res.statusCode); - } - - if (hasNoContent(context)) { - return c(null); - } - - const buffer: string[] = []; - context.stream.on('data', (d: string) => buffer.push(d)); - context.stream.on('end', () => c(buffer.join(''))); - context.stream.on('error', e); - }); -} - -export function asJson(context: IRequestContext): Promise { - return new Promise((c, e) => { - if (!isSuccess(context)) { - return e('Server returned ' + context.res.statusCode); - } - - if (hasNoContent(context)) { - return c(null); - } - - const buffer: string[] = []; - context.stream.on('data', (d: string) => buffer.push(d)); - context.stream.on('end', () => { - try { - c(JSON.parse(buffer.join(''))); - } catch (err) { - e(err); - } - }); - context.stream.on('error', e); - }); -} diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 80f063e5891..6292487e1c1 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -246,19 +246,29 @@ function deserialize(reader: IReader): any { } } +interface PendingRequest { + request: IRawPromiseRequest | IRawEventListenRequest; + timeoutTimer: any; +} + export class ChannelServer implements IChannelServer, IDisposable { private channels = new Map>(); private activeRequests = new Map(); private protocolListener: IDisposable | null; - constructor(private protocol: IMessagePassingProtocol, private ctx: TContext) { + // Requests might come in for channels which are not yet registered. + // They will timeout after `timeoutDelay`. + private pendingRequests = new Map(); + + constructor(private protocol: IMessagePassingProtocol, private ctx: TContext, private timeoutDelay: number = 1000) { this.protocolListener = this.protocol.onMessage(msg => this.onRawMessage(msg)); this.sendResponse({ type: ResponseType.Initialize }); } registerChannel(channelName: string, channel: IServerChannel): void { this.channels.set(channelName, channel); + this.flushPendingRequests(channelName); } private sendResponse(response: IRawResponse): void { @@ -309,9 +319,12 @@ export class ChannelServer implements IChannelServer; @@ -348,8 +361,10 @@ export class ChannelServer implements IChannelServer implements IChannelServer { + console.error(`Unknown channel: ${request.channelName}`); + + if (request.type === RequestType.Promise) { + this.sendResponse({ + id: request.id, + data: { name: 'Unknown channel', message: `Channel name '${request.channelName}' timed out after ${this.timeoutDelay}ms`, stack: undefined }, + type: ResponseType.PromiseError + }); + } + }, this.timeoutDelay); + + pendingRequests.push({ request, timeoutTimer: timer }); + } + + private flushPendingRequests(channelName: string): void { + const requests = this.pendingRequests.get(channelName); + + if (requests) { + for (const request of requests) { + clearTimeout(request.timeoutTimer); + + switch (request.request.type) { + case RequestType.Promise: this.onPromise(request.request); break; + case RequestType.EventListen: this.onEventListen(request.request); break; + } + } + + this.pendingRequests.delete(channelName); + } + } + public dispose(): void { if (this.protocolListener) { this.protocolListener.dispose(); @@ -587,6 +642,7 @@ export interface ClientConnectionEvent { } interface Connection extends Client { + readonly channelServer: ChannelServer; readonly channelClient: ChannelClient; } @@ -625,7 +681,7 @@ export class IPCServer implements IChannelServer, I this.channels.forEach((channel, name) => channelServer.registerChannel(name, channel)); - const connection: Connection = { channelClient, ctx }; + const connection: Connection = { channelServer, channelClient, ctx }; this._connections.add(connection); this._onDidChangeConnections.fire(connection); @@ -661,6 +717,10 @@ export class IPCServer implements IChannelServer, I registerChannel(channelName: string, channel: IServerChannel): void { this.channels.set(channelName, channel); + + this._connections.forEach(connection => { + connection.channelServer.registerChannel(channelName, channel); + }); } dispose(): void { diff --git a/src/vs/base/parts/quickopen/test/common/quickOpenScorer.test.ts b/src/vs/base/parts/quickopen/test/common/quickOpenScorer.test.ts index 47c51b87902..548cc9489f0 100644 --- a/src/vs/base/parts/quickopen/test/common/quickOpenScorer.test.ts +++ b/src/vs/base/parts/quickopen/test/common/quickOpenScorer.test.ts @@ -515,11 +515,27 @@ suite('Quick Open Scorer', () => { let query = 'vscode'; - let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor, cache, (r1, r2, query, ResourceAccessor) => -1)); + let res = [resourceA, resourceB].sort((r1, r2) => { + return compareItemsByScore(r1, r2, query, true, ResourceAccessor, cache, (r1, r2, query, ResourceAccessor) => { + if (r1 as any /* TS fail */ === resourceA) { + return -1; + } + + return 1; + }); + }); assert.equal(res[0], resourceA); assert.equal(res[1], resourceB); - res = [resourceB, resourceA].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor, cache, (r1, r2, query, ResourceAccessor) => -1)); + res = [resourceB, resourceA].sort((r1, r2) => { + return compareItemsByScore(r1, r2, query, true, ResourceAccessor, cache, (r1, r2, query, ResourceAccessor) => { + if (r1 as any /* TS fail */ === resourceB) { + return -1; + } + + return 1; + }); + }); assert.equal(res[0], resourceB); assert.equal(res[1], resourceA); }); diff --git a/src/vs/base/parts/storage/common/storage.ts b/src/vs/base/parts/storage/common/storage.ts new file mode 100644 index 00000000000..3f3892a8e19 --- /dev/null +++ b/src/vs/base/parts/storage/common/storage.ts @@ -0,0 +1,318 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { Emitter, Event } from 'vs/base/common/event'; +import { ThrottledDelayer } from 'vs/base/common/async'; +import { isUndefinedOrNull } from 'vs/base/common/types'; + +export enum StorageHint { + + // A hint to the storage that the storage + // does not exist on disk yet. This allows + // the storage library to improve startup + // time by not checking the storage for data. + STORAGE_DOES_NOT_EXIST +} + +export interface IStorageOptions { + hint?: StorageHint; +} + +export interface IUpdateRequest { + insert?: Map; + delete?: Set; +} + +export interface IStorageItemsChangeEvent { + items: Map; +} + +export interface IStorageDatabase { + + readonly onDidChangeItemsExternal: Event; + + getItems(): Promise>; + updateItems(request: IUpdateRequest): Promise; + + close(recovery?: () => Map): Promise; +} + +export interface IStorage extends IDisposable { + + readonly items: Map; + readonly size: number; + readonly onDidChangeStorage: Event; + + init(): Promise; + + get(key: string, fallbackValue: string): string; + get(key: string, fallbackValue?: string): string | undefined; + + getBoolean(key: string, fallbackValue: boolean): boolean; + getBoolean(key: string, fallbackValue?: boolean): boolean | undefined; + + getNumber(key: string, fallbackValue: number): number; + getNumber(key: string, fallbackValue?: number): number | undefined; + + set(key: string, value: string | boolean | number | undefined | null): Promise; + delete(key: string): Promise; + + close(): Promise; +} + +enum StorageState { + None, + Initialized, + Closed +} + +export class Storage extends Disposable implements IStorage { + + private static readonly DEFAULT_FLUSH_DELAY = 100; + + private readonly _onDidChangeStorage: Emitter = this._register(new Emitter()); + get onDidChangeStorage(): Event { return this._onDidChangeStorage.event; } + + private state = StorageState.None; + + private cache: Map = new Map(); + + private flushDelayer: ThrottledDelayer; + + private pendingDeletes: Set = new Set(); + private pendingInserts: Map = new Map(); + + constructor( + protected database: IStorageDatabase, + private options: IStorageOptions = Object.create(null) + ) { + super(); + + this.flushDelayer = this._register(new ThrottledDelayer(Storage.DEFAULT_FLUSH_DELAY)); + + this.registerListeners(); + } + + private registerListeners(): void { + this._register(this.database.onDidChangeItemsExternal(e => this.onDidChangeItemsExternal(e))); + } + + private onDidChangeItemsExternal(e: IStorageItemsChangeEvent): void { + // items that change external require us to update our + // caches with the values. we just accept the value and + // emit an event if there is a change. + e.items.forEach((value, key) => this.accept(key, value)); + } + + private accept(key: string, value: string): void { + if (this.state === StorageState.Closed) { + return; // Return early if we are already closed + } + + let changed = false; + + // Item got removed, check for deletion + if (isUndefinedOrNull(value)) { + changed = this.cache.delete(key); + } + + // Item got updated, check for change + else { + const currentValue = this.cache.get(key); + if (currentValue !== value) { + this.cache.set(key, value); + changed = true; + } + } + + // Signal to outside listeners + if (changed) { + this._onDidChangeStorage.fire(key); + } + } + + get items(): Map { + return this.cache; + } + + get size(): number { + return this.cache.size; + } + + async init(): Promise { + if (this.state !== StorageState.None) { + return Promise.resolve(); // either closed or already initialized + } + + this.state = StorageState.Initialized; + + if (this.options.hint === StorageHint.STORAGE_DOES_NOT_EXIST) { + // return early if we know the storage file does not exist. this is a performance + // optimization to not load all items of the underlying storage if we know that + // there can be no items because the storage does not exist. + return Promise.resolve(); + } + + this.cache = await this.database.getItems(); + } + + get(key: string, fallbackValue: string): string; + get(key: string, fallbackValue?: string): string | undefined; + get(key: string, fallbackValue?: string): string | undefined { + const value = this.cache.get(key); + + if (isUndefinedOrNull(value)) { + return fallbackValue; + } + + return value; + } + + getBoolean(key: string, fallbackValue: boolean): boolean; + getBoolean(key: string, fallbackValue?: boolean): boolean | undefined; + getBoolean(key: string, fallbackValue?: boolean): boolean | undefined { + const value = this.get(key); + + if (isUndefinedOrNull(value)) { + return fallbackValue; + } + + return value === 'true'; + } + + getNumber(key: string, fallbackValue: number): number; + getNumber(key: string, fallbackValue?: number): number | undefined; + getNumber(key: string, fallbackValue?: number): number | undefined { + const value = this.get(key); + + if (isUndefinedOrNull(value)) { + return fallbackValue; + } + + return parseInt(value, 10); + } + + set(key: string, value: string | boolean | number | null | undefined): Promise { + if (this.state === StorageState.Closed) { + return Promise.resolve(); // Return early if we are already closed + } + + // We remove the key for undefined/null values + if (isUndefinedOrNull(value)) { + return this.delete(key); + } + + // Otherwise, convert to String and store + const valueStr = String(value); + + // Return early if value already set + const currentValue = this.cache.get(key); + if (currentValue === valueStr) { + return Promise.resolve(); + } + + // Update in cache and pending + this.cache.set(key, valueStr); + this.pendingInserts.set(key, valueStr); + this.pendingDeletes.delete(key); + + // Event + this._onDidChangeStorage.fire(key); + + // Accumulate work by scheduling after timeout + return this.flushDelayer.trigger(() => this.flushPending()); + } + + delete(key: string): Promise { + if (this.state === StorageState.Closed) { + return Promise.resolve(); // Return early if we are already closed + } + + // Remove from cache and add to pending + const wasDeleted = this.cache.delete(key); + if (!wasDeleted) { + return Promise.resolve(); // Return early if value already deleted + } + + if (!this.pendingDeletes.has(key)) { + this.pendingDeletes.add(key); + } + + this.pendingInserts.delete(key); + + // Event + this._onDidChangeStorage.fire(key); + + // Accumulate work by scheduling after timeout + return this.flushDelayer.trigger(() => this.flushPending()); + } + + async close(): Promise { + if (this.state === StorageState.Closed) { + return Promise.resolve(); // return if already closed + } + + // Update state + this.state = StorageState.Closed; + + // Trigger new flush to ensure data is persisted and then close + // even if there is an error flushing. We must always ensure + // the DB is closed to avoid corruption. + // + // Recovery: we pass our cache over as recovery option in case + // the DB is not healthy. + try { + await this.flushDelayer.trigger(() => this.flushPending(), 0 /* as soon as possible */); + } catch (error) { + // Ignore + } + + await this.database.close(() => this.cache); + } + + private flushPending(): Promise { + if (this.pendingInserts.size === 0 && this.pendingDeletes.size === 0) { + return Promise.resolve(); // return early if nothing to do + } + + // Get pending data + const updateRequest: IUpdateRequest = { insert: this.pendingInserts, delete: this.pendingDeletes }; + + // Reset pending data for next run + this.pendingDeletes = new Set(); + this.pendingInserts = new Map(); + + // Update in storage + return this.database.updateItems(updateRequest); + } +} + +export class InMemoryStorageDatabase implements IStorageDatabase { + + readonly onDidChangeItemsExternal = Event.None; + + private items = new Map(); + + getItems(): Promise> { + return Promise.resolve(this.items); + } + + updateItems(request: IUpdateRequest): Promise { + if (request.insert) { + request.insert.forEach((value, key) => this.items.set(key, value)); + } + + if (request.delete) { + request.delete.forEach(key => this.items.delete(key)); + } + + return Promise.resolve(); + } + + close(): Promise { + return Promise.resolve(); + } +} \ No newline at end of file diff --git a/src/vs/base/node/storage.ts b/src/vs/base/parts/storage/node/storage.ts similarity index 61% rename from src/vs/base/node/storage.ts rename to src/vs/base/parts/storage/node/storage.ts index a92705b9557..6cebac12c9f 100644 --- a/src/vs/base/node/storage.ts +++ b/src/vs/base/parts/storage/node/storage.ts @@ -4,305 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import { Database, Statement } from 'vscode-sqlite3'; -import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; -import { Emitter, Event } from 'vs/base/common/event'; -import { ThrottledDelayer, timeout } from 'vs/base/common/async'; -import { isUndefinedOrNull } from 'vs/base/common/types'; +import { Event } from 'vs/base/common/event'; +import { timeout } from 'vs/base/common/async'; import { mapToString, setToString } from 'vs/base/common/map'; import { basename } from 'vs/base/common/path'; import { copy, renameIgnoreError, unlink } from 'vs/base/node/pfs'; import { fill } from 'vs/base/common/arrays'; - -export enum StorageHint { - - // A hint to the storage that the storage - // does not exist on disk yet. This allows - // the storage library to improve startup - // time by not checking the storage for data. - STORAGE_DOES_NOT_EXIST -} - -export interface IStorageOptions { - hint?: StorageHint; -} - -export interface IUpdateRequest { - insert?: Map; - delete?: Set; -} - -export interface IStorageItemsChangeEvent { - items: Map; -} - -export interface IStorageDatabase { - - readonly onDidChangeItemsExternal: Event; - - getItems(): Promise>; - updateItems(request: IUpdateRequest): Promise; - - close(recovery?: () => Map): Promise; - - checkIntegrity(full: boolean): Promise; -} - -export interface IStorage extends IDisposable { - - readonly items: Map; - readonly size: number; - readonly onDidChangeStorage: Event; - - init(): Promise; - - get(key: string, fallbackValue: string): string; - get(key: string, fallbackValue?: string): string | undefined; - - getBoolean(key: string, fallbackValue: boolean): boolean; - getBoolean(key: string, fallbackValue?: boolean): boolean | undefined; - - getNumber(key: string, fallbackValue: number): number; - getNumber(key: string, fallbackValue?: number): number | undefined; - - set(key: string, value: string | boolean | number | undefined | null): Promise; - delete(key: string): Promise; - - close(): Promise; - - checkIntegrity(full: boolean): Promise; -} - -enum StorageState { - None, - Initialized, - Closed -} - -export class Storage extends Disposable implements IStorage { - _serviceBrand: any; - - private static readonly DEFAULT_FLUSH_DELAY = 100; - - private readonly _onDidChangeStorage: Emitter = this._register(new Emitter()); - get onDidChangeStorage(): Event { return this._onDidChangeStorage.event; } - - private state = StorageState.None; - - private cache: Map = new Map(); - - private flushDelayer: ThrottledDelayer; - - private pendingDeletes: Set = new Set(); - private pendingInserts: Map = new Map(); - - constructor( - protected database: IStorageDatabase, - private options: IStorageOptions = Object.create(null) - ) { - super(); - - this.flushDelayer = this._register(new ThrottledDelayer(Storage.DEFAULT_FLUSH_DELAY)); - - this.registerListeners(); - } - - private registerListeners(): void { - this._register(this.database.onDidChangeItemsExternal(e => this.onDidChangeItemsExternal(e))); - } - - private onDidChangeItemsExternal(e: IStorageItemsChangeEvent): void { - // items that change external require us to update our - // caches with the values. we just accept the value and - // emit an event if there is a change. - e.items.forEach((value, key) => this.accept(key, value)); - } - - private accept(key: string, value: string): void { - if (this.state === StorageState.Closed) { - return; // Return early if we are already closed - } - - let changed = false; - - // Item got removed, check for deletion - if (isUndefinedOrNull(value)) { - changed = this.cache.delete(key); - } - - // Item got updated, check for change - else { - const currentValue = this.cache.get(key); - if (currentValue !== value) { - this.cache.set(key, value); - changed = true; - } - } - - // Signal to outside listeners - if (changed) { - this._onDidChangeStorage.fire(key); - } - } - - get items(): Map { - return this.cache; - } - - get size(): number { - return this.cache.size; - } - - async init(): Promise { - if (this.state !== StorageState.None) { - return Promise.resolve(); // either closed or already initialized - } - - this.state = StorageState.Initialized; - - if (this.options.hint === StorageHint.STORAGE_DOES_NOT_EXIST) { - // return early if we know the storage file does not exist. this is a performance - // optimization to not load all items of the underlying storage if we know that - // there can be no items because the storage does not exist. - return Promise.resolve(); - } - - this.cache = await this.database.getItems(); - } - - get(key: string, fallbackValue: string): string; - get(key: string, fallbackValue?: string): string | undefined; - get(key: string, fallbackValue?: string): string | undefined { - const value = this.cache.get(key); - - if (isUndefinedOrNull(value)) { - return fallbackValue; - } - - return value; - } - - getBoolean(key: string, fallbackValue: boolean): boolean; - getBoolean(key: string, fallbackValue?: boolean): boolean | undefined; - getBoolean(key: string, fallbackValue?: boolean): boolean | undefined { - const value = this.get(key); - - if (isUndefinedOrNull(value)) { - return fallbackValue; - } - - return value === 'true'; - } - - getNumber(key: string, fallbackValue: number): number; - getNumber(key: string, fallbackValue?: number): number | undefined; - getNumber(key: string, fallbackValue?: number): number | undefined { - const value = this.get(key); - - if (isUndefinedOrNull(value)) { - return fallbackValue; - } - - return parseInt(value, 10); - } - - set(key: string, value: string | boolean | number | null | undefined): Promise { - if (this.state === StorageState.Closed) { - return Promise.resolve(); // Return early if we are already closed - } - - // We remove the key for undefined/null values - if (isUndefinedOrNull(value)) { - return this.delete(key); - } - - // Otherwise, convert to String and store - const valueStr = String(value); - - // Return early if value already set - const currentValue = this.cache.get(key); - if (currentValue === valueStr) { - return Promise.resolve(); - } - - // Update in cache and pending - this.cache.set(key, valueStr); - this.pendingInserts.set(key, valueStr); - this.pendingDeletes.delete(key); - - // Event - this._onDidChangeStorage.fire(key); - - // Accumulate work by scheduling after timeout - return this.flushDelayer.trigger(() => this.flushPending()); - } - - delete(key: string): Promise { - if (this.state === StorageState.Closed) { - return Promise.resolve(); // Return early if we are already closed - } - - // Remove from cache and add to pending - const wasDeleted = this.cache.delete(key); - if (!wasDeleted) { - return Promise.resolve(); // Return early if value already deleted - } - - if (!this.pendingDeletes.has(key)) { - this.pendingDeletes.add(key); - } - - this.pendingInserts.delete(key); - - // Event - this._onDidChangeStorage.fire(key); - - // Accumulate work by scheduling after timeout - return this.flushDelayer.trigger(() => this.flushPending()); - } - - async close(): Promise { - if (this.state === StorageState.Closed) { - return Promise.resolve(); // return if already closed - } - - // Update state - this.state = StorageState.Closed; - - // Trigger new flush to ensure data is persisted and then close - // even if there is an error flushing. We must always ensure - // the DB is closed to avoid corruption. - // - // Recovery: we pass our cache over as recovery option in case - // the DB is not healthy. - try { - await this.flushDelayer.trigger(() => this.flushPending(), 0 /* as soon as possible */); - } catch (error) { - // Ignore - } - - await this.database.close(() => this.cache); - } - - private flushPending(): Promise { - if (this.pendingInserts.size === 0 && this.pendingDeletes.size === 0) { - return Promise.resolve(); // return early if nothing to do - } - - // Get pending data - const updateRequest: IUpdateRequest = { insert: this.pendingInserts, delete: this.pendingDeletes }; - - // Reset pending data for next run - this.pendingDeletes = new Set(); - this.pendingInserts = new Map(); - - // Update in storage - return this.database.updateItems(updateRequest); - } - - checkIntegrity(full: boolean): Promise { - return this.database.checkIntegrity(full); - } -} +import { IStorageDatabase, IStorageItemsChangeEvent, IUpdateRequest } from 'vs/base/parts/storage/common/storage'; interface IDatabaseConnection { db: Database; @@ -369,18 +77,6 @@ export class SQLiteStorageDatabase implements IStorageDatabase { } private doUpdateItems(connection: IDatabaseConnection, request: IUpdateRequest): Promise { - let updateCount = 0; - if (request.insert) { - updateCount += request.insert.size; - } - if (request.delete) { - updateCount += request.delete.size; - } - - if (updateCount === 0) { - return Promise.resolve(); - } - if (this.logger.isTracing) { this.logger.trace(`[storage ${this.name}] updateItems(): insert(${request.insert ? mapToString(request.insert) : '0'}), delete(${request.delete ? setToString(request.delete) : '0'})`); } @@ -541,7 +237,7 @@ export class SQLiteStorageDatabase implements IStorageDatabase { const connection = await this.whenConnected; const row = await this.get(connection, full ? 'PRAGMA integrity_check' : 'PRAGMA quick_check'); - const integrity = full ? row['integrity_check'] : row['quick_check']; + const integrity = full ? (row as any)['integrity_check'] : (row as any)['quick_check']; if (connection.isErroneous) { return `${integrity} (last error: ${connection.lastError})`; @@ -753,34 +449,3 @@ class SQLiteStorageDatabaseLogger { } } } - -export class InMemoryStorageDatabase implements IStorageDatabase { - - readonly onDidChangeItemsExternal = Event.None; - - private items = new Map(); - - getItems(): Promise> { - return Promise.resolve(this.items); - } - - updateItems(request: IUpdateRequest): Promise { - if (request.insert) { - request.insert.forEach((value, key) => this.items.set(key, value)); - } - - if (request.delete) { - request.delete.forEach(key => this.items.delete(key)); - } - - return Promise.resolve(); - } - - close(): Promise { - return Promise.resolve(); - } - - checkIntegrity(full: boolean): Promise { - return Promise.resolve('ok'); - } -} \ No newline at end of file diff --git a/src/vs/base/test/node/storage/storage.test.ts b/src/vs/base/parts/storage/test/node/storage.test.ts similarity index 99% rename from src/vs/base/test/node/storage/storage.test.ts rename to src/vs/base/parts/storage/test/node/storage.test.ts index 784a797b895..4c915ef2ae7 100644 --- a/src/vs/base/test/node/storage/storage.test.ts +++ b/src/vs/base/parts/storage/test/node/storage.test.ts @@ -3,7 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Storage, SQLiteStorageDatabase, IStorageDatabase, ISQLiteStorageDatabaseOptions, IStorageItemsChangeEvent } from 'vs/base/node/storage'; +import { SQLiteStorageDatabase, ISQLiteStorageDatabaseOptions } from 'vs/base/parts/storage/node/storage'; +import { Storage, IStorageDatabase, IStorageItemsChangeEvent } from 'vs/base/parts/storage/common/storage'; import { generateUuid } from 'vs/base/common/uuid'; import { join } from 'vs/base/common/path'; import { tmpdir } from 'os'; diff --git a/src/vs/base/parts/tree/browser/CollapseAll.svg b/src/vs/base/parts/tree/browser/CollapseAll.svg deleted file mode 100644 index 7d11a30f6e0..00000000000 --- a/src/vs/base/parts/tree/browser/CollapseAll.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/parts/tree/browser/CollapseAll_inverse.svg b/src/vs/base/parts/tree/browser/CollapseAll_inverse.svg deleted file mode 100644 index 46a65fff71a..00000000000 --- a/src/vs/base/parts/tree/browser/CollapseAll_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/parts/tree/browser/collapse-all-dark.svg b/src/vs/base/parts/tree/browser/collapse-all-dark.svg new file mode 100644 index 00000000000..4862c55dbeb --- /dev/null +++ b/src/vs/base/parts/tree/browser/collapse-all-dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/base/parts/tree/browser/collapse-all-hc.svg b/src/vs/base/parts/tree/browser/collapse-all-hc.svg new file mode 100644 index 00000000000..05f920b29b6 --- /dev/null +++ b/src/vs/base/parts/tree/browser/collapse-all-hc.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/base/parts/tree/browser/collapse-all-light.svg b/src/vs/base/parts/tree/browser/collapse-all-light.svg new file mode 100644 index 00000000000..6359b42e623 --- /dev/null +++ b/src/vs/base/parts/tree/browser/collapse-all-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/base/parts/tree/browser/collapsed-dark.svg b/src/vs/base/parts/tree/browser/collapsed-dark.svg deleted file mode 100755 index cf5c3641aa7..00000000000 --- a/src/vs/base/parts/tree/browser/collapsed-dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/parts/tree/browser/collapsed-hc.svg b/src/vs/base/parts/tree/browser/collapsed-hc.svg deleted file mode 100644 index 145c763338f..00000000000 --- a/src/vs/base/parts/tree/browser/collapsed-hc.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/parts/tree/browser/collapsed.svg b/src/vs/base/parts/tree/browser/collapsed.svg deleted file mode 100755 index 3a63808c358..00000000000 --- a/src/vs/base/parts/tree/browser/collapsed.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/parts/tree/browser/expanded-dark.svg b/src/vs/base/parts/tree/browser/expanded-dark.svg deleted file mode 100755 index 73d41e63990..00000000000 --- a/src/vs/base/parts/tree/browser/expanded-dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/parts/tree/browser/expanded-hc.svg b/src/vs/base/parts/tree/browser/expanded-hc.svg deleted file mode 100644 index d38d4abc89e..00000000000 --- a/src/vs/base/parts/tree/browser/expanded-hc.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/parts/tree/browser/expanded.svg b/src/vs/base/parts/tree/browser/expanded.svg deleted file mode 100755 index 75f73adbb02..00000000000 --- a/src/vs/base/parts/tree/browser/expanded.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/base/parts/tree/browser/tree-collapsed-dark.svg b/src/vs/base/parts/tree/browser/tree-collapsed-dark.svg new file mode 100644 index 00000000000..c2c2298dd5c --- /dev/null +++ b/src/vs/base/parts/tree/browser/tree-collapsed-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/parts/tree/browser/tree-collapsed-hc.svg b/src/vs/base/parts/tree/browser/tree-collapsed-hc.svg new file mode 100644 index 00000000000..3732cbc04b8 --- /dev/null +++ b/src/vs/base/parts/tree/browser/tree-collapsed-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/parts/tree/browser/tree-collapsed-light.svg b/src/vs/base/parts/tree/browser/tree-collapsed-light.svg new file mode 100644 index 00000000000..1952ad63f84 --- /dev/null +++ b/src/vs/base/parts/tree/browser/tree-collapsed-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/parts/tree/browser/tree-expanded-dark.svg b/src/vs/base/parts/tree/browser/tree-expanded-dark.svg new file mode 100644 index 00000000000..d844b383ed3 --- /dev/null +++ b/src/vs/base/parts/tree/browser/tree-expanded-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/parts/tree/browser/tree-expanded-hc.svg b/src/vs/base/parts/tree/browser/tree-expanded-hc.svg new file mode 100644 index 00000000000..9faa2b2a6ed --- /dev/null +++ b/src/vs/base/parts/tree/browser/tree-expanded-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/parts/tree/browser/tree-expanded-light.svg b/src/vs/base/parts/tree/browser/tree-expanded-light.svg new file mode 100644 index 00000000000..f09125caf91 --- /dev/null +++ b/src/vs/base/parts/tree/browser/tree-expanded-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/parts/tree/browser/tree.css b/src/vs/base/parts/tree/browser/tree.css index 6e835d22e0c..2a3cb47ddbb 100644 --- a/src/vs/base/parts/tree/browser/tree.css +++ b/src/vs/base/parts/tree/browser/tree.css @@ -66,7 +66,7 @@ content: ' '; position: absolute; display: block; - background: url('collapsed.svg') 50% 50% no-repeat; + background: url('tree-collapsed-light.svg') 50% 50% no-repeat; width: 16px; height: 100%; top: 0; @@ -74,7 +74,7 @@ } .monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.expanded > .content:before { - background-image: url('expanded.svg'); + background-image: url('tree-expanded-light.svg'); } .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children.loading > .content:before { @@ -88,11 +88,11 @@ } .vs-dark .monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.has-children > .content:before { - background-image: url('collapsed-dark.svg'); + background-image: url('tree-collapsed-dark.svg'); } .vs-dark .monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.expanded > .content:before { - background-image: url('expanded-dark.svg'); + background-image: url('tree-expanded-dark.svg'); } .vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children.loading > .content:before { @@ -100,11 +100,11 @@ } .hc-black .monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.has-children > .content:before { - background-image: url('collapsed-hc.svg'); + background-image: url('tree-collapsed-hc.svg'); } .hc-black .monaco-tree .monaco-tree-rows.show-twisties > .monaco-tree-row.expanded > .content:before { - background-image: url('expanded-hc.svg'); + background-image: url('tree-expanded-hc.svg'); } .hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children.loading > .content:before { @@ -112,10 +112,13 @@ } .monaco-tree-action.collapse-all { - background: url('CollapseAll.svg') center center no-repeat; + background: url('collapse-all-light.svg') center center no-repeat; } -.hc-black .monaco-tree-action.collapse-all, .vs-dark .monaco-tree-action.collapse-all { - background: url('CollapseAll_inverse.svg') center center no-repeat; + background: url('collapse-all-dark.svg') center center no-repeat; +} + +.hc-black .monaco-tree-action.collapse-all { + background: url('collapse-all-hc.svg') center center no-repeat; } diff --git a/src/vs/base/test/browser/comparers.test.ts b/src/vs/base/test/browser/comparers.test.ts index df74e2bbfa2..369f160803b 100644 --- a/src/vs/base/test/browser/comparers.test.ts +++ b/src/vs/base/test/browser/comparers.test.ts @@ -3,23 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { compareFileNames, compareFileExtensions, setFileNameComparer } from 'vs/base/common/comparers'; +import { compareFileNames, compareFileExtensions } from 'vs/base/common/comparers'; import * as assert from 'assert'; -import { IdleValue } from 'vs/base/common/async'; suite('Comparers', () => { test('compareFileNames', () => { - // Setup Intl - setFileNameComparer(new IdleValue(() => { - const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }); - return { - collator: collator, - collatorIsNumeric: collator.resolvedOptions().numeric - }; - })); - assert(compareFileNames(null, null) === 0, 'null should be equal'); assert(compareFileNames(null, 'abc') < 0, 'null should be come before real values'); assert(compareFileNames('', '') === 0, 'empty should be equal'); @@ -35,15 +25,6 @@ suite('Comparers', () => { test('compareFileExtensions', () => { - // Setup Intl - setFileNameComparer(new IdleValue(() => { - const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }); - return { - collator: collator, - collatorIsNumeric: collator.resolvedOptions().numeric - }; - })); - assert(compareFileExtensions(null, null) === 0, 'null should be equal'); assert(compareFileExtensions(null, '.abc') < 0, 'null should come before real files'); assert(compareFileExtensions(null, 'abc') < 0, 'null should come before real files without extension'); @@ -66,4 +47,4 @@ suite('Comparers', () => { assert(compareFileExtensions('file2.ext2', 'file1.ext10') < 0, 'extensions with numbers should be in numerical order, not alphabetical order'); assert(compareFileExtensions('file.ext01', 'file.ext1') < 0, 'extensions with equal numbers should be in alphabetical order'); }); -}); \ No newline at end of file +}); diff --git a/src/vs/base/test/browser/ui/grid/gridview.test.ts b/src/vs/base/test/browser/ui/grid/gridview.test.ts index 3d000d85a67..76f4e4ac68c 100644 --- a/src/vs/base/test/browser/ui/grid/gridview.test.ts +++ b/src/vs/base/test/browser/ui/grid/gridview.test.ts @@ -59,8 +59,8 @@ suite('Gridview', function () { ]; gridview.addView(views[0] as IView, 200, [0]); - gridview.addView(views[1][0] as IView, 200, [1]); - gridview.addView(views[1][1] as IView, 200, [1, 1]); + gridview.addView((views[1] as TestView[])[0] as IView, 200, [1]); + gridview.addView((views[1] as TestView[])[1] as IView, 200, [1, 1]); assert.deepEqual(nodesToArrays(gridview.getViews()), views); diff --git a/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts b/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts index 3c934126df9..0e93e4bb377 100644 --- a/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts +++ b/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts @@ -326,4 +326,57 @@ suite('AsyncDataTree', function () { assert(!hasClass(twistie, 'collapsed')); assert(tree.getNode(_('a')).collapsed); }); + + test('support default collapse state per element', async () => { + const container = document.createElement('div'); + container.style.width = '200px'; + container.style.height = '200px'; + + const delegate = new class implements IListVirtualDelegate { + getHeight() { return 20; } + getTemplateId(element: Element): string { return 'default'; } + }; + + const renderer = new class implements ITreeRenderer { + readonly templateId = 'default'; + renderTemplate(container: HTMLElement): HTMLElement { + return container; + } + renderElement(element: ITreeNode, index: number, templateData: HTMLElement): void { + templateData.textContent = element.element.id; + } + disposeTemplate(templateData: HTMLElement): void { + // noop + } + }; + + const getChildrenCalls: string[] = []; + const dataSource = new class implements IAsyncDataSource { + hasChildren(element: Element): boolean { + return !!element.children && element.children.length > 0; + } + getChildren(element: Element): Promise { + getChildrenCalls.push(element.id); + return Promise.resolve(element.children || []); + } + }; + + const root: Element = { + id: 'root', + children: [{ + id: 'a', children: [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }] + }] + }; + + const _: (id: string) => Element = find.bind(null, root.children); + + const tree = new AsyncDataTree(container, delegate, [renderer], dataSource, { + collapseByDefault: el => el.id !== 'a' + }); + tree.layout(200); + + await tree.setInput(root); + assert(!tree.getNode(_('a')).collapsed); + assert.deepStrictEqual(getChildrenCalls, ['root', 'a']); + }); }); \ No newline at end of file diff --git a/src/vs/base/test/common/decorators.test.ts b/src/vs/base/test/common/decorators.test.ts index aaabb2b5094..05a58c318c0 100644 --- a/src/vs/base/test/common/decorators.test.ts +++ b/src/vs/base/test/common/decorators.test.ts @@ -119,7 +119,7 @@ suite('Decorators', () => { assert.equal(foo.answer, 42); try { - foo['$memoize$answer'] = 1337; + (foo as any)['$memoize$answer'] = 1337; assert(false); } catch (e) { assert.equal(foo.answer, 42); diff --git a/src/vs/base/test/common/filters.test.ts b/src/vs/base/test/common/filters.test.ts index c4d582eeda0..b93e58cfc0a 100644 --- a/src/vs/base/test/common/filters.test.ts +++ b/src/vs/base/test/common/filters.test.ts @@ -13,8 +13,8 @@ function filterOk(filter: IFilter, word: string, wordToMatchAgainst: string, hig } } -function filterNotOk(filter: IFilter, word: string, suggestion: string) { - assert(!filter(word, suggestion)); +function filterNotOk(filter: IFilter, word: string, wordToMatchAgainst: string) { + assert(!filter(word, wordToMatchAgainst), `${word} matched ${wordToMatchAgainst}`); } suite('Filters', () => { @@ -185,23 +185,23 @@ suite('Filters', () => { assert(matchesWords('Debug Console', 'Open: Debug Console')); filterOk(matchesWords, 'gp', 'Git: Pull', [{ start: 0, end: 1 }, { start: 5, end: 6 }]); - filterOk(matchesWords, 'g p', 'Git: Pull', [{ start: 0, end: 1 }, { start: 4, end: 6 }]); + filterOk(matchesWords, 'g p', 'Git: Pull', [{ start: 0, end: 1 }, { start: 3, end: 4 }, { start: 5, end: 6 }]); filterOk(matchesWords, 'gipu', 'Git: Pull', [{ start: 0, end: 2 }, { start: 5, end: 7 }]); filterOk(matchesWords, 'gp', 'Category: Git: Pull', [{ start: 10, end: 11 }, { start: 15, end: 16 }]); - filterOk(matchesWords, 'g p', 'Category: Git: Pull', [{ start: 10, end: 11 }, { start: 14, end: 16 }]); + filterOk(matchesWords, 'g p', 'Category: Git: Pull', [{ start: 10, end: 11 }, { start: 13, end: 14 }, { start: 15, end: 16 }]); filterOk(matchesWords, 'gipu', 'Category: Git: Pull', [{ start: 10, end: 12 }, { start: 15, end: 17 }]); filterNotOk(matchesWords, 'it', 'Git: Pull'); filterNotOk(matchesWords, 'll', 'Git: Pull'); filterOk(matchesWords, 'git: プル', 'git: プル', [{ start: 0, end: 7 }]); - filterOk(matchesWords, 'git プル', 'git: プル', [{ start: 0, end: 3 }, { start: 4, end: 7 }]); + filterOk(matchesWords, 'git プル', 'git: プル', [{ start: 0, end: 4 }, { start: 5, end: 7 }]); filterOk(matchesWords, 'öäk', 'Öhm: Älles Klar', [{ start: 0, end: 1 }, { start: 5, end: 6 }, { start: 11, end: 12 }]); - assert.ok(matchesWords('gipu', 'Category: Git: Pull', true) === null); - assert.deepEqual(matchesWords('pu', 'Category: Git: Pull', true), [{ start: 15, end: 17 }]); + // assert.ok(matchesWords('gipu', 'Category: Git: Pull', true) === null); + // assert.deepEqual(matchesWords('pu', 'Category: Git: Pull', true), [{ start: 15, end: 17 }]); filterOk(matchesWords, 'bar', 'foo-bar'); filterOk(matchesWords, 'bar test', 'foo-bar test'); @@ -212,7 +212,12 @@ suite('Filters', () => { filterNotOk(matchesWords, 'bar est', 'foo-bar test'); filterNotOk(matchesWords, 'fo ar', 'foo-bar test'); filterNotOk(matchesWords, 'for', 'foo-bar test'); - filterNotOk(matchesWords, 'foo bar', 'foo-bar'); + + filterOk(matchesWords, 'foo bar', 'foo-bar'); + filterOk(matchesWords, 'foo bar', '123 foo-bar 456'); + filterOk(matchesWords, 'foo+bar', 'foo-bar'); + filterOk(matchesWords, 'foo-bar', 'foo bar'); + filterOk(matchesWords, 'foo:bar', 'foo:bar'); }); function assertMatches(pattern: string, word: string, decoratedWord: string | undefined, filter: FuzzyScorer, opts: { patternPos?: number, wordPos?: number, firstMatchCanBeWeak?: boolean } = {}) { diff --git a/src/vs/base/test/common/resources.test.ts b/src/vs/base/test/common/resources.test.ts index b9d1a99d539..cb535362222 100644 --- a/src/vs/base/test/common/resources.test.ts +++ b/src/vs/base/test/common/resources.test.ts @@ -237,8 +237,8 @@ suite('Resources', () => { } } - function assertRelativePath(u1: URI, u2: URI, expectedPath: string | undefined, ignoreJoin?: boolean) { - assert.equal(relativePath(u1, u2), expectedPath, `from ${u1.toString()} to ${u2.toString()}`); + function assertRelativePath(u1: URI, u2: URI, expectedPath: string | undefined, ignoreJoin?: boolean, ignoreCase?: boolean) { + assert.equal(relativePath(u1, u2, ignoreCase), expectedPath, `from ${u1.toString()} to ${u2.toString()}`); if (expectedPath !== undefined && !ignoreJoin) { assertEqualURI(removeTrailingPathSeparator(joinPath(u1, expectedPath)), removeTrailingPathSeparator(u2), 'joinPath on relativePath should be equal'); } @@ -263,6 +263,11 @@ suite('Resources', () => { assertRelativePath(URI.parse('foo://a2/b'), URI.parse('foo://a/b'), undefined); assertRelativePath(URI.parse('goo://a/b'), URI.parse('foo://a/b'), undefined); + assertRelativePath(URI.parse('foo://a/foo'), URI.parse('foo://A/FOO/bar/goo'), 'bar/goo', false, true); + assertRelativePath(URI.parse('foo://a/foo'), URI.parse('foo://A/FOO/BAR/GOO'), 'BAR/GOO', false, true); + assertRelativePath(URI.parse('foo://a/foo/xoo'), URI.parse('foo://A/FOO/BAR/GOO'), '../BAR/GOO', false, true); + assertRelativePath(URI.parse('foo:///c:/a/foo'), URI.parse('foo:///C:/a/foo/xoo/'), 'xoo', false, true); + if (isWindows) { assertRelativePath(URI.file('c:\\foo\\bar'), URI.file('c:\\foo\\bar'), ''); assertRelativePath(URI.file('c:\\foo\\bar\\huu'), URI.file('c:\\foo\\bar'), '..'); diff --git a/src/vs/base/test/common/uri.test.ts b/src/vs/base/test/common/uri.test.ts index a4495718fcf..0a72ec39876 100644 --- a/src/vs/base/test/common/uri.test.ts +++ b/src/vs/base/test/common/uri.test.ts @@ -63,7 +63,7 @@ suite('URI', () => { assert.equal(URI.from({ scheme: 'http', authority: '', path: 'my/path' }).toString(), 'http:/my/path'); assert.equal(URI.from({ scheme: 'http', authority: '', path: '/my/path' }).toString(), 'http:/my/path'); //http://a-test-site.com/#test=true - assert.equal(URI.from({ scheme: 'http', authority: 'a-test-site.com', path: '/', query: 'test=true' }).toString(), 'http://a-test-site.com/?test=true'); + assert.equal(URI.from({ scheme: 'http', authority: 'a-test-site.com', path: '/', query: 'test=true' }).toString(), 'http://a-test-site.com/?test%3Dtrue'); assert.equal(URI.from({ scheme: 'http', authority: 'a-test-site.com', path: '/', query: '', fragment: 'test=true' }).toString(), 'http://a-test-site.com/#test%3Dtrue'); }); @@ -102,11 +102,11 @@ suite('URI', () => { test('with, changes', () => { assert.equal(URI.parse('before:some/file/path').with({ scheme: 'after' }).toString(), 'after:some/file/path'); - assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'http', path: '/api/files/test.me', query: 't=1234' }).toString(), 'http:/api/files/test.me?t=1234'); - assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'http', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'http:/api/files/test.me?t=1234'); - assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'https', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'https:/api/files/test.me?t=1234'); - assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'HTTP', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'HTTP:/api/files/test.me?t=1234'); - assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'HTTPS', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'HTTPS:/api/files/test.me?t=1234'); + assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'http', path: '/api/files/test.me', query: 't=1234' }).toString(), 'http:/api/files/test.me?t%3D1234'); + assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'http', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'http:/api/files/test.me?t%3D1234'); + assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'https', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'https:/api/files/test.me?t%3D1234'); + assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'HTTP', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'HTTP:/api/files/test.me?t%3D1234'); + assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'HTTPS', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'HTTPS:/api/files/test.me?t%3D1234'); assert.equal(URI.from({ scheme: 's' }).with({ scheme: 'boo', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'boo:/api/files/test.me?t%3D1234'); }); @@ -262,11 +262,11 @@ suite('URI', () => { value = URI.file('c:\\test with %25\\path'); assert.equal(value.path, '/c:/test with %25/path'); - assert.equal(value.toString(), 'file:///c%3A/test%20with%20%25/path'); + assert.equal(value.toString(), 'file:///c%3A/test%20with%20%2525/path'); value = URI.file('c:\\test with %25\\c#code'); assert.equal(value.path, '/c:/test with %25/c#code'); - assert.equal(value.toString(), 'file:///c%3A/test%20with%20%25/c%23code'); + assert.equal(value.toString(), 'file:///c%3A/test%20with%20%2525/c%23code'); value = URI.file('\\\\shares'); assert.equal(value.scheme, 'file'); @@ -376,7 +376,7 @@ suite('URI', () => { let uri = URI.parse('https://go.microsoft.com/fwlink/?LinkId=518008'); assert.equal(uri.query, 'LinkId=518008'); assert.equal(uri.toString(true), 'https://go.microsoft.com/fwlink/?LinkId=518008'); - assert.equal(uri.toString(), 'https://go.microsoft.com/fwlink/?LinkId=518008'); + assert.equal(uri.toString(), 'https://go.microsoft.com/fwlink/?LinkId%3D518008'); let uri2 = URI.parse(uri.toString()); assert.equal(uri2.query, 'LinkId=518008'); @@ -385,7 +385,7 @@ suite('URI', () => { uri = URI.parse('https://go.microsoft.com/fwlink/?LinkId=518008&foö&ké¥=üü'); assert.equal(uri.query, 'LinkId=518008&foö&ké¥=üü'); assert.equal(uri.toString(true), 'https://go.microsoft.com/fwlink/?LinkId=518008&foö&ké¥=üü'); - assert.equal(uri.toString(), 'https://go.microsoft.com/fwlink/?LinkId=518008&fo%C3%B6&k%C3%A9%C2%A5=%C3%BC%C3%BC'); + assert.equal(uri.toString(), 'https://go.microsoft.com/fwlink/?LinkId%3D518008%26fo%C3%B6%26k%C3%A9%C2%A5%3D%C3%BC%C3%BC'); uri2 = URI.parse(uri.toString()); assert.equal(uri2.query, 'LinkId=518008&foö&ké¥=üü'); @@ -426,57 +426,19 @@ suite('URI', () => { assert.equal(uri.toString(true), input); }); - test('Support URL specific encodings (query component) #25852', function () { - let input = 'http://example.com/over/there?name=ferret'; - assert.equal(input, URI.parse(input).toString()); + test('Unable to open \'%A0.txt\': URI malformed #76506', function () { - input = 'http://example.com/over/there?name=ferret&foo=bar'; - assert.equal(input, URI.parse(input).toString()); + let uri = URI.file('/foo/%A0.txt'); + let uri2 = URI.parse(uri.toString()); + assert.equal(uri.scheme, uri2.scheme); + assert.equal(uri.path, uri2.path); - input = 'attp://example.com/over/there?name=ferret'; - assert.equal('attp://example.com/over/there?name%3Dferret', URI.parse(input).toString()); + uri = URI.file('/foo/%2e.txt'); + uri2 = URI.parse(uri.toString()); + assert.equal(uri.scheme, uri2.scheme); + assert.equal(uri.path, uri2.path); }); - test('Uri#parse can break path-component #45515', function () { - let uri: URI; - uri = URI.from({ scheme: 's', authority: 'a', path: '/o%2f' }); - assert.equal(uri.toString(), 's://a/o%2f'); - uri = URI.from({ scheme: 's', authority: 'a', path: '/o%2fü' }); - assert.equal(uri.toString(), 's://a/o%2f%C3%BC'); - uri = URI.from({ scheme: 's', authority: 'a', path: '/o%2f%' }); - assert.equal(uri.toString(), 's://a/o%2f%25'); - - uri = URI.file('/test with %25/c#code'); - assert.equal(uri.path, '/test with %25/c#code'); - assert.equal(uri.toString(), 'file:///test%20with%20%25/c%23code'); - - uri = URI.from({ - scheme: 'http', - authority: 'a', - path: '/o/products%2FzVNZkudXJyq8bPGTXUxx%2FBetterave-Sesame.jpg' - }); - assert.equal(uri.path, '/o/products%2FzVNZkudXJyq8bPGTXUxx%2FBetterave-Sesame.jpg'); - assert.equal(uri.toString(), 'http://a/o/products%2FzVNZkudXJyq8bPGTXUxx%2FBetterave-Sesame.jpg'); - - assert.equal(URI.parse(uri.toString()).path, '/o/products%2FzVNZkudXJyq8bPGTXUxx%2FBetterave-Sesame.jpg'); - assert.equal(uri.toString(), URI.parse(uri.toString()).toString()); // identity - - uri = URI.parse('s://a/p%2ft%c3%bc'); - assert.equal(uri.path, '/p%2ftü'); - - uri = URI.parse('s://a/%c3%bcp%2f-REST'); - assert.equal(uri.path, '/üp%2f-REST'); - - uri = URI.parse('s://a/%c3%bcp%2fd%c3%b6wn'); - assert.equal(uri.path, '/üp%2fdöwn'); - - //https://github.com/microsoft/vscode/issues/25852 - uri = URI.parse('http://www.test.com/path/service?authId=CN%3DQ10'); - assert.equal(uri.query, 'authId=CN%3DQ10'); - assert.equal(uri.toString(), 'http://www.test.com/path/service?authId=CN%3DQ10'); - }); - - test('URI - (de)serialize', function () { const values = [ diff --git a/src/vs/base/test/common/buffer.test.ts b/src/vs/base/test/node/buffer.test.ts similarity index 90% rename from src/vs/base/test/common/buffer.test.ts rename to src/vs/base/test/node/buffer.test.ts index c5a3cd676ee..65f84a66ddf 100644 --- a/src/vs/base/test/common/buffer.test.ts +++ b/src/vs/base/test/node/buffer.test.ts @@ -364,4 +364,42 @@ suite('Buffer', () => { assert.equal(ended, false); assert.equal(errors.length, 0); }); + + test('Performance issue with VSBuffer#slice #76076', function () { + // Buffer#slice creates a view + { + const buff = Buffer.from([10, 20, 30, 40]); + const b2 = buff.slice(1, 3); + assert.equal(buff[1], 20); + assert.equal(b2[0], 20); + + buff[1] = 17; // modify buff AND b2 + assert.equal(buff[1], 17); + assert.equal(b2[0], 17); + } + + // TypedArray#slice creates a copy + { + const unit = new Uint8Array([10, 20, 30, 40]); + const u2 = unit.slice(1, 3); + assert.equal(unit[1], 20); + assert.equal(u2[0], 20); + + unit[1] = 17; // modify unit, NOT b2 + assert.equal(unit[1], 17); + assert.equal(u2[0], 20); + } + + // TypedArray#subarray creates a view + { + const unit = new Uint8Array([10, 20, 30, 40]); + const u2 = unit.subarray(1, 3); + assert.equal(unit[1], 20); + assert.equal(u2[0], 20); + + unit[1] = 17; // modify unit AND b2 + assert.equal(unit[1], 17); + assert.equal(u2[0], 17); + } + }); }); diff --git a/src/vs/base/test/node/pfs/pfs.test.ts b/src/vs/base/test/node/pfs/pfs.test.ts index 4f09ad2b56d..060913bbe72 100644 --- a/src/vs/base/test/node/pfs/pfs.test.ts +++ b/src/vs/base/test/node/pfs/pfs.test.ts @@ -16,6 +16,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { isWindows, isLinux } from 'vs/base/common/platform'; import { canNormalize } from 'vs/base/common/normalization'; import { VSBuffer } from 'vs/base/common/buffer'; +import { join } from 'path'; const chunkSize = 64 * 1024; const readError = 'Error while reading'; @@ -386,6 +387,31 @@ suite('PFS', () => { } }); + test('readdirWithFileTypes', async () => { + if (canNormalize && typeof process.versions['electron'] !== 'undefined' /* needs electron */) { + const id = uuid.generateUuid(); + const parentDir = path.join(os.tmpdir(), 'vsctests', id); + const testDir = join(parentDir, 'pfs', id); + + const newDir = path.join(testDir, 'öäü'); + await pfs.mkdirp(newDir, 493); + + await pfs.writeFile(join(testDir, 'somefile.txt'), 'contents'); + + assert.ok(fs.existsSync(newDir)); + + const children = await pfs.readdirWithFileTypes(testDir); + + assert.equal(children.some(n => n.name === 'öäü'), true); // Mac always converts to NFD, so + assert.equal(children.some(n => n.isDirectory()), true); + + assert.equal(children.some(n => n.name === 'somefile.txt'), true); + assert.equal(children.some(n => n.isFile()), true); + + await pfs.rimraf(parentDir); + } + }); + test('writeFile (string)', async () => { const smallData = 'Hello World'; const bigData = (new Array(100 * 1024)).join('Large String\n'); diff --git a/src/vs/base/test/node/stream/fixtures/file.css b/src/vs/base/test/node/stream/fixtures/file.css deleted file mode 100644 index f7b51e752bb..00000000000 --- a/src/vs/base/test/node/stream/fixtures/file.css +++ /dev/null @@ -1,40 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -/*---------------------------------------------------------- -The base color for this template is #5c87b2. If you'd like -to use a different color start by replacing all instances of -#5c87b2 with your new color. -----------------------------------------------------------*/ -body -{ - background-color: #5c87b2; - font-size: .75em; - font-family: Segoe UI, Verdana, Helvetica, Sans-Serif; - margin: 8px; - padding: 0; - color: #696969; -} - -h1, h2, h3, h4, h5, h6 -{ - color: #000; - font-size: 40px; - margin: 0px; -} - -textarea -{ - font-family: Consolas -} - -#results -{ - margin-top: 2em; - margin-left: 2em; - color: black; - font-size: medium; -} - diff --git a/src/vs/base/test/node/stream/stream.test.ts b/src/vs/base/test/node/stream/stream.test.ts deleted file mode 100644 index cf30ca2c7d5..00000000000 --- a/src/vs/base/test/node/stream/stream.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; - -import * as stream from 'vs/base/node/stream'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; - -suite('Stream', () => { - test('readToMatchingString - ANSI', async () => { - const file = getPathFromAmdModule(require, './fixtures/file.css'); - - const result = await stream.readToMatchingString(file, '\n', 10, 100); - - // \r may be present on Windows - assert.equal(result!.replace('\r', ''), '/*---------------------------------------------------------------------------------------------'); - }); - - test('readToMatchingString - empty', async () => { - const file = getPathFromAmdModule(require, './fixtures/empty.txt'); - - const result = await stream.readToMatchingString(file, '\n', 10, 100); - assert.equal(result, null); - }); -}); diff --git a/src/vs/base/test/node/utils.ts b/src/vs/base/test/node/utils.ts index 58e77924fe6..5ba6f6e2472 100644 --- a/src/vs/base/test/node/utils.ts +++ b/src/vs/base/test/node/utils.ts @@ -16,8 +16,8 @@ export interface ITestFileResult { export function testFile(folder: string, file: string): Promise { const id = generateUuid(); const parentDir = join(tmpdir(), 'vsctests', id); - const newDir = join(parentDir, 'config', id); - const testFile = join(newDir, 'config.json'); + const newDir = join(parentDir, folder, id); + const testFile = join(newDir, file); return mkdirp(newDir, 493).then(() => { return { diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 30598e4a566..1e742447047 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -4,23 +4,31 @@ + + - + + + + + + + + + + + + + + - + + - - + + diff --git a/src/vs/code/browser/workbench/workbench.js b/src/vs/code/browser/workbench/workbench.js index 17ac4fef8ad..34f321f90df 100644 --- a/src/vs/code/browser/workbench/workbench.js +++ b/src/vs/code/browser/workbench/workbench.js @@ -3,44 +3,24 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -//@ts-check 'use strict'; (function () { - function loadScript(path, callback) { - let script = document.createElement('script'); - script.onload = callback; - script.async = true; - script.type = 'text/javascript'; - script.src = path; - document.head.appendChild(script); - } + require.config({ + baseUrl: `${window.location.origin}/out`, + paths: { + 'vscode-textmate': `${window.location.origin}/node_modules/vscode-textmate/release/main`, + 'onigasm-umd': `${window.location.origin}/node_modules/onigasm-umd/release/main`, + 'xterm': `${window.location.origin}/node_modules/xterm/lib/xterm.js`, + 'xterm-addon-search': `${window.location.origin}/node_modules/xterm-addon-search/lib/xterm-addon-search.js`, + 'xterm-addon-web-links': `${window.location.origin}/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`, + } + }); - loadScript('./out/vs/loader.js', function () { + require(['vs/workbench/workbench.web.api'], function (api) { + const options = JSON.parse(document.getElementById('vscode-workbench-web-configuration').getAttribute('data-settings')); - // @ts-ignore - require.config({ - baseUrl: `${window.location.origin}/out`, - paths: { - 'vscode-textmate': `${window.location.origin}/node_modules/vscode-textmate/release/main`, - 'onigasm-umd': `${window.location.origin}/node_modules/onigasm-umd/release/main`, - 'xterm': `${window.location.origin}/node_modules/xterm/lib/xterm.js`, - 'xterm-addon-search': `${window.location.origin}/node_modules/xterm-addon-search/lib/xterm-addon-search.js`, - 'xterm-addon-web-links': `${window.location.origin}/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`, - } - }); - - // @ts-ignore - require([ - 'vs/workbench/workbench.web.main', - 'vs/nls!vs/workbench/workbench.web.main', - 'vs/css!vs/workbench/workbench.web.main' - ], - // @ts-ignore - function () { - // @ts-ignore - require('vs/workbench/browser/web.main').main(self['WINDOW_CONFIGURATION']).then(undefined, console.error); - }); + api.create(document.body, options); }); })(); \ No newline at end of file diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index d753746fe85..a6bb5723f58 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -33,7 +33,7 @@ import { EnvironmentService } from 'vs/platform/environment/node/environmentServ import { IssueReporterModel, IssueReporterData as IssueReporterModelData } from 'vs/code/electron-browser/issue/issueReporterModel'; import { IssueReporterData, IssueReporterStyles, IssueType, ISettingsSearchIssueReporterData, IssueReporterFeatures, IssueReporterExtensionData } from 'vs/platform/issue/common/issue'; import BaseHtml from 'vs/code/electron-browser/issue/issueReporterPage'; -import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/node/logIpc'; +import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/common/logIpc'; import { ILogService, getLogLevel } from 'vs/platform/log/common/log'; import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel'; import { normalizeGitHubUrl } from 'vs/code/electron-browser/issue/issueReporterUtil'; @@ -336,7 +336,7 @@ export class IssueReporter extends Disposable { this.render(); }); - ['includeSystemInfo', 'includeProcessInfo', 'includeWorkspaceInfo', 'includeExtensions', 'includeSearchedExtensions', 'includeSettingsSearchDetails'].forEach(elementId => { + (['includeSystemInfo', 'includeProcessInfo', 'includeWorkspaceInfo', 'includeExtensions', 'includeSearchedExtensions', 'includeSettingsSearchDetails'] as const).forEach(elementId => { this.addEventListener(elementId, 'click', (event: Event) => { event.stopPropagation(); this.issueReporterModel.update({ [elementId]: !this.issueReporterModel.getData()[elementId] }); @@ -346,7 +346,7 @@ export class IssueReporter extends Disposable { const showInfoElements = document.getElementsByClassName('showInfo'); for (let i = 0; i < showInfoElements.length; i++) { const showInfo = showInfoElements.item(i); - showInfo!.addEventListener('click', (e) => { + showInfo!.addEventListener('click', (e: MouseEvent) => { e.preventDefault(); const label = (e.target); if (label) { @@ -676,12 +676,14 @@ export class IssueReporter extends Disposable { private logSearchError(error: Error) { this.logService.warn('issueReporter#search ', error.message); - /* __GDPR__ - "issueReporterSearchError" : { - "message" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" } - } - */ - this.telemetryService.publicLog('issueReporterSearchError', { message: error.message }); + type IssueReporterSearchErrorClassification = { + message: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' } + }; + + type IssueReporterSearchError = { + message: string; + }; + this.telemetryService.publicLog2('issueReporterSearchError', { message: error.message }); } private setUpTypes(): void { @@ -873,13 +875,15 @@ export class IssueReporter extends Disposable { return false; } - /* __GDPR__ - "issueReporterSubmit" : { - "issueType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "numSimilarIssuesDisplayed" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - } - */ - this.telemetryService.publicLog('issueReporterSubmit', { issueType: this.issueReporterModel.getData().issueType, numSimilarIssuesDisplayed: this.numberOfSearchResultsDisplayed }); + type IssueReporterSubmitClassification = { + issueType: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; + numSimilarIssuesDisplayed: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; + }; + type IssueReporterSubmitEvent = { + issueType: any; + numSimilarIssuesDisplayed: number; + }; + this.telemetryService.publicLog2('issueReporterSubmit', { issueType: this.issueReporterModel.getData().issueType, numSimilarIssuesDisplayed: this.numberOfSearchResultsDisplayed }); this.hasBeenSubmitted = true; const baseUrl = this.getIssueUrlWithTitle((this.getElementById('issue-title')).value); @@ -1106,11 +1110,7 @@ export class IssueReporter extends Disposable { // Exclude right click if (event.which < 3) { shell.openExternal((event.target).href); - - /* __GDPR__ - "issueReporterViewSimilarIssue" : { } - */ - this.telemetryService.publicLog('issueReporterViewSimilarIssue'); + this.telemetryService.publicLog2('issueReporterViewSimilarIssue'); } } @@ -1121,12 +1121,13 @@ export class IssueReporter extends Disposable { } else { const error = new Error(`${elementId} not found.`); this.logService.error(error); - /* __GDPR__ - "issueReporterGetElementError" : { - "message" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" } - } - */ - this.telemetryService.publicLog('issueReporterGetElementError', { message: error.message }); + type IssueReporterGetElementErrorClassification = { + message: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' }; + }; + type IssueReporterGetElementErrorEvent = { + message: string; + }; + this.telemetryService.publicLog2('issueReporterGetElementError', { message: error.message }); return undefined; } diff --git a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts index 58cdb40a491..321a5611e74 100644 --- a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts @@ -16,7 +16,7 @@ import { IContextMenuItem } from 'vs/base/parts/contextmenu/common/contextmenu'; import { popup } from 'vs/base/parts/contextmenu/electron-browser/contextmenu'; import { ProcessItem } from 'vs/base/common/processes'; import { addDisposableListener } from 'vs/base/browser/dom'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { isRemoteDiagnosticError, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; @@ -24,7 +24,7 @@ let mapPidToWindowTitle = new Map(); const DEBUG_FLAGS_PATTERN = /\s--(inspect|debug)(-brk|port)?=(\d+)?/; const DEBUG_PORT_PATTERN = /\s--(inspect|debug)-port=(\d+)/; -const listeners: IDisposable[] = []; +const listeners = new DisposableStore(); const collapsedStateCache: Map = new Map(); let lastRequestTime: number; @@ -171,7 +171,7 @@ function renderProcessGroupHeader(sectionName: string, body: HTMLElement, contai updateSectionCollapsedState(!collapsedStateCache.get(sectionName), body, twistie, sectionName); data.prepend(twistie); - listeners.push(addDisposableListener(data, 'click', (e) => { + listeners.add(addDisposableListener(data, 'click', (e) => { const isHidden = body.classList.contains('hidden'); updateSectionCollapsedState(isHidden, body, twistie, sectionName); })); @@ -222,7 +222,7 @@ function renderTableSection(sectionName: string, processList: FormattedProcessIt row.append(cpu, memory, pid, name); - listeners.push(addDisposableListener(row, 'contextmenu', (e) => { + listeners.add(addDisposableListener(row, 'contextmenu', (e) => { showContextMenu(e, p, sectionIsLocal); })); @@ -239,7 +239,7 @@ function updateProcessInfo(processLists: [{ name: string, rootProcess: ProcessIt } container.innerHTML = ''; - listeners.forEach(l => l.dispose()); + listeners.clear(); const tableHead = document.createElement('thead'); tableHead.innerHTML = ` diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/nodeCachedDataCleaner.ts b/src/vs/code/electron-browser/sharedProcess/contrib/nodeCachedDataCleaner.ts index fba3f2eb42f..5c0b0ef0b8c 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/nodeCachedDataCleaner.ts +++ b/src/vs/code/electron-browser/sharedProcess/contrib/nodeCachedDataCleaner.ts @@ -5,7 +5,7 @@ import { basename, dirname, join } from 'vs/base/common/path'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { readdir, rimraf, stat } from 'vs/base/node/pfs'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import product from 'vs/platform/product/node/product'; @@ -16,7 +16,7 @@ export class NodeCachedDataCleaner { ? 1000 * 60 * 60 * 24 * 7 // roughly 1 week : 1000 * 60 * 60 * 24 * 30 * 3; // roughly 3 months - private _disposables: IDisposable[] = []; + private readonly _disposables = new DisposableStore(); constructor( @IEnvironmentService private readonly _environmentService: IEnvironmentService @@ -25,7 +25,7 @@ export class NodeCachedDataCleaner { } dispose(): void { - this._disposables = dispose(this._disposables); + this._disposables.dispose(); } private _manageCachedDataSoon(): void { @@ -76,7 +76,7 @@ export class NodeCachedDataCleaner { }, 30 * 1000); - this._disposables.push(toDisposable(() => { + this._disposables.add(toDisposable(() => { if (handle) { clearTimeout(handle); handle = undefined; diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index e3632ba5b91..e713834efe6 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -19,8 +19,8 @@ import { ExtensionManagementService } from 'vs/platform/extensionManagement/node import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; -import { IRequestService } from 'vs/platform/request/node/request'; -import { RequestService } from 'vs/platform/request/electron-browser/requestService'; +import { IRequestService } from 'vs/platform/request/common/request'; +import { RequestService } from 'vs/platform/request/browser/requestService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { combinedAppender, NullTelemetryService, ITelemetryAppender, NullAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils'; import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties'; @@ -31,13 +31,13 @@ import { IWindowsService, ActiveWindowManager } from 'vs/platform/windows/common import { WindowsService } from 'vs/platform/windows/electron-browser/windowsService'; import { ipcRenderer } from 'electron'; import { ILogService, LogLevel } from 'vs/platform/log/common/log'; -import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/node/logIpc'; +import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/common/logIpc'; import { LocalizationsService } from 'vs/platform/localizations/node/localizations'; import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; import { LocalizationsChannel } from 'vs/platform/localizations/node/localizationsIpc'; import { DialogChannelClient } from 'vs/platform/dialogs/node/dialogIpc'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { IDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle'; +import { combinedDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { DownloadService } from 'vs/platform/download/node/downloadService'; import { IDownloadService } from 'vs/platform/download/common/download'; import { IChannel, IServerChannel, StaticRouter } from 'vs/base/parts/ipc/common/ipc'; @@ -48,6 +48,13 @@ import { LogsDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/ import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; +import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService'; +import { IDiagnosticsService } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { DiagnosticsChannel } from 'vs/platform/diagnostics/node/diagnosticsIpc'; +import { FileService } from 'vs/platform/files/common/fileService'; +import { IFileService } from 'vs/platform/files/common/files'; +import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider'; +import { Schemas } from 'vs/base/common/network'; export interface ISharedProcessConfiguration { readonly machineId: string; @@ -82,24 +89,24 @@ class MainProcessService implements IMainProcessService { async function main(server: Server, initData: ISharedProcessInitData, configuration: ISharedProcessConfiguration): Promise { const services = new ServiceCollection(); - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); - const onExit = () => dispose(disposables); + const onExit = () => disposables.dispose(); process.once('exit', onExit); ipcRenderer.once('handshake:goodbye', onExit); - disposables.push(server); + disposables.add(server); const environmentService = new EnvironmentService(initData.args, process.execPath); const mainRouter = new StaticRouter(ctx => ctx === 'main'); const logLevelClient = new LogLevelSetterChannelClient(server.getChannel('loglevel', mainRouter)); const logService = new FollowerLogService(logLevelClient, new SpdLogService('sharedprocess', environmentService.logsPath, initData.logLevel)); - disposables.push(logService); + disposables.add(logService); logService.info('main', JSON.stringify(configuration)); const configurationService = new ConfigurationService(environmentService.settingsResource); - disposables.push(configurationService); + disposables.add(configurationService); await configurationService.initialize(); services.set(IEnvironmentService, environmentService); @@ -119,8 +126,18 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat const dialogChannel = server.getChannel('dialog', activeWindowRouter); services.set(IDialogService, new DialogChannelClient(dialogChannel)); + // Files + const fileService = new FileService(logService); + services.set(IFileService, fileService); + disposables.add(fileService); + + const diskFileSystemProvider = new DiskFileSystemProvider(logService); + disposables.add(diskFileSystemProvider); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + const instantiationService = new InstantiationService(services); + let telemetryService: ITelemetryService; instantiationService.invokeFunction(accessor => { const services = new ServiceCollection(); const environmentService = accessor.get(IEnvironmentService); @@ -133,7 +150,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat if (!extensionDevelopmentLocationURI && !environmentService.args['disable-telemetry'] && product.enableTelemetry) { if (product.aiConfig && product.aiConfig.asimovKey && isBuilt) { appInsightsAppender = new AppInsightsAppender(eventPrefix, null, product.aiConfig.asimovKey, telemetryLogService); - disposables.push(appInsightsAppender); // Ensure the AI appender is disposed so that it flushes remaining data + disposables.add(appInsightsAppender); // Ensure the AI appender is disposed so that it flushes remaining data } const config: ITelemetryServiceConfig = { appender: combinedAppender(appInsightsAppender, new LogAppender(logService)), @@ -141,8 +158,10 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat piiPaths: [appRoot, extensionsPath] }; - services.set(ITelemetryService, new SyncDescriptor(TelemetryService, [config])); + telemetryService = new TelemetryService(config, configurationService); + services.set(ITelemetryService, telemetryService); } else { + telemetryService = NullTelemetryService; services.set(ITelemetryService, NullTelemetryService); } server.registerChannel('telemetryAppender', new TelemetryAppenderChannel(appInsightsAppender)); @@ -150,6 +169,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); services.set(ILocalizationsService, new SyncDescriptor(LocalizationsService)); + services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService)); const instantiationService2 = instantiationService.createChild(services); @@ -163,18 +183,22 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat const localizationsChannel = new LocalizationsChannel(localizationsService); server.registerChannel('localizations', localizationsChannel); + const diagnosticsService = accessor.get(IDiagnosticsService); + const diagnosticsChannel = new DiagnosticsChannel(diagnosticsService); + server.registerChannel('diagnostics', diagnosticsChannel); + // clean up deprecated extensions (extensionManagementService as ExtensionManagementService).removeDeprecatedExtensions(); // update localizations cache (localizationsService as LocalizationsService).update(); // cache clean ups - disposables.push(combinedDisposable( + disposables.add(combinedDisposable( instantiationService2.createInstance(NodeCachedDataCleaner), instantiationService2.createInstance(LanguagePackCachedDataCleaner), instantiationService2.createInstance(StorageDataCleaner), instantiationService2.createInstance(LogsDataCleaner) )); - disposables.push(extensionManagementService as ExtensionManagementService); + disposables.add(extensionManagementService as ExtensionManagementService); }); }); } diff --git a/src/vs/code/electron-browser/workbench/workbench.js b/src/vs/code/electron-browser/workbench/workbench.js index f9f21d89bf2..dfe41b3d93d 100644 --- a/src/vs/code/electron-browser/workbench/workbench.js +++ b/src/vs/code/electron-browser/workbench/workbench.js @@ -43,7 +43,6 @@ bootstrapWindow.load([ }); /** - * // configuration: IWindowConfiguration * @param {{ * partsSplashPath?: string, * highContrast?: boolean, diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index bf75167101e..f70eece8b30 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -50,7 +50,7 @@ import { DarwinUpdateService } from 'vs/platform/update/electron-main/updateServ import { IIssueService } from 'vs/platform/issue/common/issue'; import { IssueChannel } from 'vs/platform/issue/node/issueIpc'; import { IssueService } from 'vs/platform/issue/electron-main/issueService'; -import { LogLevelSetterChannel } from 'vs/platform/log/node/logIpc'; +import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc'; import { setUnexpectedErrorHandler, onUnexpectedError } from 'vs/base/common/errors'; import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener'; import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver'; @@ -81,6 +81,11 @@ import { nodeWebSocketFactory } from 'vs/platform/remote/node/nodeWebSocketFacto import { VSBuffer } from 'vs/base/common/buffer'; import { statSync } from 'fs'; import { ISignService } from 'vs/platform/sign/common/sign'; +import { IDiagnosticsService } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc'; +import { FileService } from 'vs/platform/files/common/fileService'; +import { IFileService } from 'vs/platform/files/common/files'; +import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; export class CodeApplication extends Disposable { @@ -133,8 +138,38 @@ export class CodeApplication extends Disposable { }); // Security related measures (https://electronjs.org/docs/tutorial/security) - // DO NOT CHANGE without consulting the documentation - app.on('web-contents-created', (event: Electron.Event, contents) => { + // + // !!! DO NOT CHANGE without consulting the documentation !!! + // + // app.on('remote-get-guest-web-contents', event => event.preventDefault()); // TODO@Ben TODO@Matt revisit this need for + app.on('remote-require', (event, sender, module) => { + this.logService.trace('App#on(remote-require): prevented'); + + event.preventDefault(); + }); + app.on('remote-get-global', (event, sender, module) => { + this.logService.trace(`App#on(remote-get-global): prevented on ${module}`); + + event.preventDefault(); + }); + app.on('remote-get-builtin', (event, sender, module) => { + this.logService.trace(`App#on(remote-get-builtin): prevented on ${module}`); + + if (module !== 'clipboard') { + event.preventDefault(); + } + }); + app.on('remote-get-current-window', event => { + this.logService.trace(`App#on(remote-get-current-window): prevented`); + + event.preventDefault(); + }); + app.on('remote-get-current-web-contents', event => { + this.logService.trace(`App#on(remote-get-current-web-contents): prevented`); + + event.preventDefault(); + }); + app.on('web-contents-created', (_event: Electron.Event, contents) => { contents.on('will-attach-webview', (event: Electron.Event, webPreferences, params) => { const isValidWebviewSource = (source: string): boolean => { @@ -254,21 +289,18 @@ export class CodeApplication extends Disposable { ipc.on('vscode:reloadWindow', (event: Event) => event.sender.reload()); - // After waking up from sleep (after window opened) + // Some listeners after window opened (async () => { await this.lifecycleService.when(LifecycleMainPhase.AfterWindowOpen); + // After waking up from sleep (after window opened) powerMonitor.on('resume', () => { if (this.windowsMainService) { this.windowsMainService.sendToAll('vscode:osResume', undefined); } }); - })(); - - // Keyboard layout changes (after window opened) - (async () => { - await this.lifecycleService.when(LifecycleMainPhase.AfterWindowOpen); + // Keyboard layout changes (after window opened) const nativeKeymap = await import('native-keymap'); nativeKeymap.onDidChangeKeyboardLayout(() => { if (this.windowsMainService) { @@ -350,12 +382,10 @@ export class CodeApplication extends Disposable { // Create driver if (this.environmentService.driverHandle) { - (async () => { - const server = await serveDriver(electronIpcServer, this.environmentService.driverHandle!, this.environmentService, appInstantiationService); + const server = await serveDriver(electronIpcServer, this.environmentService.driverHandle!, this.environmentService, appInstantiationService); - this.logService.info('Driver started at:', this.environmentService.driverHandle); - this._register(server); - })(); + this.logService.info('Driver started at:', this.environmentService.driverHandle); + this._register(server); } // Setup Auth Handler @@ -391,6 +421,13 @@ export class CodeApplication extends Disposable { private async createServices(machineId: string, sharedProcess: SharedProcess, sharedProcessClient: Promise>): Promise { const services = new ServiceCollection(); + // Files + const fileService = this._register(new FileService(this.logService)); + services.set(IFileService, fileService); + + const diskFileSystemProvider = this._register(new DiskFileSystemProvider(this.logService)); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + switch (process.platform) { case 'win32': services.set(IUpdateService, new SyncDescriptor(Win32UpdateService)); @@ -412,6 +449,10 @@ export class CodeApplication extends Disposable { services.set(IWindowsMainService, new SyncDescriptor(WindowsManager, [machineId, this.userEnv])); services.set(IWindowsService, new SyncDescriptor(WindowsService, [sharedProcess])); services.set(ILaunchService, new SyncDescriptor(LaunchService)); + + const diagnosticsChannel = getDelayedChannel(sharedProcessClient.then(client => client.getChannel('diagnostics'))); + services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService, [diagnosticsChannel])); + services.set(IIssueService, new SyncDescriptor(IssueService, [machineId, this.userEnv])); services.set(IMenubarService, new SyncDescriptor(MenubarService)); @@ -528,7 +569,7 @@ export class CodeApplication extends Disposable { this.lifecycleService.phase = LifecycleMainPhase.Ready; // Propagate to clients - const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService); // TODO@Joao: unfold this + const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService); // Create a URL handler which forwards to the last active window const activeWindowManager = new ActiveWindowManager(windowsService); diff --git a/src/vs/code/electron-main/auth.ts b/src/vs/code/electron-main/auth.ts index ed92533c32f..6fbd3fcce46 100644 --- a/src/vs/code/electron-main/auth.ts +++ b/src/vs/code/electron-main/auth.ts @@ -54,7 +54,11 @@ export class ProxyAuthHandler { width: 450, height: 220, show: true, - title: 'VS Code' + title: 'VS Code', + webPreferences: { + nodeIntegration: true, + webviewTag: true + } }; const focusedWindow = this.windowsMainService.getFocusedWindow(); diff --git a/src/vs/code/electron-main/logUploader.ts b/src/vs/code/electron-main/logUploader.ts deleted file mode 100644 index 4e601fe8a65..00000000000 --- a/src/vs/code/electron-main/logUploader.ts +++ /dev/null @@ -1,153 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as os from 'os'; -import * as cp from 'child_process'; -import * as fs from 'fs'; - -import * as path from 'vs/base/common/path'; -import { localize } from 'vs/nls'; -import product from 'vs/platform/product/node/product'; -import { IRequestService } from 'vs/platform/request/node/request'; -import { IRequestContext } from 'vs/base/node/request'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { ILaunchService } from 'vs/platform/launch/electron-main/launchService'; - -interface PostResult { - readonly blob_id: string; -} - -class Endpoint { - private constructor( - readonly url: string - ) { } - - static getFromProduct(): Endpoint | undefined { - const logUploaderUrl = product.logUploaderUrl; - return logUploaderUrl ? new Endpoint(logUploaderUrl) : undefined; - } -} - -export async function uploadLogs( - launchService: ILaunchService, - requestService: IRequestService, - environmentService: IEnvironmentService -): Promise { - const endpoint = Endpoint.getFromProduct(); - if (!endpoint) { - console.error(localize('invalidEndpoint', 'Invalid log uploader endpoint')); - return; - } - - const logsPath = await launchService.getLogsPath(); - - if (await promptUserToConfirmLogUpload(logsPath, environmentService)) { - console.log(localize('beginUploading', 'Uploading...')); - const outZip = await zipLogs(logsPath); - const result = await postLogs(endpoint, outZip, requestService); - console.log(localize('didUploadLogs', 'Upload successful! Log file ID: {0}', result.blob_id)); - } -} - -function promptUserToConfirmLogUpload( - logsPath: string, - environmentService: IEnvironmentService -): boolean { - const confirmKey = 'iConfirmLogsUpload'; - if ((environmentService.args['upload-logs'] || '').toLowerCase() === confirmKey.toLowerCase()) { - return true; - } else { - const message = localize('logUploadPromptHeader', 'You are about to upload your session logs to a secure Microsoft endpoint that only Microsoft\'s members of the VS Code team can access.') - + '\n\n' + localize('logUploadPromptBody', 'Session logs may contain personal information such as full paths or file contents. Please review and redact your session log files here: \'{0}\'', logsPath) - + '\n\n' + localize('logUploadPromptBodyDetails', 'By continuing you confirm that you have reviewed and redacted your session log files and that you agree to Microsoft using them to debug VS Code.') - + '\n\n' + localize('logUploadPromptAcceptInstructions', 'Please run code with \'--upload-logs={0}\' to proceed with upload', confirmKey); - console.log(message); - return false; - } -} - -async function postLogs( - endpoint: Endpoint, - outZip: string, - requestService: IRequestService -): Promise { - const dotter = setInterval(() => console.log('.'), 5000); - let result: IRequestContext; - try { - result = await requestService.request({ - url: endpoint.url, - type: 'POST', - data: Buffer.from(fs.readFileSync(outZip)).toString('base64'), - headers: { - 'Content-Type': 'application/zip' - } - }, CancellationToken.None); - } catch (e) { - clearInterval(dotter); - console.log(localize('postError', 'Error posting logs: {0}', e)); - throw e; - } - - return new Promise((resolve, reject) => { - const parts: Buffer[] = []; - result.stream.on('data', data => { - parts.push(data); - }); - - result.stream.on('end', () => { - clearInterval(dotter); - try { - const response = Buffer.concat(parts).toString('utf-8'); - if (result.res.statusCode === 200) { - resolve(JSON.parse(response)); - } else { - const errorMessage = localize('responseError', 'Error posting logs. Got {0} — {1}', result.res.statusCode, response); - console.log(errorMessage); - reject(new Error(errorMessage)); - } - } catch (e) { - console.log(localize('parseError', 'Error parsing response')); - reject(e); - } - }); - }); -} - -function zipLogs( - logsPath: string -): Promise { - const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vscode-log-upload')); - const outZip = path.join(tempDir, 'logs.zip'); - return new Promise((resolve, reject) => { - doZip(logsPath, outZip, tempDir, (err, stdout, stderr) => { - if (err) { - console.error(localize('zipError', 'Error zipping logs: {0}', err.message)); - reject(err); - } else { - resolve(outZip); - } - }); - }); -} - -function doZip( - logsPath: string, - outZip: string, - tempDir: string, - callback: (error: Error, stdout: string, stderr: string) => void -) { - switch (os.platform()) { - case 'win32': - // Copy directory first to avoid file locking issues - const sub = path.join(tempDir, 'sub'); - return cp.execFile('powershell', ['-Command', - `[System.IO.Directory]::CreateDirectory("${sub}"); Copy-Item -recurse "${logsPath}" "${sub}"; Compress-Archive -Path "${sub}" -DestinationPath "${outZip}"`], - { cwd: logsPath }, - callback); - default: - return cp.execFile('zip', ['-r', outZip, '.'], { cwd: logsPath }, callback); - } -} diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index e881d6a1e2f..897fe6ef386 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -26,22 +26,21 @@ import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/ import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; -import { IRequestService } from 'vs/platform/request/node/request'; +import { IRequestService } from 'vs/platform/request/common/request'; import { RequestService } from 'vs/platform/request/electron-main/requestService'; import * as fs from 'fs'; import { CodeApplication } from 'vs/code/electron-main/app'; import { localize } from 'vs/nls'; import { mnemonicButtonLabel } from 'vs/base/common/labels'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; -import { IDiagnosticsService, DiagnosticsService } from 'vs/platform/diagnostics/electron-main/diagnosticsService'; import { BufferLogService } from 'vs/platform/log/common/bufferLog'; -import { uploadLogs } from 'vs/code/electron-main/logUploader'; import { setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { IThemeMainService, ThemeMainService } from 'vs/platform/theme/electron-main/themeMainService'; import { Client } from 'vs/base/parts/ipc/common/ipc.net'; import { once } from 'vs/base/common/functional'; import { ISignService } from 'vs/platform/sign/common/sign'; import { SignService } from 'vs/platform/sign/node/signService'; +import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc'; class ExpectedError extends Error { readonly isExpected = true; @@ -147,7 +146,6 @@ class CodeMain { services.set(ILifecycleService, new SyncDescriptor(LifecycleService)); services.set(IStateService, new SyncDescriptor(StateService)); services.set(IRequestService, new SyncDescriptor(RequestService)); - services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService)); services.set(IThemeMainService, new SyncDescriptor(ThemeMainService)); services.set(ISignService, new SyncDescriptor(SignService)); @@ -163,7 +161,7 @@ class CodeMain { environmentService.logsPath, environmentService.globalStorageHome, environmentService.workspaceStorageHome, - environmentService.backupHome + environmentService.backupHome.fsPath ].map((path): undefined | Promise => path ? mkdirp(path) : undefined)); // Configuration service @@ -263,7 +261,7 @@ class CodeMain { // Skip this if we are running with --wait where it is expected that we wait for a while. // Also skip when gathering diagnostics (--status) which can take a longer time. let startupWarningDialogHandle: NodeJS.Timeout | undefined = undefined; - if (!environmentService.wait && !environmentService.status && !environmentService.args['upload-logs']) { + if (!environmentService.wait && !environmentService.status) { startupWarningDialogHandle = setTimeout(() => { this.showStartupWarningDialog( localize('secondInstanceNoResponse', "Another instance of {0} is running but not responding", product.nameShort), @@ -278,23 +276,19 @@ class CodeMain { // Process Info if (environmentService.args.status) { return instantiationService.invokeFunction(async accessor => { - const diagnostics = await accessor.get(IDiagnosticsService).getDiagnostics(launchClient); + // Create a diagnostic service connected to the existing shared process + const sharedProcessClient = await connect(environmentService.sharedIPCHandle, 'main'); + const diagnosticsChannel = sharedProcessClient.getChannel('diagnostics'); + const diagnosticsService = new DiagnosticsService(diagnosticsChannel); + const mainProcessInfo = await launchClient.getMainProcessInfo(); + const remoteDiagnostics = await launchClient.getRemoteDiagnostics({ includeProcesses: true, includeWorkspaceMetadata: true }); + const diagnostics = await diagnosticsService.getDiagnostics(mainProcessInfo, remoteDiagnostics); console.log(diagnostics); throw new ExpectedError(); }); } - // Log uploader - if (typeof environmentService.args['upload-logs'] !== 'undefined') { - return instantiationService.invokeFunction(async accessor => { - await uploadLogs(launchClient, accessor.get(IRequestService), environmentService); - - throw new ExpectedError(); - }); - } - - // Windows: allow to set foreground if (platform.isWindows) { await this.windowsAllowSetForegroundWindow(launchClient, logService); @@ -322,13 +316,6 @@ class CodeMain { throw new ExpectedError('Terminating...'); } - // Log uploader usage info - if (typeof environmentService.args['upload-logs'] !== 'undefined') { - logService.warn('Warning: The --upload-logs argument can only be used if Code is already running. Please run it again after Code has started.'); - - throw new ExpectedError('Terminating...'); - } - // dock might be hidden at this case due to a retry if (platform.isMacintosh) { app.dock.show(); diff --git a/src/vs/code/electron-main/sharedProcess.ts b/src/vs/code/electron-main/sharedProcess.ts index 8076c873cc6..60926b0d146 100644 --- a/src/vs/code/electron-main/sharedProcess.ts +++ b/src/vs/code/electron-main/sharedProcess.ts @@ -12,7 +12,7 @@ import { Barrier } from 'vs/base/common/async'; import { ILogService } from 'vs/platform/log/common/log'; import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain'; import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService'; -import { dispose, toDisposable, IDisposable } from 'vs/base/common/lifecycle'; +import { toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; export class SharedProcess implements ISharedProcess { @@ -38,6 +38,7 @@ export class SharedProcess implements ISharedProcess { images: false, webaudio: false, webgl: false, + nodeIntegration: true, disableBlinkFeatures: 'Auxclick' // do NOT change, allows us to identify this window as shared-process in the process explorer } }); @@ -66,10 +67,10 @@ export class SharedProcess implements ISharedProcess { this.window.on('close', onClose); - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); this.lifecycleService.onWillShutdown(() => { - dispose(disposables); + disposables.dispose(); // Shut the shared process down when we are quitting // @@ -103,7 +104,7 @@ export class SharedProcess implements ISharedProcess { logLevel: this.logService.getLevel() }); - disposables.push(toDisposable(() => sender.send('handshake:goodbye'))); + disposables.add(toDisposable(() => sender.send('handshake:goodbye'))); ipcMain.once('handshake:im ready', () => c(undefined)); }); }); diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index ec398df67ed..e6cb0ebb5e5 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -13,7 +13,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { parseArgs } from 'vs/platform/environment/node/argv'; import product from 'vs/platform/product/node/product'; -import { IWindowSettings, MenuBarVisibility, IWindowConfiguration, ReadyState, IRunActionInWindowRequest, getTitleBarStyle } from 'vs/platform/windows/common/windows'; +import { IWindowSettings, MenuBarVisibility, IWindowConfiguration, ReadyState, getTitleBarStyle } from 'vs/platform/windows/common/windows'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform'; import { ICodeWindow, IWindowState, WindowMode } from 'vs/platform/windows/electron-main/windows'; @@ -26,6 +26,8 @@ import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainServ import { endsWith } from 'vs/base/common/strings'; import { RunOnceScheduler } from 'vs/base/common/async'; +const RUN_TEXTMATE_IN_WORKER = false; + export interface IWindowCreationOptions { state: IWindowState; extensionDevelopmentPath?: string | string[]; @@ -40,14 +42,6 @@ export const defaultWindowState = function (mode = WindowMode.Normal): IWindowSt }; }; -interface IWorkbenchEditorConfiguration { - workbench: { - editor: { - swipeToNavigate: boolean - } - }; -} - interface ITouchBarSegment extends Electron.SegmentedControlSegment { id: string; } @@ -134,7 +128,10 @@ export class CodeWindow extends Disposable implements ICodeWindow { // want to enforce that Code stays in the foreground. This triggers a disable_hidden_ // flag that Electron provides via patch: // https://github.com/electron/libchromiumcontent/blob/master/patches/common/chromium/disable_hidden.patch - backgroundThrottling: false + backgroundThrottling: false, + nodeIntegration: true, + nodeIntegrationInWorker: RUN_TEXTMATE_IN_WORKER, + webviewTag: true } }; @@ -156,7 +153,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { } } - if (isMacintosh && windowConfig && windowConfig.nativeTabs === true) { + const useNativeTabs = isMacintosh && windowConfig && windowConfig.nativeTabs === true; + if (useNativeTabs) { options.tabbingIdentifier = product.nameShort; // this opts in to sierra tabs } @@ -180,7 +178,11 @@ export class CodeWindow extends Disposable implements ICodeWindow { // TODO@Ben (Electron 4 regression): when running on multiple displays where the target display // to open the window has a larger resolution than the primary display, the window will not size // correctly unless we set the bounds again (https://github.com/microsoft/vscode/issues/74872) - if (isMacintosh && hasMultipleDisplays) { + // + // However, when running with native tabs with multiple windows we cannot use this workaround + // because there is a potential that the new window will be added as native tab instead of being + // a window on its own. In that case calling setBounds() would cause https://github.com/microsoft/vscode/issues/75830 + if (isMacintosh && hasMultipleDisplays && (!useNativeTabs || BrowserWindow.getAllWindows().length === 1)) { if ([this.windowState.width, this.windowState.height, this.windowState.x, this.windowState.y].every(value => typeof value === 'number')) { this._win.setBounds({ width: this.windowState.width!, @@ -311,7 +313,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { const urls = ['https://marketplace.visualstudio.com/*', 'https://*.vsassets.io/*']; this._win.webContents.session.webRequest.onBeforeSendHeaders({ urls }, (details, cb) => { this.marketplaceHeadersPromise.then(headers => { - const requestHeaders = objects.assign(details.requestHeaders, headers); + const requestHeaders = objects.assign(details.requestHeaders, headers) as { [key: string]: string | undefined }; if (!this.configurationService.getValue('extensions.disableExperimentalAzureSearch')) { requestHeaders['Cookie'] = `${requestHeaders['Cookie'] ? requestHeaders['Cookie'] + ';' : ''}EnableExternalSearchForVSCode=true`; } @@ -335,12 +337,14 @@ export class CodeWindow extends Disposable implements ICodeWindow { }); this._win.webContents.session.webRequest.onHeadersReceived(null!, (details, callback) => { - const contentType: string[] = (details.responseHeaders['content-type'] || details.responseHeaders['Content-Type']); + const responseHeaders = details.responseHeaders as { [key: string]: string[] }; + + const contentType: string[] = (responseHeaders['content-type'] || responseHeaders['Content-Type']); if (contentType && Array.isArray(contentType) && contentType.some(x => x.toLowerCase().indexOf('image/svg') >= 0)) { return callback({ cancel: true }); } - return callback({ cancel: false, responseHeaders: details.responseHeaders }); + return callback({ cancel: false, responseHeaders }); }); // Remember that we loaded @@ -366,9 +370,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { } }); - // App commands support - this.registerNavigationListenerOn('app-command', 'browser-backward', 'browser-forward', false); - // Window Focus this._win.on('focus', () => { this._lastFocusTime = Date.now(); @@ -454,30 +455,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { this.currentMenuBarVisibility = newMenuBarVisibility; this.setMenuBarVisibility(newMenuBarVisibility); } - - // Swipe command support (macOS) - if (isMacintosh) { - const config = this.configurationService.getValue(); - if (config && config.workbench && config.workbench.editor && config.workbench.editor.swipeToNavigate) { - this.registerNavigationListenerOn('swipe', 'left', 'right', true); - } else { - this._win.removeAllListeners('swipe'); - } - } - } - - private registerNavigationListenerOn(command: 'swipe' | 'app-command', back: 'left' | 'browser-backward', forward: 'right' | 'browser-forward', acrossEditors: boolean) { - this._win.on(command as 'swipe' /* | 'app-command' */, (e: Electron.Event, cmd: string) => { - if (!this.isReady) { - return; // window must be ready - } - - if (cmd === back) { - this.send('vscode:runAction', { id: acrossEditors ? 'workbench.action.openPreviousRecentlyUsedEditor' : 'workbench.action.navigateBack', from: 'mouse' } as IRunActionInWindowRequest); - } else if (cmd === forward) { - this.send('vscode:runAction', { id: acrossEditors ? 'workbench.action.openNextRecentlyUsedEditor' : 'workbench.action.navigateForward', from: 'mouse' } as IRunActionInWindowRequest); - } - }); } addTabbedWindow(window: ICodeWindow): void { @@ -607,9 +584,10 @@ export class CodeWindow extends Disposable implements ICodeWindow { // Config (combination of process.argv and window configuration) const environment = parseArgs(process.argv); const config = objects.assign(environment, windowConfiguration); - for (let key in config) { - if (config[key] === undefined || config[key] === null || config[key] === '' || config[key] === false) { - delete config[key]; // only send over properties that have a true value + for (const key in config) { + const configValue = (config as any)[key]; + if (configValue === undefined || configValue === null || configValue === '' || configValue === false) { + delete (config as any)[key]; // only send over properties that have a true value } } @@ -683,7 +661,12 @@ export class CodeWindow extends Disposable implements ICodeWindow { // only consider non-minimized window states if (mode === WindowMode.Normal || mode === WindowMode.Maximized) { - const bounds = this.getBounds(); + let bounds: Electron.Rectangle; + if (mode === WindowMode.Normal) { + bounds = this.getBounds(); + } else { + bounds = this._win.getNormalBounds(); // make sure to persist the normal bounds when maximized to be able to restore them + } state.x = bounds.x; state.y = bounds.y; @@ -726,7 +709,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { // Single Monitor: be strict about x/y positioning if (displays.length === 1) { const displayWorkingArea = this.getWorkingArea(displays[0]); - if (state.mode !== WindowMode.Maximized && displayWorkingArea) { + if (displayWorkingArea) { if (state.x < displayWorkingArea.x) { state.x = displayWorkingArea.x; // prevent window from falling out of the screen to the left } @@ -752,10 +735,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { } } - if (state.mode === WindowMode.Maximized) { - return defaultWindowState(WindowMode.Maximized); // when maximized, make sure we have good values when the user restores the window - } - return state; } @@ -783,14 +762,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { bounds.x + bounds.width > displayWorkingArea.x && // prevent window from falling out of the screen to the left bounds.y + bounds.height > displayWorkingArea.y // prevent window from falling out of the scree nto the top ) { - if (state.mode === WindowMode.Maximized) { - const defaults = defaultWindowState(WindowMode.Maximized); // when maximized, make sure we have good values when the user restores the window - defaults.x = state.x; // carefull to keep x/y position so that the window ends up on the correct monitor - defaults.y = state.y; - - return defaults; - } - return state; } @@ -864,16 +835,17 @@ export class CodeWindow extends Disposable implements ICodeWindow { } private useNativeFullScreen(): boolean { - const windowConfig = this.configurationService.getValue('window'); - if (!windowConfig || typeof windowConfig.nativeFullScreen !== 'boolean') { - return true; // default - } + return true; // TODO@ben enable simple fullscreen again (https://github.com/microsoft/vscode/issues/75054) + // const windowConfig = this.configurationService.getValue('window'); + // if (!windowConfig || typeof windowConfig.nativeFullScreen !== 'boolean') { + // return true; // default + // } - if (windowConfig.nativeTabs) { - return true; // https://github.com/electron/electron/issues/16142 - } + // if (windowConfig.nativeTabs) { + // return true; // https://github.com/electron/electron/issues/16142 + // } - return windowConfig.nativeFullScreen !== false; + // return windowConfig.nativeFullScreen !== false; } isMinimized(): boolean { diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 1087d110e84..ad3025e5c3c 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -1331,7 +1331,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService { // For all other cases we first call into registerEmptyWindowBackupSync() to set it before // loading the window. if (options.emptyWindowBackupInfo) { - configuration.backupPath = join(this.environmentService.backupHome, options.emptyWindowBackupInfo.backupFolder); + configuration.backupPath = join(this.environmentService.backupHome.fsPath, options.emptyWindowBackupInfo.backupFolder); } let window: ICodeWindow | undefined; @@ -1709,14 +1709,13 @@ export class WindowsManager extends Disposable implements IWindowsMainService { private onWindowError(window: ICodeWindow, error: WindowError): void { this.logService.error(error === WindowError.CRASHED ? '[VS Code]: render process crashed!' : '[VS Code]: detected unresponsive'); - - /* __GDPR__ - "windowerror" : { - "type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true } - } - */ - this.telemetryService.publicLog('windowerror', { type: error }); - + type WindowErrorClassification = { + type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + }; + type WindowErrorEvent = { + type: WindowError; + }; + this.telemetryService.publicLog2('windowerror', { type: error }); // Unresponsive if (error === WindowError.UNRESPONSIVE) { if (window.isExtensionDevelopmentHost || window.isExtensionTestHost || (window.win && window.win.webContents && window.win.webContents.isDevToolsOpened())) { diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index e434b71a863..afa7acafa94 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { spawn, ChildProcess } from 'child_process'; +import { spawn, ChildProcess, SpawnOptions } from 'child_process'; import { assign } from 'vs/base/common/objects'; import { buildHelpMessage, buildVersionMessage, addArg, createWaitMarkerFile } from 'vs/platform/environment/node/argv'; import { parseCLIProcessArgv } from 'vs/platform/environment/node/argvHelper'; @@ -19,13 +19,15 @@ import { resolveTerminalEncoding } from 'vs/base/node/encoding'; import * as iconv from 'iconv-lite'; import { isWindows } from 'vs/base/common/platform'; import { ProfilingSession, Target } from 'v8-inspect-profiler'; +import { isString } from 'vs/base/common/types'; function shouldSpawnCliProcess(argv: ParsedArgs): boolean { return !!argv['install-source'] || !!argv['list-extensions'] || !!argv['install-extension'] || !!argv['uninstall-extension'] - || !!argv['locate-extension']; + || !!argv['locate-extension'] + || !!argv['telemetry']; } interface IMainCli { @@ -125,7 +127,7 @@ export async function main(argv: string[]): Promise { const processCallbacks: ((child: ChildProcess) => Promise)[] = []; - const verbose = args.verbose || args.status || typeof args['upload-logs'] !== 'undefined'; + const verbose = args.verbose || args.status; if (verbose) { env['ELECTRON_ENABLE_LOGGING'] = '1'; @@ -338,21 +340,20 @@ export async function main(argv: string[]): Promise { }); } - if (args['js-flags']) { - const match = /max_old_space_size=(\d+)/g.exec(args['js-flags']); + const jsFlags = args['js-flags']; + if (isString(jsFlags)) { + const match = /max_old_space_size=(\d+)/g.exec(jsFlags); if (match && !args['max-memory']) { addArg(argv, `--max-memory=${match[1]}`); } } - const options = { + const options: SpawnOptions = { detached: true, env }; - if (typeof args['upload-logs'] !== 'undefined') { - options['stdio'] = ['pipe', 'pipe', 'pipe']; - } else if (!verbose) { + if (!verbose) { options['stdio'] = 'ignore'; } diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index dafebd1c91f..092c1f6be7c 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -22,7 +22,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { combinedAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties'; -import { IRequestService } from 'vs/platform/request/node/request'; +import { IRequestService } from 'vs/platform/request/common/request'; import { RequestService } from 'vs/platform/request/node/requestService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; @@ -41,6 +41,11 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { LocalizationsService } from 'vs/platform/localizations/node/localizations'; import { Schemas } from 'vs/base/common/network'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; +import { buildTelemetryMessage } from 'vs/platform/telemetry/node/telemetry'; +import { FileService } from 'vs/platform/files/common/fileService'; +import { IFileService } from 'vs/platform/files/common/files'; +import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; +import { DisposableStore } from 'vs/base/common/lifecycle'; const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id); const notInstalled = (id: string) => localize('notInstalled', "Extension '{0}' is not installed.", id); @@ -84,7 +89,7 @@ export class Main { } else if (argv['install-extension']) { const arg = argv['install-extension']; const args: string[] = typeof arg === 'string' ? [arg] : arg; - await this.installExtensions(args, argv['force']); + await this.installExtensions(args, !!argv['force']); } else if (argv['uninstall-extension']) { const arg = argv['uninstall-extension']; @@ -94,6 +99,8 @@ export class Main { const arg = argv['locate-extension']; const ids: string[] = typeof arg === 'string' ? [arg] : arg; await this.locateExtension(ids); + } else if (argv['telemetry']) { + console.log(buildTelemetryMessage(this.environmentService.appRoot, this.environmentService.extensionsPath)); } } @@ -277,6 +284,7 @@ const eventPrefix = 'monacoworkbench'; export async function main(argv: ParsedArgs): Promise { const services = new ServiceCollection(); + const disposables = new DisposableStore(); const environmentService = new EnvironmentService(argv, process.execPath); const logService: ILogService = new SpdLogService('cli', environmentService.logsPath, getLogLevel(environmentService)); @@ -286,6 +294,7 @@ export async function main(argv: ParsedArgs): Promise { await Promise.all([environmentService.appSettingsHome.fsPath, environmentService.extensionsPath].map(p => mkdirp(p))); const configurationService = new ConfigurationService(environmentService.settingsResource); + disposables.add(configurationService); await configurationService.initialize(); services.set(IEnvironmentService, environmentService); @@ -293,15 +302,26 @@ export async function main(argv: ParsedArgs): Promise { services.set(IConfigurationService, configurationService); services.set(IStateService, new SyncDescriptor(StateService)); + // Files + const fileService = new FileService(logService); + disposables.add(fileService); + services.set(IFileService, fileService); + + const diskFileSystemProvider = new DiskFileSystemProvider(logService); + disposables.add(diskFileSystemProvider); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + const instantiationService: IInstantiationService = new InstantiationService(services); - return instantiationService.invokeFunction(accessor => { + return instantiationService.invokeFunction(async accessor => { const envService = accessor.get(IEnvironmentService); const stateService = accessor.get(IStateService); const { appRoot, extensionsPath, extensionDevelopmentLocationURI: extensionDevelopmentLocationURI, isBuilt, installSourcePath } = envService; const services = new ServiceCollection(); + + services.set(IRequestService, new SyncDescriptor(RequestService)); services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); @@ -320,6 +340,9 @@ export async function main(argv: ParsedArgs): Promise { }; services.set(ITelemetryService, new SyncDescriptor(TelemetryService, [config])); + + // Dispose the AI adapter so that remaining data gets flushed. + disposables.add(combinedAppender(...appenders)); } else { services.set(ITelemetryService, NullTelemetryService); } @@ -327,9 +350,10 @@ export async function main(argv: ParsedArgs): Promise { const instantiationService2 = instantiationService.createChild(services); const main = instantiationService2.createInstance(Main); - return main.run(argv).then(() => { - // Dispose the AI adapter so that remaining data gets flushed. - return combinedAppender(...appenders).dispose(); - }); + try { + await main.run(argv); + } finally { + disposables.dispose(); + } }); } \ No newline at end of file diff --git a/src/vs/code/node/shellEnv.ts b/src/vs/code/node/shellEnv.ts index eea6922afbe..fee0648ea13 100644 --- a/src/vs/code/node/shellEnv.ts +++ b/src/vs/code/node/shellEnv.ts @@ -96,10 +96,10 @@ export function getShellEnvironment(logService: ILogService, environmentService: logService.trace('getShellEnvironment: disable-user-env-probe set, skipping'); _shellEnv = Promise.resolve({}); } else if (isWindows) { - logService.trace('getShellEnvironment: runing on windows, skipping'); + logService.trace('getShellEnvironment: running on Windows, skipping'); _shellEnv = Promise.resolve({}); } else if (process.env['VSCODE_CLI'] === '1') { - logService.trace('getShellEnvironment: runing on CLI, skipping'); + logService.trace('getShellEnvironment: running on CLI, skipping'); _shellEnv = Promise.resolve({}); } else { logService.trace('getShellEnvironment: running on Unix'); diff --git a/src/vs/code/test/node/argv.test.ts b/src/vs/code/test/node/argv.test.ts index 6ce5684fab0..6ac49bc9988 100644 --- a/src/vs/code/test/node/argv.test.ts +++ b/src/vs/code/test/node/argv.test.ts @@ -4,10 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import { formatOptions, Option, addArg } from 'vs/platform/environment/node/argv'; +import { ParsedArgs } from 'vs/platform/environment/common/environment'; suite('formatOptions', () => { - function o(id: string, description: string): Option { + function o(id: keyof ParsedArgs, description: string): Option { return { id, description, type: 'string' }; @@ -16,30 +17,30 @@ suite('formatOptions', () => { test('Text should display small columns correctly', () => { assert.deepEqual( formatOptions([ - o('foo', 'bar') + o('add', 'bar') ], 80), - [' --foo bar'] + [' --add bar'] ); assert.deepEqual( formatOptions([ - o('f', 'bar'), - o('fo', 'ba'), - o('foo', 'b') + o('add', 'bar'), + o('wait', 'ba'), + o('trace', 'b') ], 80), [ - ' --f bar', - ' --fo ba', - ' --foo b' + ' --add bar', + ' --wait ba', + ' --trace b' ]); }); test('Text should wrap', () => { assert.deepEqual( formatOptions([ - o('foo', ('bar ').repeat(9)) + o('add', ('bar ').repeat(9)) ], 40), [ - ' --foo bar bar bar bar bar bar bar bar', + ' --add bar bar bar bar bar bar bar bar', ' bar' ]); }); @@ -47,10 +48,10 @@ suite('formatOptions', () => { test('Text should revert to the condensed view when the terminal is too narrow', () => { assert.deepEqual( formatOptions([ - o('foo', ('bar ').repeat(9)) + o('add', ('bar ').repeat(9)) ], 30), [ - ' --foo', + ' --add', ' bar bar bar bar bar bar bar bar bar ' ]); }); diff --git a/src/vs/css.build.js b/src/vs/css.build.js index 146ebe33277..69c6240891d 100644 --- a/src/vs/css.build.js +++ b/src/vs/css.build.js @@ -17,7 +17,7 @@ var _cssPluginGlobal = this; var CSSBuildLoaderPlugin; (function (CSSBuildLoaderPlugin) { - var global = _cssPluginGlobal || {}; + var global = (_cssPluginGlobal || {}); /** * Known issue: * - In IE there is no way to know if the CSS file loaded successfully or not. @@ -319,7 +319,7 @@ var CSSBuildLoaderPlugin; global.cssInlinedResources = global.cssInlinedResources || []; var normalizedFSPath = fsPath.replace(/\\/g, '/'); if (global.cssInlinedResources.indexOf(normalizedFSPath) >= 0) { - // console.warn('CSS INLINING IMAGE AT ' + fsPath + ' MORE THAN ONCE. CONSIDER CONSOLIDATING CSS RULES'); + console.warn('CSS INLINING IMAGE AT ' + fsPath + ' MORE THAN ONCE. CONSIDER CONSOLIDATING CSS RULES'); } global.cssInlinedResources.push(normalizedFSPath); var MIME = /\.svg$/.test(url) ? 'image/svg+xml' : 'image/png'; diff --git a/src/vs/editor/browser/config/configuration.ts b/src/vs/editor/browser/config/configuration.ts index f97a692dd67..cdb50af8be8 100644 --- a/src/vs/editor/browser/config/configuration.ts +++ b/src/vs/editor/browser/config/configuration.ts @@ -14,7 +14,6 @@ import { CommonEditorConfiguration, IEnvConfiguration } from 'vs/editor/common/c import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { BareFontInfo, FontInfo } from 'vs/editor/common/config/fontInfo'; import { IDimension } from 'vs/editor/common/editorCommon'; -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; class CSSBasedConfigurationCache { @@ -62,28 +61,17 @@ export function readFontInfo(bareFontInfo: BareFontInfo): FontInfo { return CSSBasedConfiguration.INSTANCE.readConfiguration(bareFontInfo); } -export function restoreFontInfo(storageService: IStorageService): void { - const strStoredFontInfo = storageService.get('editorFontInfo', StorageScope.GLOBAL); - if (typeof strStoredFontInfo !== 'string') { - return; - } - let storedFontInfo: ISerializedFontInfo[] | null = null; - try { - storedFontInfo = JSON.parse(strStoredFontInfo); - } catch (err) { - return; - } - if (!Array.isArray(storedFontInfo)) { - return; - } - CSSBasedConfiguration.INSTANCE.restoreFontInfo(storedFontInfo); +export function restoreFontInfo(fontInfo: ISerializedFontInfo[]): void { + CSSBasedConfiguration.INSTANCE.restoreFontInfo(fontInfo); } -export function saveFontInfo(storageService: IStorageService): void { - const knownFontInfo = CSSBasedConfiguration.INSTANCE.saveFontInfo(); - if (knownFontInfo.length > 0) { - storageService.store('editorFontInfo', JSON.stringify(knownFontInfo), StorageScope.GLOBAL); +export function serializeFontInfo(): ISerializedFontInfo[] | null { + const fontInfo = CSSBasedConfiguration.INSTANCE.saveFontInfo(); + if (fontInfo.length > 0) { + return fontInfo; } + + return null; } export interface ISerializedFontInfo { diff --git a/src/vs/editor/browser/controller/pointerHandler.ts b/src/vs/editor/browser/controller/pointerHandler.ts index f744847b48f..e4a4a03146f 100644 --- a/src/vs/editor/browser/controller/pointerHandler.ts +++ b/src/vs/editor/browser/controller/pointerHandler.ts @@ -5,7 +5,7 @@ import * as dom from 'vs/base/browser/dom'; import { EventType, Gesture, GestureEvent } from 'vs/base/browser/touch'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { IPointerHandlerHelper, MouseHandler } from 'vs/editor/browser/controller/mouseHandler'; import { IMouseTarget } from 'vs/editor/browser/editorBrowser'; import { EditorMouseEvent } from 'vs/editor/browser/editorDom'; @@ -195,11 +195,6 @@ class TouchHandler extends MouseHandler { this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Tap, (e) => this.onTap(e))); this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Change, (e) => this.onChange(e))); this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Contextmenu, (e: MouseEvent) => this._onContextMenu(new EditorMouseEvent(e, this.viewHelper.viewDomNode), false))); - - } - - public dispose(): void { - super.dispose(); } private onTap(event: GestureEvent): void { @@ -219,26 +214,23 @@ class TouchHandler extends MouseHandler { } } -export class PointerHandler implements IDisposable { +export class PointerHandler extends Disposable { private readonly handler: MouseHandler; constructor(context: ViewContext, viewController: ViewController, viewHelper: IPointerHandlerHelper) { + super(); if (window.navigator.msPointerEnabled) { - this.handler = new MsPointerHandler(context, viewController, viewHelper); + this.handler = this._register(new MsPointerHandler(context, viewController, viewHelper)); } else if ((window).TouchEvent) { - this.handler = new TouchHandler(context, viewController, viewHelper); + this.handler = this._register(new TouchHandler(context, viewController, viewHelper)); } else if (window.navigator.pointerEnabled || (window).PointerEvent) { - this.handler = new StandardPointerHandler(context, viewController, viewHelper); + this.handler = this._register(new StandardPointerHandler(context, viewController, viewHelper)); } else { - this.handler = new MouseHandler(context, viewController, viewHelper); + this.handler = this._register(new MouseHandler(context, viewController, viewHelper)); } } public getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget | null { return this.handler.getTargetAtClientPoint(clientX, clientY); } - - public dispose(): void { - this.handler.dispose(); - } } diff --git a/src/vs/editor/browser/services/bulkEditService.ts b/src/vs/editor/browser/services/bulkEditService.ts index 9411568fc79..1bbda5bf6ef 100644 --- a/src/vs/editor/browser/services/bulkEditService.ts +++ b/src/vs/editor/browser/services/bulkEditService.ts @@ -6,14 +6,14 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { WorkspaceEdit } from 'vs/editor/common/modes'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IProgressRunner } from 'vs/platform/progress/common/progress'; +import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress'; export const IBulkEditService = createDecorator('IWorkspaceEditService'); export interface IBulkEditOptions { editor?: ICodeEditor; - progress?: IProgressRunner; + progress?: IProgress; } export interface IBulkEditResult { diff --git a/src/vs/editor/browser/services/codeEditorServiceImpl.ts b/src/vs/editor/browser/services/codeEditorServiceImpl.ts index 7ad0bcc4078..f439007c476 100644 --- a/src/vs/editor/browser/services/codeEditorServiceImpl.ts +++ b/src/vs/editor/browser/services/codeEditorServiceImpl.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as dom from 'vs/base/browser/dom'; -import { IDisposable, dispose as disposeAll } from 'vs/base/common/lifecycle'; +import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import * as strings from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -17,18 +17,17 @@ import { ITheme, IThemeService, ThemeColor } from 'vs/platform/theme/common/them export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService { private readonly _styleSheet: HTMLStyleElement; - private readonly _decorationOptionProviders: { [key: string]: IModelDecorationOptionsProvider }; + private readonly _decorationOptionProviders = new Map(); private readonly _themeService: IThemeService; constructor(@IThemeService themeService: IThemeService, styleSheet = dom.createStyleSheet()) { super(); this._styleSheet = styleSheet; - this._decorationOptionProviders = Object.create(null); this._themeService = themeService; } public registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void { - let provider = this._decorationOptionProviders[key]; + let provider = this._decorationOptionProviders.get(key); if (!provider) { const providerArgs: ProviderArguments = { styleSheet: this._styleSheet, @@ -41,17 +40,17 @@ export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService { } else { provider = new DecorationSubTypeOptionsProvider(this._themeService, providerArgs); } - this._decorationOptionProviders[key] = provider; + this._decorationOptionProviders.set(key, provider); } provider.refCount++; } public removeDecorationType(key: string): void { - const provider = this._decorationOptionProviders[key]; + const provider = this._decorationOptionProviders.get(key); if (provider) { provider.refCount--; if (provider.refCount <= 0) { - delete this._decorationOptionProviders[key]; + this._decorationOptionProviders.delete(key); provider.dispose(); this.listCodeEditors().forEach((ed) => ed.removeDecorations(key)); } @@ -59,7 +58,7 @@ export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService { } public resolveDecorationOptions(decorationTypeKey: string, writable: boolean): IModelDecorationOptions { - const provider = this._decorationOptionProviders[decorationTypeKey]; + const provider = this._decorationOptionProviders.get(decorationTypeKey); if (!provider) { throw new Error('Unknown decoration type key: ' + decorationTypeKey); } @@ -124,7 +123,7 @@ interface ProviderArguments { class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider { - private _disposables: IDisposable[]; + private readonly _disposables = new DisposableStore(); public refCount: number; public className: string | undefined; @@ -139,11 +138,10 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider { constructor(themeService: IThemeService, providerArgs: ProviderArguments) { this.refCount = 0; - this._disposables = []; const createCSSRules = (type: ModelDecorationCSSRuleType) => { const rules = new DecorationCSSRules(type, providerArgs, themeService); - this._disposables.push(rules); + this._disposables.add(rules); if (rules.hasContent) { return rules.className; } @@ -151,7 +149,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider { }; const createInlineCSSRules = (type: ModelDecorationCSSRuleType) => { const rules = new DecorationCSSRules(type, providerArgs, themeService); - this._disposables.push(rules); + this._disposables.add(rules); if (rules.hasContent) { return { className: rules.className, hasLetterSpacing: rules.hasLetterSpacing }; } @@ -203,7 +201,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider { } public dispose(): void { - this._disposables = disposeAll(this._disposables); + this._disposables.dispose(); } } @@ -401,7 +399,7 @@ class DecorationCSSRules { if (typeof opts !== 'undefined') { this.collectBorderSettingsCSSText(opts, cssTextArr); if (typeof opts.contentIconPath !== 'undefined') { - cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, URI.revive(opts.contentIconPath).toString(true).replace(/'/g, '%27'))); + cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, dom.asDomUri(URI.revive(opts.contentIconPath)).toString(true).replace(/'/g, '%27'))); } if (typeof opts.contentText === 'string') { const truncated = opts.contentText.match(/^.*$/m)![0]; // only take first line @@ -428,7 +426,7 @@ class DecorationCSSRules { const cssTextArr: string[] = []; if (typeof opts.gutterIconPath !== 'undefined') { - cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, URI.revive(opts.gutterIconPath).toString(true).replace(/'/g, '%27'))); + cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, dom.asDomUri(URI.revive(opts.gutterIconPath)).toString(true).replace(/'/g, '%27'))); if (typeof opts.gutterIconSize !== 'undefined') { cssTextArr.push(strings.format(_CSS_MAP.gutterIconSize, opts.gutterIconSize)); } diff --git a/src/vs/editor/browser/viewParts/lines/rangeUtil.ts b/src/vs/editor/browser/viewParts/lines/rangeUtil.ts index 1561687a35e..5344effa706 100644 --- a/src/vs/editor/browser/viewParts/lines/rangeUtil.ts +++ b/src/vs/editor/browser/viewParts/lines/rangeUtil.ts @@ -126,7 +126,7 @@ export class RangeUtil { if (startChildIndex !== endChildIndex) { if (endChildIndex > 0 && endOffset === 0) { endChildIndex--; - endOffset = Number.MAX_VALUE; + endOffset = Constants.MAX_SAFE_SMALL_INTEGER; } } diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index 6dd6de47613..8184682f4ae 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -23,9 +23,10 @@ import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/v import { getOrCreateMinimapCharRenderer } from 'vs/editor/common/view/runtimeMinimapCharRenderer'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; -import { ViewLineData } from 'vs/editor/common/viewModel/viewModel'; +import { ViewLineData, ViewModelDecoration } from 'vs/editor/common/viewModel/viewModel'; import { scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { ModelDecorationMinimapOptions } from 'vs/editor/common/model/textModel'; function getMinimapLineHeight(renderMinimap: RenderMinimap): number { if (renderMinimap === RenderMinimap.Large) { @@ -335,10 +336,7 @@ class RenderData { * Check if the current RenderData matches accurately the new desired layout and no painting is needed. */ public linesEquals(layout: MinimapLayout): boolean { - if (this.renderedLayout.startLineNumber !== layout.startLineNumber) { - return false; - } - if (this.renderedLayout.endLineNumber !== layout.endLineNumber) { + if (!this.scrollEquals(layout)) { return false; } @@ -354,6 +352,14 @@ class RenderData { return true; } + /** + * Check if the current RenderData matches the new layout's scroll position + */ + public scrollEquals(layout: MinimapLayout): boolean { + return this.renderedLayout.startLineNumber === layout.startLineNumber + && this.renderedLayout.endLineNumber === layout.endLineNumber; + } + _get(): { imageData: ImageData; rendLineNumberStart: number; lines: MinimapLine[]; } { const tmp = this._renderedLines._get(); return { @@ -435,6 +441,7 @@ export class Minimap extends ViewPart { private readonly _domNode: FastDomNode; private readonly _shadow: FastDomNode; private readonly _canvas: FastDomNode; + private readonly _decorationsCanvas: FastDomNode; private readonly _slider: FastDomNode; private readonly _sliderHorizontal: FastDomNode; private readonly _tokensColorTracker: MinimapTokensColorTracker; @@ -444,6 +451,7 @@ export class Minimap extends ViewPart { private _options: MinimapOptions; private _lastRenderData: RenderData | null; + private _renderDecorations: boolean = false; private _buffers: MinimapBuffers | null; constructor(context: ViewContext) { @@ -469,6 +477,12 @@ export class Minimap extends ViewPart { this._canvas.setLeft(0); this._domNode.appendChild(this._canvas); + this._decorationsCanvas = createFastDomNode(document.createElement('canvas')); + this._decorationsCanvas.setPosition('absolute'); + this._decorationsCanvas.setClassName('minimap-decorations-layer'); + this._decorationsCanvas.setLeft(0); + this._domNode.appendChild(this._decorationsCanvas); + this._slider = createFastDomNode(document.createElement('div')); this._slider.setPosition('absolute'); this._slider.setClassName('minimap-slider'); @@ -484,7 +498,7 @@ export class Minimap extends ViewPart { this._applyLayout(); - this._mouseDownListener = dom.addStandardDisposableListener(this._canvas.domNode, 'mousedown', (e) => { + this._mouseDownListener = dom.addStandardDisposableListener(this._domNode.domNode, 'mousedown', (e) => { e.preventDefault(); const renderMinimap = this._options.renderMinimap; @@ -513,6 +527,7 @@ export class Minimap extends ViewPart { this._sliderMouseDownListener = dom.addStandardDisposableListener(this._slider.domNode, 'mousedown', (e) => { e.preventDefault(); + e.stopPropagation(); if (e.leftButton && this._lastRenderData) { const initialMousePosition = e.posy; @@ -569,10 +584,17 @@ export class Minimap extends ViewPart { this._domNode.setWidth(this._options.minimapWidth); this._domNode.setHeight(this._options.minimapHeight); this._shadow.setHeight(this._options.minimapHeight); + this._canvas.setWidth(this._options.canvasOuterWidth); this._canvas.setHeight(this._options.canvasOuterHeight); this._canvas.domNode.width = this._options.canvasInnerWidth; this._canvas.domNode.height = this._options.canvasInnerHeight; + + this._decorationsCanvas.setWidth(this._options.canvasOuterWidth); + this._decorationsCanvas.setHeight(this._options.canvasOuterHeight); + this._decorationsCanvas.domNode.width = this._options.canvasInnerWidth; + this._decorationsCanvas.domNode.height = this._options.canvasInnerHeight; + this._slider.setWidth(this._options.minimapWidth); } @@ -629,6 +651,7 @@ export class Minimap extends ViewPart { return true; } public onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean { + this._renderDecorations = true; return true; } public onTokensChanged(e: viewEvents.ViewTokensChangedEvent): boolean { @@ -647,6 +670,11 @@ export class Minimap extends ViewPart { return true; } + public onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean { + this._renderDecorations = true; + return true; + } + // --- end event handlers public prepareRender(ctx: RenderingContext): void { @@ -689,9 +717,105 @@ export class Minimap extends ViewPart { this._sliderHorizontal.setTop(0); this._sliderHorizontal.setHeight(layout.sliderHeight); + this.renderDecorations(layout); this._lastRenderData = this.renderLines(layout); } + private renderDecorations(layout: MinimapLayout) { + if (this._renderDecorations) { + this._renderDecorations = false; + const decorations = this._context.model.getDecorationsInViewport(new Range(layout.startLineNumber, 1, layout.endLineNumber, this._context.model.getLineMaxColumn(layout.endLineNumber))); + + const { renderMinimap, canvasInnerWidth, canvasInnerHeight } = this._options; + const lineHeight = getMinimapLineHeight(renderMinimap); + const characterWidth = getMinimapCharWidth(renderMinimap); + const tabSize = this._context.model.getOptions().tabSize; + const canvasContext = this._decorationsCanvas.domNode.getContext('2d')!; + + canvasContext.clearRect(0, 0, canvasInnerWidth, canvasInnerHeight); + + // If the minimap is rendered using blocks, text takes up half the line height + const lineHeightRatio = renderMinimap === RenderMinimap.LargeBlocks || renderMinimap === RenderMinimap.SmallBlocks ? 0.5 : 1; + const height = lineHeight * lineHeightRatio; + + // Loop over decorations, ignoring those that don't have the minimap property set and rendering rectangles for each line the decoration spans + const lineOffsetMap = new Map(); + for (let i = 0; i < decorations.length; i++) { + const decoration = decorations[i]; + + if (!decoration.options.minimap) { + continue; + } + + for (let line = decoration.range.startLineNumber; line <= decoration.range.endLineNumber; line++) { + this.renderDecorationOnLine(canvasContext, lineOffsetMap, decoration, layout, line, height, lineHeight, tabSize, characterWidth); + } + } + } + } + + private renderDecorationOnLine(canvasContext: CanvasRenderingContext2D, + lineOffsetMap: Map, + decoration: ViewModelDecoration, + layout: MinimapLayout, + lineNumber: number, + height: number, + lineHeight: number, + tabSize: number, + charWidth: number): void { + const y = (lineNumber - layout.startLineNumber) * lineHeight; + + // Cache line offset data so that it is only read once per line + let lineIndexToXOffset = lineOffsetMap.get(lineNumber); + const isFirstDecorationForLine = !lineIndexToXOffset; + if (!lineIndexToXOffset) { + const lineData = this._context.model.getLineContent(lineNumber); + lineIndexToXOffset = [0]; + for (let i = 1; i < lineData.length + 1; i++) { + const charCode = lineData.charCodeAt(i - 1); + const dx = charCode === CharCode.Tab + ? tabSize * charWidth + : strings.isFullWidthCharacter(charCode) + ? 2 * charWidth + : charWidth; + + lineIndexToXOffset[i] = lineIndexToXOffset[i - 1] + dx; + } + + lineOffsetMap.set(lineNumber, lineIndexToXOffset); + } + + const { startColumn, endColumn, startLineNumber, endLineNumber } = decoration.range; + const x = startLineNumber === lineNumber ? lineIndexToXOffset[startColumn - 1] : 0; + + const endColumnForLine = endLineNumber > lineNumber ? lineIndexToXOffset.length - 1 : endColumn - 1; + + if (endColumnForLine > 0) { + // If the decoration starts at the last character of the column and spans over it, ensure it has a width + const width = lineIndexToXOffset[endColumnForLine] - x || 2; + + this.renderDecoration(canvasContext, decoration.options.minimap, x, y, width, height); + } + + if (isFirstDecorationForLine) { + this.renderLineHighlight(canvasContext, decoration.options.minimap, y, height); + } + + } + + private renderLineHighlight(canvasContext: CanvasRenderingContext2D, minimapOptions: ModelDecorationMinimapOptions, y: number, height: number): void { + const decorationColor = minimapOptions.getColor(this._context.theme); + canvasContext.fillStyle = decorationColor && decorationColor.transparent(0.5).toString() || ''; + canvasContext.fillRect(0, y, canvasContext.canvas.width, height); + } + + private renderDecoration(canvasContext: CanvasRenderingContext2D, minimapOptions: ModelDecorationMinimapOptions, x: number, y: number, width: number, height: number) { + const decorationColor = minimapOptions.getColor(this._context.theme); + + canvasContext.fillStyle = decorationColor && decorationColor.toString() || ''; + canvasContext.fillRect(x, y, width, height); + } + private renderLines(layout: MinimapLayout): RenderData { const renderMinimap = this._options.renderMinimap; const startLineNumber = layout.startLineNumber; diff --git a/src/vs/workbench/browser/media/images/panel/add-alt1.svg b/src/vs/editor/browser/widget/media/addition-dark.svg similarity index 63% rename from src/vs/workbench/browser/media/images/panel/add-alt1.svg rename to src/vs/editor/browser/widget/media/addition-dark.svg index fb50c6c2849..4d9389336b9 100644 --- a/src/vs/workbench/browser/media/images/panel/add-alt1.svg +++ b/src/vs/editor/browser/widget/media/addition-dark.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/editor/browser/widget/media/addition-inverse.svg b/src/vs/editor/browser/widget/media/addition-inverse.svg deleted file mode 100644 index 3475c1e1963..00000000000 --- a/src/vs/editor/browser/widget/media/addition-inverse.svg +++ /dev/null @@ -1 +0,0 @@ -Layer 1 \ No newline at end of file diff --git a/src/vs/workbench/contrib/debug/browser/media/reverse-continue-inverse.svg b/src/vs/editor/browser/widget/media/addition-light.svg similarity index 61% rename from src/vs/workbench/contrib/debug/browser/media/reverse-continue-inverse.svg rename to src/vs/editor/browser/widget/media/addition-light.svg index 5eb56cfd7b2..01a9de7d5ab 100644 --- a/src/vs/workbench/contrib/debug/browser/media/reverse-continue-inverse.svg +++ b/src/vs/editor/browser/widget/media/addition-light.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/editor/browser/widget/media/addition.svg b/src/vs/editor/browser/widget/media/addition.svg deleted file mode 100644 index bdecdb0e45b..00000000000 --- a/src/vs/editor/browser/widget/media/addition.svg +++ /dev/null @@ -1 +0,0 @@ -Layer 1 \ No newline at end of file diff --git a/src/vs/workbench/browser/media/images/search/stop-alt1.svg b/src/vs/editor/browser/widget/media/deletion-dark.svg similarity index 64% rename from src/vs/workbench/browser/media/images/search/stop-alt1.svg rename to src/vs/editor/browser/widget/media/deletion-dark.svg index 52f3aa26ce2..4c5a9c1e3a5 100644 --- a/src/vs/workbench/browser/media/images/search/stop-alt1.svg +++ b/src/vs/editor/browser/widget/media/deletion-dark.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/editor/browser/widget/media/deletion-inverse.svg b/src/vs/editor/browser/widget/media/deletion-inverse.svg deleted file mode 100644 index 2de46fcf5b5..00000000000 --- a/src/vs/editor/browser/widget/media/deletion-inverse.svg +++ /dev/null @@ -1 +0,0 @@ -Layer 1 \ No newline at end of file diff --git a/src/vs/workbench/browser/media/images/git/stage-alt1.svg b/src/vs/editor/browser/widget/media/deletion-light.svg similarity index 63% rename from src/vs/workbench/browser/media/images/git/stage-alt1.svg rename to src/vs/editor/browser/widget/media/deletion-light.svg index fb50c6c2849..d12a8ee3135 100644 --- a/src/vs/workbench/browser/media/images/git/stage-alt1.svg +++ b/src/vs/editor/browser/widget/media/deletion-light.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/editor/browser/widget/media/deletion.svg b/src/vs/editor/browser/widget/media/deletion.svg deleted file mode 100644 index f5d128b2df8..00000000000 --- a/src/vs/editor/browser/widget/media/deletion.svg +++ /dev/null @@ -1 +0,0 @@ -Layer 1 \ No newline at end of file diff --git a/src/vs/editor/browser/widget/media/diffEditor.css b/src/vs/editor/browser/widget/media/diffEditor.css index 5e71f38a9bd..d70b8b88043 100644 --- a/src/vs/editor/browser/widget/media/diffEditor.css +++ b/src/vs/editor/browser/widget/media/diffEditor.css @@ -40,8 +40,7 @@ background-size: 60%; opacity: 0.7; background-repeat: no-repeat; - background-position: 50% 50%; - background-position: center; + background-position: 75% center; background-size: 11px 11px; } .monaco-editor.hc-black .insert-sign, @@ -52,24 +51,24 @@ } .monaco-editor .insert-sign, .monaco-diff-editor .insert-sign { - background-image: url('addition.svg'); + background-image: url('addition-light.svg'); } .monaco-editor .delete-sign, .monaco-diff-editor .delete-sign { - background-image: url('deletion.svg'); + background-image: url('deletion-light.svg'); } .monaco-editor.vs-dark .insert-sign, .monaco-diff-editor.vs-dark .insert-sign, .monaco-editor.hc-black .insert-sign, .monaco-diff-editor.hc-black .insert-sign { - background-image: url('addition-inverse.svg'); + background-image: url('addition-dark.svg'); } .monaco-editor.vs-dark .delete-sign, .monaco-diff-editor.vs-dark .delete-sign, .monaco-editor.hc-black .delete-sign, .monaco-diff-editor.hc-black .delete-sign { - background-image: url('deletion-inverse.svg'); + background-image: url('deletion-dark.svg'); } .monaco-editor .inline-deleted-margin-view-zone { diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 3752591e93f..5866654f0ca 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -153,8 +153,8 @@ export abstract class CommonEditorConfiguration extends Disposable implements ed return true; } - private static _subsetEquals(base: object, subset: object): boolean { - for (let key in subset) { + private static _subsetEquals(base: { [key: string]: any }, subset: { [key: string]: any }): boolean { + for (const key in subset) { if (hasOwnProperty.call(subset, key)) { const subsetValue = subset[key]; const baseValue = base[key]; diff --git a/src/vs/editor/common/core/position.ts b/src/vs/editor/common/core/position.ts index 4c711e9142c..e9f64d97b72 100644 --- a/src/vs/editor/common/core/position.ts +++ b/src/vs/editor/common/core/position.ts @@ -36,7 +36,7 @@ export class Position { } /** - * Create a new postion from this position. + * Create a new position from this position. * * @param newLineNumber new line number * @param newColumn new column diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index ebc34ca227f..3de16ed77a4 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -26,25 +26,45 @@ export enum OverviewRulerLane { } /** - * Options for rendering a model decoration in the overview ruler. + * Position in the minimap to render the decoration. */ -export interface IModelDecorationOverviewRulerOptions { +export enum MinimapPosition { + Inline = 1 +} + +export interface IDecorationOptions { /** - * CSS color to render in the overview ruler. + * CSS color to render. * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry */ color: string | ThemeColor | undefined; /** - * CSS color to render in the overview ruler. + * CSS color to render. * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry */ darkColor?: string | ThemeColor; +} + +/** + * Options for rendering a model decoration in the overview ruler. + */ +export interface IModelDecorationOverviewRulerOptions extends IDecorationOptions { /** * The position in the overview ruler. */ position: OverviewRulerLane; } +/** + * Options for rendering a model decoration in the overview ruler. + */ +export interface IModelDecorationMinimapOptions extends IDecorationOptions { + /** + * The position in the overview ruler. + */ + position: MinimapPosition; +} + /** * Options for a model decoration. */ @@ -89,6 +109,10 @@ export interface IModelDecorationOptions { * If set, render this decoration in the overview ruler. */ overviewRuler?: IModelDecorationOverviewRulerOptions | null; + /** + * If set, render this decoration in the minimap. + */ + minimap?: IModelDecorationMinimapOptions | null; /** * If set, the decoration will be rendered in the glyph margin with this CSS class name. */ @@ -759,7 +783,7 @@ export interface ITextModel { * Flush all tokenization state. * @internal */ - flushTokens(): void; + resetTokenization(): void; /** * Force tokenization information for `lineNumber` to be accurate. @@ -1092,6 +1116,12 @@ export interface ITextModel { * @internal */ onDidChangeTokens(listener: (e: IModelTokensChangedEvent) => void): IDisposable; + /** + * An event emitted when the model has been attached to the first editor or detached from the last editor. + * @event + * @internal + */ + onDidChangeAttached(listener: () => void): IDisposable; /** * An event emitted right before disposing the model. * @event diff --git a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts index 04de0bc01fc..445ddde972f 100644 --- a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts +++ b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts @@ -611,25 +611,25 @@ export class PieceTreeBase { let resultLen = 0; const searcher = new Searcher(searchData.wordSeparators, searchData.regex); - let startPostion = this.nodeAt2(searchRange.startLineNumber, searchRange.startColumn); - if (startPostion === null) { + let startPosition = this.nodeAt2(searchRange.startLineNumber, searchRange.startColumn); + if (startPosition === null) { return []; } let endPosition = this.nodeAt2(searchRange.endLineNumber, searchRange.endColumn); if (endPosition === null) { return []; } - let start = this.positionInBuffer(startPostion.node, startPostion.remainder); + let start = this.positionInBuffer(startPosition.node, startPosition.remainder); let end = this.positionInBuffer(endPosition.node, endPosition.remainder); - if (startPostion.node === endPosition.node) { - this.findMatchesInNode(startPostion.node, searcher, searchRange.startLineNumber, searchRange.startColumn, start, end, searchData, captureMatches, limitResultCount, resultLen, result); + if (startPosition.node === endPosition.node) { + this.findMatchesInNode(startPosition.node, searcher, searchRange.startLineNumber, searchRange.startColumn, start, end, searchData, captureMatches, limitResultCount, resultLen, result); return result; } let startLineNumber = searchRange.startLineNumber; - let currentNode = startPostion.node; + let currentNode = startPosition.node; while (currentNode !== endPosition.node) { let lineBreakCnt = this.getLineFeedCnt(currentNode.piece.bufferIndex, start, currentNode.piece.end); @@ -663,9 +663,9 @@ export class PieceTreeBase { } startLineNumber++; - startPostion = this.nodeAt2(startLineNumber, 1); - currentNode = startPostion.node; - start = this.positionInBuffer(startPostion.node, startPostion.remainder); + startPosition = this.nodeAt2(startLineNumber, 1); + currentNode = startPosition.node; + start = this.positionInBuffer(startPosition.node, startPosition.remainder); } if (startLineNumber === searchRange.endLineNumber) { diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 2a640ac9d01..c8b89e889cf 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -8,7 +8,6 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { IMarkdownString } from 'vs/base/common/htmlContent'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; -import { StopWatch } from 'vs/base/common/stopwatch'; import * as strings from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/config/editorOptions'; @@ -23,9 +22,9 @@ import { IntervalNode, IntervalTree, getNodeIsInOverviewRuler, recomputeMaxEnd } import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder'; import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent, IModelTokensChangedEvent, InternalModelContentChangeEvent, ModelRawChange, ModelRawContentChangedEvent, ModelRawEOLChanged, ModelRawFlush, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/model/textModelEvents'; import { SearchData, SearchParams, TextModelSearch } from 'vs/editor/common/model/textModelSearch'; -import { ModelLinesTokens, ModelTokensChangedEventBuilder } from 'vs/editor/common/model/textModelTokens'; +import { TextModelTokenization, countEOL } from 'vs/editor/common/model/textModelTokens'; import { getWordAtText } from 'vs/editor/common/model/wordHelper'; -import { IState, LanguageId, LanguageIdentifier, TokenizationRegistry, FormattingOptions } from 'vs/editor/common/modes'; +import { LanguageId, LanguageIdentifier, FormattingOptions } from 'vs/editor/common/modes'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { NULL_LANGUAGE_IDENTIFIER } from 'vs/editor/common/modes/nullMode'; import { ignoreBracketsInToken } from 'vs/editor/common/modes/supports'; @@ -33,8 +32,8 @@ import { BracketsUtils, RichEditBracket, RichEditBrackets } from 'vs/editor/comm import { ITheme, ThemeColor } from 'vs/platform/theme/common/themeService'; import { withUndefinedAsNull } from 'vs/base/common/types'; import { VSBufferReadableStream, VSBuffer } from 'vs/base/common/buffer'; - -const CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048; +import { TokensStore, MultilineTokens } from 'vs/editor/common/model/tokensStore'; +import { Color } from 'vs/base/common/color'; function createTextBufferBuilder() { return new PieceTreeTextBufferBuilder(); @@ -235,6 +234,9 @@ export class TextModel extends Disposable implements model.ITextModel { private readonly _onDidChangeOptions: Emitter = this._register(new Emitter()); public readonly onDidChangeOptions: Event = this._onDidChangeOptions.event; + private readonly _onDidChangeAttached: Emitter = this._register(new Emitter()); + public readonly onDidChangeAttached: Event = this._onDidChangeAttached.event; + private readonly _eventEmitter: DidChangeContentEmitter = this._register(new DidChangeContentEmitter()); public onDidChangeRawContentFast(listener: (e: ModelRawContentChangedEvent) => void): IDisposable { return this._eventEmitter.fastEvent((e: InternalModelContentChangeEvent) => listener(e.rawContentChangedEvent)); @@ -242,6 +244,9 @@ export class TextModel extends Disposable implements model.ITextModel { public onDidChangeRawContent(listener: (e: ModelRawContentChangedEvent) => void): IDisposable { return this._eventEmitter.slowEvent((e: InternalModelContentChangeEvent) => listener(e.rawContentChangedEvent)); } + public onDidChangeContentFast(listener: (e: IModelContentChangedEvent) => void): IDisposable { + return this._eventEmitter.fastEvent((e: InternalModelContentChangeEvent) => listener(e.contentChangedEvent)); + } public onDidChangeContent(listener: (e: IModelContentChangedEvent) => void): IDisposable { return this._eventEmitter.slowEvent((e: InternalModelContentChangeEvent) => listener(e.contentChangedEvent)); } @@ -284,10 +289,9 @@ export class TextModel extends Disposable implements model.ITextModel { //#region Tokenization private _languageIdentifier: LanguageIdentifier; - private readonly _tokenizationListener: IDisposable; private readonly _languageRegistryListener: IDisposable; - private _revalidateTokensTimeout: any; - /*private*/_tokens: ModelLinesTokens; + private readonly _tokens: TokensStore; + private readonly _tokenization: TextModelTokenization; //#endregion constructor(source: string | model.ITextBufferFactory, creationOptions: model.ITextModelCreationOptions, languageIdentifier: LanguageIdentifier | null, associatedResource: URI | null = null) { @@ -330,31 +334,12 @@ export class TextModel extends Disposable implements model.ITextModel { this._isDisposing = false; this._languageIdentifier = languageIdentifier || NULL_LANGUAGE_IDENTIFIER; - this._tokenizationListener = TokenizationRegistry.onDidChange((e) => { - if (e.changedLanguages.indexOf(this._languageIdentifier.language) === -1) { - return; - } - this._resetTokenizationState(); - this.emitModelTokensChangedEvent({ - tokenizationSupportChanged: true, - ranges: [{ - fromLineNumber: 1, - toLineNumber: this.getLineCount() - }] - }); - - if (this._shouldAutoTokenize()) { - this._warmUpTokens(); - } - }); - this._revalidateTokensTimeout = -1; this._languageRegistryListener = LanguageConfigurationRegistry.onDidChange((e) => { if (e.languageIdentifier.id === this._languageIdentifier.id) { this._onDidChangeLanguageConfiguration.fire({}); } }); - this._resetTokenizationState(); this._instanceId = singleLetter(MODEL_ID); this._lastDecorationId = 0; @@ -365,16 +350,17 @@ export class TextModel extends Disposable implements model.ITextModel { this._isUndoing = false; this._isRedoing = false; this._trimAutoWhitespaceLines = null; + + this._tokens = new TokensStore(); + this._tokenization = new TextModelTokenization(this); } public dispose(): void { this._isDisposing = true; this._onWillDispose.fire(); - this._tokenizationListener.dispose(); this._languageRegistryListener.dispose(); - this._clearTimers(); + this._tokenization.dispose(); this._isDisposed = true; - // Null out members, such that any use of a disposed model will throw exceptions sooner rather than later super.dispose(); this._isDisposing = false; } @@ -439,8 +425,8 @@ export class TextModel extends Disposable implements model.ITextModel { this._buffer = textBuffer; this._increaseVersionId(); - // Cancel tokenization, clear all tokens and begin tokenizing - this._resetTokenizationState(); + // Flush all tokens + this._tokens.flush(); // Destroy all my decorations this._decorations = Object.create(null); @@ -524,36 +510,18 @@ export class TextModel extends Disposable implements model.ITextModel { } } - private _resetTokenizationState(): void { - this._clearTimers(); - let tokenizationSupport = ( - this._isTooLargeForTokenization - ? null - : TokenizationRegistry.get(this._languageIdentifier.language) - ); - this._tokens = new ModelLinesTokens(this._languageIdentifier, tokenizationSupport); - this._beginBackgroundTokenization(); - } - - private _clearTimers(): void { - if (this._revalidateTokensTimeout !== -1) { - clearTimeout(this._revalidateTokensTimeout); - this._revalidateTokensTimeout = -1; - } - } - public onBeforeAttached(): void { this._attachedEditorCount++; - // Warm up tokens for the editor - this._warmUpTokens(); + if (this._attachedEditorCount === 1) { + this._onDidChangeAttached.fire(undefined); + } } public onBeforeDetached(): void { this._attachedEditorCount--; - } - - private _shouldAutoTokenize(): boolean { - return this.isAttachedToEditor(); + if (this._attachedEditorCount === 0) { + this._onDidChangeAttached.fire(undefined); + } } public isAttachedToEditor(): boolean { @@ -1292,36 +1260,6 @@ export class TextModel extends Disposable implements model.ITextModel { } } - private static _eolCount(text: string): [number, number] { - let eolCount = 0; - let firstLineLength = 0; - for (let i = 0, len = text.length; i < len; i++) { - const chr = text.charCodeAt(i); - - if (chr === CharCode.CarriageReturn) { - if (eolCount === 0) { - firstLineLength = i; - } - eolCount++; - if (i + 1 < len && text.charCodeAt(i + 1) === CharCode.LineFeed) { - // \r\n... case - i++; // skip \n - } else { - // \r... case - } - } else if (chr === CharCode.LineFeed) { - if (eolCount === 0) { - firstLineLength = i; - } - eolCount++; - } - } - if (eolCount === 0) { - firstLineLength = text.length; - } - return [eolCount, firstLineLength]; - } - private _applyEdits(rawOperations: model.IIdentifiedSingleEditOperation[]): model.IIdentifiedSingleEditOperation[] { for (let i = 0, len = rawOperations.length; i < len; i++) { rawOperations[i].range = this.validateRange(rawOperations[i].range); @@ -1340,13 +1278,8 @@ export class TextModel extends Disposable implements model.ITextModel { let lineCount = oldLineCount; for (let i = 0, len = contentChanges.length; i < len; i++) { const change = contentChanges[i]; - const [eolCount, firstLineLength] = TextModel._eolCount(change.text); - try { - this._tokens.applyEdits(change.range, eolCount, firstLineLength); - } catch (err) { - // emergency recovery => reset tokens - this._tokens = new ModelLinesTokens(this._tokens.languageIdentifier, this._tokens.tokenizationSupport); - } + const [eolCount, firstLineLength] = countEOL(change.text); + this._tokens.applyEdits(change.range, eolCount, firstLineLength); this._onDidChangeDecorations.fire(); this._decorationsTree.acceptReplace(change.rangeOffset, change.rangeLength, change.text.length, change.forceMoveMarkers); @@ -1407,10 +1340,6 @@ export class TextModel extends Disposable implements model.ITextModel { ); } - if (this._tokens.hasLinesToTokenize(this._buffer)) { - this._beginBackgroundTokenization(); - } - return result.reverseEdits; } @@ -1775,93 +1704,60 @@ export class TextModel extends Disposable implements model.ITextModel { //#region Tokenization + public setLineTokens(lineNumber: number, tokens: Uint32Array): void { + if (lineNumber < 1 || lineNumber > this.getLineCount()) { + throw new Error('Illegal value for lineNumber'); + } + + this._tokens.setTokens(this._languageIdentifier.id, lineNumber - 1, this._buffer.getLineLength(lineNumber), tokens); + } + + public setTokens(tokens: MultilineTokens[]): void { + if (tokens.length === 0) { + return; + } + + let ranges: { fromLineNumber: number; toLineNumber: number; }[] = []; + + for (let i = 0, len = tokens.length; i < len; i++) { + const element = tokens[i]; + ranges.push({ fromLineNumber: element.startLineNumber, toLineNumber: element.startLineNumber + element.tokens.length - 1 }); + for (let j = 0, lenJ = element.tokens.length; j < lenJ; j++) { + this.setLineTokens(element.startLineNumber + j, element.tokens[j]); + } + } + + this._emitModelTokensChangedEvent({ + tokenizationSupportChanged: false, + ranges: ranges + }); + } + public tokenizeViewport(startLineNumber: number, endLineNumber: number): void { - if (!this._tokens.tokenizationSupport) { - // nothing to do - return; - } - startLineNumber = Math.max(1, startLineNumber); - endLineNumber = Math.min(this.getLineCount(), endLineNumber); + endLineNumber = Math.min(this._buffer.getLineCount(), endLineNumber); + this._tokenization.tokenizeViewport(startLineNumber, endLineNumber); + } - if (endLineNumber <= this._tokens.inValidLineStartIndex) { - // nothing to do - return; - } + public clearTokens(): void { + this._tokens.flush(); + this._emitModelTokensChangedEvent({ + tokenizationSupportChanged: true, + ranges: [{ + fromLineNumber: 1, + toLineNumber: this._buffer.getLineCount() + }] + }); + } - if (startLineNumber <= this._tokens.inValidLineStartIndex) { - // tokenization has reached the viewport start... - this.forceTokenization(endLineNumber); - return; - } - - let nonWhitespaceColumn = this.getLineFirstNonWhitespaceColumn(startLineNumber); - let fakeLines: string[] = []; - let initialState: IState | null = null; - for (let i = startLineNumber - 1; nonWhitespaceColumn > 0 && i >= 1; i--) { - let newNonWhitespaceIndex = this.getLineFirstNonWhitespaceColumn(i); - - if (newNonWhitespaceIndex === 0) { - continue; - } - - if (newNonWhitespaceIndex < nonWhitespaceColumn) { - initialState = this._tokens._getState(i - 1); - if (initialState) { - break; - } - fakeLines.push(this.getLineContent(i)); - nonWhitespaceColumn = newNonWhitespaceIndex; - } - } - - if (!initialState) { - initialState = this._tokens.tokenizationSupport.getInitialState(); - } - - let state = initialState.clone(); - for (let i = fakeLines.length - 1; i >= 0; i--) { - let r = this._tokens._tokenizeText(this._buffer, fakeLines[i], state); - if (r) { - state = r.endState.clone(); - } else { - state = initialState.clone(); - } - } - - const eventBuilder = new ModelTokensChangedEventBuilder(); - for (let i = startLineNumber; i <= endLineNumber; i++) { - let text = this.getLineContent(i); - let r = this._tokens._tokenizeText(this._buffer, text, state); - if (r) { - this._tokens._setTokens(this._tokens.languageIdentifier.id, i - 1, text.length, r.tokens); - - // We cannot trust these states/tokens to be valid! - // (see https://github.com/Microsoft/vscode/issues/67607) - this._tokens._setIsInvalid(i - 1, true); - this._tokens._setState(i - 1, state); - state = r.endState.clone(); - eventBuilder.registerChangedTokens(i); - } else { - state = initialState.clone(); - } - } - - const e = eventBuilder.build(); - if (e) { + private _emitModelTokensChangedEvent(e: IModelTokensChangedEvent): void { + if (!this._isDisposing) { this._onDidChangeTokens.fire(e); } } - public flushTokens(): void { - this._resetTokenizationState(); - this.emitModelTokensChangedEvent({ - tokenizationSupportChanged: false, - ranges: [{ - fromLineNumber: 1, - toLineNumber: this.getLineCount() - }] - }); + public resetTokenization(): void { + this._tokenization.reset(); } public forceTokenization(lineNumber: number): void { @@ -1869,30 +1765,11 @@ export class TextModel extends Disposable implements model.ITextModel { throw new Error('Illegal value for lineNumber'); } - const eventBuilder = new ModelTokensChangedEventBuilder(); - - this._tokens._updateTokensUntilLine(this._buffer, eventBuilder, lineNumber); - - const e = eventBuilder.build(); - if (e) { - this._onDidChangeTokens.fire(e); - } + this._tokenization.forceTokenization(lineNumber); } public isCheapToTokenize(lineNumber: number): boolean { - if (!this._tokens.isCheapToTokenize(lineNumber)) { - return false; - } - - if (lineNumber < this._tokens.inValidLineStartIndex + 1) { - return true; - } - - if (this.getLineLength(lineNumber) < CHEAP_TOKENIZATION_LENGTH_LIMIT) { - return true; - } - - return false; + return this._tokenization.isCheapToTokenize(lineNumber); } public tokenizeIfCheap(lineNumber: number): void { @@ -1910,7 +1787,7 @@ export class TextModel extends Disposable implements model.ITextModel { } private _getLineTokens(lineNumber: number): LineTokens { - const lineText = this._buffer.getLineContent(lineNumber); + const lineText = this.getLineContent(lineNumber); return this._tokens.getTokens(this._languageIdentifier.id, lineNumber - 1, lineText); } @@ -1935,81 +1812,14 @@ export class TextModel extends Disposable implements model.ITextModel { this._languageIdentifier = languageIdentifier; - // Cancel tokenization, clear all tokens and begin tokenizing - this._resetTokenizationState(); - - this.emitModelTokensChangedEvent({ - tokenizationSupportChanged: true, - ranges: [{ - fromLineNumber: 1, - toLineNumber: this.getLineCount() - }] - }); this._onDidChangeLanguage.fire(e); this._onDidChangeLanguageConfiguration.fire({}); } - public getLanguageIdAtPosition(_lineNumber: number, _column: number): LanguageId { - if (!this._tokens.tokenizationSupport) { - return this._languageIdentifier.id; - } - let { lineNumber, column } = this.validatePosition({ lineNumber: _lineNumber, column: _column }); - - let lineTokens = this._getLineTokens(lineNumber); - return lineTokens.getLanguageId(lineTokens.findTokenIndexAtOffset(column - 1)); - } - - private _beginBackgroundTokenization(): void { - if (this._shouldAutoTokenize() && this._revalidateTokensTimeout === -1) { - this._revalidateTokensTimeout = setTimeout(() => { - this._revalidateTokensTimeout = -1; - this._revalidateTokensNow(); - }, 0); - } - } - - _warmUpTokens(): void { - // Warm up first 100 lines (if it takes less than 50ms) - const maxLineNumber = Math.min(100, this.getLineCount()); - this._revalidateTokensNow(maxLineNumber); - - if (this._tokens.hasLinesToTokenize(this._buffer)) { - this._beginBackgroundTokenization(); - } - } - - private _revalidateTokensNow(toLineNumber: number = this._buffer.getLineCount()): void { - const MAX_ALLOWED_TIME = 20; - const eventBuilder = new ModelTokensChangedEventBuilder(); - const sw = StopWatch.create(false); - - while (this._tokens.hasLinesToTokenize(this._buffer)) { - if (sw.elapsed() > MAX_ALLOWED_TIME) { - // Stop if MAX_ALLOWED_TIME is reached - break; - } - - const tokenizedLineNumber = this._tokens._tokenizeOneLine(this._buffer, eventBuilder); - - if (tokenizedLineNumber >= toLineNumber) { - break; - } - } - - if (this._tokens.hasLinesToTokenize(this._buffer)) { - this._beginBackgroundTokenization(); - } - - const e = eventBuilder.build(); - if (e) { - this._onDidChangeTokens.fire(e); - } - } - - private emitModelTokensChangedEvent(e: IModelTokensChangedEvent): void { - if (!this._isDisposing) { - this._onDidChangeTokens.fire(e); - } + public getLanguageIdAtPosition(lineNumber: number, column: number): LanguageId { + const position = this.validatePosition(new Position(lineNumber, column)); + const lineTokens = this.getLineTokens(position.lineNumber); + return lineTokens.getLanguageId(lineTokens.findTokenIndexAtOffset(position.column - 1)); } // Having tokens allows implementing additional helper methods @@ -2823,17 +2633,25 @@ function cleanClassName(className: string): string { return className.replace(/[^a-z0-9\-_]/gi, ' '); } -export class ModelDecorationOverviewRulerOptions implements model.IModelDecorationOverviewRulerOptions { +class DecorationOptions implements model.IDecorationOptions { readonly color: string | ThemeColor; readonly darkColor: string | ThemeColor; + + constructor(options: model.IDecorationOptions) { + this.color = options.color || strings.empty; + this.darkColor = options.darkColor || strings.empty; + + } +} + +export class ModelDecorationOverviewRulerOptions extends DecorationOptions { readonly position: model.OverviewRulerLane; private _resolvedColor: string | null; constructor(options: model.IModelDecorationOverviewRulerOptions) { - this.color = options.color || strings.empty; - this.darkColor = options.darkColor || strings.empty; - this.position = (typeof options.position === 'number' ? options.position : model.OverviewRulerLane.Center); + super(options); this._resolvedColor = null; + this.position = (typeof options.position === 'number' ? options.position : model.OverviewRulerLane.Center); } public getColor(theme: ITheme): string { @@ -2863,6 +2681,36 @@ export class ModelDecorationOverviewRulerOptions implements model.IModelDecorati } } +export class ModelDecorationMinimapOptions extends DecorationOptions { + readonly position: model.MinimapPosition; + private _resolvedColor: Color | undefined; + + + constructor(options: model.IModelDecorationMinimapOptions) { + super(options); + this.position = options.position; + } + + public getColor(theme: ITheme): Color | undefined { + if (!this._resolvedColor) { + if (theme.type !== 'light' && this.darkColor) { + this._resolvedColor = this._resolveColor(this.darkColor, theme); + } else { + this._resolvedColor = this._resolveColor(this.color, theme); + } + } + + return this._resolvedColor; + } + + private _resolveColor(color: string | ThemeColor, theme: ITheme): Color | undefined { + if (typeof color === 'string') { + return Color.fromHex(color); + } + return theme.getColor(color.id); + } +} + export class ModelDecorationOptions implements model.IModelDecorationOptions { public static EMPTY: ModelDecorationOptions; @@ -2884,6 +2732,7 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions { readonly showIfCollapsed: boolean; readonly collapseOnReplaceEdit: boolean; readonly overviewRuler: ModelDecorationOverviewRulerOptions | null; + readonly minimap: ModelDecorationMinimapOptions | null; readonly glyphMarginClassName: string | null; readonly linesDecorationsClassName: string | null; readonly marginClassName: string | null; @@ -2902,6 +2751,7 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions { this.showIfCollapsed = options.showIfCollapsed || false; this.collapseOnReplaceEdit = options.collapseOnReplaceEdit || false; this.overviewRuler = options.overviewRuler ? new ModelDecorationOverviewRulerOptions(options.overviewRuler) : null; + this.minimap = options.minimap ? new ModelDecorationMinimapOptions(options.minimap) : null; this.glyphMarginClassName = options.glyphMarginClassName ? cleanClassName(options.glyphMarginClassName) : null; this.linesDecorationsClassName = options.linesDecorationsClassName ? cleanClassName(options.linesDecorationsClassName) : null; this.marginClassName = options.marginClassName ? cleanClassName(options.marginClassName) : null; diff --git a/src/vs/editor/common/model/textModelTokens.ts b/src/vs/editor/common/model/textModelTokens.ts index 8387872c18f..b959ba7a1b6 100644 --- a/src/vs/editor/common/model/textModelTokens.ts +++ b/src/vs/editor/common/model/textModelTokens.ts @@ -7,501 +7,486 @@ import * as arrays from 'vs/base/common/arrays'; import { onUnexpectedError } from 'vs/base/common/errors'; import { LineTokens } from 'vs/editor/common/core/lineTokens'; import { Position } from 'vs/editor/common/core/position'; -import { Range } from 'vs/editor/common/core/range'; +import { IRange } from 'vs/editor/common/core/range'; import { TokenizationResult2 } from 'vs/editor/common/core/token'; -import { ITextBuffer } from 'vs/editor/common/model'; -import { IModelTokensChangedEvent } from 'vs/editor/common/model/textModelEvents'; -import { ColorId, FontStyle, IState, ITokenizationSupport, LanguageId, LanguageIdentifier, MetadataConsts, StandardTokenType, TokenMetadata } from 'vs/editor/common/modes'; +import { RawContentChangedType } from 'vs/editor/common/model/textModelEvents'; +import { IState, ITokenizationSupport, LanguageIdentifier, TokenizationRegistry } from 'vs/editor/common/modes'; import { nullTokenize2 } from 'vs/editor/common/modes/nullMode'; +import { TextModel } from 'vs/editor/common/model/textModel'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { StopWatch } from 'vs/base/common/stopwatch'; +import { CharCode } from 'vs/base/common/charCode'; +import { MultilineTokensBuilder } from 'vs/editor/common/model/tokensStore'; -function getDefaultMetadata(topLevelLanguageId: LanguageId): number { - return ( - (topLevelLanguageId << MetadataConsts.LANGUAGEID_OFFSET) - | (StandardTokenType.Other << MetadataConsts.TOKEN_TYPE_OFFSET) - | (FontStyle.None << MetadataConsts.FONT_STYLE_OFFSET) - | (ColorId.DefaultForeground << MetadataConsts.FOREGROUND_OFFSET) - | (ColorId.DefaultBackground << MetadataConsts.BACKGROUND_OFFSET) - ) >>> 0; +export function countEOL(text: string): [number, number] { + let eolCount = 0; + let firstLineLength = 0; + for (let i = 0, len = text.length; i < len; i++) { + const chr = text.charCodeAt(i); + + if (chr === CharCode.CarriageReturn) { + if (eolCount === 0) { + firstLineLength = i; + } + eolCount++; + if (i + 1 < len && text.charCodeAt(i + 1) === CharCode.LineFeed) { + // \r\n... case + i++; // skip \n + } else { + // \r... case + } + } else if (chr === CharCode.LineFeed) { + if (eolCount === 0) { + firstLineLength = i; + } + eolCount++; + } + } + if (eolCount === 0) { + firstLineLength = text.length; + } + return [eolCount, firstLineLength]; } -const EMPTY_LINE_TOKENS = (new Uint32Array(0)).buffer; - -class ModelLineTokens { - _state: IState | null; - _lineTokens: ArrayBuffer | null; - _invalid: boolean; - - constructor(state: IState | null) { - this._state = state; - this._lineTokens = null; - this._invalid = true; - } - - public deleteBeginning(toChIndex: number): void { - if (this._lineTokens === null || this._lineTokens === EMPTY_LINE_TOKENS) { - return; - } - this.delete(0, toChIndex); - } - - public deleteEnding(fromChIndex: number): void { - if (this._lineTokens === null || this._lineTokens === EMPTY_LINE_TOKENS) { - return; - } - - const tokens = new Uint32Array(this._lineTokens); - const lineTextLength = tokens[tokens.length - 2]; - this.delete(fromChIndex, lineTextLength); - } - - public delete(fromChIndex: number, toChIndex: number): void { - if (this._lineTokens === null || this._lineTokens === EMPTY_LINE_TOKENS || fromChIndex === toChIndex) { - return; - } - - const tokens = new Uint32Array(this._lineTokens); - const tokensCount = (tokens.length >>> 1); - - // special case: deleting everything - if (fromChIndex === 0 && tokens[tokens.length - 2] === toChIndex) { - this._lineTokens = EMPTY_LINE_TOKENS; - return; - } - - const fromTokenIndex = LineTokens.findIndexInTokensArray(tokens, fromChIndex); - const fromTokenStartOffset = (fromTokenIndex > 0 ? tokens[(fromTokenIndex - 1) << 1] : 0); - const fromTokenEndOffset = tokens[fromTokenIndex << 1]; - - if (toChIndex < fromTokenEndOffset) { - // the delete range is inside a single token - const delta = (toChIndex - fromChIndex); - for (let i = fromTokenIndex; i < tokensCount; i++) { - tokens[i << 1] -= delta; - } - return; - } - - let dest: number; - let lastEnd: number; - if (fromTokenStartOffset !== fromChIndex) { - tokens[fromTokenIndex << 1] = fromChIndex; - dest = ((fromTokenIndex + 1) << 1); - lastEnd = fromChIndex; - } else { - dest = (fromTokenIndex << 1); - lastEnd = fromTokenStartOffset; - } - - const delta = (toChIndex - fromChIndex); - for (let tokenIndex = fromTokenIndex + 1; tokenIndex < tokensCount; tokenIndex++) { - const tokenEndOffset = tokens[tokenIndex << 1] - delta; - if (tokenEndOffset > lastEnd) { - tokens[dest++] = tokenEndOffset; - tokens[dest++] = tokens[(tokenIndex << 1) + 1]; - lastEnd = tokenEndOffset; - } - } - - if (dest === tokens.length) { - // nothing to trim - return; - } - - let tmp = new Uint32Array(dest); - tmp.set(tokens.subarray(0, dest), 0); - this._lineTokens = tmp.buffer; - } - - public append(_otherTokens: ArrayBuffer | null): void { - if (_otherTokens === EMPTY_LINE_TOKENS) { - return; - } - if (this._lineTokens === EMPTY_LINE_TOKENS) { - this._lineTokens = _otherTokens; - return; - } - if (this._lineTokens === null) { - return; - } - if (_otherTokens === null) { - // cannot determine combined line length... - this._lineTokens = null; - return; - } - const myTokens = new Uint32Array(this._lineTokens); - const otherTokens = new Uint32Array(_otherTokens); - const otherTokensCount = (otherTokens.length >>> 1); - - let result = new Uint32Array(myTokens.length + otherTokens.length); - result.set(myTokens, 0); - let dest = myTokens.length; - const delta = myTokens[myTokens.length - 2]; - for (let i = 0; i < otherTokensCount; i++) { - result[dest++] = otherTokens[(i << 1)] + delta; - result[dest++] = otherTokens[(i << 1) + 1]; - } - this._lineTokens = result.buffer; - } - - public insert(chIndex: number, textLength: number): void { - if (!this._lineTokens) { - // nothing to do - return; - } - - const tokens = new Uint32Array(this._lineTokens); - const tokensCount = (tokens.length >>> 1); - - let fromTokenIndex = LineTokens.findIndexInTokensArray(tokens, chIndex); - if (fromTokenIndex > 0) { - const fromTokenStartOffset = tokens[(fromTokenIndex - 1) << 1]; - if (fromTokenStartOffset === chIndex) { - fromTokenIndex--; - } - } - for (let tokenIndex = fromTokenIndex; tokenIndex < tokensCount; tokenIndex++) { - tokens[tokenIndex << 1] += textLength; - } - } +const enum Constants { + CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048 } -export class ModelLinesTokens { - - public readonly languageIdentifier: LanguageIdentifier; - public readonly tokenizationSupport: ITokenizationSupport | null; - private _tokens: ModelLineTokens[]; +export class TokenizationStateStore { + private _beginState: (IState | null)[]; + private _valid: boolean[]; + private _len: number; private _invalidLineStartIndex: number; - private _lastState: IState | null; - constructor(languageIdentifier: LanguageIdentifier, tokenizationSupport: ITokenizationSupport | null) { - this.languageIdentifier = languageIdentifier; - this.tokenizationSupport = tokenizationSupport; - this._tokens = []; - if (this.tokenizationSupport) { - let initialState: IState | null = null; - try { - initialState = this.tokenizationSupport.getInitialState(); - } catch (e) { - onUnexpectedError(e); - this.tokenizationSupport = null; - } - - if (initialState) { - this._tokens[0] = new ModelLineTokens(initialState); - } - } - - this._invalidLineStartIndex = 0; - this._lastState = null; + constructor() { + this._reset(null); } - public get inValidLineStartIndex() { + private _reset(initialState: IState | null): void { + this._beginState = []; + this._valid = []; + this._len = 0; + this._invalidLineStartIndex = 0; + + if (initialState) { + this._setBeginState(0, initialState); + } + } + + public flush(initialState: IState | null): void { + this._reset(initialState); + } + + public get invalidLineStartIndex() { return this._invalidLineStartIndex; } - public getTokens(topLevelLanguageId: LanguageId, lineIndex: number, lineText: string): LineTokens { - let rawLineTokens: ArrayBuffer | null = null; - if (lineIndex < this._tokens.length && this._tokens[lineIndex]) { - rawLineTokens = this._tokens[lineIndex]._lineTokens; + private _invalidateLine(lineIndex: number): void { + if (lineIndex < this._len) { + this._valid[lineIndex] = false; } - if (rawLineTokens !== null && rawLineTokens !== EMPTY_LINE_TOKENS) { - return new LineTokens(new Uint32Array(rawLineTokens), lineText); - } - - let lineTokens = new Uint32Array(2); - lineTokens[0] = lineText.length; - lineTokens[1] = getDefaultMetadata(topLevelLanguageId); - return new LineTokens(lineTokens, lineText); - } - - public isCheapToTokenize(lineNumber: number): boolean { - const firstInvalidLineNumber = this._invalidLineStartIndex + 1; - return (firstInvalidLineNumber >= lineNumber); - } - - public hasLinesToTokenize(buffer: ITextBuffer): boolean { - return (this._invalidLineStartIndex < buffer.getLineCount()); - } - - public invalidateLine(lineIndex: number): void { - this._setIsInvalid(lineIndex, true); if (lineIndex < this._invalidLineStartIndex) { - this._setIsInvalid(this._invalidLineStartIndex, true); this._invalidLineStartIndex = lineIndex; } } - _setIsInvalid(lineIndex: number, invalid: boolean): void { - if (lineIndex < this._tokens.length && this._tokens[lineIndex]) { - this._tokens[lineIndex]._invalid = invalid; + private _isValid(lineIndex: number): boolean { + if (lineIndex < this._len) { + return this._valid[lineIndex]; } + return false; } - _isInvalid(lineIndex: number): boolean { - if (lineIndex < this._tokens.length && this._tokens[lineIndex]) { - return this._tokens[lineIndex]._invalid; - } - return true; - } - - _getState(lineIndex: number): IState | null { - if (lineIndex < this._tokens.length && this._tokens[lineIndex]) { - return this._tokens[lineIndex]._state; + public getBeginState(lineIndex: number): IState | null { + if (lineIndex < this._len) { + return this._beginState[lineIndex]; } return null; } - _setTokens(topLevelLanguageId: LanguageId, lineIndex: number, lineTextLength: number, tokens: Uint32Array): void { - let target: ModelLineTokens; - if (lineIndex < this._tokens.length && this._tokens[lineIndex]) { - target = this._tokens[lineIndex]; - } else { - target = new ModelLineTokens(null); - this._tokens[lineIndex] = target; + private _ensureLine(lineIndex: number): void { + while (lineIndex >= this._len) { + this._beginState[this._len] = null; + this._valid[this._len] = false; + this._len++; } - - if (lineTextLength === 0) { - let hasDifferentLanguageId = false; - if (tokens && tokens.length > 1) { - hasDifferentLanguageId = (TokenMetadata.getLanguageId(tokens[1]) !== topLevelLanguageId); - } - - if (!hasDifferentLanguageId) { - target._lineTokens = EMPTY_LINE_TOKENS; - return; - } - } - - if (!tokens || tokens.length === 0) { - tokens = new Uint32Array(2); - tokens[0] = 0; - tokens[1] = getDefaultMetadata(topLevelLanguageId); - } - - LineTokens.convertToEndOffset(tokens, lineTextLength); - - target._lineTokens = tokens.buffer; } - _setState(lineIndex: number, state: IState): void { - if (lineIndex < this._tokens.length && this._tokens[lineIndex]) { - this._tokens[lineIndex]._state = state; - } else { - const tmp = new ModelLineTokens(state); - this._tokens[lineIndex] = tmp; + private _deleteLines(start: number, deleteCount: number): void { + if (deleteCount === 0) { + return; } + this._beginState.splice(start, deleteCount); + this._valid.splice(start, deleteCount); + this._len -= deleteCount; + } + + private _insertLines(insertIndex: number, insertCount: number): void { + if (insertCount === 0) { + return; + } + let beginState: (IState | null)[] = []; + let valid: boolean[] = []; + for (let i = 0; i < insertCount; i++) { + beginState[i] = null; + valid[i] = false; + } + this._beginState = arrays.arrayInsert(this._beginState, insertIndex, beginState); + this._valid = arrays.arrayInsert(this._valid, insertIndex, valid); + this._len += insertCount; + } + + private _setValid(lineIndex: number, valid: boolean): void { + this._ensureLine(lineIndex); + this._valid[lineIndex] = valid; + } + + private _setBeginState(lineIndex: number, beginState: IState | null): void { + this._ensureLine(lineIndex); + this._beginState[lineIndex] = beginState; + } + + public setEndState(linesLength: number, lineIndex: number, endState: IState): void { + this._setValid(lineIndex, true); + this._invalidLineStartIndex = lineIndex + 1; + + // Check if this was the last line + if (lineIndex === linesLength - 1) { + return; + } + + // Check if the end state has changed + const previousEndState = this.getBeginState(lineIndex + 1); + if (previousEndState === null || !endState.equals(previousEndState)) { + this._setBeginState(lineIndex + 1, endState); + this._invalidateLine(lineIndex + 1); + return; + } + + // Perhaps we can skip tokenizing some lines... + let i = lineIndex + 1; + while (i < linesLength) { + if (!this._isValid(i)) { + break; + } + i++; + } + this._invalidLineStartIndex = i; + } + + public setFakeTokens(lineIndex: number): void { + this._setValid(lineIndex, false); } //#region Editing - public applyEdits(range: Range, eolCount: number, firstLineLength: number): void { - + public applyEdits(range: IRange, eolCount: number): void { const deletingLinesCnt = range.endLineNumber - range.startLineNumber; const insertingLinesCnt = eolCount; const editingLinesCnt = Math.min(deletingLinesCnt, insertingLinesCnt); for (let j = editingLinesCnt; j >= 0; j--) { - this.invalidateLine(range.startLineNumber + j - 1); + this._invalidateLine(range.startLineNumber + j - 1); } this._acceptDeleteRange(range); - this._acceptInsertText(new Position(range.startLineNumber, range.startColumn), eolCount, firstLineLength); + this._acceptInsertText(new Position(range.startLineNumber, range.startColumn), eolCount); } - private _acceptDeleteRange(range: Range): void { + private _acceptDeleteRange(range: IRange): void { const firstLineIndex = range.startLineNumber - 1; - if (firstLineIndex >= this._tokens.length) { + if (firstLineIndex >= this._len) { return; } - if (range.startLineNumber === range.endLineNumber) { - if (range.startColumn === range.endColumn) { - // Nothing to delete - return; - } - - this._tokens[firstLineIndex].delete(range.startColumn - 1, range.endColumn - 1); - return; - } - - const firstLine = this._tokens[firstLineIndex]; - firstLine.deleteEnding(range.startColumn - 1); - - const lastLineIndex = range.endLineNumber - 1; - let lastLineTokens: ArrayBuffer | null = null; - if (lastLineIndex < this._tokens.length) { - const lastLine = this._tokens[lastLineIndex]; - lastLine.deleteBeginning(range.endColumn - 1); - lastLineTokens = lastLine._lineTokens; - } - - // Take remaining text on last line and append it to remaining text on first line - firstLine.append(lastLineTokens); - - // Delete middle lines - this._tokens.splice(range.startLineNumber, range.endLineNumber - range.startLineNumber); + this._deleteLines(range.startLineNumber, range.endLineNumber - range.startLineNumber); } - private _acceptInsertText(position: Position, eolCount: number, firstLineLength: number): void { - - if (eolCount === 0 && firstLineLength === 0) { - // Nothing to insert - return; - } + private _acceptInsertText(position: Position, eolCount: number): void { const lineIndex = position.lineNumber - 1; - if (lineIndex >= this._tokens.length) { + if (lineIndex >= this._len) { return; } - if (eolCount === 0) { - // Inserting text on one line - this._tokens[lineIndex].insert(position.column - 1, firstLineLength); - return; - } - - const line = this._tokens[lineIndex]; - line.deleteEnding(position.column - 1); - line.insert(position.column - 1, firstLineLength); - - let insert: ModelLineTokens[] = new Array(eolCount); - for (let i = eolCount - 1; i >= 0; i--) { - insert[i] = new ModelLineTokens(null); - } - this._tokens = arrays.arrayInsert(this._tokens, position.lineNumber, insert); + this._insertLines(position.lineNumber, eolCount); } //#endregion +} - //#region Tokenization +export class TextModelTokenization extends Disposable { - public _tokenizeOneLine(buffer: ITextBuffer, eventBuilder: ModelTokensChangedEventBuilder): number { - if (!this.hasLinesToTokenize(buffer)) { - return buffer.getLineCount() + 1; + private readonly _textModel: TextModel; + private readonly _tokenizationStateStore: TokenizationStateStore; + private _revalidateTokensTimeout: any; + private _tokenizationSupport: ITokenizationSupport | null; + + constructor(textModel: TextModel) { + super(); + this._textModel = textModel; + this._tokenizationStateStore = new TokenizationStateStore(); + this._revalidateTokensTimeout = -1; + this._tokenizationSupport = null; + + this._register(TokenizationRegistry.onDidChange((e) => { + const languageIdentifier = this._textModel.getLanguageIdentifier(); + if (e.changedLanguages.indexOf(languageIdentifier.language) === -1) { + return; + } + + this._resetTokenizationState(); + this._textModel.clearTokens(); + })); + + this._register(this._textModel.onDidChangeRawContentFast((e) => { + if (e.containsEvent(RawContentChangedType.Flush)) { + this._resetTokenizationState(); + return; + } + })); + + this._register(this._textModel.onDidChangeContentFast((e) => { + for (let i = 0, len = e.changes.length; i < len; i++) { + const change = e.changes[i]; + const [eolCount] = countEOL(change.text); + this._tokenizationStateStore.applyEdits(change.range, eolCount); + } + + this._beginBackgroundTokenization(); + })); + + this._register(this._textModel.onDidChangeAttached(() => { + this._beginBackgroundTokenization(); + })); + + this._register(this._textModel.onDidChangeLanguage(() => { + this._resetTokenizationState(); + this._textModel.clearTokens(); + })); + + this._resetTokenizationState(); + } + + public dispose(): void { + this._clearTimers(); + super.dispose(); + } + + private _clearTimers(): void { + if (this._revalidateTokensTimeout !== -1) { + clearTimeout(this._revalidateTokensTimeout); + this._revalidateTokensTimeout = -1; } - const lineNumber = this._invalidLineStartIndex + 1; - this._updateTokensUntilLine(buffer, eventBuilder, lineNumber); + } + + private _resetTokenizationState(): void { + this._clearTimers(); + const [tokenizationSupport, initialState] = initializeTokenization(this._textModel); + this._tokenizationSupport = tokenizationSupport; + this._tokenizationStateStore.flush(initialState); + this._beginBackgroundTokenization(); + } + + private _beginBackgroundTokenization(): void { + if (this._textModel.isAttachedToEditor() && this._hasLinesToTokenize() && this._revalidateTokensTimeout === -1) { + this._revalidateTokensTimeout = setTimeout(() => { + this._revalidateTokensTimeout = -1; + this._revalidateTokensNow(); + }, 0); + } + } + + private _revalidateTokensNow(toLineNumber: number = this._textModel.getLineCount()): void { + const MAX_ALLOWED_TIME = 20; + const builder = new MultilineTokensBuilder(); + const sw = StopWatch.create(false); + + while (this._hasLinesToTokenize()) { + if (sw.elapsed() > MAX_ALLOWED_TIME) { + // Stop if MAX_ALLOWED_TIME is reached + break; + } + + const tokenizedLineNumber = this._tokenizeOneInvalidLine(builder); + + if (tokenizedLineNumber >= toLineNumber) { + break; + } + } + + this._beginBackgroundTokenization(); + this._textModel.setTokens(builder.tokens); + } + + public tokenizeViewport(startLineNumber: number, endLineNumber: number): void { + const builder = new MultilineTokensBuilder(); + this._tokenizeViewport(builder, startLineNumber, endLineNumber); + this._textModel.setTokens(builder.tokens); + } + + public reset(): void { + this._resetTokenizationState(); + this._textModel.clearTokens(); + } + + public forceTokenization(lineNumber: number): void { + const builder = new MultilineTokensBuilder(); + this._updateTokensUntilLine(builder, lineNumber); + this._textModel.setTokens(builder.tokens); + } + + public isCheapToTokenize(lineNumber: number): boolean { + if (!this._tokenizationSupport) { + return true; + } + + const firstInvalidLineNumber = this._tokenizationStateStore.invalidLineStartIndex + 1; + if (lineNumber > firstInvalidLineNumber) { + return false; + } + + if (lineNumber < firstInvalidLineNumber) { + return true; + } + + if (this._textModel.getLineLength(lineNumber) < Constants.CHEAP_TOKENIZATION_LENGTH_LIMIT) { + return true; + } + + return false; + } + + private _hasLinesToTokenize(): boolean { + if (!this._tokenizationSupport) { + return false; + } + return (this._tokenizationStateStore.invalidLineStartIndex < this._textModel.getLineCount()); + } + + private _tokenizeOneInvalidLine(builder: MultilineTokensBuilder): number { + if (!this._hasLinesToTokenize()) { + return this._textModel.getLineCount() + 1; + } + const lineNumber = this._tokenizationStateStore.invalidLineStartIndex + 1; + this._updateTokensUntilLine(builder, lineNumber); return lineNumber; } - public _tokenizeText(buffer: ITextBuffer, text: string, state: IState): TokenizationResult2 { - let r: TokenizationResult2 | null = null; - - if (this.tokenizationSupport) { - try { - r = this.tokenizationSupport.tokenize2(text, state, 0); - } catch (e) { - onUnexpectedError(e); - } - } - - if (!r) { - r = nullTokenize2(this.languageIdentifier.id, text, state, 0); - } - return r; - } - - public _updateTokensUntilLine(buffer: ITextBuffer, eventBuilder: ModelTokensChangedEventBuilder, lineNumber: number): void { - if (!this.tokenizationSupport) { - this._invalidLineStartIndex = buffer.getLineCount(); + private _updateTokensUntilLine(builder: MultilineTokensBuilder, lineNumber: number): void { + if (!this._tokenizationSupport) { return; } - - const linesLength = buffer.getLineCount(); + const languageIdentifier = this._textModel.getLanguageIdentifier(); + const linesLength = this._textModel.getLineCount(); const endLineIndex = lineNumber - 1; // Validate all states up to and including endLineIndex - for (let lineIndex = this._invalidLineStartIndex; lineIndex <= endLineIndex; lineIndex++) { - const endStateIndex = lineIndex + 1; - const text = buffer.getLineContent(lineIndex + 1); - const lineStartState = this._getState(lineIndex); + for (let lineIndex = this._tokenizationStateStore.invalidLineStartIndex; lineIndex <= endLineIndex; lineIndex++) { + const text = this._textModel.getLineContent(lineIndex + 1); + const lineStartState = this._tokenizationStateStore.getBeginState(lineIndex); - let r: TokenizationResult2 | null = null; + const r = safeTokenize(languageIdentifier, this._tokenizationSupport, text, lineStartState!); + builder.add(lineIndex + 1, r.tokens); + this._tokenizationStateStore.setEndState(linesLength, lineIndex, r.endState); + lineIndex = this._tokenizationStateStore.invalidLineStartIndex - 1; // -1 because the outer loop increments it + } + } - try { - // Tokenize only the first X characters - let freshState = lineStartState!.clone(); - r = this.tokenizationSupport.tokenize2(text, freshState, 0); - } catch (e) { - onUnexpectedError(e); + private _tokenizeViewport(builder: MultilineTokensBuilder, startLineNumber: number, endLineNumber: number): void { + if (!this._tokenizationSupport) { + // nothing to do + return; + } + + if (endLineNumber <= this._tokenizationStateStore.invalidLineStartIndex) { + // nothing to do + return; + } + + if (startLineNumber <= this._tokenizationStateStore.invalidLineStartIndex) { + // tokenization has reached the viewport start... + this._updateTokensUntilLine(builder, endLineNumber); + return; + } + + let nonWhitespaceColumn = this._textModel.getLineFirstNonWhitespaceColumn(startLineNumber); + let fakeLines: string[] = []; + let initialState: IState | null = null; + for (let i = startLineNumber - 1; nonWhitespaceColumn > 0 && i >= 1; i--) { + let newNonWhitespaceIndex = this._textModel.getLineFirstNonWhitespaceColumn(i); + + if (newNonWhitespaceIndex === 0) { + continue; } - if (!r) { - r = nullTokenize2(this.languageIdentifier.id, text, lineStartState, 0); - } - this._setTokens(this.languageIdentifier.id, lineIndex, text.length, r.tokens); - eventBuilder.registerChangedTokens(lineIndex + 1); - this._setIsInvalid(lineIndex, false); - - if (endStateIndex < linesLength) { - const previousEndState = this._getState(endStateIndex); - if (previousEndState !== null && r.endState.equals(previousEndState)) { - // The end state of this line remains the same - let nextInvalidLineIndex = lineIndex + 1; - while (nextInvalidLineIndex < linesLength) { - if (this._isInvalid(nextInvalidLineIndex)) { - break; - } - if (nextInvalidLineIndex + 1 < linesLength) { - if (this._getState(nextInvalidLineIndex + 1) === null) { - break; - } - } else { - if (this._lastState === null) { - break; - } - } - nextInvalidLineIndex++; - } - this._invalidLineStartIndex = Math.max(this._invalidLineStartIndex, nextInvalidLineIndex); - lineIndex = nextInvalidLineIndex - 1; // -1 because the outer loop increments it - } else { - this._setState(endStateIndex, r.endState); + if (newNonWhitespaceIndex < nonWhitespaceColumn) { + initialState = this._tokenizationStateStore.getBeginState(i - 1); + if (initialState) { + break; } - } else { - this._lastState = r.endState; + fakeLines.push(this._textModel.getLineContent(i)); + nonWhitespaceColumn = newNonWhitespaceIndex; } } - this._invalidLineStartIndex = Math.max(this._invalidLineStartIndex, endLineIndex + 1); - } - // #endregion + if (!initialState) { + initialState = this._tokenizationSupport.getInitialState(); + } + + const languageIdentifier = this._textModel.getLanguageIdentifier(); + let state = initialState; + for (let i = fakeLines.length - 1; i >= 0; i--) { + let r = safeTokenize(languageIdentifier, this._tokenizationSupport, fakeLines[i], state); + state = r.endState; + } + + for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) { + let text = this._textModel.getLineContent(lineNumber); + let r = safeTokenize(languageIdentifier, this._tokenizationSupport, text, state); + builder.add(lineNumber, r.tokens); + this._tokenizationStateStore.setFakeTokens(lineNumber - 1); + state = r.endState; + } + } } -export class ModelTokensChangedEventBuilder { - - private readonly _ranges: { fromLineNumber: number; toLineNumber: number; }[]; - - constructor() { - this._ranges = []; +function initializeTokenization(textModel: TextModel): [ITokenizationSupport | null, IState | null] { + const languageIdentifier = textModel.getLanguageIdentifier(); + let tokenizationSupport = ( + textModel.isTooLargeForTokenization() + ? null + : TokenizationRegistry.get(languageIdentifier.language) + ); + let initialState: IState | null = null; + if (tokenizationSupport) { + try { + initialState = tokenizationSupport.getInitialState(); + } catch (e) { + onUnexpectedError(e); + tokenizationSupport = null; + } } + return [tokenizationSupport, initialState]; +} - public registerChangedTokens(lineNumber: number): void { - const ranges = this._ranges; - const rangesLength = ranges.length; - const previousRange = rangesLength > 0 ? ranges[rangesLength - 1] : null; +function safeTokenize(languageIdentifier: LanguageIdentifier, tokenizationSupport: ITokenizationSupport | null, text: string, state: IState): TokenizationResult2 { + let r: TokenizationResult2 | null = null; - if (previousRange && previousRange.toLineNumber === lineNumber - 1) { - // extend previous range - previousRange.toLineNumber++; - } else { - // insert new range - ranges[rangesLength] = { - fromLineNumber: lineNumber, - toLineNumber: lineNumber - }; + if (tokenizationSupport) { + try { + r = tokenizationSupport.tokenize2(text, state.clone(), 0); + } catch (e) { + onUnexpectedError(e); } } - public build(): IModelTokensChangedEvent | null { - if (this._ranges.length === 0) { - return null; - } - return { - tokenizationSupportChanged: false, - ranges: this._ranges - }; + if (!r) { + r = nullTokenize2(languageIdentifier.id, text, state, 0); } + + LineTokens.convertToEndOffset(r.tokens, text.length); + return r; } diff --git a/src/vs/editor/common/model/tokensStore.ts b/src/vs/editor/common/model/tokensStore.ts new file mode 100644 index 00000000000..3ee6ab6ced3 --- /dev/null +++ b/src/vs/editor/common/model/tokensStore.ts @@ -0,0 +1,330 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as arrays from 'vs/base/common/arrays'; +import { LineTokens } from 'vs/editor/common/core/lineTokens'; +import { Position } from 'vs/editor/common/core/position'; +import { IRange } from 'vs/editor/common/core/range'; +import { ColorId, FontStyle, LanguageId, MetadataConsts, StandardTokenType, TokenMetadata } from 'vs/editor/common/modes'; + +function getDefaultMetadata(topLevelLanguageId: LanguageId): number { + return ( + (topLevelLanguageId << MetadataConsts.LANGUAGEID_OFFSET) + | (StandardTokenType.Other << MetadataConsts.TOKEN_TYPE_OFFSET) + | (FontStyle.None << MetadataConsts.FONT_STYLE_OFFSET) + | (ColorId.DefaultForeground << MetadataConsts.FOREGROUND_OFFSET) + | (ColorId.DefaultBackground << MetadataConsts.BACKGROUND_OFFSET) + ) >>> 0; +} + +const EMPTY_LINE_TOKENS = (new Uint32Array(0)).buffer; + +export class MultilineTokensBuilder { + + public readonly tokens: MultilineTokens[]; + + constructor() { + this.tokens = []; + } + + public add(lineNumber: number, lineTokens: Uint32Array): void { + if (this.tokens.length > 0) { + const last = this.tokens[this.tokens.length - 1]; + const lastLineNumber = last.startLineNumber + last.tokens.length - 1; + if (lastLineNumber + 1 === lineNumber) { + // append + last.tokens.push(lineTokens); + return; + } + } + this.tokens.push(new MultilineTokens(lineNumber, lineTokens)); + } +} + +export class MultilineTokens { + + public readonly startLineNumber: number; + public readonly tokens: Uint32Array[]; + + constructor(lineNumber: number, tokens: Uint32Array) { + this.startLineNumber = lineNumber; + this.tokens = [tokens]; + } +} + +export class TokensStore { + private _lineTokens: (ArrayBuffer | null)[]; + private _len: number; + + constructor() { + this._lineTokens = []; + this._len = 0; + } + + public flush(): void { + this._lineTokens = []; + this._len = 0; + } + + public getTokens(topLevelLanguageId: LanguageId, lineIndex: number, lineText: string): LineTokens { + let rawLineTokens: ArrayBuffer | null = null; + if (lineIndex < this._len) { + rawLineTokens = this._lineTokens[lineIndex]; + } + + if (rawLineTokens !== null && rawLineTokens !== EMPTY_LINE_TOKENS) { + return new LineTokens(new Uint32Array(rawLineTokens), lineText); + } + + let lineTokens = new Uint32Array(2); + lineTokens[0] = lineText.length; + lineTokens[1] = getDefaultMetadata(topLevelLanguageId); + return new LineTokens(lineTokens, lineText); + } + + private static _massageTokens(topLevelLanguageId: LanguageId, lineTextLength: number, tokens: Uint32Array): ArrayBuffer { + if (lineTextLength === 0) { + let hasDifferentLanguageId = false; + if (tokens && tokens.length > 1) { + hasDifferentLanguageId = (TokenMetadata.getLanguageId(tokens[1]) !== topLevelLanguageId); + } + + if (!hasDifferentLanguageId) { + return EMPTY_LINE_TOKENS; + } + } + + if (!tokens || tokens.length === 0) { + tokens = new Uint32Array(2); + tokens[0] = lineTextLength; + tokens[1] = getDefaultMetadata(topLevelLanguageId); + } + + return tokens.buffer; + } + + private _ensureLine(lineIndex: number): void { + while (lineIndex >= this._len) { + this._lineTokens[this._len] = null; + this._len++; + } + } + + private _deleteLines(start: number, deleteCount: number): void { + if (deleteCount === 0) { + return; + } + this._lineTokens.splice(start, deleteCount); + this._len -= deleteCount; + } + + private _insertLines(insertIndex: number, insertCount: number): void { + if (insertCount === 0) { + return; + } + let lineTokens: (ArrayBuffer | null)[] = []; + for (let i = 0; i < insertCount; i++) { + lineTokens[i] = null; + } + this._lineTokens = arrays.arrayInsert(this._lineTokens, insertIndex, lineTokens); + this._len += insertCount; + } + + public setTokens(topLevelLanguageId: LanguageId, lineIndex: number, lineTextLength: number, _tokens: Uint32Array): void { + const tokens = TokensStore._massageTokens(topLevelLanguageId, lineTextLength, _tokens); + this._ensureLine(lineIndex); + this._lineTokens[lineIndex] = tokens; + } + + //#region Editing + + public applyEdits(range: IRange, eolCount: number, firstLineLength: number): void { + this._acceptDeleteRange(range); + this._acceptInsertText(new Position(range.startLineNumber, range.startColumn), eolCount, firstLineLength); + } + + private _acceptDeleteRange(range: IRange): void { + + const firstLineIndex = range.startLineNumber - 1; + if (firstLineIndex >= this._len) { + return; + } + + if (range.startLineNumber === range.endLineNumber) { + if (range.startColumn === range.endColumn) { + // Nothing to delete + return; + } + + this._lineTokens[firstLineIndex] = TokensStore._delete(this._lineTokens[firstLineIndex], range.startColumn - 1, range.endColumn - 1); + return; + } + + this._lineTokens[firstLineIndex] = TokensStore._deleteEnding(this._lineTokens[firstLineIndex], range.startColumn - 1); + + const lastLineIndex = range.endLineNumber - 1; + let lastLineTokens: ArrayBuffer | null = null; + if (lastLineIndex < this._len) { + lastLineTokens = TokensStore._deleteBeginning(this._lineTokens[lastLineIndex], range.endColumn - 1); + } + + // Take remaining text on last line and append it to remaining text on first line + this._lineTokens[firstLineIndex] = TokensStore._append(this._lineTokens[firstLineIndex], lastLineTokens); + + // Delete middle lines + this._deleteLines(range.startLineNumber, range.endLineNumber - range.startLineNumber); + } + + private _acceptInsertText(position: Position, eolCount: number, firstLineLength: number): void { + + if (eolCount === 0 && firstLineLength === 0) { + // Nothing to insert + return; + } + + const lineIndex = position.lineNumber - 1; + if (lineIndex >= this._len) { + return; + } + + if (eolCount === 0) { + // Inserting text on one line + this._lineTokens[lineIndex] = TokensStore._insert(this._lineTokens[lineIndex], position.column - 1, firstLineLength); + return; + } + + this._lineTokens[lineIndex] = TokensStore._deleteEnding(this._lineTokens[lineIndex], position.column - 1); + this._lineTokens[lineIndex] = TokensStore._insert(this._lineTokens[lineIndex], position.column - 1, firstLineLength); + + this._insertLines(position.lineNumber, eolCount); + } + + private static _deleteBeginning(lineTokens: ArrayBuffer | null, toChIndex: number): ArrayBuffer | null { + if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) { + return lineTokens; + } + return TokensStore._delete(lineTokens, 0, toChIndex); + } + + private static _deleteEnding(lineTokens: ArrayBuffer | null, fromChIndex: number): ArrayBuffer | null { + if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) { + return lineTokens; + } + + const tokens = new Uint32Array(lineTokens); + const lineTextLength = tokens[tokens.length - 2]; + return TokensStore._delete(lineTokens, fromChIndex, lineTextLength); + } + + private static _delete(lineTokens: ArrayBuffer | null, fromChIndex: number, toChIndex: number): ArrayBuffer | null { + if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS || fromChIndex === toChIndex) { + return lineTokens; + } + + const tokens = new Uint32Array(lineTokens); + const tokensCount = (tokens.length >>> 1); + + // special case: deleting everything + if (fromChIndex === 0 && tokens[tokens.length - 2] === toChIndex) { + return EMPTY_LINE_TOKENS; + } + + const fromTokenIndex = LineTokens.findIndexInTokensArray(tokens, fromChIndex); + const fromTokenStartOffset = (fromTokenIndex > 0 ? tokens[(fromTokenIndex - 1) << 1] : 0); + const fromTokenEndOffset = tokens[fromTokenIndex << 1]; + + if (toChIndex < fromTokenEndOffset) { + // the delete range is inside a single token + const delta = (toChIndex - fromChIndex); + for (let i = fromTokenIndex; i < tokensCount; i++) { + tokens[i << 1] -= delta; + } + return lineTokens; + } + + let dest: number; + let lastEnd: number; + if (fromTokenStartOffset !== fromChIndex) { + tokens[fromTokenIndex << 1] = fromChIndex; + dest = ((fromTokenIndex + 1) << 1); + lastEnd = fromChIndex; + } else { + dest = (fromTokenIndex << 1); + lastEnd = fromTokenStartOffset; + } + + const delta = (toChIndex - fromChIndex); + for (let tokenIndex = fromTokenIndex + 1; tokenIndex < tokensCount; tokenIndex++) { + const tokenEndOffset = tokens[tokenIndex << 1] - delta; + if (tokenEndOffset > lastEnd) { + tokens[dest++] = tokenEndOffset; + tokens[dest++] = tokens[(tokenIndex << 1) + 1]; + lastEnd = tokenEndOffset; + } + } + + if (dest === tokens.length) { + // nothing to trim + return lineTokens; + } + + let tmp = new Uint32Array(dest); + tmp.set(tokens.subarray(0, dest), 0); + return tmp.buffer; + } + + private static _append(lineTokens: ArrayBuffer | null, _otherTokens: ArrayBuffer | null): ArrayBuffer | null { + if (_otherTokens === EMPTY_LINE_TOKENS) { + return lineTokens; + } + if (lineTokens === EMPTY_LINE_TOKENS) { + return _otherTokens; + } + if (lineTokens === null) { + return lineTokens; + } + if (_otherTokens === null) { + // cannot determine combined line length... + return null; + } + const myTokens = new Uint32Array(lineTokens); + const otherTokens = new Uint32Array(_otherTokens); + const otherTokensCount = (otherTokens.length >>> 1); + + let result = new Uint32Array(myTokens.length + otherTokens.length); + result.set(myTokens, 0); + let dest = myTokens.length; + const delta = myTokens[myTokens.length - 2]; + for (let i = 0; i < otherTokensCount; i++) { + result[dest++] = otherTokens[(i << 1)] + delta; + result[dest++] = otherTokens[(i << 1) + 1]; + } + return result.buffer; + } + + private static _insert(lineTokens: ArrayBuffer | null, chIndex: number, textLength: number): ArrayBuffer | null { + if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) { + // nothing to do + return lineTokens; + } + + const tokens = new Uint32Array(lineTokens); + const tokensCount = (tokens.length >>> 1); + + let fromTokenIndex = LineTokens.findIndexInTokensArray(tokens, chIndex); + if (fromTokenIndex > 0) { + const fromTokenStartOffset = tokens[(fromTokenIndex - 1) << 1]; + if (fromTokenStartOffset === chIndex) { + fromTokenIndex--; + } + } + for (let tokenIndex = fromTokenIndex; tokenIndex < tokensCount; tokenIndex++) { + tokens[tokenIndex << 1] += textLength; + } + return lineTokens; + } + + //#endregion +} diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index 0584508a387..f9caed90bae 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -17,8 +17,8 @@ import { TokenizationResult, TokenizationResult2 } from 'vs/editor/common/core/t import * as model from 'vs/editor/common/model'; import { LanguageFeatureRegistry } from 'vs/editor/common/modes/languageFeatureRegistry'; import { TokenizationRegistryImpl } from 'vs/editor/common/modes/tokenizationRegistry'; -import { IMarkerData } from 'vs/platform/markers/common/markers'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { IMarkerData } from 'vs/platform/markers/common/markers'; /** * Open ended enum at runtime @@ -510,6 +510,11 @@ export interface CompletionContext { */ export interface CompletionItemProvider { + /** + * @internal + */ + _debugDisplayName?: string; + triggerCharacters?: string[]; /** * Provide completion items for the given position and document. @@ -628,6 +633,10 @@ export interface SignatureHelp { activeParameter: number; } +export interface SignatureHelpResult extends IDisposable { + value: SignatureHelp; +} + export enum SignatureHelpTriggerKind { Invoke = 1, TriggerCharacter = 2, @@ -653,7 +662,7 @@ export interface SignatureHelpProvider { /** * Provide help for the signature at the given position and document. */ - provideSignatureHelp(model: model.ITextModel, position: Position, token: CancellationToken, context: SignatureHelpContext): ProviderResult; + provideSignatureHelp(model: model.ITextModel, position: Position, token: CancellationToken, context: SignatureHelpContext): ProviderResult; } /** @@ -1232,19 +1241,7 @@ export interface CommentThreadTemplate { export interface CommentInfo { extensionId?: string; threads: CommentThread[]; - commentingRanges?: (IRange[] | CommentingRanges); - reply?: Command; - draftMode?: DraftMode; - template?: CommentThreadTemplate; -} - -/** - * @internal - */ -export enum DraftMode { - NotSupported, - InDraft, - NotInDraft + commentingRanges: CommentingRanges; } /** @@ -1284,7 +1281,7 @@ export interface CommentInput { /** * @internal */ -export interface CommentThread2 { +export interface CommentThread { commentThreadHandle: number; controllerHandle: number; extensionId?: string; @@ -1298,11 +1295,6 @@ export interface CommentThread2 { collapsibleState?: CommentThreadCollapsibleState; input?: CommentInput; onDidChangeInput: Event; - acceptInputCommand?: Command; - additionalCommands?: Command[]; - deleteCommand?: Command; - onDidChangeAcceptInputCommand: Event; - onDidChangeAdditionalCommands: Event; onDidChangeRange: Event; onDidChangeLabel: Event; onDidChangeCollasibleState: Event; @@ -1316,30 +1308,6 @@ export interface CommentThread2 { export interface CommentingRanges { readonly resource: URI; ranges: IRange[]; - newCommentThreadCallback?: (uri: UriComponents, range: IRange) => Promise; -} - -/** - * @internal - */ -export interface CommentThread { - extensionId?: string; - threadId: string | null; - resource: string | null; - range: IRange; - comments: Comment[] | undefined; - collapsibleState?: CommentThreadCollapsibleState; - reply?: Command; - isDisposed?: boolean; - contextValue?: string; -} - -/** - * @internal - */ -export interface NewCommentAction { - ranges: IRange[]; - actions: Command[]; } /** @@ -1371,12 +1339,6 @@ export interface Comment { readonly userName: string; readonly userIconPath?: string; readonly contextValue?: string; - readonly canEdit?: boolean; - readonly canDelete?: boolean; - readonly selectCommand?: Command; - readonly editCommand?: Command; - readonly deleteCommand?: Command; - readonly isDraft?: boolean; readonly commentReactions?: CommentReaction[]; readonly label?: string; readonly mode?: CommentMode; @@ -1389,54 +1351,17 @@ export interface CommentThreadChangedEvent { /** * Added comment threads. */ - readonly added: (CommentThread | CommentThread2)[]; + readonly added: CommentThread[]; /** * Removed comment threads. */ - readonly removed: (CommentThread | CommentThread2)[]; + readonly removed: CommentThread[]; /** * Changed comment threads. */ - readonly changed: (CommentThread | CommentThread2)[]; - - /** - * changed draft mode. - */ - readonly draftMode?: DraftMode; -} - -/** - * @internal - */ -export interface DocumentCommentProvider { - provideDocumentComments(resource: URI, token: CancellationToken): Promise; - createNewCommentThread(resource: URI, range: Range, text: string, token: CancellationToken): Promise; - replyToCommentThread(resource: URI, range: Range, thread: CommentThread, text: string, token: CancellationToken): Promise; - editComment(resource: URI, comment: Comment, text: string, token: CancellationToken): Promise; - deleteComment(resource: URI, comment: Comment, token: CancellationToken): Promise; - startDraft?(resource: URI, token: CancellationToken): Promise; - deleteDraft?(resource: URI, token: CancellationToken): Promise; - finishDraft?(resource: URI, token: CancellationToken): Promise; - - startDraftLabel?: string; - deleteDraftLabel?: string; - finishDraftLabel?: string; - - addReaction?(resource: URI, comment: Comment, reaction: CommentReaction, token: CancellationToken): Promise; - deleteReaction?(resource: URI, comment: Comment, reaction: CommentReaction, token: CancellationToken): Promise; - reactionGroup?: CommentReaction[]; - - onDidChangeCommentThreads?(): Event; -} - -/** - * @internal - */ -export interface WorkspaceCommentProvider { - provideWorkspaceComments(token: CancellationToken): Promise; - onDidChangeCommentThreads(): Event; + readonly changed: CommentThread[]; } /** diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index a4c9dd6e8fd..06c11b3303e 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -22,7 +22,8 @@ import { ILinkComputerTarget, computeLinks } from 'vs/editor/common/modes/linkCo import { BasicInplaceReplace } from 'vs/editor/common/modes/supports/inplaceReplaceSupport'; import { IDiffComputationResult } from 'vs/editor/common/services/editorWorkerService'; import { createMonacoBaseAPI } from 'vs/editor/common/standalone/standaloneBase'; -import { getAllPropertyNames } from 'vs/base/common/types'; +import * as types from 'vs/base/common/types'; +import { EditorWorkerHost } from 'vs/editor/common/services/editorWorkerServiceImpl'; export interface IMirrorModel { readonly uri: URI; @@ -30,7 +31,11 @@ export interface IMirrorModel { getValue(): string; } -export interface IWorkerContext { +export interface IWorkerContext { + /** + * A proxy to the main thread host object. + */ + host: H; /** * Get all available mirror models in this worker. */ @@ -322,17 +327,53 @@ declare var require: any; /** * @internal */ -export abstract class BaseEditorSimpleWorker { +export class EditorSimpleWorker implements IRequestHandler, IDisposable { + _requestHandlerBrand: any; + + private readonly _host: EditorWorkerHost; + private _models: { [uri: string]: MirrorModel; }; private readonly _foreignModuleFactory: IForeignModuleFactory | null; private _foreignModule: any; - constructor(foreignModuleFactory: IForeignModuleFactory | null) { + constructor(host: EditorWorkerHost, foreignModuleFactory: IForeignModuleFactory | null) { + this._host = host; + this._models = Object.create(null); this._foreignModuleFactory = foreignModuleFactory; this._foreignModule = null; } - protected abstract _getModel(uri: string): ICommonModel; - protected abstract _getModels(): ICommonModel[]; + public dispose(): void { + this._models = Object.create(null); + } + + protected _getModel(uri: string): ICommonModel { + return this._models[uri]; + } + + private _getModels(): ICommonModel[] { + let all: MirrorModel[] = []; + Object.keys(this._models).forEach((key) => all.push(this._models[key])); + return all; + } + + public acceptNewModel(data: IRawModelData): void { + this._models[data.url] = new MirrorModel(URI.parse(data.url), data.lines, data.EOL, data.versionId); + } + + public acceptModelChanged(strURL: string, e: IModelChangedEvent): void { + if (!this._models[strURL]) { + return; + } + let model = this._models[strURL]; + model.onEvents(e); + } + + public acceptRemovedModel(strURL: string): void { + if (!this._models[strURL]) { + return; + } + delete this._models[strURL]; + } // ---- BEGIN diff -------------------------------------------------------------------------- @@ -440,7 +481,7 @@ export abstract class BaseEditorSimpleWorker { } // make sure diff won't take too long - if (Math.max(text.length, original.length) > BaseEditorSimpleWorker._diffLimit) { + if (Math.max(text.length, original.length) > EditorSimpleWorker._diffLimit) { result.push({ range, text }); continue; } @@ -503,7 +544,7 @@ export abstract class BaseEditorSimpleWorker { for ( let iter = model.createWordIterator(wordDefRegExp), e = iter.next(); - !e.done && suggestions.length <= BaseEditorSimpleWorker._suggestionsLimit; + !e.done && suggestions.length <= EditorSimpleWorker._suggestionsLimit; e = iter.next() ) { const word = e.value; @@ -591,8 +632,15 @@ export abstract class BaseEditorSimpleWorker { // ---- BEGIN foreign module support -------------------------------------------------------------------------- - public loadForeignModule(moduleId: string, createData: any): Promise { - let ctx: IWorkerContext = { + public loadForeignModule(moduleId: string, createData: any, foreignHostMethods: string[]): Promise { + const proxyMethodRequest = (method: string, args: any[]): Promise => { + return this._host.fhr(method, args); + }; + + const foreignHost = types.createProxyObject(foreignHostMethods, proxyMethodRequest); + + let ctx: IWorkerContext = { + host: foreignHost, getMirrorModels: (): IMirrorModel[] => { return this._getModels(); } @@ -601,27 +649,14 @@ export abstract class BaseEditorSimpleWorker { if (this._foreignModuleFactory) { this._foreignModule = this._foreignModuleFactory(ctx, createData); // static foreing module - let methods: string[] = []; - for (const prop of getAllPropertyNames(this._foreignModule)) { - if (typeof this._foreignModule[prop] === 'function') { - methods.push(prop); - } - } - return Promise.resolve(methods); + return Promise.resolve(types.getAllMethodNames(this._foreignModule)); } // ESM-comment-begin return new Promise((resolve, reject) => { require([moduleId], (foreignModule: { create: IForeignModuleFactory }) => { this._foreignModule = foreignModule.create(ctx, createData); - let methods: string[] = []; - for (const prop of getAllPropertyNames(this._foreignModule)) { - if (typeof this._foreignModule[prop] === 'function') { - methods.push(prop); - } - } - - resolve(methods); + resolve(types.getAllMethodNames(this._foreignModule)); }, reject); }); @@ -648,59 +683,12 @@ export abstract class BaseEditorSimpleWorker { // ---- END foreign module support -------------------------------------------------------------------------- } -/** - * @internal - */ -export class EditorSimpleWorkerImpl extends BaseEditorSimpleWorker implements IRequestHandler, IDisposable { - _requestHandlerBrand: any; - - private _models: { [uri: string]: MirrorModel; }; - - constructor(foreignModuleFactory: IForeignModuleFactory | null) { - super(foreignModuleFactory); - this._models = Object.create(null); - } - - public dispose(): void { - this._models = Object.create(null); - } - - protected _getModel(uri: string): ICommonModel { - return this._models[uri]; - } - - protected _getModels(): ICommonModel[] { - let all: MirrorModel[] = []; - Object.keys(this._models).forEach((key) => all.push(this._models[key])); - return all; - } - - public acceptNewModel(data: IRawModelData): void { - this._models[data.url] = new MirrorModel(URI.parse(data.url), data.lines, data.EOL, data.versionId); - } - - public acceptModelChanged(strURL: string, e: IModelChangedEvent): void { - if (!this._models[strURL]) { - return; - } - let model = this._models[strURL]; - model.onEvents(e); - } - - public acceptRemovedModel(strURL: string): void { - if (!this._models[strURL]) { - return; - } - delete this._models[strURL]; - } -} - /** * Called on the worker side * @internal */ -export function create(): IRequestHandler { - return new EditorSimpleWorkerImpl(null); +export function create(host: EditorWorkerHost): IRequestHandler { + return new EditorSimpleWorker(host, null); } // This is only available in a Web Worker diff --git a/src/vs/editor/common/services/editorWorkerServiceImpl.ts b/src/vs/editor/common/services/editorWorkerServiceImpl.ts index d42a7f7782e..1d46cc3a263 100644 --- a/src/vs/editor/common/services/editorWorkerServiceImpl.ts +++ b/src/vs/editor/common/services/editorWorkerServiceImpl.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { IntervalTimer } from 'vs/base/common/async'; -import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; -import { SimpleWorkerClient, logOnceWebWorkerWarning } from 'vs/base/common/worker/simpleWorker'; +import { SimpleWorkerClient, logOnceWebWorkerWarning, IWorkerClient } from 'vs/base/common/worker/simpleWorker'; import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IPosition, Position } from 'vs/editor/common/core/position'; @@ -15,7 +15,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import * as modes from 'vs/editor/common/modes'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; -import { EditorSimpleWorkerImpl } from 'vs/editor/common/services/editorSimpleWorker'; +import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker'; import { IDiffComputationResult, IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; @@ -133,6 +133,8 @@ class WordBasedCompletionItemProvider implements modes.CompletionItemProvider { private readonly _configurationService: ITextResourceConfigurationService; private readonly _modelService: IModelService; + readonly _debugDisplayName = 'wordbasedCompletions'; + constructor( workerManager: WorkerManager, configurationService: ITextResourceConfigurationService, @@ -222,12 +224,12 @@ class WorkerManager extends Disposable { class EditorModelManager extends Disposable { - private readonly _proxy: EditorSimpleWorkerImpl; + private readonly _proxy: EditorSimpleWorker; private readonly _modelService: IModelService; - private _syncedModels: { [modelUrl: string]: IDisposable[]; } = Object.create(null); + private _syncedModels: { [modelUrl: string]: IDisposable; } = Object.create(null); private _syncedModelsLastUsedTime: { [modelUrl: string]: number; } = Object.create(null); - constructor(proxy: EditorSimpleWorkerImpl, modelService: IModelService, keepIdleModels: boolean) { + constructor(proxy: EditorSimpleWorker, modelService: IModelService, keepIdleModels: boolean) { super(); this._proxy = proxy; this._modelService = modelService; @@ -295,14 +297,14 @@ class EditorModelManager extends Disposable { versionId: model.getVersionId() }); - let toDispose: IDisposable[] = []; - toDispose.push(model.onDidChangeContent((e) => { + const toDispose = new DisposableStore(); + toDispose.add(model.onDidChangeContent((e) => { this._proxy.acceptModelChanged(modelUrl.toString(), e); })); - toDispose.push(model.onWillDispose(() => { + toDispose.add(model.onWillDispose(() => { this._stopModelSync(modelUrl); })); - toDispose.push(toDisposable(() => { + toDispose.add(toDisposable(() => { this._proxy.acceptRemovedModel(modelUrl); })); @@ -317,11 +319,6 @@ class EditorModelManager extends Disposable { } } -interface IWorkerClient { - getProxyObject(): Promise; - dispose(): void; -} - class SynchronousWorkerClient implements IWorkerClient { private readonly _instance: T; private readonly _proxyObj: Promise; @@ -340,10 +337,24 @@ class SynchronousWorkerClient implements IWorkerClient } } +export class EditorWorkerHost { + + private readonly _workerClient: EditorWorkerClient; + + constructor(workerClient: EditorWorkerClient) { + this._workerClient = workerClient; + } + + // foreign host request + public fhr(method: string, args: any[]): Promise { + return this._workerClient.fhr(method, args); + } +} + export class EditorWorkerClient extends Disposable { private readonly _modelService: IModelService; - private _worker: IWorkerClient | null; + private _worker: IWorkerClient | null; private readonly _workerFactory: DefaultWorkerFactory; private _modelManager: EditorModelManager | null; @@ -355,37 +366,43 @@ export class EditorWorkerClient extends Disposable { this._modelManager = null; } - private _getOrCreateWorker(): IWorkerClient { + // foreign host request + public fhr(method: string, args: any[]): Promise { + throw new Error(`Not implemented!`); + } + + private _getOrCreateWorker(): IWorkerClient { if (!this._worker) { try { - this._worker = this._register(new SimpleWorkerClient( + this._worker = this._register(new SimpleWorkerClient( this._workerFactory, - 'vs/editor/common/services/editorSimpleWorker' + 'vs/editor/common/services/editorSimpleWorker', + new EditorWorkerHost(this) )); } catch (err) { logOnceWebWorkerWarning(err); - this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl(null)); + this._worker = new SynchronousWorkerClient(new EditorSimpleWorker(new EditorWorkerHost(this), null)); } } return this._worker; } - protected _getProxy(): Promise { + protected _getProxy(): Promise { return this._getOrCreateWorker().getProxyObject().then(undefined, (err) => { logOnceWebWorkerWarning(err); - this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl(null)); + this._worker = new SynchronousWorkerClient(new EditorSimpleWorker(new EditorWorkerHost(this), null)); return this._getOrCreateWorker().getProxyObject(); }); } - private _getOrCreateModelManager(proxy: EditorSimpleWorkerImpl): EditorModelManager { + private _getOrCreateModelManager(proxy: EditorSimpleWorker): EditorModelManager { if (!this._modelManager) { this._modelManager = this._register(new EditorModelManager(proxy, this._modelService, false)); } return this._modelManager; } - protected _withSyncedResources(resources: URI[]): Promise { + protected _withSyncedResources(resources: URI[]): Promise { return this._getProxy().then((proxy) => { this._getOrCreateModelManager(proxy).ensureSyncedResources(resources); return proxy; diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts index 166bec43d97..00a95b42c78 100644 --- a/src/vs/editor/common/services/modelServiceImpl.ts +++ b/src/vs/editor/common/services/modelServiceImpl.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/config/editorOptions'; @@ -30,7 +30,7 @@ class ModelData implements IDisposable { private _languageSelection: ILanguageSelection | null; private _languageSelectionListener: IDisposable | null; - private _modelEventListeners: IDisposable[]; + private readonly _modelEventListeners = new DisposableStore(); constructor( model: ITextModel, @@ -42,9 +42,8 @@ class ModelData implements IDisposable { this._languageSelection = null; this._languageSelectionListener = null; - this._modelEventListeners = []; - this._modelEventListeners.push(model.onWillDispose(() => onWillDispose(model))); - this._modelEventListeners.push(model.onDidChangeLanguage((e) => onDidChangeLanguage(model, e))); + this._modelEventListeners.add(model.onWillDispose(() => onWillDispose(model))); + this._modelEventListeners.add(model.onDidChangeLanguage((e) => onDidChangeLanguage(model, e))); } private _disposeLanguageSelection(): void { @@ -59,7 +58,7 @@ class ModelData implements IDisposable { } public dispose(): void { - this._modelEventListeners = dispose(this._modelEventListeners); + this._modelEventListeners.dispose(); this._disposeLanguageSelection(); } diff --git a/src/vs/editor/common/services/resourceConfiguration.ts b/src/vs/editor/common/services/resourceConfiguration.ts index 79e3624f425..311556df882 100644 --- a/src/vs/editor/common/services/resourceConfiguration.ts +++ b/src/vs/editor/common/services/resourceConfiguration.ts @@ -25,7 +25,7 @@ export interface ITextResourceConfigurationService { * Value can be of native type or an object keyed off the section name. * * @param resource - Resource for which the configuration has to be fetched. - * @param postion - Position in the resource for which configuration has to be fetched. + * @param position - Position in the resource for which configuration has to be fetched. * @param section - Section of the configuraion. * */ diff --git a/src/vs/editor/common/services/webWorker.ts b/src/vs/editor/common/services/webWorker.ts index a75cd977352..0ae55dffaa0 100644 --- a/src/vs/editor/common/services/webWorker.ts +++ b/src/vs/editor/common/services/webWorker.ts @@ -6,6 +6,7 @@ import { URI } from 'vs/base/common/uri'; import { EditorWorkerClient } from 'vs/editor/common/services/editorWorkerServiceImpl'; import { IModelService } from 'vs/editor/common/services/modelService'; +import * as types from 'vs/base/common/types'; /** * Create a new web worker that has model syncing capabilities built in. @@ -48,11 +49,16 @@ export interface IWebWorkerOptions { * A label to be used to identify the web worker for debugging purposes. */ label?: string; + /** + * An object that can be used by the web worker to make calls back to the main thread. + */ + host?: any; } class MonacoWebWorkerImpl extends EditorWorkerClient implements MonacoWebWorker { private readonly _foreignModuleId: string; + private readonly _foreignModuleHost: { [method: string]: Function } | null; private _foreignModuleCreateData: any | null; private _foreignProxy: Promise | null; @@ -60,13 +66,28 @@ class MonacoWebWorkerImpl extends EditorWorkerClient implements MonacoWebWork super(modelService, opts.label); this._foreignModuleId = opts.moduleId; this._foreignModuleCreateData = opts.createData || null; + this._foreignModuleHost = opts.host || null; this._foreignProxy = null; } + // foreign host request + public fhr(method: string, args: any[]): Promise { + if (!this._foreignModuleHost || typeof this._foreignModuleHost[method] !== 'function') { + return Promise.reject(new Error('Missing method ' + method + ' or missing main thread foreign host.')); + } + + try { + return Promise.resolve(this._foreignModuleHost[method].apply(this._foreignModuleHost, args)); + } catch (e) { + return Promise.reject(e); + } + } + private _getForeignProxy(): Promise { if (!this._foreignProxy) { this._foreignProxy = this._getProxy().then((proxy) => { - return proxy.loadForeignModule(this._foreignModuleId, this._foreignModuleCreateData).then((foreignMethods) => { + const foreignHostMethods = this._foreignModuleHost ? types.getAllMethodNames(this._foreignModuleHost) : []; + return proxy.loadForeignModule(this._foreignModuleId, this._foreignModuleCreateData, foreignHostMethods).then((foreignMethods) => { this._foreignModuleCreateData = null; const proxyMethodRequest = (method: string, args: any[]): Promise => { diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index 113afbafc34..df80861b2a8 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -228,6 +228,13 @@ export enum OverviewRulerLane { Full = 7 } +/** + * Position in the minimap to render the decoration. + */ +export enum MinimapPosition { + Inline = 1 +} + /** * End of line character preference. */ diff --git a/src/vs/editor/contrib/codeAction/codeAction.ts b/src/vs/editor/contrib/codeAction/codeAction.ts index 0888af550ee..93873f17ffb 100644 --- a/src/vs/editor/contrib/codeAction/codeAction.ts +++ b/src/vs/editor/contrib/codeAction/codeAction.ts @@ -132,6 +132,7 @@ registerLanguageCommand('_executeCodeActionProvider', async function (accessor, model.validateRange(range), { type: 'manual', filter: { includeSourceActions: true, kind: kind && kind.value ? new CodeActionKind(kind.value) : undefined } }, CancellationToken.None); - codeActionSet.dispose(); + + setTimeout(() => codeActionSet.dispose(), 0); return codeActionSet.actions; }); diff --git a/src/vs/editor/contrib/codeAction/codeActionCommands.ts b/src/vs/editor/contrib/codeAction/codeActionCommands.ts index 520d3140b43..4484c4405dc 100644 --- a/src/vs/editor/contrib/codeAction/codeActionCommands.ts +++ b/src/vs/editor/contrib/codeAction/codeActionCommands.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { Disposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { escapeRegExpCharacters } from 'vs/base/common/strings'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, EditorCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; @@ -12,21 +12,21 @@ import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { CodeAction } from 'vs/editor/common/modes'; +import { CodeActionUi } from 'vs/editor/contrib/codeAction/codeActionUi'; import { MessageController } from 'vs/editor/contrib/message/messageController'; import * as nls from 'vs/nls'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IMarkerService } from 'vs/platform/markers/common/markers'; -import { ILocalProgressService } from 'vs/platform/progress/common/progress'; -import { CodeActionModel, SUPPORTED_CODE_ACTIONS, CodeActionsState } from './codeActionModel'; -import { CodeActionAutoApply, CodeActionFilter, CodeActionKind, CodeActionTrigger } from './codeActionTrigger'; -import { CodeActionWidget } from './codeActionWidget'; -import { LightBulbWidget } from './lightBulbWidget'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { onUnexpectedError } from 'vs/base/common/errors'; +import { IMarkerService } from 'vs/platform/markers/common/markers'; +import { IEditorProgressService } from 'vs/platform/progress/common/progress'; +import { CodeActionModel, CodeActionsState, SUPPORTED_CODE_ACTIONS } from './codeActionModel'; +import { CodeActionAutoApply, CodeActionFilter, CodeActionKind, CodeActionTrigger } from './codeActionTrigger'; import { CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction'; +import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; +import { IPosition } from 'vs/editor/common/core/position'; function contextKeyForSupportedActions(kind: CodeActionKind) { return ContextKeyExpr.regex( @@ -34,6 +34,7 @@ function contextKeyForSupportedActions(kind: CodeActionKind) { new RegExp('(\\s|^)' + escapeRegExpCharacters(kind.value) + '\\b')); } + export class QuickFixController extends Disposable implements IEditorContribution { private static readonly ID = 'editor.contrib.quickFixController'; @@ -44,89 +45,43 @@ export class QuickFixController extends Disposable implements IEditorContributio private readonly _editor: ICodeEditor; private readonly _model: CodeActionModel; - private readonly _codeActionWidget: CodeActionWidget; - private readonly _lightBulbWidget: LightBulbWidget; - private _currentCodeActions: CodeActionSet | undefined; + private readonly _ui: CodeActionUi; constructor( editor: ICodeEditor, @IMarkerService markerService: IMarkerService, @IContextKeyService contextKeyService: IContextKeyService, - @ILocalProgressService progressService: ILocalProgressService, + @IEditorProgressService progressService: IEditorProgressService, @IContextMenuService contextMenuService: IContextMenuService, + @IKeybindingService keybindingService: IKeybindingService, @ICommandService private readonly _commandService: ICommandService, - @IKeybindingService private readonly _keybindingService: IKeybindingService, @IBulkEditService private readonly _bulkEditService: IBulkEditService, ) { super(); this._editor = editor; this._model = this._register(new CodeActionModel(this._editor, markerService, contextKeyService, progressService)); - this._codeActionWidget = new CodeActionWidget(editor, contextMenuService, { - onSelectCodeAction: async (action) => { + this._register(this._model.onDidChangeState((newState) => this.update(newState))); + + this._ui = this._register(new CodeActionUi(editor, QuickFixAction.Id, { + applyCodeAction: async (action, retrigger) => { try { await this._applyCodeAction(action); } finally { - // Retrigger - this._trigger({ type: 'auto', filter: {} }); - } - } - }); - this._lightBulbWidget = this._register(new LightBulbWidget(editor)); - - this._updateLightBulbTitle(); - - this._register(this._lightBulbWidget.onClick(this._handleLightBulbSelect, this)); - this._register(this._model.onDidChangeState((newState) => this._onDidChangeCodeActionsState(newState))); - this._register(this._keybindingService.onDidUpdateKeybindings(this._updateLightBulbTitle, this)); - } - - dipose() { - super.dispose(); - dispose(this._currentCodeActions); - } - - private _onDidChangeCodeActionsState(newState: CodeActionsState.State): void { - if (newState.type === CodeActionsState.Type.Triggered) { - newState.actions.then(actions => { - dispose(this._currentCodeActions); - this._currentCodeActions = actions; - - if (!actions.actions.length && newState.trigger.context) { - MessageController.get(this._editor).showMessage(newState.trigger.context.notAvailableMessage, newState.trigger.context.position); - } - }); - - if (newState.trigger.filter && newState.trigger.filter.kind) { - // Triggered for specific scope - newState.actions.then(codeActions => { - if (codeActions.actions.length > 0) { - // Apply if we only have one action or requested autoApply - if (newState.trigger.autoApply === CodeActionAutoApply.First || (newState.trigger.autoApply === CodeActionAutoApply.IfSingle && codeActions.actions.length === 1)) { - this._applyCodeAction(codeActions.actions[0]); - return; - } + if (retrigger) { + this._trigger({ type: 'auto', filter: {} }); } - this._codeActionWidget.show(newState.actions, newState.position); - - }).catch(onUnexpectedError); - } else if (newState.trigger.type === 'manual') { - this._codeActionWidget.show(newState.actions, newState.position); - } else { - // auto magically triggered - // * update an existing list of code actions - // * manage light bulb - if (this._codeActionWidget.isVisible) { - this._codeActionWidget.show(newState.actions, newState.position); - } else { - this._lightBulbWidget.tryShow(newState); } } - } else { - dispose(this._currentCodeActions); - this._currentCodeActions = undefined; - this._lightBulbWidget.hide(); - } + }, contextMenuService, keybindingService)); + } + + private update(newState: CodeActionsState.State): void { + this._ui.update(newState); + } + + public showCodeActions(actions: Promise, at: IAnchor | IPosition) { + return this._ui.showCodeActionList(actions, at); } public getId(): string { @@ -151,21 +106,6 @@ export class QuickFixController extends Disposable implements IEditorContributio return this._model.trigger(trigger); } - private _handleLightBulbSelect(e: { x: number, y: number, state: CodeActionsState.Triggered }): void { - this._codeActionWidget.show(e.state.actions, e); - } - - private _updateLightBulbTitle(): void { - const kb = this._keybindingService.lookupKeybinding(QuickFixAction.Id); - let title: string; - if (kb) { - title = nls.localize('quickFixWithKb', "Show Fixes ({0})", kb.getLabel()); - } else { - title = nls.localize('quickFix', "Show Fixes"); - } - this._lightBulbWidget.title = title; - } - private _applyCodeAction(action: CodeAction): Promise { return applyCodeAction(action, this._bulkEditService, this._commandService, this._editor); } diff --git a/src/vs/editor/contrib/codeAction/codeActionModel.ts b/src/vs/editor/contrib/codeAction/codeActionModel.ts index 8b6cc5a4863..d1b33028aee 100644 --- a/src/vs/editor/contrib/codeAction/codeActionModel.ts +++ b/src/vs/editor/contrib/codeAction/codeActionModel.ts @@ -14,7 +14,7 @@ import { Selection } from 'vs/editor/common/core/selection'; import { CodeActionProviderRegistry } from 'vs/editor/common/modes'; import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IMarkerService } from 'vs/platform/markers/common/markers'; -import { ILocalProgressService } from 'vs/platform/progress/common/progress'; +import { IEditorProgressService } from 'vs/platform/progress/common/progress'; import { getCodeActions, CodeActionSet } from './codeAction'; import { CodeActionTrigger } from './codeActionTrigger'; @@ -107,7 +107,7 @@ class CodeActionOracle extends Disposable { } } } - return selection ? selection : undefined; + return selection; } private _createEventAndSignalChange(trigger: CodeActionTrigger, selection: Selection | undefined): TriggeredCodeAction { @@ -167,7 +167,7 @@ export class CodeActionModel extends Disposable { private readonly _editor: ICodeEditor, private readonly _markerService: IMarkerService, contextKeyService: IContextKeyService, - private readonly _progressService?: ILocalProgressService + private readonly _progressService?: IEditorProgressService ) { super(); this._supportedCodeActions = SUPPORTED_CODE_ACTIONS.bindTo(contextKeyService); diff --git a/src/vs/editor/contrib/codeAction/codeActionUi.ts b/src/vs/editor/contrib/codeAction/codeActionUi.ts new file mode 100644 index 00000000000..8b5bf92538d --- /dev/null +++ b/src/vs/editor/contrib/codeAction/codeActionUi.ts @@ -0,0 +1,113 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { onUnexpectedError } from 'vs/base/common/errors'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { CodeAction } from 'vs/editor/common/modes'; +import { CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction'; +import { MessageController } from 'vs/editor/contrib/message/messageController'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { CodeActionsState } from './codeActionModel'; +import { CodeActionAutoApply } from './codeActionTrigger'; +import { CodeActionWidget } from './codeActionWidget'; +import { LightBulbWidget } from './lightBulbWidget'; +import { IPosition } from 'vs/editor/common/core/position'; +import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; + +export class CodeActionUi extends Disposable { + + private readonly _codeActionWidget: CodeActionWidget; + private readonly _lightBulbWidget: LightBulbWidget; + private readonly _activeCodeActions = this._register(new MutableDisposable()); + + constructor( + private readonly _editor: ICodeEditor, + quickFixActionId: string, + private readonly delegate: { + applyCodeAction: (action: CodeAction, regtriggerAfterApply: boolean) => void + }, + @IContextMenuService contextMenuService: IContextMenuService, + @IKeybindingService keybindingService: IKeybindingService, + ) { + super(); + + this._codeActionWidget = this._register(new CodeActionWidget(this._editor, contextMenuService, { + onSelectCodeAction: async (action) => { + this.delegate.applyCodeAction(action, /* retrigger */ true); + } + })); + this._lightBulbWidget = this._register(new LightBulbWidget(this._editor, quickFixActionId, keybindingService)); + + this._register(this._lightBulbWidget.onClick(this._handleLightBulbSelect, this)); + } + + public async update(newState: CodeActionsState.State): Promise { + if (newState.type !== CodeActionsState.Type.Triggered) { + this._lightBulbWidget.hide(); + return; + } + + let actions: CodeActionSet; + try { + actions = await newState.actions; + } catch (e) { + onUnexpectedError(e); + return; + } + + this._lightBulbWidget.update(actions, newState.position); + + if (!actions.actions.length && newState.trigger.context) { + MessageController.get(this._editor).showMessage(newState.trigger.context.notAvailableMessage, newState.trigger.context.position); + this._activeCodeActions.value = actions; + return; + } + + if (newState.trigger.type === 'manual') { + if (newState.trigger.filter && newState.trigger.filter.kind) { + // Triggered for specific scope + if (actions.actions.length > 0) { + // Apply if we only have one action or requested autoApply + if (newState.trigger.autoApply === CodeActionAutoApply.First || (newState.trigger.autoApply === CodeActionAutoApply.IfSingle && actions.actions.length === 1)) { + try { + await this.delegate.applyCodeAction(actions.actions[0], false); + } finally { + actions.dispose(); + } + return; + } + } + } + this._activeCodeActions.value = actions; + this._codeActionWidget.show(actions, newState.position); + } else { + // auto magically triggered + if (this._codeActionWidget.isVisible) { + // TODO: Figure out if we should update the showing menu? + actions.dispose(); + } else { + this._activeCodeActions.value = actions; + } + } + } + + public async showCodeActionList(codeActions: Promise, at?: IAnchor | IPosition): Promise { + let actions: CodeActionSet; + try { + actions = await codeActions; + } catch (e) { + onUnexpectedError(e); + return; + } + + this._codeActionWidget.show(actions, at); + } + + private _handleLightBulbSelect(e: { x: number, y: number, actions: CodeActionSet }): void { + this._codeActionWidget.show(e.actions, e); + } +} diff --git a/src/vs/editor/contrib/codeAction/codeActionWidget.ts b/src/vs/editor/contrib/codeAction/codeActionWidget.ts index f05a1aba075..ebbeeccb1ee 100644 --- a/src/vs/editor/contrib/codeAction/codeActionWidget.ts +++ b/src/vs/editor/contrib/codeAction/codeActionWidget.ts @@ -7,28 +7,32 @@ import { getDomNodePagePosition } from 'vs/base/browser/dom'; import { Action } from 'vs/base/common/actions'; import { canceled } from 'vs/base/common/errors'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { Position } from 'vs/editor/common/core/position'; +import { Position, IPosition } from 'vs/editor/common/core/position'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { CodeAction } from 'vs/editor/common/modes'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; interface CodeActionWidgetDelegate { onSelectCodeAction: (action: CodeAction) => Promise; } -export class CodeActionWidget { +export class CodeActionWidget extends Disposable { private _visible: boolean; + private readonly _showingActions = this._register(new MutableDisposable()); constructor( private readonly _editor: ICodeEditor, private readonly _contextMenuService: IContextMenuService, - private readonly _delegate: CodeActionWidgetDelegate - ) { } + private readonly _delegate: CodeActionWidgetDelegate, + ) { + super(); + } - public async show(actionsToShow: Promise, at?: { x: number; y: number } | Position): Promise { - const codeActions = await actionsToShow; + public async show(codeActions: CodeActionSet, at?: IAnchor | IPosition): Promise { if (!codeActions.actions.length) { this._visible = false; return; @@ -41,6 +45,8 @@ export class CodeActionWidget { this._visible = true; const actions = codeActions.actions.map(action => this.codeActionToAction(action)); + + this._showingActions.value = codeActions; this._contextMenuService.showContextMenu({ getAnchor: () => { if (Position.isIPosition(at)) { @@ -67,7 +73,7 @@ export class CodeActionWidget { return this._visible; } - private _toCoords(position: Position): { x: number, y: number } { + private _toCoords(position: IPosition): { x: number, y: number } { if (!this._editor.hasModel()) { return { x: 0, y: 0 }; } diff --git a/src/vs/editor/contrib/codeAction/lightBulbWidget.css b/src/vs/editor/contrib/codeAction/lightBulbWidget.css index e496371d9a4..df27dfd2104 100644 --- a/src/vs/editor/contrib/codeAction/lightBulbWidget.css +++ b/src/vs/editor/contrib/codeAction/lightBulbWidget.css @@ -18,11 +18,11 @@ } .monaco-editor.vs .lightbulb-glyph { - background: url('lightbulb.svg') center center no-repeat; + background: url('lightbulb-light.svg') center center no-repeat; } .monaco-editor.vs .lightbulb-glyph.autofixable { - background: url('lightbulb-autofix.svg') center center no-repeat; + background: url('lightbulb-autofix-light.svg') center center no-repeat; } .monaco-editor.vs-dark .lightbulb-glyph, diff --git a/src/vs/editor/contrib/codeAction/lightBulbWidget.ts b/src/vs/editor/contrib/codeAction/lightBulbWidget.ts index aadc318a386..455798e4a9d 100644 --- a/src/vs/editor/contrib/codeAction/lightBulbWidget.ts +++ b/src/vs/editor/contrib/codeAction/lightBulbWidget.ts @@ -5,48 +5,70 @@ import * as dom from 'vs/base/browser/dom'; import { GlobalMouseMoveMonitor, IStandardMouseMoveEventData, standardMouseMoveMerger } from 'vs/base/browser/globalMouseMoveMonitor'; -import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import 'vs/css!./lightBulbWidget'; import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser'; +import { IPosition } from 'vs/editor/common/core/position'; import { TextModel } from 'vs/editor/common/model/textModel'; import { CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction'; -import { CodeActionsState } from './codeActionModel'; +import * as nls from 'vs/nls'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; + +namespace LightBulbState { + + export const enum Type { + Hidden, + Showing, + } + + export const Hidden = new class { readonly type = Type.Hidden; }; + + export class Showing { + readonly type = Type.Showing; + + constructor( + public readonly actions: CodeActionSet, + public readonly editorPosition: IPosition, + public readonly widgetPosition: IContentWidgetPosition, + ) { } + } + + export type State = typeof Hidden | Showing; +} + export class LightBulbWidget extends Disposable implements IContentWidget { private static readonly _posPref = [ContentWidgetPositionPreference.EXACT]; private readonly _domNode: HTMLDivElement; - private readonly _editor: ICodeEditor; - private readonly _onClick = this._register(new Emitter<{ x: number; y: number; state: CodeActionsState.Triggered }>()); + private readonly _onClick = this._register(new Emitter<{ x: number; y: number; actions: CodeActionSet }>()); public readonly onClick = this._onClick.event; - private _position: IContentWidgetPosition | null; - private _state: CodeActionsState.State = CodeActionsState.Empty; - private _futureFixes = new CancellationTokenSource(); + private _state: LightBulbState.State = LightBulbState.Hidden; - constructor(editor: ICodeEditor) { + constructor( + private readonly _editor: ICodeEditor, + private readonly _quickFixActionId: string, + @IKeybindingService private readonly _keybindingService: IKeybindingService + ) { super(); this._domNode = document.createElement('div'); this._domNode.className = 'lightbulb-glyph'; - this._editor = editor; this._editor.addContentWidget(this); - this._register(this._editor.onDidChangeModel(_ => this._futureFixes.cancel())); - this._register(this._editor.onDidChangeModelLanguage(_ => this._futureFixes.cancel())); this._register(this._editor.onDidChangeModelContent(_ => { // cancel when the line in question has been removed const editorModel = this._editor.getModel(); - if (this._state.type !== CodeActionsState.Type.Triggered || !editorModel || this._state.position.lineNumber >= editorModel.getLineCount()) { - this._futureFixes.cancel(); + if (this._state.type !== LightBulbState.Type.Showing || !editorModel || this._state.editorPosition.lineNumber >= editorModel.getLineCount()) { + this.hide(); } })); this._register(dom.addStandardDisposableListener(this._domNode, 'mousedown', e => { - if (this._state.type !== CodeActionsState.Type.Triggered) { + if (this._state.type !== LightBulbState.Type.Showing) { return; } @@ -59,14 +81,14 @@ export class LightBulbWidget extends Disposable implements IContentWidget { const { lineHeight } = this._editor.getConfiguration(); let pad = Math.floor(lineHeight / 3); - if (this._position && this._position.position !== null && this._position.position.lineNumber < this._state.position.lineNumber) { + if (this._state.widgetPosition.position !== null && this._state.widgetPosition.position.lineNumber < this._state.editorPosition.lineNumber) { pad += lineHeight; } this._onClick.fire({ x: e.posx, y: top + height + pad, - state: this._state + actions: this._state.actions }); })); this._register(dom.addDisposableListener(this._domNode, 'mouseenter', (e: MouseEvent) => { @@ -88,6 +110,9 @@ export class LightBulbWidget extends Disposable implements IContentWidget { this.hide(); } })); + + this._updateLightBulbTitle(); + this._register(this._keybindingService.onDidUpdateKeybindings(this._updateLightBulbTitle, this)); } dispose(): void { @@ -104,55 +129,23 @@ export class LightBulbWidget extends Disposable implements IContentWidget { } getPosition(): IContentWidgetPosition | null { - return this._position; + return this._state.type === LightBulbState.Type.Showing ? this._state.widgetPosition : null; } - tryShow(newState: CodeActionsState.Triggered) { - if (this._position && (!newState.position || this._position.position && this._position.position.lineNumber !== newState.position.lineNumber)) { - // hide when getting a 'hide'-request or when currently - // showing on another line - this.hide(); - } else if (this._futureFixes) { - // cancel pending show request in any case - this._futureFixes.cancel(); + public update(actions: CodeActionSet, atPosition: IPosition) { + if (actions.actions.length <= 0) { + return this.hide(); } - this._futureFixes = new CancellationTokenSource(); - const { token } = this._futureFixes; - this._state = newState; - - const selection = this._state.rangeOrSelection; - this._state.actions.then(fixes => { - if (!token.isCancellationRequested && fixes.actions.length > 0 && selection) { - this._show(fixes); - } else { - this.hide(); - } - }).catch(() => { - this.hide(); - }); - } - - set title(value: string) { - this._domNode.title = value; - } - - get title(): string { - return this._domNode.title; - } - - private _show(codeActions: CodeActionSet): void { const config = this._editor.getConfiguration(); if (!config.contribInfo.lightbulbEnabled) { - return; + return this.hide(); } - if (this._state.type !== CodeActionsState.Type.Triggered) { - return; - } - const { lineNumber, column } = this._state.position; + + const { lineNumber, column } = atPosition; const model = this._editor.getModel(); if (!model) { - return; + return this.hide(); } const tabSize = model.getOptions().tabSize; @@ -172,23 +165,35 @@ export class LightBulbWidget extends Disposable implements IContentWidget { } else if (column * config.fontInfo.spaceWidth < 22) { // cannot show lightbulb above/below and showing // it inline would overlay the cursor... - this.hide(); - return; + return this.hide(); } } - this._position = { + this._state = new LightBulbState.Showing(actions, atPosition, { position: { lineNumber: effectiveLineNumber, column: 1 }, preference: LightBulbWidget._posPref - }; - dom.toggleClass(this._domNode, 'autofixable', codeActions.hasAutoFix); + }); + dom.toggleClass(this._domNode, 'autofixable', actions.hasAutoFix); this._editor.layoutContentWidget(this); } - hide(): void { - this._position = null; - this._state = CodeActionsState.Empty; - this._futureFixes.cancel(); + private set title(value: string) { + this._domNode.title = value; + } + + public hide(): void { + this._state = LightBulbState.Hidden; this._editor.layoutContentWidget(this); } + + private _updateLightBulbTitle(): void { + const kb = this._keybindingService.lookupKeybinding(this._quickFixActionId); + let title: string; + if (kb) { + title = nls.localize('quickFixWithKb', "Show Fixes ({0})", kb.getLabel()); + } else { + title = nls.localize('quickFix', "Show Fixes"); + } + this.title = title; + } } diff --git a/src/vs/editor/contrib/codeAction/lightbulb-autofix-dark.svg b/src/vs/editor/contrib/codeAction/lightbulb-autofix-dark.svg index 40678e79d7d..34d4f3aedf6 100644 --- a/src/vs/editor/contrib/codeAction/lightbulb-autofix-dark.svg +++ b/src/vs/editor/contrib/codeAction/lightbulb-autofix-dark.svg @@ -1,10 +1,4 @@ - - - - - - - - + + diff --git a/src/vs/editor/contrib/codeAction/lightbulb-autofix-hc.svg b/src/vs/editor/contrib/codeAction/lightbulb-autofix-hc.svg new file mode 100644 index 00000000000..34d4f3aedf6 --- /dev/null +++ b/src/vs/editor/contrib/codeAction/lightbulb-autofix-hc.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/editor/contrib/codeAction/lightbulb-autofix-light.svg b/src/vs/editor/contrib/codeAction/lightbulb-autofix-light.svg new file mode 100644 index 00000000000..c34a0c2805d --- /dev/null +++ b/src/vs/editor/contrib/codeAction/lightbulb-autofix-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/editor/contrib/codeAction/lightbulb-dark.svg b/src/vs/editor/contrib/codeAction/lightbulb-dark.svg index 520f78f3e55..d2b6e1287a1 100644 --- a/src/vs/editor/contrib/codeAction/lightbulb-dark.svg +++ b/src/vs/editor/contrib/codeAction/lightbulb-dark.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/src/vs/editor/contrib/codeAction/lightbulb-hc.svg b/src/vs/editor/contrib/codeAction/lightbulb-hc.svg new file mode 100644 index 00000000000..d2b6e1287a1 --- /dev/null +++ b/src/vs/editor/contrib/codeAction/lightbulb-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/codeAction/lightbulb-light.svg b/src/vs/editor/contrib/codeAction/lightbulb-light.svg new file mode 100644 index 00000000000..8572effd089 --- /dev/null +++ b/src/vs/editor/contrib/codeAction/lightbulb-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/editor/contrib/codelens/codeLensCache.ts b/src/vs/editor/contrib/codelens/codeLensCache.ts index 3df6eb028c5..9bddbb1d355 100644 --- a/src/vs/editor/contrib/codelens/codeLensCache.ts +++ b/src/vs/editor/contrib/codelens/codeLensCache.ts @@ -9,9 +9,10 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { CodeLensModel } from 'vs/editor/contrib/codelens/codelens'; import { LRUCache, values } from 'vs/base/common/map'; import { CodeLensProvider, CodeLensList, CodeLens } from 'vs/editor/common/modes'; -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { IStorageService, StorageScope, WillSaveStateReason } from 'vs/platform/storage/common/storage'; import { Range } from 'vs/editor/common/core/range'; import { runWhenIdle } from 'vs/base/common/async'; +import { once } from 'vs/base/common/functional'; export const ICodeLensCache = createDecorator('ICodeLensCache'); @@ -59,9 +60,10 @@ export class CodeLensCache implements ICodeLensCache { this._deserialize(raw); // store lens data on shutdown - const listener = storageService.onWillSaveState(() => { - storageService.store(key, this._serialize(), StorageScope.WORKSPACE); - listener.dispose(); + once(storageService.onWillSaveState)(e => { + if (e.reason === WillSaveStateReason.SHUTDOWN) { + storageService.store(key, this._serialize(), StorageScope.WORKSPACE); + } }); } diff --git a/src/vs/editor/contrib/codelens/codelens.ts b/src/vs/editor/contrib/codelens/codelens.ts index 65ab529f510..96ccedce7ee 100644 --- a/src/vs/editor/contrib/codelens/codelens.ts +++ b/src/vs/editor/contrib/codelens/codelens.ts @@ -101,7 +101,7 @@ registerLanguageCommand('_executeCodeLensProvider', function (accessor, args) { } } - return Promise.all(resolve).finally(() => value.dispose()); + return Promise.all(resolve).finally(() => setTimeout(() => value.dispose(), 0)); }).then(() => { return result; diff --git a/src/vs/editor/contrib/codelens/codelensController.ts b/src/vs/editor/contrib/codelens/codelensController.ts index 6859b18a275..9f36b691705 100644 --- a/src/vs/editor/contrib/codelens/codelensController.ts +++ b/src/vs/editor/contrib/codelens/codelensController.ts @@ -5,11 +5,10 @@ import { CancelablePromise, RunOnceScheduler, createCancelablePromise, disposableTimeout } from 'vs/base/common/async'; import { onUnexpectedError, onUnexpectedExternalError } from 'vs/base/common/errors'; -import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { toDisposable, DisposableStore, dispose } from 'vs/base/common/lifecycle'; import { StableEditorScrollState } from 'vs/editor/browser/core/editorState'; import * as editorBrowser from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; -import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { IModelDecorationsChangeAccessor } from 'vs/editor/common/model'; import { CodeLensProviderRegistry, CodeLens } from 'vs/editor/common/modes'; @@ -29,6 +28,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { private readonly _localToDispose = new DisposableStore(); private _lenses: CodeLensWidget[] = []; private _currentFindCodeLensSymbolsPromise: CancelablePromise | undefined; + private _oldCodeLensModels = new DisposableStore(); private _currentCodeLensModel: CodeLensModel | undefined; private _modelChangeCounter: number = 0; private _currentResolveCodeLensSymbolsPromise: CancelablePromise | undefined; @@ -44,8 +44,8 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { this._globalToDispose.add(this._editor.onDidChangeModel(() => this._onModelChange())); this._globalToDispose.add(this._editor.onDidChangeModelLanguage(() => this._onModelChange())); - this._globalToDispose.add(this._editor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => { - let prevIsEnabled = this._isEnabled; + this._globalToDispose.add(this._editor.onDidChangeConfiguration(() => { + const prevIsEnabled = this._isEnabled; this._isEnabled = this._editor.getConfiguration().contribInfo.codeLens; if (prevIsEnabled !== this._isEnabled) { this._onModelChange(); @@ -58,6 +58,8 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { dispose(): void { this._localDispose(); this._globalToDispose.dispose(); + this._oldCodeLensModels.dispose(); + dispose(this._currentCodeLensModel); } private _localDispose(): void { @@ -71,6 +73,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { this._currentResolveCodeLensSymbolsPromise = undefined; } this._localToDispose.clear(); + this._oldCodeLensModels.clear(); dispose(this._currentCodeLensModel); } @@ -132,8 +135,9 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { this._currentFindCodeLensSymbolsPromise.then(result => { if (counterValue === this._modelChangeCounter) { // only the last one wins - // lifecycle -> dispose old model - dispose(this._currentCodeLensModel); + if (this._currentCodeLensModel) { + this._oldCodeLensModels.add(this._currentCodeLensModel); + } this._currentCodeLensModel = result; // cache model to reduce flicker @@ -147,9 +151,9 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { }, 250); this._localToDispose.add(scheduler); this._localToDispose.add(this._detectVisibleLenses); - this._localToDispose.add(this._editor.onDidChangeModelContent((e) => { - this._editor.changeDecorations((changeAccessor) => { - this._editor.changeViewZones((viewAccessor) => { + this._localToDispose.add(this._editor.onDidChangeModelContent(() => { + this._editor.changeDecorations(decorationsAccessor => { + this._editor.changeViewZones(viewZonesAccessor => { let toDispose: CodeLensWidget[] = []; let lastLensLineNumber: number = -1; @@ -160,17 +164,17 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { toDispose.push(lens); } else { - lens.update(viewAccessor); + lens.update(viewZonesAccessor); lastLensLineNumber = lens.getLineNumber(); } }); let helper = new CodeLensHelper(); toDispose.forEach((l) => { - l.dispose(helper, viewAccessor); + l.dispose(helper, viewZonesAccessor); this._lenses.splice(this._lenses.indexOf(l), 1); }); - helper.commit(changeAccessor); + helper.commit(decorationsAccessor); }); }); @@ -184,15 +188,15 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { this._detectVisibleLenses.schedule(); } })); - this._localToDispose.add(this._editor.onDidLayoutChange(e => { + this._localToDispose.add(this._editor.onDidLayoutChange(() => { this._detectVisibleLenses.schedule(); })); this._localToDispose.add(toDisposable(() => { if (this._editor.getModel()) { const scrollState = StableEditorScrollState.capture(this._editor); - this._editor.changeDecorations((changeAccessor) => { - this._editor.changeViewZones((accessor) => { - this._disposeAllLenses(changeAccessor, accessor); + this._editor.changeDecorations(decorationsAccessor => { + this._editor.changeViewZones(viewZonesAccessor => { + this._disposeAllLenses(decorationsAccessor, viewZonesAccessor); }); }); scrollState.restore(this._editor); @@ -257,10 +261,12 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { const scrollState = StableEditorScrollState.capture(this._editor); - this._editor.changeDecorations((changeAccessor) => { - this._editor.changeViewZones((accessor) => { + this._editor.changeDecorations(decorationsAccessor => { + this._editor.changeViewZones(viewZoneAccessor => { - let codeLensIndex = 0, groupsIndex = 0, helper = new CodeLensHelper(); + const helper = new CodeLensHelper(); + let codeLensIndex = 0; + let groupsIndex = 0; while (groupsIndex < groups.length && codeLensIndex < this._lenses.length) { @@ -268,14 +274,14 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { let codeLensLineNumber = this._lenses[codeLensIndex].getLineNumber(); if (codeLensLineNumber < symbolsLineNumber) { - this._lenses[codeLensIndex].dispose(helper, accessor); + this._lenses[codeLensIndex].dispose(helper, viewZoneAccessor); this._lenses.splice(codeLensIndex, 1); } else if (codeLensLineNumber === symbolsLineNumber) { this._lenses[codeLensIndex].updateCodeLensSymbols(groups[groupsIndex], helper); groupsIndex++; codeLensIndex++; } else { - this._lenses.splice(codeLensIndex, 0, new CodeLensWidget(groups[groupsIndex], this._editor, helper, accessor, () => this._detectVisibleLenses.schedule())); + this._lenses.splice(codeLensIndex, 0, new CodeLensWidget(groups[groupsIndex], this._editor, helper, viewZoneAccessor, () => this._detectVisibleLenses.schedule())); codeLensIndex++; groupsIndex++; } @@ -283,17 +289,17 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { // Delete extra code lenses while (codeLensIndex < this._lenses.length) { - this._lenses[codeLensIndex].dispose(helper, accessor); + this._lenses[codeLensIndex].dispose(helper, viewZoneAccessor); this._lenses.splice(codeLensIndex, 1); } // Create extra symbols while (groupsIndex < groups.length) { - this._lenses.push(new CodeLensWidget(groups[groupsIndex], this._editor, helper, accessor, () => this._detectVisibleLenses.schedule())); + this._lenses.push(new CodeLensWidget(groups[groupsIndex], this._editor, helper, viewZoneAccessor, () => this._detectVisibleLenses.schedule())); groupsIndex++; } - helper.commit(changeAccessor); + helper.commit(decorationsAccessor); }); }); @@ -342,16 +348,20 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { }); return Promise.all(promises).then(() => { - lenses[i].updateCommands(resolvedSymbols); + if (!token.isCancellationRequested) { + lenses[i].updateCommands(resolvedSymbols); + } }); }); return Promise.all(promises); }); - this._currentResolveCodeLensSymbolsPromise.catch(err => { - onUnexpectedError(err); - }).finally(() => { + this._currentResolveCodeLensSymbolsPromise.then(() => { + this._oldCodeLensModels.clear(); // dispose old models once we have updated the UI with the current model + this._currentResolveCodeLensSymbolsPromise = undefined; + }, err => { + onUnexpectedError(err); // can also be cancellation! this._currentResolveCodeLensSymbolsPromise = undefined; }); } diff --git a/src/vs/editor/contrib/colorPicker/colorDetector.ts b/src/vs/editor/contrib/colorPicker/colorDetector.ts index 93ce80a2499..0ccf498c009 100644 --- a/src/vs/editor/contrib/colorPicker/colorDetector.ts +++ b/src/vs/editor/contrib/colorPicker/colorDetector.ts @@ -36,7 +36,7 @@ export class ColorDetector extends Disposable implements IEditorContribution { private _colorDatas = new Map(); private _colorDecoratorIds: string[] = []; - private readonly _decorationsTypes: { [key: string]: boolean } = {}; + private readonly _decorationsTypes = new Set(); private _isEnabled: boolean; @@ -78,7 +78,7 @@ export class ColorDetector extends Disposable implements IEditorContribution { // handle deprecated settings. [languageId].colorDecorators.enable const deprecatedConfig = this._configurationService.getValue<{}>(languageId.language); if (deprecatedConfig) { - const colorDecorators = deprecatedConfig['colorDecorators']; // deprecatedConfig.valueOf('.colorDecorators.enable'); + const colorDecorators = (deprecatedConfig as any)['colorDecorators']; // deprecatedConfig.valueOf('.colorDecorators.enable'); if (colorDecorators && colorDecorators['enable'] !== undefined && !colorDecorators['enable']) { return colorDecorators['enable']; } @@ -180,7 +180,7 @@ export class ColorDetector extends Disposable implements IEditorContribution { let color = `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`; let key = 'colorBox-' + subKey; - if (!this._decorationsTypes[key] && !newDecorationsTypes[key]) { + if (!this._decorationsTypes.has(key) && !newDecorationsTypes[key]) { this._codeEditorService.registerDecorationType(key, { before: { contentText: ' ', @@ -210,11 +210,11 @@ export class ColorDetector extends Disposable implements IEditorContribution { }); } - for (let subType in this._decorationsTypes) { + this._decorationsTypes.forEach(subType => { if (!newDecorationsTypes[subType]) { this._codeEditorService.removeDecorationType(subType); } - } + }); this._colorDecoratorIds = this._editor.deltaDecorations(this._colorDecoratorIds, decorations); } @@ -223,9 +223,9 @@ export class ColorDetector extends Disposable implements IEditorContribution { this._decorationsIds = this._editor.deltaDecorations(this._decorationsIds, []); this._colorDecoratorIds = this._editor.deltaDecorations(this._colorDecoratorIds, []); - for (let subType in this._decorationsTypes) { + this._decorationsTypes.forEach(subType => { this._codeEditorService.removeDecorationType(subType); - } + }); } getColorData(position: Position): IColorData | null { diff --git a/src/vs/editor/contrib/colorPicker/colorPicker.css b/src/vs/editor/contrib/colorPicker/colorPicker.css index b1978528c95..d1d83d46b2b 100644 --- a/src/vs/editor/contrib/colorPicker/colorPicker.css +++ b/src/vs/editor/contrib/colorPicker/colorPicker.css @@ -84,21 +84,21 @@ .colorpicker-body .hue-strip { position: relative; margin-left: 8px; - cursor: -webkit-grab; + cursor: grab; background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); } .colorpicker-body .opacity-strip { position: relative; margin-left: 8px; - cursor: -webkit-grab; + cursor: grab; background: url('images/opacity-background.png'); background-size: 9px 9px; image-rendering: pixelated; } .colorpicker-body .strip.grabbing { - cursor: -webkit-grabbing; + cursor: grabbing; } .colorpicker-body .slider { diff --git a/src/vs/editor/contrib/comment/test/lineCommentCommand.test.ts b/src/vs/editor/contrib/comment/test/lineCommentCommand.test.ts index e9c0c51499a..5f8b23c6ed7 100644 --- a/src/vs/editor/contrib/comment/test/lineCommentCommand.test.ts +++ b/src/vs/editor/contrib/comment/test/lineCommentCommand.test.ts @@ -986,7 +986,8 @@ suite('Editor Contrib - Line Comment in mixed modes', () => { selection, (sel) => new LineCommentCommand(sel, 4, Type.Toggle), expectedLines, - expectedSelection + expectedSelection, + true ); innerMode.dispose(); outerMode.dispose(); diff --git a/src/vs/editor/contrib/contextmenu/contextmenu.ts b/src/vs/editor/contrib/contextmenu/contextmenu.ts index a0c3f8903a5..2209b38da7f 100644 --- a/src/vs/editor/contrib/contextmenu/contextmenu.ts +++ b/src/vs/editor/contrib/contextmenu/contextmenu.ts @@ -10,7 +10,7 @@ import { ActionViewItem, Separator } from 'vs/base/browser/ui/actionbar/actionba import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; import { IAction } from 'vs/base/common/actions'; import { KeyCode, KeyMod, ResolvedKeybinding } from 'vs/base/common/keyCodes'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { EditorAction, ServicesAccessor, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { IEditorContribution, ScrollType } from 'vs/editor/common/editorCommon'; @@ -31,7 +31,7 @@ export class ContextMenuController implements IEditorContribution { return editor.getContribution(ContextMenuController.ID); } - private _toDispose: IDisposable[] = []; + private readonly _toDispose = new DisposableStore(); private _contextMenuIsBeingShownCount: number = 0; private readonly _editor: ICodeEditor; @@ -45,13 +45,13 @@ export class ContextMenuController implements IEditorContribution { ) { this._editor = editor; - this._toDispose.push(this._editor.onContextMenu((e: IEditorMouseEvent) => this._onContextMenu(e))); - this._toDispose.push(this._editor.onMouseWheel((e: IMouseWheelEvent) => { + this._toDispose.add(this._editor.onContextMenu((e: IEditorMouseEvent) => this._onContextMenu(e))); + this._toDispose.add(this._editor.onMouseWheel((e: IMouseWheelEvent) => { if (this._contextMenuIsBeingShownCount > 0) { this._contextViewService.hideContextView(); } })); - this._toDispose.push(this._editor.onKeyDown((e: IKeyboardEvent) => { + this._toDispose.add(this._editor.onKeyDown((e: IKeyboardEvent) => { if (e.keyCode === KeyCode.ContextMenu) { // Chrome is funny like that e.preventDefault(); @@ -217,7 +217,7 @@ export class ContextMenuController implements IEditorContribution { this._contextViewService.hideContextView(); } - this._toDispose = dispose(this._toDispose); + this._toDispose.dispose(); } } diff --git a/src/vs/editor/contrib/dnd/dragAndDropCommand.ts b/src/vs/editor/contrib/dnd/dragAndDropCommand.ts index 12d405648c9..f2c9aa86932 100644 --- a/src/vs/editor/contrib/dnd/dragAndDropCommand.ts +++ b/src/vs/editor/contrib/dnd/dragAndDropCommand.ts @@ -91,7 +91,7 @@ export class DragAndDropCommand implements editorCommon.ICommand { this.selection.endColumn ); } else { - // The target position is before the selection's end postion. Since the selection doesn't contain the target position, the selection is one-line and target position is before this selection. + // The target position is before the selection's end position. Since the selection doesn't contain the target position, the selection is one-line and target position is before this selection. this.targetSelection = new Selection( this.targetPosition.lineNumber - this.selection.endLineNumber + this.selection.startLineNumber, this.targetPosition.column, diff --git a/src/vs/editor/contrib/documentSymbols/media/BooleanData_16x.svg b/src/vs/editor/contrib/documentSymbols/media/BooleanData_16x.svg deleted file mode 100644 index d9fd295d0b6..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/BooleanData_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/BooleanData_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/BooleanData_16x_darkp.svg deleted file mode 100644 index 48e8c5a3838..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/BooleanData_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Class_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Class_16x.svg deleted file mode 100644 index e553c3633e5..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Class_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Class_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Class_16x_darkp.svg deleted file mode 100644 index c43aad29efd..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Class_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/ColorPalette_ColorPalette_16x.svg b/src/vs/editor/contrib/documentSymbols/media/ColorPalette_ColorPalette_16x.svg deleted file mode 100644 index 2af5cc6faef..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/ColorPalette_ColorPalette_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/ColorPalette_ColorPalette_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/ColorPalette_ColorPalette_16x_darkp.svg deleted file mode 100644 index a2df3032cb1..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/ColorPalette_ColorPalette_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Constant_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Constant_16x.svg deleted file mode 100644 index ed2a1751005..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Constant_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Constant_16x_inverse.svg b/src/vs/editor/contrib/documentSymbols/media/Constant_16x_inverse.svg deleted file mode 100644 index 173e427f964..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Constant_16x_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Document_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Document_16x.svg deleted file mode 100644 index 7b36178ab46..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Document_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Document_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Document_16x_darkp.svg deleted file mode 100644 index bced3a467ee..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Document_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/EnumItem_16x.svg b/src/vs/editor/contrib/documentSymbols/media/EnumItem_16x.svg deleted file mode 100755 index aa901ec1934..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/EnumItem_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/EnumItem_inverse_16x.svg b/src/vs/editor/contrib/documentSymbols/media/EnumItem_inverse_16x.svg deleted file mode 100755 index 791759092fc..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/EnumItem_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Enumerator_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Enumerator_16x.svg deleted file mode 100755 index e4a9551fd5a..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Enumerator_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Enumerator_inverse_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Enumerator_inverse_16x.svg deleted file mode 100755 index d8e9f4f107a..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Enumerator_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Event_16x_vscode.svg b/src/vs/editor/contrib/documentSymbols/media/Event_16x_vscode.svg deleted file mode 100644 index 0e202ec10be..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Event_16x_vscode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Event_16x_vscode_inverse.svg b/src/vs/editor/contrib/documentSymbols/media/Event_16x_vscode_inverse.svg deleted file mode 100644 index a508edcd3d6..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Event_16x_vscode_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Field_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Field_16x.svg deleted file mode 100644 index e1b5aa5e31d..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Field_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Field_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Field_16x_darkp.svg deleted file mode 100644 index 5fc48ceff0f..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Field_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Indexer_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Indexer_16x.svg deleted file mode 100644 index ff55f31ffa3..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Indexer_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Indexer_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Indexer_16x_darkp.svg deleted file mode 100644 index 2f3788e7730..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Indexer_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/IntelliSenseKeyword_16x.svg b/src/vs/editor/contrib/documentSymbols/media/IntelliSenseKeyword_16x.svg deleted file mode 100644 index 7a80c7fe260..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/IntelliSenseKeyword_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/IntelliSenseKeyword_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/IntelliSenseKeyword_16x_darkp.svg deleted file mode 100644 index ef98b5133fd..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/IntelliSenseKeyword_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Interface_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Interface_16x.svg deleted file mode 100644 index 0c08c8d50af..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Interface_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Interface_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Interface_16x_darkp.svg deleted file mode 100644 index f7c2934a55c..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Interface_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/LocalVariable_16x_vscode.svg b/src/vs/editor/contrib/documentSymbols/media/LocalVariable_16x_vscode.svg deleted file mode 100644 index e78894b6c63..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/LocalVariable_16x_vscode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/LocalVariable_16x_vscode_inverse.svg b/src/vs/editor/contrib/documentSymbols/media/LocalVariable_16x_vscode_inverse.svg deleted file mode 100644 index 44a44b489d1..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/LocalVariable_16x_vscode_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Method_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Method_16x.svg deleted file mode 100644 index e1b587f9cc0..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Method_16x.svg +++ /dev/null @@ -1 +0,0 @@ -Method_16x \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Method_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Method_16x_darkp.svg deleted file mode 100644 index 0b7dd26efd3..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Method_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ -Method_16x \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Namespace_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Namespace_16x.svg deleted file mode 100644 index 772b9152cb5..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Namespace_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Namespace_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Namespace_16x_darkp.svg deleted file mode 100644 index dc052a068ca..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Namespace_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Numeric_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Numeric_16x.svg deleted file mode 100644 index ac848f89b8c..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Numeric_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Numeric_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Numeric_16x_darkp.svg deleted file mode 100644 index 4144eea0c06..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Numeric_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Operator_16x_vscode.svg b/src/vs/editor/contrib/documentSymbols/media/Operator_16x_vscode.svg deleted file mode 100644 index ba2f2d091cf..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Operator_16x_vscode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Operator_16x_vscode_inverse.svg b/src/vs/editor/contrib/documentSymbols/media/Operator_16x_vscode_inverse.svg deleted file mode 100644 index 21e1e814b2e..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Operator_16x_vscode_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Property_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Property_16x.svg deleted file mode 100644 index cac629e1132..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Property_16x.svg +++ /dev/null @@ -1 +0,0 @@ -Property_16x \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Property_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Property_16x_darkp.svg deleted file mode 100644 index bad83c9a321..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Property_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ -Property_16x \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Snippet_16x.svg b/src/vs/editor/contrib/documentSymbols/media/Snippet_16x.svg deleted file mode 100644 index 640c247786e..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Snippet_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Snippet_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/Snippet_16x_darkp.svg deleted file mode 100644 index 0fb4b8bc9e3..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Snippet_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/String_16x.svg b/src/vs/editor/contrib/documentSymbols/media/String_16x.svg deleted file mode 100644 index 880d50dd03f..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/String_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/String_16x_darkp.svg b/src/vs/editor/contrib/documentSymbols/media/String_16x_darkp.svg deleted file mode 100644 index de3ea3b37eb..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/String_16x_darkp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Structure_16x_vscode.svg b/src/vs/editor/contrib/documentSymbols/media/Structure_16x_vscode.svg deleted file mode 100644 index e776cbc5651..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Structure_16x_vscode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Structure_16x_vscode_inverse.svg b/src/vs/editor/contrib/documentSymbols/media/Structure_16x_vscode_inverse.svg deleted file mode 100644 index 1b76b62be9a..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Structure_16x_vscode_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Template_16x_vscode.svg b/src/vs/editor/contrib/documentSymbols/media/Template_16x_vscode.svg deleted file mode 100644 index 788cc8d6450..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Template_16x_vscode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/Template_16x_vscode_inverse.svg b/src/vs/editor/contrib/documentSymbols/media/Template_16x_vscode_inverse.svg deleted file mode 100644 index 6cec71cb033..00000000000 --- a/src/vs/editor/contrib/documentSymbols/media/Template_16x_vscode_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/documentSymbols/media/boolean-dark.svg b/src/vs/editor/contrib/documentSymbols/media/boolean-dark.svg new file mode 100644 index 00000000000..e009568b131 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/boolean-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/boolean-light.svg b/src/vs/editor/contrib/documentSymbols/media/boolean-light.svg new file mode 100644 index 00000000000..06613f8bedd --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/boolean-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/class-dark.svg b/src/vs/editor/contrib/documentSymbols/media/class-dark.svg new file mode 100644 index 00000000000..a71e221f6bd --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/class-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/class-light.svg b/src/vs/editor/contrib/documentSymbols/media/class-light.svg new file mode 100644 index 00000000000..aa106f18f87 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/class-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/constant-dark.svg b/src/vs/editor/contrib/documentSymbols/media/constant-dark.svg new file mode 100644 index 00000000000..0e90ecafcd8 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/constant-dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/constant-light.svg b/src/vs/editor/contrib/documentSymbols/media/constant-light.svg new file mode 100644 index 00000000000..1a369c1d8aa --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/constant-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/enumerator-dark.svg b/src/vs/editor/contrib/documentSymbols/media/enumerator-dark.svg new file mode 100644 index 00000000000..82d4ff29c44 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/enumerator-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/enumerator-item-dark.svg b/src/vs/editor/contrib/documentSymbols/media/enumerator-item-dark.svg new file mode 100644 index 00000000000..23c697fdf17 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/enumerator-item-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/enumerator-item-light.svg b/src/vs/editor/contrib/documentSymbols/media/enumerator-item-light.svg new file mode 100644 index 00000000000..a99045d3352 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/enumerator-item-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/enumerator-light.svg b/src/vs/editor/contrib/documentSymbols/media/enumerator-light.svg new file mode 100644 index 00000000000..e2441a0dc16 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/enumerator-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/event-dark.svg b/src/vs/editor/contrib/documentSymbols/media/event-dark.svg new file mode 100644 index 00000000000..051bef316e9 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/event-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/event-light.svg b/src/vs/editor/contrib/documentSymbols/media/event-light.svg new file mode 100644 index 00000000000..712344d1f92 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/event-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/field-dark.svg b/src/vs/editor/contrib/documentSymbols/media/field-dark.svg new file mode 100644 index 00000000000..15623061c5d --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/field-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/field-light.svg b/src/vs/editor/contrib/documentSymbols/media/field-light.svg new file mode 100644 index 00000000000..72dd79504f6 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/field-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/file-dark.svg b/src/vs/editor/contrib/documentSymbols/media/file-dark.svg new file mode 100644 index 00000000000..5ed5762a1f0 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/file-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/file-light.svg b/src/vs/editor/contrib/documentSymbols/media/file-light.svg new file mode 100644 index 00000000000..ad54e13b1b1 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/file-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/indexer-dark.svg b/src/vs/editor/contrib/documentSymbols/media/indexer-dark.svg new file mode 100644 index 00000000000..e92131d3d02 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/indexer-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/indexer-light.svg b/src/vs/editor/contrib/documentSymbols/media/indexer-light.svg new file mode 100644 index 00000000000..207899642c8 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/indexer-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/interface-dark.svg b/src/vs/editor/contrib/documentSymbols/media/interface-dark.svg new file mode 100644 index 00000000000..6d482b2abde --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/interface-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/interface-light.svg b/src/vs/editor/contrib/documentSymbols/media/interface-light.svg new file mode 100644 index 00000000000..a397dd00b00 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/interface-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/workbench/browser/media/images/intellisense/keyword-alt1.svg b/src/vs/editor/contrib/documentSymbols/media/keyword-dark.svg similarity index 89% rename from src/vs/workbench/browser/media/images/intellisense/keyword-alt1.svg rename to src/vs/editor/contrib/documentSymbols/media/keyword-dark.svg index f21364efec0..70ba6ea9331 100644 --- a/src/vs/workbench/browser/media/images/intellisense/keyword-alt1.svg +++ b/src/vs/editor/contrib/documentSymbols/media/keyword-dark.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/editor/contrib/documentSymbols/media/keyword-light.svg b/src/vs/editor/contrib/documentSymbols/media/keyword-light.svg new file mode 100644 index 00000000000..fc57528a3ef --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/keyword-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/method-dark.svg b/src/vs/editor/contrib/documentSymbols/media/method-dark.svg new file mode 100644 index 00000000000..970d7b61480 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/method-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/method-light.svg b/src/vs/editor/contrib/documentSymbols/media/method-light.svg new file mode 100644 index 00000000000..403a9b90dd9 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/method-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/namespace-dark.svg b/src/vs/editor/contrib/documentSymbols/media/namespace-dark.svg new file mode 100644 index 00000000000..9a725bb41fd --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/namespace-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/namespace-light.svg b/src/vs/editor/contrib/documentSymbols/media/namespace-light.svg new file mode 100644 index 00000000000..1339da7ce21 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/namespace-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/numeric-dark.svg b/src/vs/editor/contrib/documentSymbols/media/numeric-dark.svg new file mode 100644 index 00000000000..a1573df0107 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/numeric-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/numeric-light.svg b/src/vs/editor/contrib/documentSymbols/media/numeric-light.svg new file mode 100644 index 00000000000..ea0e56e0225 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/numeric-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/operator-dark.svg b/src/vs/editor/contrib/documentSymbols/media/operator-dark.svg new file mode 100644 index 00000000000..957f5f44f17 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/operator-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/operator-light.svg b/src/vs/editor/contrib/documentSymbols/media/operator-light.svg new file mode 100644 index 00000000000..bf6ed57996a --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/operator-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/property-dark.svg b/src/vs/editor/contrib/documentSymbols/media/property-dark.svg new file mode 100644 index 00000000000..23e07ffa19b --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/property-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/property-light.svg b/src/vs/editor/contrib/documentSymbols/media/property-light.svg new file mode 100644 index 00000000000..be642dd152d --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/property-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/snippet-dark.svg b/src/vs/editor/contrib/documentSymbols/media/snippet-dark.svg new file mode 100644 index 00000000000..79799f98c26 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/snippet-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/snippet-light.svg b/src/vs/editor/contrib/documentSymbols/media/snippet-light.svg new file mode 100644 index 00000000000..45fa3a001e8 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/snippet-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/string-dark.svg b/src/vs/editor/contrib/documentSymbols/media/string-dark.svg new file mode 100644 index 00000000000..80fb9d6567d --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/string-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/string-light.svg b/src/vs/editor/contrib/documentSymbols/media/string-light.svg new file mode 100644 index 00000000000..02a0282e906 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/string-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/structure-dark.svg b/src/vs/editor/contrib/documentSymbols/media/structure-dark.svg new file mode 100644 index 00000000000..13766a5dcea --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/structure-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/structure-light.svg b/src/vs/editor/contrib/documentSymbols/media/structure-light.svg new file mode 100644 index 00000000000..c96bcfa61b0 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/structure-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/symbol-icons.css b/src/vs/editor/contrib/documentSymbols/media/symbol-icons.css index 2a6a31185fa..2579de84f34 100644 --- a/src/vs/editor/contrib/documentSymbols/media/symbol-icons.css +++ b/src/vs/editor/contrib/documentSymbols/media/symbol-icons.css @@ -15,268 +15,269 @@ width: 16px; min-height: 14px; min-width: 16px; + background-position: center; } /* default icons */ .monaco-workbench .symbol-icon { - background-image: url('Field_16x.svg'); + background-image: url('field-light.svg'); background-repeat: no-repeat; } .vs-dark .monaco-workbench .symbol-icon, .hc-black .monaco-workbench .symbol-icon { - background-image: url('Field_16x_darkp.svg'); + background-image: url('field-dark.svg'); } /* constant */ .monaco-workbench .symbol-icon.constant { - background-image: url('Constant_16x.svg'); + background-image: url('constant-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.constant, .hc-black .monaco-workbench .symbol-icon.constant { - background-image: url('Constant_16x_inverse.svg'); + background-image: url('constant-dark.svg'); } /* enum */ .monaco-workbench .symbol-icon.enum { - background-image: url('Enumerator_16x.svg'); + background-image: url('enumerator-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.enum, .hc-black .monaco-workbench .symbol-icon.enum { - background-image: url('Enumerator_inverse_16x.svg'); + background-image: url('enumerator-dark.svg'); } /* enum-member */ .monaco-workbench .symbol-icon.enum-member { - background-image: url('EnumItem_16x.svg'); + background-image: url('enumerator-item-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.enum-member, .hc-black .monaco-workbench .symbol-icon.enum-member { - background-image: url('EnumItem_inverse_16x.svg'); + background-image: url('enumerator-item-dark.svg'); } /* struct */ .monaco-workbench .symbol-icon.struct { - background-image: url('Structure_16x_vscode.svg'); + background-image: url('structure-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.struct, .hc-black .monaco-workbench .symbol-icon.struct { - background-image: url('Structure_16x_vscode_inverse.svg'); + background-image: url('structure-dark.svg'); } /* event */ .monaco-workbench .symbol-icon.event { - background-image: url('Event_16x_vscode.svg'); + background-image: url('event-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.event, .hc-black .monaco-workbench .symbol-icon.event { - background-image: url('Event_16x_vscode_inverse.svg'); + background-image: url('event-dark.svg'); } /* operator */ .monaco-workbench .symbol-icon.operator { - background-image: url('Operator_16x_vscode.svg'); + background-image: url('operator-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.operator, .hc-black .monaco-workbench .symbol-icon.operator { - background-image: url('Operator_16x_vscode_inverse.svg'); + background-image: url('operator-dark.svg'); } /* type paramter */ .monaco-workbench .symbol-icon.type-parameter { - background-image: url('Template_16x_vscode.svg'); + background-image: url('template-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.type-parameter, .hc-black .monaco-workbench .symbol-icon.type-parameter { - background-image: url('Template_16x_vscode_inverse.svg'); + background-image: url('template-dark.svg'); } /* boolean, null */ .monaco-workbench .symbol-icon.boolean { - background-image: url('BooleanData_16x.svg'); + background-image: url('boolean-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.boolean, .hc-black .monaco-workbench .symbol-icon.boolean { - background-image: url('BooleanData_16x_darkp.svg'); + background-image: url('boolean-dark.svg'); } /* null */ .monaco-workbench .symbol-icon.null { - background-image: url('BooleanData_16x.svg'); + background-image: url('boolean-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.null, .hc-black .monaco-workbench .symbol-icon.null { - background-image: url('BooleanData_16x_darkp.svg'); + background-image: url('boolean-dark.svg'); } /* class */ .monaco-workbench .symbol-icon.class { - background-image: url('Class_16x.svg'); + background-image: url('class-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.class, .hc-black .monaco-workbench .symbol-icon.class { - background-image: url('Class_16x_darkp.svg'); + background-image: url('class-dark.svg'); } /* constructor */ .monaco-workbench .symbol-icon.constructor { - background-image: url('Method_16x.svg'); + background-image: url('method-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.constructor, .hc-black .monaco-workbench .symbol-icon.constructor { - background-image: url('Method_16x_darkp.svg'); + background-image: url('method-dark.svg'); } /* file */ .monaco-workbench .symbol-icon.file { - background-image: url('Document_16x.svg'); + background-image: url('file-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.file, .hc-black .monaco-workbench .symbol-icon.file { - background-image: url('Document_16x_darkp.svg'); + background-image: url('file-dark.svg'); } /* field */ .monaco-workbench .symbol-icon.field { - background-image: url('Field_16x.svg'); + background-image: url('field-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.field, .hc-black .monaco-workbench .symbol-icon.field { - background-image: url('Field_16x_darkp.svg'); + background-image: url('field-dark.svg'); } /* variable */ .monaco-workbench .symbol-icon.variable { - background-image: url('LocalVariable_16x_vscode.svg'); + background-image: url('variable-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.variable, .hc-black .monaco-workbench .symbol-icon.variable { - background-image: url('LocalVariable_16x_vscode_inverse.svg'); + background-image: url('variable-dark.svg'); } /* array */ .monaco-workbench .symbol-icon.array { - background-image: url('Indexer_16x.svg'); + background-image: url('indexer-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.array, .hc-black .monaco-workbench .symbol-icon.array { - background-image: url('Indexer_16x_darkp.svg'); + background-image: url('indexer-dark.svg'); } /* keyword */ /* todo@joh not used? */ .monaco-workbench .symbol-icon.keyword { - background-image: url('IntelliSenseKeyword_16x.svg'); + background-image: url('keyword-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.keyword, .hc-black .monaco-workbench .symbol-icon.keyword { - background-image: url('IntelliSenseKeyword_16x_darkp.svg'); + background-image: url('keyword-light.svg'); } /* interface */ .monaco-workbench .symbol-icon.interface { - background-image: url('Interface_16x.svg'); + background-image: url('interface-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.interface, .hc-black .monaco-workbench .symbol-icon.interface { - background-image: url('Interface_16x_darkp.svg'); + background-image: url('interface-dark.svg'); } /* method */ .monaco-workbench .symbol-icon.method { - background-image: url('Method_16x.svg'); + background-image: url('method-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.method, .hc-black .monaco-workbench .symbol-icon.method { - background-image: url('Method_16x_darkp.svg'); + background-image: url('method-dark.svg'); } /* function */ .monaco-workbench .symbol-icon.function { - background-image: url('Method_16x.svg'); + background-image: url('method-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.function, .hc-black .monaco-workbench .symbol-icon.function { - background-image: url('Method_16x_darkp.svg'); + background-image: url('method-dark.svg'); } /* object */ .monaco-workbench .symbol-icon.object { - background-image: url('Namespace_16x.svg'); + background-image: url('namespace-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.object, .hc-black .monaco-workbench .symbol-icon.object { - background-image: url('Namespace_16x_darkp.svg'); + background-image: url('namespace-dark.svg'); } /* namespace */ .monaco-workbench .symbol-icon.namespace { - background-image: url('Namespace_16x.svg'); + background-image: url('namespace-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.namespace, .hc-black .monaco-workbench .symbol-icon.namespace { - background-image: url('Namespace_16x_darkp.svg'); + background-image: url('namespace-dark.svg'); } /* package */ .monaco-workbench .symbol-icon.package { - background-image: url('Namespace_16x.svg'); + background-image: url('namespace-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.package, .hc-black .monaco-workbench .symbol-icon.package { - background-image: url('Namespace_16x_darkp.svg'); + background-image: url('namespace-dark.svg'); } /* module */ .monaco-workbench .symbol-icon.module { - background-image: url('Namespace_16x.svg'); + background-image: url('namespace-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.module, .hc-black .monaco-workbench .symbol-icon.module { - background-image: url('Namespace_16x_darkp.svg'); + background-image: url('namespace-dark.svg'); } /* number */ .monaco-workbench .symbol-icon.number { - background-image: url('Numeric_16x.svg'); + background-image: url('numeric-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.number, .hc-black .monaco-workbench .symbol-icon.number { - background-image: url('Numeric_16x_darkp.svg'); + background-image: url('numeric-dark.svg'); } /* property */ .monaco-workbench .symbol-icon.property { - background-image: url('Property_16x.svg'); + background-image: url('property-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.property, .hc-black .monaco-workbench .symbol-icon.property { - background-image: url('Property_16x_darkp.svg'); + background-image: url('property-dark.svg'); } /* snippet */ /* todo@joh unused? */ .monaco-workbench .symbol-icon.snippet { - background-image: url('Snippet_16x.svg'); + background-image: url('snippet-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.snippet, .hc-black .monaco-workbench .symbol-icon.snippet { - background-image: url('Snippet_16x_darkp.svg'); + background-image: url('snippet-dark.svg'); } /* string */ .monaco-workbench .symbol-icon.string { - background-image: url('String_16x.svg'); + background-image: url('string-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.string, .hc-black .monaco-workbench .symbol-icon.string { - background-image: url('String_16x_darkp.svg'); + background-image: url('string-dark.svg'); } /* key */ .monaco-workbench .symbol-icon.key { - background-image: url('String_16x.svg'); + background-image: url('string-light.svg'); } .vs-dark .monaco-workbench .symbol-icon.key, .hc-black .monaco-workbench .symbol-icon.key { - background-image: url('String_16x_darkp.svg'); + background-image: url('string-dark.svg'); } diff --git a/src/vs/editor/contrib/documentSymbols/media/template-dark.svg b/src/vs/editor/contrib/documentSymbols/media/template-dark.svg new file mode 100644 index 00000000000..425ced36f0e --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/template-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/template-light.svg b/src/vs/editor/contrib/documentSymbols/media/template-light.svg new file mode 100644 index 00000000000..496d8f7c85c --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/template-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/variable-dark.svg b/src/vs/editor/contrib/documentSymbols/media/variable-dark.svg new file mode 100644 index 00000000000..687fcabfff5 --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/variable-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/media/variable-light.svg b/src/vs/editor/contrib/documentSymbols/media/variable-light.svg new file mode 100644 index 00000000000..ede7e9434dd --- /dev/null +++ b/src/vs/editor/contrib/documentSymbols/media/variable-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/documentSymbols/outlineTree.ts b/src/vs/editor/contrib/documentSymbols/outlineTree.ts index 926d6a3da2f..551ff4b4726 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineTree.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineTree.ts @@ -15,20 +15,18 @@ import { Range } from 'vs/editor/common/core/range'; import { SymbolKind, symbolKindToCssClass } from 'vs/editor/common/modes'; import { OutlineElement, OutlineGroup, OutlineModel, TreeElement } from 'vs/editor/contrib/documentSymbols/outlineModel'; import { localize } from 'vs/nls'; -import { IKeybindingService, IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { OutlineConfigKeys } from 'vs/editor/contrib/documentSymbols/outline'; import { MarkerSeverity } from 'vs/platform/markers/common/markers'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { listErrorForeground, listWarningForeground } from 'vs/platform/theme/common/colorRegistry'; +import { IdleValue } from 'vs/base/common/async'; export type OutlineItem = OutlineGroup | OutlineElement; export class OutlineNavigationLabelProvider implements IKeyboardNavigationLabelProvider { - constructor(@IKeybindingService private readonly _keybindingService: IKeybindingService) { } - getKeyboardNavigationLabel(element: OutlineItem): { toString(): string; } { if (element instanceof OutlineGroup) { return element.provider.displayName || element.id; @@ -36,10 +34,6 @@ export class OutlineNavigationLabelProvider implements IKeyboardNavigationLabelP return element.symbol.name; } } - - mightProducePrintableCharacter(event: IKeyboardEvent): boolean { - return this._keybindingService.mightProducePrintableCharacter(event); - } } @@ -215,6 +209,8 @@ export const enum OutlineSortOrder { export class OutlineItemComparator implements ITreeSorter { + private readonly _collator = new IdleValue(() => new Intl.Collator(undefined, { numeric: true })); + constructor( public type: OutlineSortOrder = OutlineSortOrder.ByPosition ) { } @@ -225,11 +221,11 @@ export class OutlineItemComparator implements ITreeSorter { } else if (a instanceof OutlineElement && b instanceof OutlineElement) { if (this.type === OutlineSortOrder.ByKind) { - return a.symbol.kind - b.symbol.kind || a.symbol.name.localeCompare(b.symbol.name); + return a.symbol.kind - b.symbol.kind || this._collator.getValue().compare(a.symbol.name, b.symbol.name); } else if (this.type === OutlineSortOrder.ByName) { - return a.symbol.name.localeCompare(b.symbol.name) || Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range); + return this._collator.getValue().compare(a.symbol.name, b.symbol.name) || Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range); } else if (this.type === OutlineSortOrder.ByPosition) { - return Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range) || a.symbol.name.localeCompare(b.symbol.name); + return Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range) || this._collator.getValue().compare(a.symbol.name, b.symbol.name); } } return 0; diff --git a/src/vs/editor/contrib/find/findDecorations.ts b/src/vs/editor/contrib/find/findDecorations.ts index bb115977387..ee93bccc3cf 100644 --- a/src/vs/editor/contrib/find/findDecorations.ts +++ b/src/vs/editor/contrib/find/findDecorations.ts @@ -7,9 +7,9 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { IActiveCodeEditor } from 'vs/editor/browser/editorBrowser'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; -import { FindMatch, IModelDecorationsChangeAccessor, IModelDeltaDecoration, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model'; +import { FindMatch, IModelDecorationsChangeAccessor, IModelDeltaDecoration, OverviewRulerLane, TrackedRangeStickiness, MinimapPosition } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; -import { overviewRulerFindMatchForeground } from 'vs/platform/theme/common/colorRegistry'; +import { overviewRulerFindMatchForeground, minimapFindMatch } from 'vs/platform/theme/common/colorRegistry'; import { themeColorFromId } from 'vs/platform/theme/common/themeService'; export class FindDecorations implements IDisposable { @@ -269,6 +269,10 @@ export class FindDecorations implements IDisposable { overviewRuler: { color: themeColorFromId(overviewRulerFindMatchForeground), position: OverviewRulerLane.Center + }, + minimap: { + color: themeColorFromId(minimapFindMatch), + position: MinimapPosition.Inline } }); @@ -279,6 +283,10 @@ export class FindDecorations implements IDisposable { overviewRuler: { color: themeColorFromId(overviewRulerFindMatchForeground), position: OverviewRulerLane.Center + }, + minimap: { + color: themeColorFromId(minimapFindMatch), + position: MinimapPosition.Inline } }); diff --git a/src/vs/editor/contrib/find/findWidget.css b/src/vs/editor/contrib/find/findWidget.css index b6fbab87454..0f2a7720c67 100644 --- a/src/vs/editor/contrib/find/findWidget.css +++ b/src/vs/editor/contrib/find/findWidget.css @@ -96,8 +96,8 @@ display: flex; display: -webkit-flex; flex: initial; - margin: 0 1px 0 3px; - padding: 2px 2px 0 2px; + margin: 0 0 0 3px; + padding: 2px 0 0 2px; height: 25px; vertical-align: middle; box-sizing: border-box; @@ -151,11 +151,11 @@ } .monaco-editor .find-widget .previous { - background-image: url('images/previous.svg'); + background-image: url('images/chevron-previous-light.svg'); } .monaco-editor .find-widget .next { - background-image: url('images/next.svg'); + background-image: url('images/chevron-next-light.svg'); } .monaco-editor .find-widget .disabled { @@ -175,8 +175,8 @@ content: ''; display: inline-block; background-repeat: no-repeat; - background-position: 0 0; - background-image: url('images/cancelSelectionFind.svg'); + background-position: center; + background-image: url('images/find-selection-light.svg'); width: 20px; height: 20px; border: none; @@ -200,23 +200,23 @@ } .monaco-editor .find-widget .close-fw { - background-image: url('images/close.svg'); + background-image: url('images/close-light.svg'); } .monaco-editor .find-widget .expand { - background-image: url('images/expando-expanded.svg'); + background-image: url('images/tree-expanded-light.svg'); } .monaco-editor .find-widget .collapse { - background-image: url('images/expando-collapsed.svg'); + background-image: url('images/tree-collapsed-light.svg'); } .monaco-editor .find-widget .replace { - background-image: url('images/replace.svg'); + background-image: url('images/replace-light.svg'); } .monaco-editor .find-widget .replace-all { - background-image: url('images/replace-all.svg'); + background-image: url('images/replace-all-light.svg'); } .monaco-editor .find-widget > .replace-part { @@ -272,17 +272,17 @@ .monaco-editor.hc-black .find-widget .previous, .monaco-editor.vs-dark .find-widget .previous { - background-image: url('images/previous-inverse.svg'); + background-image: url('images/chevron-previous-dark.svg'); } .monaco-editor.hc-black .find-widget .next, .monaco-editor.vs-dark .find-widget .next { - background-image: url('images/next-inverse.svg'); + background-image: url('images/chevron-next-dark.svg'); } .monaco-editor.hc-black .find-widget .monaco-checkbox .label, .monaco-editor.vs-dark .find-widget .monaco-checkbox .label { - background-image: url('images/cancelSelectionFind-inverse.svg'); + background-image: url('images/find-selection-dark.svg'); } .monaco-editor.vs-dark .find-widget .monaco-checkbox .checkbox:not(:disabled):hover:before + .label { @@ -300,22 +300,22 @@ .monaco-editor.hc-black .find-widget .replace, .monaco-editor.vs-dark .find-widget .replace { - background-image: url('images/replace-inverse.svg'); + background-image: url('images/replace-dark.svg'); } .monaco-editor.hc-black .find-widget .replace-all, .monaco-editor.vs-dark .find-widget .replace-all { - background-image: url('images/replace-all-inverse.svg'); + background-image: url('images/replace-all-dark.svg'); } .monaco-editor.hc-black .find-widget .expand, .monaco-editor.vs-dark .find-widget .expand { - background-image: url('images/expando-expanded-dark.svg'); + background-image: url('images/tree-expanded-dark.svg'); } .monaco-editor.hc-black .find-widget .collapse, .monaco-editor.vs-dark .find-widget .collapse { - background-image: url('images/expando-collapsed-dark.svg'); + background-image: url('images/tree-collapsed-dark.svg'); } .monaco-editor.hc-black .find-widget .button:not(.disabled):hover, diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 2fba7cf35cf..5e7febe1ccf 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -27,7 +27,7 @@ import { CONTEXT_FIND_INPUT_FOCUSED, CONTEXT_REPLACE_INPUT_FOCUSED, FIND_IDS, MA import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/findState'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { contrastBorder, editorFindMatch, editorFindMatchBorder, editorFindMatchHighlight, editorFindMatchHighlightBorder, editorFindRangeHighlight, editorFindRangeHighlightBorder, editorWidgetBackground, editorWidgetBorder, editorWidgetResizeBorder, errorForeground, inputActiveOptionBorder, inputBackground, inputBorder, inputForeground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground, inputValidationInfoBackground, inputValidationInfoBorder, inputValidationInfoForeground, inputValidationWarningBackground, inputValidationWarningBorder, inputValidationWarningForeground, widgetShadow } from 'vs/platform/theme/common/colorRegistry'; +import { contrastBorder, editorFindMatch, editorFindMatchBorder, editorFindMatchHighlight, editorFindMatchHighlightBorder, editorFindRangeHighlight, editorFindRangeHighlightBorder, editorWidgetBackground, editorWidgetBorder, editorWidgetResizeBorder, errorForeground, inputActiveOptionBorder, inputBackground, inputBorder, inputForeground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground, inputValidationInfoBackground, inputValidationInfoBorder, inputValidationInfoForeground, inputValidationWarningBackground, inputValidationWarningBorder, inputValidationWarningForeground, widgetShadow, editorWidgetForeground } from 'vs/platform/theme/common/colorRegistry'; import { ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ContextScopedFindInput, ContextScopedHistoryInputBox } from 'vs/platform/browser/contextScopedHistoryWidget'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; @@ -1193,6 +1193,11 @@ registerThemingParticipant((theme, collector) => { collector.addRule(`.monaco-editor .find-widget { border: 2px solid ${hcBorder}; }`); } + const foreground = theme.getColor(editorWidgetForeground); + if (foreground) { + collector.addRule(`.monaco-editor .find-widget { color: ${foreground}; }`); + } + const error = theme.getColor(errorForeground); if (error) { collector.addRule(`.monaco-editor .find-widget.no-results .matchesCount { color: ${error}; }`); diff --git a/src/vs/editor/contrib/find/images/cancelSelectionFind-inverse.svg b/src/vs/editor/contrib/find/images/cancelSelectionFind-inverse.svg deleted file mode 100644 index d776fcde98a..00000000000 --- a/src/vs/editor/contrib/find/images/cancelSelectionFind-inverse.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/vs/editor/contrib/find/images/cancelSelectionFind.svg b/src/vs/editor/contrib/find/images/cancelSelectionFind.svg deleted file mode 100644 index cdff5731a82..00000000000 --- a/src/vs/editor/contrib/find/images/cancelSelectionFind.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/vs/editor/contrib/find/images/chevron-next-dark.svg b/src/vs/editor/contrib/find/images/chevron-next-dark.svg new file mode 100644 index 00000000000..dbe70d742de --- /dev/null +++ b/src/vs/editor/contrib/find/images/chevron-next-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/chevron-next-light.svg b/src/vs/editor/contrib/find/images/chevron-next-light.svg new file mode 100644 index 00000000000..ec824f41cc0 --- /dev/null +++ b/src/vs/editor/contrib/find/images/chevron-next-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/chevron-previous-dark.svg b/src/vs/editor/contrib/find/images/chevron-previous-dark.svg new file mode 100644 index 00000000000..5db4f79da85 --- /dev/null +++ b/src/vs/editor/contrib/find/images/chevron-previous-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/chevron-previous-light.svg b/src/vs/editor/contrib/find/images/chevron-previous-light.svg new file mode 100644 index 00000000000..aac3a5020cd --- /dev/null +++ b/src/vs/editor/contrib/find/images/chevron-previous-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/close-dark.svg b/src/vs/editor/contrib/find/images/close-dark.svg index 751e89b3b02..75644595d19 100644 --- a/src/vs/editor/contrib/find/images/close-dark.svg +++ b/src/vs/editor/contrib/find/images/close-dark.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/src/vs/editor/contrib/find/images/close-light.svg b/src/vs/editor/contrib/find/images/close-light.svg new file mode 100644 index 00000000000..cf5f28ca35c --- /dev/null +++ b/src/vs/editor/contrib/find/images/close-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/close.svg b/src/vs/editor/contrib/find/images/close.svg deleted file mode 100644 index fde34404d4e..00000000000 --- a/src/vs/editor/contrib/find/images/close.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/browser/media/images/notifications/close-alt1.svg b/src/vs/editor/contrib/find/images/find-selection-dark.svg similarity index 56% rename from src/vs/workbench/browser/media/images/notifications/close-alt1.svg rename to src/vs/editor/contrib/find/images/find-selection-dark.svg index 64618b61760..6fc07d81a55 100644 --- a/src/vs/workbench/browser/media/images/notifications/close-alt1.svg +++ b/src/vs/editor/contrib/find/images/find-selection-dark.svg @@ -1,4 +1,3 @@ - - + diff --git a/src/vs/editor/contrib/find/images/find-selection-light.svg b/src/vs/editor/contrib/find/images/find-selection-light.svg new file mode 100644 index 00000000000..3608b15d29e --- /dev/null +++ b/src/vs/editor/contrib/find/images/find-selection-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/next-inverse.svg b/src/vs/editor/contrib/find/images/next-inverse.svg deleted file mode 100644 index 50482917af1..00000000000 --- a/src/vs/editor/contrib/find/images/next-inverse.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/vs/editor/contrib/find/images/next.svg b/src/vs/editor/contrib/find/images/next.svg deleted file mode 100644 index a2a011453aa..00000000000 --- a/src/vs/editor/contrib/find/images/next.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/vs/editor/contrib/find/images/previous-inverse.svg b/src/vs/editor/contrib/find/images/previous-inverse.svg deleted file mode 100644 index 8ff41da5daf..00000000000 --- a/src/vs/editor/contrib/find/images/previous-inverse.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/vs/editor/contrib/find/images/previous.svg b/src/vs/editor/contrib/find/images/previous.svg deleted file mode 100644 index 3c8b367a934..00000000000 --- a/src/vs/editor/contrib/find/images/previous.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/vs/editor/contrib/find/images/replace-all-dark.svg b/src/vs/editor/contrib/find/images/replace-all-dark.svg new file mode 100644 index 00000000000..07bd41a789f --- /dev/null +++ b/src/vs/editor/contrib/find/images/replace-all-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/replace-all-inverse.svg b/src/vs/editor/contrib/find/images/replace-all-inverse.svg deleted file mode 100644 index 45312b60899..00000000000 --- a/src/vs/editor/contrib/find/images/replace-all-inverse.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - diff --git a/src/vs/editor/contrib/find/images/replace-all-light.svg b/src/vs/editor/contrib/find/images/replace-all-light.svg new file mode 100644 index 00000000000..cd3974fae7e --- /dev/null +++ b/src/vs/editor/contrib/find/images/replace-all-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/replace-all.svg b/src/vs/editor/contrib/find/images/replace-all.svg deleted file mode 100644 index 4254f7c6d10..00000000000 --- a/src/vs/editor/contrib/find/images/replace-all.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - diff --git a/src/vs/editor/contrib/find/images/replace-dark.svg b/src/vs/editor/contrib/find/images/replace-dark.svg new file mode 100644 index 00000000000..5882b22c589 --- /dev/null +++ b/src/vs/editor/contrib/find/images/replace-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/replace-inverse.svg b/src/vs/editor/contrib/find/images/replace-inverse.svg deleted file mode 100644 index 9a59e263780..00000000000 --- a/src/vs/editor/contrib/find/images/replace-inverse.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/src/vs/editor/contrib/find/images/replace-light.svg b/src/vs/editor/contrib/find/images/replace-light.svg new file mode 100644 index 00000000000..220f2aba40c --- /dev/null +++ b/src/vs/editor/contrib/find/images/replace-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/replace.svg b/src/vs/editor/contrib/find/images/replace.svg deleted file mode 100644 index 8b1eb0de23c..00000000000 --- a/src/vs/editor/contrib/find/images/replace.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/src/vs/editor/contrib/find/images/tree-collapsed-dark.svg b/src/vs/editor/contrib/find/images/tree-collapsed-dark.svg new file mode 100644 index 00000000000..17de497f336 --- /dev/null +++ b/src/vs/editor/contrib/find/images/tree-collapsed-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/tree-collapsed-light.svg b/src/vs/editor/contrib/find/images/tree-collapsed-light.svg new file mode 100644 index 00000000000..296499b8e5c --- /dev/null +++ b/src/vs/editor/contrib/find/images/tree-collapsed-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/tree-expanded-dark.svg b/src/vs/editor/contrib/find/images/tree-expanded-dark.svg new file mode 100644 index 00000000000..a1df6a8d44a --- /dev/null +++ b/src/vs/editor/contrib/find/images/tree-expanded-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/images/tree-expanded-light.svg b/src/vs/editor/contrib/find/images/tree-expanded-light.svg new file mode 100644 index 00000000000..e60e357f573 --- /dev/null +++ b/src/vs/editor/contrib/find/images/tree-expanded-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/find/simpleFindWidget.css b/src/vs/editor/contrib/find/simpleFindWidget.css index 136970945a4..4a796be0870 100644 --- a/src/vs/editor/contrib/find/simpleFindWidget.css +++ b/src/vs/editor/contrib/find/simpleFindWidget.css @@ -52,25 +52,25 @@ } .monaco-workbench .simple-find-part .button.previous { - background-image: url('images/previous.svg'); + background-image: url('images/chevron-previous-light.svg'); } .monaco-workbench .simple-find-part .button.next { - background-image: url('images/next.svg'); + background-image: url('images/chevron-next-light.svg'); } .monaco-workbench .simple-find-part .button.close-fw { - background-image: url('images/close.svg'); + background-image: url('images/close-light.svg'); } .hc-black .monaco-workbench .simple-find-part .button.previous, .vs-dark .monaco-workbench .simple-find-part .button.previous { - background-image: url('images/previous-inverse.svg'); + background-image: url('images/chevron-previous-dark.svg'); } .hc-black .monaco-workbench .simple-find-part .button.next, .vs-dark .monaco-workbench .simple-find-part .button.next { - background-image: url('images/next-inverse.svg'); + background-image: url('images/chevron-next-dark.svg'); } .hc-black .monaco-workbench .simple-find-part .button.close-fw, @@ -78,7 +78,7 @@ background-image: url('images/close-dark.svg'); } -monaco-workbench .simple-find-part .button.disabled { +.monaco-workbench .simple-find-part .button.disabled { opacity: 0.3; cursor: default; } \ No newline at end of file diff --git a/src/vs/editor/contrib/find/simpleFindWidget.ts b/src/vs/editor/contrib/find/simpleFindWidget.ts index 2c1cb22025f..31c75f9f7a6 100644 --- a/src/vs/editor/contrib/find/simpleFindWidget.ts +++ b/src/vs/editor/contrib/find/simpleFindWidget.ts @@ -33,6 +33,9 @@ export abstract class SimpleFindWidget extends Widget { private readonly _focusTracker: dom.IFocusTracker; private readonly _findInputFocusTracker: dom.IFocusTracker; private readonly _updateHistoryDelayer: Delayer; + private prevBtn: SimpleButton; + private nextBtn: SimpleButton; + private foundMatch: boolean; constructor( @IContextViewService private readonly _contextViewService: IContextViewService, @@ -54,6 +57,8 @@ export abstract class SimpleFindWidget extends Widget { new RegExp(value); return null; } catch (e) { + this.foundMatch = false; + this._updateButtons(); return { content: e.message }; } } @@ -63,7 +68,8 @@ export abstract class SimpleFindWidget extends Widget { this._updateHistoryDelayer = new Delayer(500); this.oninput(this._findInput.domNode, (e) => { - this.onInputChanged(); + this.foundMatch = this.onInputChanged(); + this._updateButtons(); this._delayedUpdateHistory(); }); @@ -99,7 +105,7 @@ export abstract class SimpleFindWidget extends Widget { } })); - const prevBtn = this._register(new SimpleButton({ + this.prevBtn = this._register(new SimpleButton({ label: NLS_PREVIOUS_MATCH_BTN_LABEL, className: 'previous', onTrigger: () => { @@ -107,7 +113,7 @@ export abstract class SimpleFindWidget extends Widget { } })); - const nextBtn = this._register(new SimpleButton({ + this.nextBtn = this._register(new SimpleButton({ label: NLS_NEXT_MATCH_BTN_LABEL, className: 'next', onTrigger: () => { @@ -126,8 +132,8 @@ export abstract class SimpleFindWidget extends Widget { this._innerDomNode = document.createElement('div'); this._innerDomNode.classList.add('simple-find-part'); this._innerDomNode.appendChild(this._findInput.domNode); - this._innerDomNode.appendChild(prevBtn.domNode); - this._innerDomNode.appendChild(nextBtn.domNode); + this._innerDomNode.appendChild(this.prevBtn.domNode); + this._innerDomNode.appendChild(this.nextBtn.domNode); this._innerDomNode.appendChild(closeBtn.domNode); // _domNode wraps _innerDomNode, ensuring that @@ -156,7 +162,7 @@ export abstract class SimpleFindWidget extends Widget { })); } - protected abstract onInputChanged(): void; + protected abstract onInputChanged(): boolean; protected abstract find(previous: boolean): void; protected abstract onFocusTrackerFocus(): void; protected abstract onFocusTrackerBlur(): void; @@ -213,6 +219,7 @@ export abstract class SimpleFindWidget extends Widget { } this._isVisible = true; + this._updateButtons(); setTimeout(() => { dom.addClass(this._innerDomNode, 'visible'); @@ -243,6 +250,7 @@ export abstract class SimpleFindWidget extends Widget { // Need to delay toggling visibility until after Transition, then visibility hidden - removes from tabIndex list setTimeout(() => { this._isVisible = false; + this._updateButtons(); dom.removeClass(this._innerDomNode, 'visible'); }, 200); } @@ -267,6 +275,12 @@ export abstract class SimpleFindWidget extends Widget { protected _getCaseSensitiveValue(): boolean { return this._findInput.getCaseSensitive(); } + + private _updateButtons() { + let hasInput = this.inputValue.length > 0; + this.prevBtn.setEnabled(this._isVisible && hasInput && this.foundMatch); + this.nextBtn.setEnabled(this._isVisible && hasInput && this.foundMatch); + } } // theming diff --git a/src/vs/editor/contrib/folding/arrow-collapse-dark.svg b/src/vs/editor/contrib/folding/arrow-collapse-dark.svg deleted file mode 100644 index 1d7ce3b6bcb..00000000000 --- a/src/vs/editor/contrib/folding/arrow-collapse-dark.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/vs/editor/contrib/folding/arrow-collapse.svg b/src/vs/editor/contrib/folding/arrow-collapse.svg deleted file mode 100644 index 9e6896640c8..00000000000 --- a/src/vs/editor/contrib/folding/arrow-collapse.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/vs/editor/contrib/folding/arrow-expand-dark.svg b/src/vs/editor/contrib/folding/arrow-expand-dark.svg deleted file mode 100644 index 4d1a5ca84d7..00000000000 --- a/src/vs/editor/contrib/folding/arrow-expand-dark.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/vs/editor/contrib/folding/arrow-expand.svg b/src/vs/editor/contrib/folding/arrow-expand.svg deleted file mode 100644 index f1472e2751a..00000000000 --- a/src/vs/editor/contrib/folding/arrow-expand.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/vs/editor/contrib/folding/folding.css b/src/vs/editor/contrib/folding/folding.css index b5d3b7049d3..79511b6c0c1 100644 --- a/src/vs/editor/contrib/folding/folding.css +++ b/src/vs/editor/contrib/folding/folding.css @@ -14,12 +14,16 @@ } .monaco-editor .margin-view-overlays .folding { - background-image: url('arrow-expand.svg'); + background-image: url('tree-expanded-light.svg'); } .monaco-editor.hc-black .margin-view-overlays .folding, .monaco-editor.vs-dark .margin-view-overlays .folding { - background-image: url('arrow-expand-dark.svg'); + background-image: url('tree-expanded-dark.svg'); +} + +.monaco-editor.hc-black .margin-view-overlays .folding { + background-image: url('tree-expanded-hc.svg'); } .monaco-editor .margin-view-overlays:hover .folding, @@ -28,13 +32,16 @@ } .monaco-editor .margin-view-overlays .folding.collapsed { - background-image: url('arrow-collapse.svg'); + background-image: url('tree-collapsed-light.svg'); opacity: 1; } -.monaco-editor.hc-black .margin-view-overlays .folding.collapsed, .monaco-editor.vs-dark .margin-view-overlays .folding.collapsed { - background-image: url('arrow-collapse-dark.svg'); + background-image: url('tree-collapsed-dark.svg'); +} + +.monaco-editor.hc-black .margin-view-overlays .folding.collapsed { + background-image: url('tree-collapsed-hc.svg'); } .monaco-editor .inline-folded:after { diff --git a/src/vs/editor/contrib/folding/folding.ts b/src/vs/editor/contrib/folding/folding.ts index e5d922f71f6..9a9ea25c545 100644 --- a/src/vs/editor/contrib/folding/folding.ts +++ b/src/vs/editor/contrib/folding/folding.ts @@ -31,7 +31,9 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { InitializingRangeProvider, ID_INIT_PROVIDER } from 'vs/editor/contrib/folding/intializingRangeProvider'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { onUnexpectedError } from 'vs/base/common/errors'; +import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +const CONTEXT_FOLDING_ENABLED = new RawContextKey('foldingEnabled', false); export const ID = 'editor.contrib.folding'; export interface RangeProvider { @@ -73,12 +75,15 @@ export class FoldingController extends Disposable implements IEditorContribution private foldingModelPromise: Promise | null; private updateScheduler: Delayer | null; - + private foldingEnabled: IContextKey; private cursorChangedScheduler: RunOnceScheduler | null; private readonly localToDispose = this._register(new DisposableStore()); - constructor(editor: ICodeEditor) { + constructor( + editor: ICodeEditor, + @IContextKeyService private readonly contextKeyService: IContextKeyService + ) { super(); this.editor = editor; this._isEnabled = this.editor.getConfiguration().contribInfo.folding; @@ -88,6 +93,8 @@ export class FoldingController extends Disposable implements IEditorContribution this.foldingDecorationProvider = new FoldingDecorationProvider(editor); this.foldingDecorationProvider.autoHideFoldingControls = this._autoHideFoldingControls; + this.foldingEnabled = CONTEXT_FOLDING_ENABLED.bindTo(this.contextKeyService); + this.foldingEnabled.set(this._isEnabled); this._register(this.editor.onDidChangeModel(() => this.onModelChanged())); @@ -95,6 +102,7 @@ export class FoldingController extends Disposable implements IEditorContribution if (e.contribInfo) { let oldIsEnabled = this._isEnabled; this._isEnabled = this.editor.getConfiguration().contribInfo.folding; + this.foldingEnabled.set(this._isEnabled); if (oldIsEnabled !== this._isEnabled) { this.onModelChanged(); } @@ -496,7 +504,7 @@ class UnfoldAction extends FoldingAction { id: 'editor.unfold', label: nls.localize('unfoldAction.label', "Unfold"), alias: 'Unfold', - precondition: undefined, + precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_CLOSE_SQUARE_BRACKET, @@ -560,7 +568,7 @@ class UnFoldRecursivelyAction extends FoldingAction { id: 'editor.unfoldRecursively', label: nls.localize('unFoldRecursivelyAction.label', "Unfold Recursively"), alias: 'Unfold Recursively', - precondition: undefined, + precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.US_CLOSE_SQUARE_BRACKET), @@ -581,7 +589,7 @@ class FoldAction extends FoldingAction { id: 'editor.fold', label: nls.localize('foldAction.label', "Fold"), alias: 'Fold', - precondition: undefined, + precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_OPEN_SQUARE_BRACKET, @@ -645,7 +653,7 @@ class FoldRecursivelyAction extends FoldingAction { id: 'editor.foldRecursively', label: nls.localize('foldRecursivelyAction.label', "Fold Recursively"), alias: 'Fold Recursively', - precondition: undefined, + precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.US_OPEN_SQUARE_BRACKET), @@ -667,7 +675,7 @@ class FoldAllBlockCommentsAction extends FoldingAction { id: 'editor.foldAllBlockComments', label: nls.localize('foldAllBlockComments.label', "Fold All Block Comments"), alias: 'Fold All Block Comments', - precondition: undefined, + precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.US_SLASH), @@ -700,7 +708,7 @@ class FoldAllRegionsAction extends FoldingAction { id: 'editor.foldAllMarkerRegions', label: nls.localize('foldAllMarkerRegions.label', "Fold All Regions"), alias: 'Fold All Regions', - precondition: undefined, + precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_8), @@ -733,7 +741,7 @@ class UnfoldAllRegionsAction extends FoldingAction { id: 'editor.unfoldAllMarkerRegions', label: nls.localize('unfoldAllMarkerRegions.label', "Unfold All Regions"), alias: 'Unfold All Regions', - precondition: undefined, + precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_9), @@ -766,7 +774,7 @@ class FoldAllAction extends FoldingAction { id: 'editor.foldAll', label: nls.localize('foldAllAction.label', "Fold All"), alias: 'Fold All', - precondition: undefined, + precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_0), @@ -787,7 +795,7 @@ class UnfoldAllAction extends FoldingAction { id: 'editor.unfoldAll', label: nls.localize('unfoldAllAction.label', "Unfold All"), alias: 'Unfold All', - precondition: undefined, + precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_J), @@ -831,7 +839,7 @@ for (let i = 1; i <= 7; i++) { id: FoldLevelAction.ID(i), label: nls.localize('foldLevelAction.label', "Fold Level {0}", i), alias: `Fold Level ${i}`, - precondition: undefined, + precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | (KeyCode.KEY_0 + i)), diff --git a/src/vs/editor/contrib/folding/foldingModel.ts b/src/vs/editor/contrib/folding/foldingModel.ts index 0375be9f13f..70906b653eb 100644 --- a/src/vs/editor/contrib/folding/foldingModel.ts +++ b/src/vs/editor/contrib/folding/foldingModel.ts @@ -47,7 +47,7 @@ export class FoldingModel { if (!regions.length) { return; } - let processed = {}; + let processed: { [key: string]: boolean | undefined } = {}; this._decorationProvider.changeDecorations(accessor => { for (let region of regions) { let index = region.regionIndex; diff --git a/src/vs/editor/contrib/folding/tree-collapsed-dark.svg b/src/vs/editor/contrib/folding/tree-collapsed-dark.svg new file mode 100644 index 00000000000..243be1451cc --- /dev/null +++ b/src/vs/editor/contrib/folding/tree-collapsed-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/folding/tree-collapsed-hc.svg b/src/vs/editor/contrib/folding/tree-collapsed-hc.svg new file mode 100644 index 00000000000..40ba72b7086 --- /dev/null +++ b/src/vs/editor/contrib/folding/tree-collapsed-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/folding/tree-collapsed-light.svg b/src/vs/editor/contrib/folding/tree-collapsed-light.svg new file mode 100644 index 00000000000..0d746558a4f --- /dev/null +++ b/src/vs/editor/contrib/folding/tree-collapsed-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/folding/tree-expanded-dark.svg b/src/vs/editor/contrib/folding/tree-expanded-dark.svg new file mode 100644 index 00000000000..5570923e175 --- /dev/null +++ b/src/vs/editor/contrib/folding/tree-expanded-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/folding/tree-expanded-hc.svg b/src/vs/editor/contrib/folding/tree-expanded-hc.svg new file mode 100644 index 00000000000..b370009330c --- /dev/null +++ b/src/vs/editor/contrib/folding/tree-expanded-hc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/folding/tree-expanded-light.svg b/src/vs/editor/contrib/folding/tree-expanded-light.svg new file mode 100644 index 00000000000..939ebc8b969 --- /dev/null +++ b/src/vs/editor/contrib/folding/tree-expanded-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/goToDefinition/goToDefinitionCommands.ts b/src/vs/editor/contrib/goToDefinition/goToDefinitionCommands.ts index bf6e607945c..baad3f0bb17 100644 --- a/src/vs/editor/contrib/goToDefinition/goToDefinitionCommands.ts +++ b/src/vs/editor/contrib/goToDefinition/goToDefinitionCommands.ts @@ -25,7 +25,7 @@ import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { ILocalProgressService } from 'vs/platform/progress/common/progress'; +import { IEditorProgressService } from 'vs/platform/progress/common/progress'; import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition, getDeclarationsAtPosition } from './goToDefinition'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { EditorStateCancellationTokenSource, CodeEditorStateFlag } from 'vs/editor/browser/core/editorState'; @@ -58,7 +58,7 @@ export class DefinitionAction extends EditorAction { } const notificationService = accessor.get(INotificationService); const editorService = accessor.get(ICodeEditorService); - const progressService = accessor.get(ILocalProgressService); + const progressService = accessor.get(IEditorProgressService); const symbolNavService = accessor.get(ISymbolNavigationService); const model = editor.getModel(); diff --git a/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts b/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts index 7c81a73fb15..717c7ba4d13 100644 --- a/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts +++ b/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts @@ -10,13 +10,13 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { onUnexpectedError } from 'vs/base/common/errors'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { Range } from 'vs/editor/common/core/range'; +import { Range, IRange } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { DefinitionProviderRegistry, LocationLink } from 'vs/editor/common/modes'; import { ICodeEditor, IMouseTarget, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { getDefinitionsAtPosition } from './goToDefinition'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { editorActiveLinkForeground } from 'vs/platform/theme/common/colorRegistry'; @@ -33,7 +33,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC static MAX_SOURCE_PREVIEW_LINES = 8; private readonly editor: ICodeEditor; - private toUnhook: IDisposable[]; + private readonly toUnhook = new DisposableStore(); private decorations: string[]; private currentWordUnderMouse: IWordAtPosition | null; private previousPromise: CancelablePromise | null; @@ -43,19 +43,18 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC @ITextModelService private readonly textModelResolverService: ITextModelService, @IModeService private readonly modeService: IModeService ) { - this.toUnhook = []; this.decorations = []; this.editor = editor; this.previousPromise = null; let linkGesture = new ClickLinkGesture(editor); - this.toUnhook.push(linkGesture); + this.toUnhook.add(linkGesture); - this.toUnhook.push(linkGesture.onMouseMoveOrRelevantKeyDown(([mouseEvent, keyboardEvent]) => { + this.toUnhook.add(linkGesture.onMouseMoveOrRelevantKeyDown(([mouseEvent, keyboardEvent]) => { this.startFindDefinition(mouseEvent, withNullAsUndefined(keyboardEvent)); })); - this.toUnhook.push(linkGesture.onExecute((mouseEvent: ClickLinkMouseEvent) => { + this.toUnhook.add(linkGesture.onExecute((mouseEvent: ClickLinkMouseEvent) => { if (this.isEnabled(mouseEvent)) { this.gotoDefinition(mouseEvent.target, mouseEvent.hasSideBySideModifier).then(() => { this.removeDecorations(); @@ -66,7 +65,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC } })); - this.toUnhook.push(linkGesture.onCancel(() => { + this.toUnhook.add(linkGesture.onCancel(() => { this.removeDecorations(); this.currentWordUnderMouse = null; })); @@ -150,7 +149,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC return; } - const previewValue = this.getPreviewValue(textEditorModel, startLineNumber); + const previewValue = this.getPreviewValue(textEditorModel, startLineNumber, result); let wordRange: Range; if (result.originSelectionRange) { @@ -170,8 +169,8 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC }).then(undefined, onUnexpectedError); } - private getPreviewValue(textEditorModel: ITextModel, startLineNumber: number) { - let rangeToUse = this.getPreviewRangeBasedOnBrackets(textEditorModel, startLineNumber); + private getPreviewValue(textEditorModel: ITextModel, startLineNumber: number, result: LocationLink) { + let rangeToUse = result.targetSelectionRange ? result.range : this.getPreviewRangeBasedOnBrackets(textEditorModel, startLineNumber); const numberOfLinesInRange = rangeToUse.endLineNumber - rangeToUse.startLineNumber; if (numberOfLinesInRange >= GotoDefinitionWithMouseEditorContribution.MAX_SOURCE_PREVIEW_LINES) { rangeToUse = this.getPreviewRangeBasedOnIndentation(textEditorModel, startLineNumber); @@ -181,7 +180,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC return previewValue; } - private stripIndentationFromPreviewRange(textEditorModel: ITextModel, startLineNumber: number, previewRange: Range) { + private stripIndentationFromPreviewRange(textEditorModel: ITextModel, startLineNumber: number, previewRange: IRange) { const startIndent = textEditorModel.getLineFirstNonWhitespaceColumn(startLineNumber); let minIndent = startIndent; @@ -303,7 +302,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC } public dispose(): void { - this.toUnhook = dispose(this.toUnhook); + this.toUnhook.dispose(); } } diff --git a/src/vs/editor/contrib/gotoError/gotoError.ts b/src/vs/editor/contrib/gotoError/gotoError.ts index 4e46bd7e2b1..8f1231cbfb8 100644 --- a/src/vs/editor/contrib/gotoError/gotoError.ts +++ b/src/vs/editor/contrib/gotoError/gotoError.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { Emitter } from 'vs/base/common/event'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IMarker, IMarkerService, MarkerSeverity } from 'vs/platform/markers/common/markers'; @@ -206,7 +206,7 @@ export class MarkerController implements editorCommon.IEditorContribution { private _model: MarkerModel | null = null; private _widget: MarkerNavigationWidget | null = null; private readonly _widgetVisible: IContextKey; - private _disposeOnClose: IDisposable[] = []; + private readonly _disposeOnClose = new DisposableStore(); constructor( editor: ICodeEditor, @@ -226,11 +226,12 @@ export class MarkerController implements editorCommon.IEditorContribution { public dispose(): void { this._cleanUp(); + this._disposeOnClose.dispose(); } private _cleanUp(): void { this._widgetVisible.reset(); - this._disposeOnClose = dispose(this._disposeOnClose); + this._disposeOnClose.clear(); this._widget = null; this._model = null; } @@ -255,19 +256,21 @@ export class MarkerController implements editorCommon.IEditorContribution { this._widgetVisible.set(true); this._widget.onDidClose(() => this._cleanUp(), this, this._disposeOnClose); - this._disposeOnClose.push(this._model); - this._disposeOnClose.push(this._widget); - this._disposeOnClose.push(...actions); - this._disposeOnClose.push(this._widget.onDidSelectRelatedInformation(related => { + this._disposeOnClose.add(this._model); + this._disposeOnClose.add(this._widget); + for (const action of actions) { + this._disposeOnClose.add(action); + } + this._disposeOnClose.add(this._widget.onDidSelectRelatedInformation(related => { this._editorService.openCodeEditor({ resource: related.resource, options: { pinned: true, revealIfOpened: true, selection: Range.lift(related).collapseToStart() } }, this._editor).then(undefined, onUnexpectedError); this.closeMarkersNavigation(false); })); - this._disposeOnClose.push(this._editor.onDidChangeModel(() => this._cleanUp())); + this._disposeOnClose.add(this._editor.onDidChangeModel(() => this._cleanUp())); - this._disposeOnClose.push(this._model.onCurrentMarkerChanged(marker => { + this._disposeOnClose.add(this._model.onCurrentMarkerChanged(marker => { if (!marker || !this._model) { this._cleanUp(); } else { @@ -279,7 +282,7 @@ export class MarkerController implements editorCommon.IEditorContribution { }); } })); - this._disposeOnClose.push(this._model.onMarkerSetChanged(() => { + this._disposeOnClose.add(this._model.onMarkerSetChanged(() => { if (!this._widget || !this._widget.position || !this._model) { return; } diff --git a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts index 8f2bef91435..7d93dc2fb37 100644 --- a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts +++ b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts @@ -25,7 +25,6 @@ import { basename } from 'vs/base/common/resources'; import { IAction } from 'vs/base/common/actions'; import { IActionBarOptions, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar'; import { peekViewTitleForeground, peekViewTitleInfoForeground } from 'vs/editor/contrib/referenceSearch/referencesWidget'; -import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon'; class MessageWidget { @@ -286,10 +285,6 @@ export class MarkerNavigationWidget extends PeekViewWidget { this._icon.className = SeverityIcon.className(MarkerSeverity.toSeverity(this._severity)); this.editor.revealPositionInCenter(position, ScrollType.Smooth); - - if (this.editor.getConfiguration().accessibilitySupport !== AccessibilitySupport.Disabled) { - this.focus(); - } } updateMarker(marker: IMarker): void { diff --git a/src/vs/editor/contrib/hover/hover.ts b/src/vs/editor/contrib/hover/hover.ts index b1f7a06c0fe..8dcf20dd2b8 100644 --- a/src/vs/editor/contrib/hover/hover.ts +++ b/src/vs/editor/contrib/hover/hover.ts @@ -25,9 +25,6 @@ import { editorHoverBackground, editorHoverBorder, editorHoverHighlight, textCod import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; -import { ICommandService } from 'vs/platform/commands/common/commands'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; export class ModesHoverController implements IEditorContribution { @@ -68,9 +65,6 @@ export class ModesHoverController implements IEditorContribution { @IModeService private readonly _modeService: IModeService, @IMarkerDecorationsService private readonly _markerDecorationsService: IMarkerDecorationsService, @IKeybindingService private readonly _keybindingService: IKeybindingService, - @IContextMenuService private readonly _contextMenuService: IContextMenuService, - @IBulkEditService private readonly _bulkEditService: IBulkEditService, - @ICommandService private readonly _commandService: ICommandService, @IThemeService private readonly _themeService: IThemeService ) { this._isMouseDown = false; @@ -211,7 +205,7 @@ export class ModesHoverController implements IEditorContribution { } private _createHoverWidget() { - this._contentWidget = new ModesContentHoverWidget(this._editor, this._markerDecorationsService, this._themeService, this._keybindingService, this._contextMenuService, this._bulkEditService, this._commandService, this._modeService, this._openerService); + this._contentWidget = new ModesContentHoverWidget(this._editor, this._markerDecorationsService, this._themeService, this._keybindingService, this._modeService, this._openerService); this._glyphWidget = new ModesGlyphHoverWidget(this._editor, this._modeService, this._openerService); } diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index b195cec1938..80c7a0661c9 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -8,12 +8,12 @@ import * as dom from 'vs/base/browser/dom'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Color, RGBA } from 'vs/base/common/color'; import { IMarkdownString, MarkdownString, isEmptyMarkdownString, markedStringsEquals } from 'vs/base/common/htmlContent'; -import { Disposable, IDisposable, toDisposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, toDisposable, DisposableStore, combinedDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; -import { DocumentColorProvider, Hover as MarkdownHover, HoverProviderRegistry, IColor } from 'vs/editor/common/modes'; +import { DocumentColorProvider, Hover as MarkdownHover, HoverProviderRegistry, IColor, CodeAction } from 'vs/editor/common/modes'; import { getColorPresentations } from 'vs/editor/contrib/colorPicker/color'; import { ColorDetector } from 'vs/editor/contrib/colorPicker/colorDetector'; import { ColorPickerModel } from 'vs/editor/contrib/colorPicker/colorPickerModel'; @@ -31,13 +31,9 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { IOpenerService, NullOpenerService } from 'vs/platform/opener/common/opener'; import { MarkerController, NextMarkerAction } from 'vs/editor/contrib/gotoError/gotoError'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService'; -import { ICommandService } from 'vs/platform/commands/common/commands'; import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; -import { getCodeActions } from 'vs/editor/contrib/codeAction/codeAction'; -import { applyCodeAction, QuickFixAction } from 'vs/editor/contrib/codeAction/codeActionCommands'; -import { Action } from 'vs/base/common/actions'; +import { getCodeActions, CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction'; +import { QuickFixAction, QuickFixController } from 'vs/editor/contrib/codeAction/codeActionCommands'; import { CodeActionKind } from 'vs/editor/contrib/codeAction/codeActionTrigger'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IIdentifiedSingleEditOperation } from 'vs/editor/common/model'; @@ -187,10 +183,6 @@ class ModesContentComputer implements IHoverComputer { } } -interface ActionSet extends IDisposable { - readonly actions: Action[]; -} - export class ModesContentHoverWidget extends ContentHoverWidget { static readonly ID = 'editor.contrib.modesContentHoverWidget'; @@ -204,16 +196,13 @@ export class ModesContentHoverWidget extends ContentHoverWidget { private _shouldFocus: boolean; private _colorPicker: ColorPickerWidget | null; - private renderDisposable: IDisposable = Disposable.None; + private readonly renderDisposable = this._register(new MutableDisposable()); constructor( editor: ICodeEditor, markerDecorationsService: IMarkerDecorationsService, private readonly _themeService: IThemeService, private readonly _keybindingService: IKeybindingService, - private readonly _contextMenuService: IContextMenuService, - private readonly _bulkEditService: IBulkEditService, - private readonly _commandService: ICommandService, private readonly _modeService: IModeService, private readonly _openerService: IOpenerService | null = NullOpenerService, ) { @@ -247,8 +236,6 @@ export class ModesContentHoverWidget extends ContentHoverWidget { } dispose(): void { - this.renderDisposable.dispose(); - this.renderDisposable = Disposable.None; this._hoverOperation.cancel(); super.dispose(); } @@ -316,8 +303,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget { this._isChangingDecorations = true; this._highlightDecorations = this._editor.deltaDecorations(this._highlightDecorations, []); this._isChangingDecorations = false; - this.renderDisposable.dispose(); - this.renderDisposable = Disposable.None; + this.renderDisposable.clear(); this._colorPicker = null; } @@ -349,7 +335,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget { let isEmptyHoverContent = true; let containColorPicker = false; - let markdownDisposeables: IDisposable[] = []; + const markdownDisposeables = new DisposableStore(); const markerMessages: MarkerHover[] = []; messages.forEach((msg) => { if (!msg.range) { @@ -440,7 +426,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget { this.updateContents(fragment); this._colorPicker.layout(); - this.renderDisposable = combinedDisposable(colorListener, colorChangeListener, widget, ...markdownDisposeables); + this.renderDisposable.value = combinedDisposable(colorListener, colorChangeListener, widget, markdownDisposeables); }); } else { if (msg instanceof MarkerHover) { @@ -452,15 +438,14 @@ export class ModesContentHoverWidget extends ContentHoverWidget { .forEach(contents => { const markdownHoverElement = $('div.hover-row.markdown-hover'); const hoverContentsElement = dom.append(markdownHoverElement, $('div.hover-contents')); - const renderer = new MarkdownRenderer(this._editor, this._modeService, this._openerService); - markdownDisposeables.push(renderer.onDidRenderCodeBlock(() => { + const renderer = markdownDisposeables.add(new MarkdownRenderer(this._editor, this._modeService, this._openerService)); + markdownDisposeables.add(renderer.onDidRenderCodeBlock(() => { hoverContentsElement.className = 'hover-contents code-hover-contents'; this.onContentsChange(); })); - const renderedContents = renderer.render(contents); + const renderedContents = markdownDisposeables.add(renderer.render(contents)); hoverContentsElement.appendChild(renderedContents.element); fragment.appendChild(markdownHoverElement); - markdownDisposeables.push(renderedContents); isEmptyHoverContent = false; }); } @@ -538,12 +523,12 @@ export class ModesContentHoverWidget extends ContentHoverWidget { run: async (target) => { const codeActionsPromise = this.getCodeActions(markerHover.marker); disposables.add(toDisposable(() => codeActionsPromise.cancel())); - const actions = await codeActionsPromise; - disposables.add(actions); + + const controller = QuickFixController.get(this._editor); const elementPosition = dom.getDomNodePagePosition(target); - this._contextMenuService.showContextMenu({ - getAnchor: () => ({ x: elementPosition.left + 6, y: elementPosition.top + elementPosition.height + 6 }), - getActions: () => actions.actions + controller.showCodeActions(codeActionsPromise, { + x: elementPosition.left + 6, + y: elementPosition.top + elementPosition.height + 6 }); } })); @@ -558,36 +543,26 @@ export class ModesContentHoverWidget extends ContentHoverWidget { } })); } - this.renderDisposable = disposables; + this.renderDisposable.value = disposables; return hoverElement; } - private getCodeActions(marker: IMarker): CancelablePromise { - return createCancelablePromise(async cancellationToken => { - const codeActions = await getCodeActions(this._editor.getModel()!, new Range(marker.startLineNumber, marker.startColumn, marker.endLineNumber, marker.endColumn), { type: 'manual', filter: { kind: CodeActionKind.QuickFix } }, cancellationToken); - if (codeActions.actions.length) { - const disposables = new DisposableStore(); - const actions: Action[] = []; - for (const codeAction of codeActions.actions) { - disposables.add(disposables); - actions.push(new Action( - codeAction.command ? codeAction.command.id : codeAction.title, - codeAction.title, - undefined, - true, - () => applyCodeAction(codeAction, this._bulkEditService, this._commandService))); - } - return { - actions: actions, - dispose: () => disposables.dispose() - }; - } + private getCodeActions(marker: IMarker): CancelablePromise { + const noAction: CodeAction = { + title: nls.localize('editor.action.quickFix.noneMessage', "No code actions available"), + kind: CodeActionKind.QuickFix.value, + }; + return createCancelablePromise(async (cancellationToken): Promise => { + const result = await getCodeActions( + this._editor.getModel()!, + new Range(marker.startLineNumber, marker.startColumn, marker.endLineNumber, marker.endColumn), + { type: 'manual', filter: { kind: CodeActionKind.QuickFix } }, + cancellationToken); return { - actions: [ - new Action('', nls.localize('editor.action.quickFix.noneMessage', "No code actions available")) - ], - dispose() { } + actions: result.actions.length ? result.actions : [noAction], + hasAutoFix: result.hasAutoFix, + dispose: () => result.dispose(), }; }); } diff --git a/src/vs/editor/contrib/hover/modesGlyphHover.ts b/src/vs/editor/contrib/hover/modesGlyphHover.ts index 2d83df2cea3..b2b78438a79 100644 --- a/src/vs/editor/contrib/hover/modesGlyphHover.ts +++ b/src/vs/editor/contrib/hover/modesGlyphHover.ts @@ -5,7 +5,7 @@ import { $ } from 'vs/base/browser/dom'; import { IMarkdownString, isEmptyMarkdownString } from 'vs/base/common/htmlContent'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { HoverOperation, HoverStartMode, IHoverComputer } from 'vs/editor/contrib/hover/hoverOperation'; import { GlyphHoverWidget } from 'vs/editor/contrib/hover/hoverWidgets'; @@ -91,7 +91,7 @@ export class ModesGlyphHoverWidget extends GlyphHoverWidget { private readonly _markdownRenderer: MarkdownRenderer; private readonly _computer: MarginComputer; private readonly _hoverOperation: HoverOperation; - private _renderDisposeables: IDisposable[]; + private readonly _renderDisposeables = this._register(new DisposableStore()); constructor( editor: ICodeEditor, @@ -102,7 +102,7 @@ export class ModesGlyphHoverWidget extends GlyphHoverWidget { this._lastLineNumber = -1; - this._markdownRenderer = new MarkdownRenderer(this._editor, modeService, openerService); + this._markdownRenderer = this._register(new MarkdownRenderer(this._editor, modeService, openerService)); this._computer = new MarginComputer(this._editor); this._hoverOperation = new HoverOperation( @@ -116,7 +116,6 @@ export class ModesGlyphHoverWidget extends GlyphHoverWidget { } public dispose(): void { - this._renderDisposeables = dispose(this._renderDisposeables); this._hoverOperation.cancel(); super.dispose(); } @@ -163,16 +162,15 @@ export class ModesGlyphHoverWidget extends GlyphHoverWidget { } private _renderMessages(lineNumber: number, messages: IHoverMessage[]): void { - dispose(this._renderDisposeables); - this._renderDisposeables = []; + this._renderDisposeables.clear(); const fragment = document.createDocumentFragment(); - messages.forEach((msg) => { + for (const msg of messages) { const renderedContents = this._markdownRenderer.render(msg.value); - this._renderDisposeables.push(renderedContents); + this._renderDisposeables.add(renderedContents); fragment.appendChild($('div.hover-row', undefined, renderedContents.element)); - }); + } this.updateContents(fragment); this.showAt(lineNumber); diff --git a/src/vs/editor/contrib/links/links.ts b/src/vs/editor/contrib/links/links.ts index ed3b65ef042..de26df3e3d4 100644 --- a/src/vs/editor/contrib/links/links.ts +++ b/src/vs/editor/contrib/links/links.ts @@ -9,7 +9,7 @@ import * as async from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import { onUnexpectedError } from 'vs/base/common/errors'; import { MarkdownString } from 'vs/base/common/htmlContent'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import { ICodeEditor, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { EditorAction, ServicesAccessor, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; @@ -27,26 +27,26 @@ import { registerThemingParticipant } from 'vs/platform/theme/common/themeServic const HOVER_MESSAGE_GENERAL_META = new MarkdownString().appendText( platform.isMacintosh - ? nls.localize('links.navigate.mac', "Cmd + click to follow link") - : nls.localize('links.navigate', "Ctrl + click to follow link") + ? nls.localize('links.navigate.mac', "Follow link (cmd + click)") + : nls.localize('links.navigate', "Follow link (ctrl + click)") ); const HOVER_MESSAGE_COMMAND_META = new MarkdownString().appendText( platform.isMacintosh - ? nls.localize('links.command.mac', "Cmd + click to execute command") - : nls.localize('links.command', "Ctrl + click to execute command") + ? nls.localize('links.command.mac', "Execute command (cmd + click)") + : nls.localize('links.command', "Execute command (ctrl + click)") ); const HOVER_MESSAGE_GENERAL_ALT = new MarkdownString().appendText( platform.isMacintosh - ? nls.localize('links.navigate.al.mac', "Option + click to follow link") - : nls.localize('links.navigate.al', "Alt + click to follow link") + ? nls.localize('links.navigate.al.mac', "Follow link (option + click)") + : nls.localize('links.navigate.al', "Follow link (alt + click)") ); const HOVER_MESSAGE_COMMAND_ALT = new MarkdownString().appendText( platform.isMacintosh - ? nls.localize('links.command.al.mac', "Option + click to execute command") - : nls.localize('links.command.al', "Alt + click to execute command") + ? nls.localize('links.command.al.mac', "Execute command (option + click)") + : nls.localize('links.command.al', "Execute command (alt + click)") ); const decoration = { @@ -116,11 +116,11 @@ class LinkOccurrence { const message = new MarkdownString().appendText( platform.isMacintosh ? useMetaKey - ? nls.localize('links.custom.mac', "Cmd + click to {0}", link.tooltip) - : nls.localize('links.custom.mac.al', "Option + click to {0}", link.tooltip) + ? nls.localize('links.custom.mac', "{0} (cmd + click)", link.tooltip) + : nls.localize('links.custom.mac.al', "{0} (option + click)", link.tooltip) : useMetaKey - ? nls.localize('links.custom', "Ctrl + click to {0}", link.tooltip) - : nls.localize('links.custom.al', "Alt + click to {0}", link.tooltip) + ? nls.localize('links.custom', "{0} (ctrl + click)", link.tooltip) + : nls.localize('links.custom.al', "{0} (alt + click)", link.tooltip) ); options.hoverMessage = message; } @@ -172,7 +172,7 @@ class LinkDetector implements editorCommon.IEditorContribution { private readonly editor: ICodeEditor; private enabled: boolean; - private listenersToRemove: IDisposable[]; + private readonly listenersToRemove = new DisposableStore(); private readonly timeout: async.TimeoutTimer; private computePromise: async.CancelablePromise | null; private activeLinksList: LinksList | null; @@ -189,22 +189,21 @@ class LinkDetector implements editorCommon.IEditorContribution { this.editor = editor; this.openerService = openerService; this.notificationService = notificationService; - this.listenersToRemove = []; let clickLinkGesture = new ClickLinkGesture(editor); - this.listenersToRemove.push(clickLinkGesture); - this.listenersToRemove.push(clickLinkGesture.onMouseMoveOrRelevantKeyDown(([mouseEvent, keyboardEvent]) => { + this.listenersToRemove.add(clickLinkGesture); + this.listenersToRemove.add(clickLinkGesture.onMouseMoveOrRelevantKeyDown(([mouseEvent, keyboardEvent]) => { this._onEditorMouseMove(mouseEvent, keyboardEvent); })); - this.listenersToRemove.push(clickLinkGesture.onExecute((e) => { + this.listenersToRemove.add(clickLinkGesture.onExecute((e) => { this.onEditorMouseUp(e); })); - this.listenersToRemove.push(clickLinkGesture.onCancel((e) => { + this.listenersToRemove.add(clickLinkGesture.onCancel((e) => { this.cleanUpActiveLinkDecoration(); })); this.enabled = editor.getConfiguration().contribInfo.links; - this.listenersToRemove.push(editor.onDidChangeConfiguration((e) => { + this.listenersToRemove.add(editor.onDidChangeConfiguration((e) => { let enabled = editor.getConfiguration().contribInfo.links; if (this.enabled === enabled) { // No change in our configuration option @@ -221,10 +220,10 @@ class LinkDetector implements editorCommon.IEditorContribution { // Start computing (for the getting enabled case) this.beginCompute(); })); - this.listenersToRemove.push(editor.onDidChangeModelContent((e) => this.onChange())); - this.listenersToRemove.push(editor.onDidChangeModel((e) => this.onModelChanged())); - this.listenersToRemove.push(editor.onDidChangeModelLanguage((e) => this.onModelModeChanged())); - this.listenersToRemove.push(LinkProviderRegistry.onDidChange((e) => this.onModelModeChanged())); + this.listenersToRemove.add(editor.onDidChangeModelContent((e) => this.onChange())); + this.listenersToRemove.add(editor.onDidChangeModel((e) => this.onModelChanged())); + this.listenersToRemove.add(editor.onDidChangeModelLanguage((e) => this.onModelModeChanged())); + this.listenersToRemove.add(LinkProviderRegistry.onDidChange((e) => this.onModelModeChanged())); this.timeout = new async.TimeoutTimer(); this.computePromise = null; @@ -414,7 +413,7 @@ class LinkDetector implements editorCommon.IEditorContribution { } public dispose(): void { - this.listenersToRemove = dispose(this.listenersToRemove); + this.listenersToRemove.dispose(); this.stop(); this.timeout.dispose(); } diff --git a/src/vs/editor/contrib/markdown/markdownRenderer.ts b/src/vs/editor/contrib/markdown/markdownRenderer.ts index bd3a38b421c..5825a919bf5 100644 --- a/src/vs/editor/contrib/markdown/markdownRenderer.ts +++ b/src/vs/editor/contrib/markdown/markdownRenderer.ts @@ -13,16 +13,16 @@ import { tokenizeToString } from 'vs/editor/common/modes/textToHtmlTokenizer'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { optional } from 'vs/platform/instantiation/common/instantiation'; import { Event, Emitter } from 'vs/base/common/event'; -import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { IDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle'; import { TokenizationRegistry } from 'vs/editor/common/modes'; export interface IMarkdownRenderResult extends IDisposable { element: HTMLElement; } -export class MarkdownRenderer { +export class MarkdownRenderer extends Disposable { - private _onDidRenderCodeBlock = new Emitter(); + private _onDidRenderCodeBlock = this._register(new Emitter()); readonly onDidRenderCodeBlock: Event = this._onDidRenderCodeBlock.event; constructor( @@ -30,6 +30,7 @@ export class MarkdownRenderer { @IModeService private readonly _modeService: IModeService, @optional(IOpenerService) private readonly _openerService: IOpenerService | null = NullOpenerService, ) { + super(); } private getOptions(disposeables: DisposableStore): RenderOptions { diff --git a/src/vs/editor/contrib/message/messageController.ts b/src/vs/editor/contrib/message/messageController.ts index d6e6b5c4c33..e57a0987498 100644 --- a/src/vs/editor/contrib/message/messageController.ts +++ b/src/vs/editor/contrib/message/messageController.ts @@ -7,7 +7,7 @@ import 'vs/css!./messageController'; import * as nls from 'vs/nls'; import { TimeoutTimer } from 'vs/base/common/async'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; +import { IDisposable, Disposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; import { alert } from 'vs/base/browser/ui/aria/aria'; import { Range } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; @@ -29,14 +29,16 @@ export class MessageController extends Disposable implements editorCommon.IEdito return editor.getContribution(MessageController._id); } + private readonly closeTimeout = 3000; // close after 3s + getId(): string { return MessageController._id; } private readonly _editor: ICodeEditor; private readonly _visible: IContextKey; - private _messageWidget?: MessageWidget; - private _messageListeners: IDisposable[] = []; + private readonly _messageWidget = this._register(new MutableDisposable()); + private readonly _messageListeners = this._register(new DisposableStore()); constructor( editor: ICodeEditor, @@ -62,22 +64,21 @@ export class MessageController extends Disposable implements editorCommon.IEdito alert(message); this._visible.set(true); - dispose(this._messageWidget); - this._messageListeners = dispose(this._messageListeners); - this._messageWidget = new MessageWidget(this._editor, position, message); + this._messageWidget.clear(); + this._messageListeners.clear(); + this._messageWidget.value = new MessageWidget(this._editor, position, message); // close on blur, cursor, model change, dispose - this._messageListeners.push(this._editor.onDidBlurEditorText(() => this.closeMessage())); - this._messageListeners.push(this._editor.onDidChangeCursorPosition(() => this.closeMessage())); - this._messageListeners.push(this._editor.onDidDispose(() => this.closeMessage())); - this._messageListeners.push(this._editor.onDidChangeModel(() => this.closeMessage())); + this._messageListeners.add(this._editor.onDidBlurEditorText(() => this.closeMessage())); + this._messageListeners.add(this._editor.onDidChangeCursorPosition(() => this.closeMessage())); + this._messageListeners.add(this._editor.onDidDispose(() => this.closeMessage())); + this._messageListeners.add(this._editor.onDidChangeModel(() => this.closeMessage())); - // close after 3s - this._messageListeners.push(new TimeoutTimer(() => this.closeMessage(), 3000)); + this._messageListeners.add(new TimeoutTimer(() => this.closeMessage(), this.closeTimeout)); // close on mouse move let bounds: Range; - this._messageListeners.push(this._editor.onMouseMove(e => { + this._messageListeners.add(this._editor.onMouseMove(e => { // outside the text area if (!e.target.position) { return; @@ -95,9 +96,9 @@ export class MessageController extends Disposable implements editorCommon.IEdito closeMessage(): void { this._visible.reset(); - this._messageListeners = dispose(this._messageListeners); - if (this._messageWidget) { - this._messageListeners.push(MessageWidget.fadeOut(this._messageWidget)); + this._messageListeners.clear(); + if (this._messageWidget.value) { + this._messageListeners.add(MessageWidget.fadeOut(this._messageWidget.value)); } } diff --git a/src/vs/editor/contrib/multicursor/test/multicursor.test.ts b/src/vs/editor/contrib/multicursor/test/multicursor.test.ts index f2715cbe06a..74068f74cf9 100644 --- a/src/vs/editor/contrib/multicursor/test/multicursor.test.ts +++ b/src/vs/editor/contrib/multicursor/test/multicursor.test.ts @@ -60,14 +60,15 @@ suite('Multicursor selection', () => { let queryState: { [key: string]: any; } = {}; let serviceCollection = new ServiceCollection(); serviceCollection.set(IStorageService, { - _serviceBrand: undefined, + _serviceBrand: undefined as any, onDidChangeStorage: Event.None, onWillSaveState: Event.None, get: (key: string) => queryState[key], getBoolean: (key: string) => !!queryState[key], getNumber: (key: string) => undefined!, store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); }, - remove: (key) => undefined + remove: (key) => undefined, + logStorage: () => undefined } as IStorageService); test('issue #8817: Cursor position changes when you cancel multicursor', () => { diff --git a/src/vs/editor/contrib/parameterHints/parameterHintsModel.ts b/src/vs/editor/contrib/parameterHints/parameterHintsModel.ts index d52dc794849..c34c68a84a2 100644 --- a/src/vs/editor/contrib/parameterHints/parameterHintsModel.ts +++ b/src/vs/editor/contrib/parameterHints/parameterHintsModel.ts @@ -6,7 +6,7 @@ import { CancelablePromise, createCancelablePromise, Delayer } from 'vs/base/common/async'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; import { CharacterSet } from 'vs/editor/common/core/characterClassifier'; @@ -30,7 +30,7 @@ namespace ParameterHintState { export class Pending { readonly type = Type.Pending; constructor( - readonly request: CancelablePromise + readonly request: CancelablePromise ) { } } @@ -54,6 +54,7 @@ export class ParameterHintsModel extends Disposable { private readonly editor: ICodeEditor; private enabled: boolean; private _state: ParameterHintState.State = ParameterHintState.Default; + private readonly _lastSignatureHelpResult = this._register(new MutableDisposable()); private triggerChars = new CharacterSet(); private retriggerChars = new CharacterSet(); @@ -92,7 +93,6 @@ export class ParameterHintsModel extends Disposable { } cancel(silent: boolean = false): void { - this.state = ParameterHintState.Default; this.throttledDelayer.cancel(); @@ -181,14 +181,22 @@ export class ParameterHintsModel extends Disposable { return this.state.request.then(result => { // Check that we are still resolving the correct signature help if (triggerId !== this.triggerId) { + if (result) { + result.dispose(); + } return false; } - if (!result || !result.signatures || result.signatures.length === 0) { + if (!result || !result.value.signatures || result.value.signatures.length === 0) { + if (result) { + result.dispose(); + } + this._lastSignatureHelpResult.clear(); this.cancel(); return false; } else { - this.state = new ParameterHintState.Active(result); + this.state = new ParameterHintState.Active(result.value); + this._lastSignatureHelpResult.value = result; this._onChangedHints.fire(this.state.hints); return true; } diff --git a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts index f7eae70292e..53bf31abcc5 100644 --- a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts +++ b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts @@ -8,7 +8,7 @@ import { domEvent, stop } from 'vs/base/browser/event'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { Event } from 'vs/base/common/event'; -import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { IDisposable, Disposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; import 'vs/css!./parameterHints'; import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser'; import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions'; @@ -31,7 +31,7 @@ export class ParameterHintsWidget extends Disposable implements IContentWidget, private readonly markdownRenderer: MarkdownRenderer; private readonly renderDisposeables = this._register(new DisposableStore()); - private model: ParameterHintsModel | null; + private readonly model = this._register(new MutableDisposable()); private readonly keyVisible: IContextKey; private readonly keyMultipleSignatures: IContextKey; private element: HTMLElement; @@ -52,13 +52,13 @@ export class ParameterHintsWidget extends Disposable implements IContentWidget, @IModeService modeService: IModeService, ) { super(); - this.markdownRenderer = new MarkdownRenderer(editor, modeService, openerService); - this.model = new ParameterHintsModel(editor); + this.markdownRenderer = this._register(new MarkdownRenderer(editor, modeService, openerService)); + this.model.value = new ParameterHintsModel(editor); this.keyVisible = Context.Visible.bindTo(contextKeyService); this.keyMultipleSignatures = Context.MultipleSignatures.bindTo(contextKeyService); this.visible = false; - this._register(this.model.onChangedHints(newParameterHints => { + this._register(this.model.value.onChangedHints(newParameterHints => { if (newParameterHints) { this.show(); this.render(newParameterHints); @@ -282,22 +282,22 @@ export class ParameterHintsWidget extends Disposable implements IContentWidget, } next(): void { - if (this.model) { + if (this.model.value) { this.editor.focus(); - this.model.next(); + this.model.value.next(); } } previous(): void { - if (this.model) { + if (this.model.value) { this.editor.focus(); - this.model.previous(); + this.model.value.previous(); } } cancel(): void { - if (this.model) { - this.model.cancel(); + if (this.model.value) { + this.model.value.cancel(); } } @@ -310,8 +310,8 @@ export class ParameterHintsWidget extends Disposable implements IContentWidget, } trigger(context: TriggerContext): void { - if (this.model) { - this.model.trigger(context, 0); + if (this.model.value) { + this.model.value.trigger(context, 0); } } @@ -319,15 +319,6 @@ export class ParameterHintsWidget extends Disposable implements IContentWidget, const height = Math.max(this.editor.getLayoutInfo().height / 4, 250); this.element.style.maxHeight = `${height}px`; } - - dispose(): void { - super.dispose(); - - if (this.model) { - this.model.dispose(); - this.model = null; - } - } } registerThemingParticipant((theme, collector) => { diff --git a/src/vs/editor/contrib/parameterHints/provideSignatureHelp.ts b/src/vs/editor/contrib/parameterHints/provideSignatureHelp.ts index 87ea878abfd..8aaf09f8b6f 100644 --- a/src/vs/editor/contrib/parameterHints/provideSignatureHelp.ts +++ b/src/vs/editor/contrib/parameterHints/provideSignatureHelp.ts @@ -17,18 +17,32 @@ export const Context = { MultipleSignatures: new RawContextKey('parameterHintsMultipleSignatures', false), }; -export function provideSignatureHelp(model: ITextModel, position: Position, context: modes.SignatureHelpContext, token: CancellationToken): Promise { +export function provideSignatureHelp( + model: ITextModel, + position: Position, + context: modes.SignatureHelpContext, + token: CancellationToken +): Promise { const supports = modes.SignatureHelpProviderRegistry.ordered(model); return first(supports.map(support => () => { - return Promise.resolve(support.provideSignatureHelp(model, position, token, context)).catch(onUnexpectedExternalError); + return Promise.resolve(support.provideSignatureHelp(model, position, token, context)) + .catch(e => onUnexpectedExternalError(e)); })); } -registerDefaultLanguageCommand('_executeSignatureHelpProvider', (model, position, args) => - provideSignatureHelp(model, position, { +registerDefaultLanguageCommand('_executeSignatureHelpProvider', async (model, position, args) => { + const result = await provideSignatureHelp(model, position, { triggerKind: modes.SignatureHelpTriggerKind.Invoke, isRetrigger: false, triggerCharacter: args['triggerCharacter'] - }, CancellationToken.None)); + }, CancellationToken.None); + + if (!result) { + return undefined; + } + + setTimeout(() => result.dispose(), 0); + return result.value; +}); diff --git a/src/vs/editor/contrib/parameterHints/test/parameterHintsModel.test.ts b/src/vs/editor/contrib/parameterHints/test/parameterHintsModel.test.ts index 8ccff16267a..a6ffca40e20 100644 --- a/src/vs/editor/contrib/parameterHints/test/parameterHintsModel.test.ts +++ b/src/vs/editor/contrib/parameterHints/test/parameterHintsModel.test.ts @@ -23,7 +23,7 @@ const mockFile = URI.parse('test:somefile.ttt'); const mockFileSelector = { scheme: 'test' }; -const emptySigHelpResult = { +const emptySigHelp: modes.SignatureHelp = { signatures: [{ label: 'none', parameters: [] @@ -31,6 +31,12 @@ const emptySigHelpResult = { activeParameter: 0, activeSignature: 0 }; + +const emptySigHelpResult: modes.SignatureHelpResult = { + value: emptySigHelp, + dispose: () => { } +}; + suite('ParameterHintsModel', () => { const disposables = new DisposableStore(); @@ -88,7 +94,7 @@ suite('ParameterHintsModel', () => { signatureHelpTriggerCharacters = [triggerChar]; signatureHelpRetriggerCharacters = []; - provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): modes.SignatureHelp | Promise { + provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): modes.SignatureHelpResult | Promise { ++invokeCount; if (invokeCount === 1) { assert.strictEqual(context.triggerKind, modes.SignatureHelpTriggerKind.TriggerCharacter); @@ -103,7 +109,7 @@ suite('ParameterHintsModel', () => { assert.strictEqual(context.triggerKind, modes.SignatureHelpTriggerKind.TriggerCharacter); assert.strictEqual(context.isRetrigger, true); assert.strictEqual(context.triggerCharacter, triggerChar); - assert.strictEqual(context.activeSignatureHelp, emptySigHelpResult); + assert.strictEqual(context.activeSignatureHelp, emptySigHelp); done(); } @@ -126,7 +132,7 @@ suite('ParameterHintsModel', () => { signatureHelpTriggerCharacters = [triggerChar]; signatureHelpRetriggerCharacters = []; - provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): modes.SignatureHelp | Promise { + provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): modes.SignatureHelpResult | Promise { ++invokeCount; if (invokeCount === 1) { assert.strictEqual(context.triggerKind, modes.SignatureHelpTriggerKind.TriggerCharacter); @@ -192,7 +198,7 @@ suite('ParameterHintsModel', () => { signatureHelpTriggerCharacters = ['a', 'b']; signatureHelpRetriggerCharacters = []; - provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): modes.SignatureHelp | Promise { + provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): modes.SignatureHelpResult | Promise { ++invokeCount; if (invokeCount === 1) { assert.strictEqual(context.triggerKind, modes.SignatureHelpTriggerKind.TriggerCharacter); @@ -227,7 +233,7 @@ suite('ParameterHintsModel', () => { signatureHelpRetriggerCharacters = []; - provideSignatureHelp(_model: ITextModel, _position: Position, token: CancellationToken): modes.SignatureHelp | Promise { + provideSignatureHelp(_model: ITextModel, _position: Position, token: CancellationToken): modes.SignatureHelpResult | Promise { const count = invokeCount++; token.onCancellationRequested(() => { didRequestCancellationOf = count; }); @@ -236,15 +242,18 @@ suite('ParameterHintsModel', () => { hintsModel.trigger({ triggerKind: modes.SignatureHelpTriggerKind.Invoke }, 0); } - return new Promise(resolve => { + return new Promise(resolve => { setTimeout(() => { resolve({ - signatures: [{ - label: '' + count, - parameters: [] - }], - activeParameter: 0, - activeSignature: 0 + value: { + signatures: [{ + label: '' + count, + parameters: [] + }], + activeParameter: 0, + activeSignature: 0 + }, + dispose: () => { } }); }, 100); }); @@ -280,7 +289,7 @@ suite('ParameterHintsModel', () => { signatureHelpTriggerCharacters = [triggerChar]; signatureHelpRetriggerCharacters = [retriggerChar]; - provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): modes.SignatureHelp | Promise { + provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): modes.SignatureHelpResult | Promise { ++invokeCount; if (invokeCount === 1) { assert.strictEqual(context.triggerKind, modes.SignatureHelpTriggerKind.TriggerCharacter); @@ -322,20 +331,23 @@ suite('ParameterHintsModel', () => { signatureHelpTriggerCharacters = [triggerChar]; signatureHelpRetriggerCharacters = []; - async provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): Promise { + async provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): Promise { if (!context.isRetrigger) { // retrigger after delay for widget to show up setTimeout(() => editor.trigger('keyboard', Handler.Type, { text: triggerChar }), 50); return { - activeParameter: 0, - activeSignature: 0, - signatures: [{ - label: firstProviderId, - parameters: [ - { label: paramterLabel } - ] - }] + value: { + activeParameter: 0, + activeSignature: 0, + signatures: [{ + label: firstProviderId, + parameters: [ + { label: paramterLabel } + ] + }] + }, + dispose: () => { } }; } @@ -347,15 +359,18 @@ suite('ParameterHintsModel', () => { signatureHelpTriggerCharacters = [triggerChar]; signatureHelpRetriggerCharacters = []; - async provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): Promise { + async provideSignatureHelp(_model: ITextModel, _position: Position, _token: CancellationToken, context: modes.SignatureHelpContext): Promise { if (context.isRetrigger) { return { - activeParameter: 0, - activeSignature: context.activeSignatureHelp ? context.activeSignatureHelp.activeSignature + 1 : 0, - signatures: [{ - label: secondProviderId, - parameters: context.activeSignatureHelp ? context.activeSignatureHelp.signatures[0].parameters : [] - }] + value: { + activeParameter: 0, + activeSignature: context.activeSignatureHelp ? context.activeSignatureHelp.activeSignature + 1 : 0, + signatures: [{ + label: secondProviderId, + parameters: context.activeSignatureHelp ? context.activeSignatureHelp.signatures[0].parameters : [] + }] + }, + dispose: () => { } }; } @@ -365,23 +380,23 @@ suite('ParameterHintsModel', () => { editor.trigger('keyboard', Handler.Type, { text: triggerChar }); - const firstHint = await getNextHint(model); - assert.strictEqual(firstHint!.signatures[0].label, firstProviderId); - assert.strictEqual(firstHint!.activeSignature, 0); - assert.strictEqual(firstHint!.signatures[0].parameters[0].label, paramterLabel); + const firstHint = (await getNextHint(model))!.value; + assert.strictEqual(firstHint.signatures[0].label, firstProviderId); + assert.strictEqual(firstHint.activeSignature, 0); + assert.strictEqual(firstHint.signatures[0].parameters[0].label, paramterLabel); - const secondHint = await getNextHint(model); - assert.strictEqual(secondHint!.signatures[0].label, secondProviderId); - assert.strictEqual(secondHint!.activeSignature, 1); - assert.strictEqual(secondHint!.signatures[0].parameters[0].label, paramterLabel); + const secondHint = (await getNextHint(model))!.value; + assert.strictEqual(secondHint.signatures[0].label, secondProviderId); + assert.strictEqual(secondHint.activeSignature, 1); + assert.strictEqual(secondHint.signatures[0].parameters[0].label, paramterLabel); }); }); function getNextHint(model: ParameterHintsModel) { - return new Promise(resolve => { + return new Promise(resolve => { const sub = model.onChangedHints(e => { sub.dispose(); - return resolve(e); + return resolve(e ? { value: e, dispose: () => { } } : undefined); }); }); } diff --git a/src/vs/editor/contrib/referenceSearch/media/chevron-next-dark.svg b/src/vs/editor/contrib/referenceSearch/media/chevron-next-dark.svg new file mode 100644 index 00000000000..455532ddb7a --- /dev/null +++ b/src/vs/editor/contrib/referenceSearch/media/chevron-next-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/referenceSearch/media/chevron-next-light.svg b/src/vs/editor/contrib/referenceSearch/media/chevron-next-light.svg new file mode 100644 index 00000000000..a443086f358 --- /dev/null +++ b/src/vs/editor/contrib/referenceSearch/media/chevron-next-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/referenceSearch/media/chevron-previous-dark.svg b/src/vs/editor/contrib/referenceSearch/media/chevron-previous-dark.svg new file mode 100644 index 00000000000..5ca3526019f --- /dev/null +++ b/src/vs/editor/contrib/referenceSearch/media/chevron-previous-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/referenceSearch/media/chevron-previous-light.svg b/src/vs/editor/contrib/referenceSearch/media/chevron-previous-light.svg new file mode 100644 index 00000000000..87e179a7f3c --- /dev/null +++ b/src/vs/editor/contrib/referenceSearch/media/chevron-previous-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/referenceSearch/media/close-dark.svg b/src/vs/editor/contrib/referenceSearch/media/close-dark.svg new file mode 100644 index 00000000000..bffa4e9dabb --- /dev/null +++ b/src/vs/editor/contrib/referenceSearch/media/close-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/referenceSearch/media/close-light.svg b/src/vs/editor/contrib/referenceSearch/media/close-light.svg new file mode 100644 index 00000000000..b44dee661af --- /dev/null +++ b/src/vs/editor/contrib/referenceSearch/media/close-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/referenceSearch/media/peekViewWidget.css b/src/vs/editor/contrib/referenceSearch/media/peekViewWidget.css index ac669d39341..8b5b64413fc 100644 --- a/src/vs/editor/contrib/referenceSearch/media/peekViewWidget.css +++ b/src/vs/editor/contrib/referenceSearch/media/peekViewWidget.css @@ -57,7 +57,7 @@ } .monaco-editor .peekview-widget .head .peekview-actions .action-label.icon.close-peekview-action { - background: url('close.svg') center center no-repeat; + background: url('close-light.svg') center center no-repeat; } .monaco-editor .peekview-widget > .body { @@ -70,30 +70,23 @@ .monaco-editor.hc-black .peekview-widget .head .peekview-actions .action-label.icon.close-peekview-action, .monaco-editor.vs-dark .peekview-widget .head .peekview-actions .action-label.icon.close-peekview-action { - background: url('close-inverse.svg') center center no-repeat; + background: url('close-dark.svg') center center no-repeat; } .monaco-editor .peekview-widget .peekview-actions .icon.chevron-up { - background: url('chevron-up-inverse.svg') center center no-repeat; -} - -.vs-dark .monaco-editor .peekview-widget .peekview-actions .icon.chevron-up { - background: url('chevron-up.svg') center center no-repeat; + background: url('chevron-previous-light.svg') center center no-repeat; } +.vs-dark .monaco-editor .peekview-widget .peekview-actions .icon.chevron-up, .hc-black .monaco-editor .peekview-widget .peekview-actions .icon.chevron-up { - background: url('chevron-up-inverse-hc.svg') center center no-repeat; + background: url('chevron-previous-dark.svg') center center no-repeat; } .monaco-editor .peekview-widget .peekview-actions .icon.chevron-down { - background: url('chevron-down-inverse.svg') center center no-repeat; -} - -.vs-dark .monaco-editor .peekview-widget .peekview-actions .icon.chevron-down { - background: url('chevron-down.svg') center center no-repeat; + background: url('chevron-next-light.svg') center center no-repeat; } +.vs-dark .monaco-editor .peekview-widget .peekview-actions .icon.chevron-down, .hc-black .monaco-editor .peekview-widget .peekview-actions .icon.chevron-down { - background: url('chevron-down-hc.svg') center center no-repeat; -} - + background: url('chevron-next-dark.svg') center center no-repeat; +} \ No newline at end of file diff --git a/src/vs/editor/contrib/rename/rename.ts b/src/vs/editor/contrib/rename/rename.ts index 28ec66cfaf7..ab06982895b 100644 --- a/src/vs/editor/contrib/rename/rename.ts +++ b/src/vs/editor/contrib/rename/rename.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { illegalArgument, onUnexpectedError } from 'vs/base/common/errors'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { ILocalProgressService } from 'vs/platform/progress/common/progress'; +import { IEditorProgressService } from 'vs/platform/progress/common/progress'; import { registerEditorAction, registerEditorContribution, ServicesAccessor, EditorAction, EditorCommand, registerEditorCommand, registerDefaultLanguageCommand } from 'vs/editor/browser/editorExtensions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; @@ -114,7 +114,7 @@ class RenameController extends Disposable implements IEditorContribution { private readonly editor: ICodeEditor, @INotificationService private readonly _notificationService: INotificationService, @IBulkEditService private readonly _bulkEditService: IBulkEditService, - @ILocalProgressService private readonly _progressService: ILocalProgressService, + @IEditorProgressService private readonly _progressService: IEditorProgressService, @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IThemeService private readonly _themeService: IThemeService, ) { diff --git a/src/vs/editor/contrib/snippet/snippetController2.ts b/src/vs/editor/contrib/snippet/snippetController2.ts index daccfa9eec8..c24659b44d2 100644 --- a/src/vs/editor/contrib/snippet/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/snippetController2.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { dispose, DisposableStore } from 'vs/base/common/lifecycle'; import { repeat } from 'vs/base/common/strings'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorCommand, registerEditorCommand, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; @@ -20,6 +20,24 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis import { ILogService } from 'vs/platform/log/common/log'; import { SnippetSession } from './snippetSession'; +export interface ISnippetInsertOptions { + overwriteBefore: number; + overwriteAfter: number; + adjustWhitespace: boolean; + undoStopBefore: boolean; + undoStopAfter: boolean; + clipboardText: string | undefined; +} + +const _defaultOptions: ISnippetInsertOptions = { + overwriteBefore: 0, + overwriteAfter: 0, + undoStopBefore: true, + undoStopAfter: true, + adjustWhitespace: true, + clipboardText: undefined +}; + export class SnippetController2 implements IEditorContribution { static get(editor: ICodeEditor): SnippetController2 { @@ -35,7 +53,7 @@ export class SnippetController2 implements IEditorContribution { private readonly _hasPrevTabstop: IContextKey; private _session?: SnippetSession; - private _snippetListener: IDisposable[] = []; + private _snippetListener = new DisposableStore(); private _modelVersionId: number; private _currentChoice?: Choice; @@ -54,6 +72,7 @@ export class SnippetController2 implements IEditorContribution { this._hasPrevTabstop.reset(); this._hasNextTabstop.reset(); dispose(this._session); + this._snippetListener.dispose(); } getId(): string { @@ -62,15 +81,13 @@ export class SnippetController2 implements IEditorContribution { insert( template: string, - overwriteBefore: number = 0, overwriteAfter: number = 0, - undoStopBefore: boolean = true, undoStopAfter: boolean = true, - adjustWhitespace: boolean = true, + opts?: Partial ): void { // this is here to find out more about the yet-not-understood // error that sometimes happens when we fail to inserted a nested // snippet try { - this._doInsert(template, overwriteBefore, overwriteAfter, undoStopBefore, undoStopAfter, adjustWhitespace); + this._doInsert(template, typeof opts === 'undefined' ? _defaultOptions : { ..._defaultOptions, ...opts }); } catch (e) { this.cancel(); @@ -83,9 +100,7 @@ export class SnippetController2 implements IEditorContribution { private _doInsert( template: string, - overwriteBefore: number = 0, overwriteAfter: number = 0, - undoStopBefore: boolean = true, undoStopAfter: boolean = true, - adjustWhitespace: boolean = true, + opts: ISnippetInsertOptions ): void { if (!this._editor.hasModel()) { return; @@ -93,31 +108,29 @@ export class SnippetController2 implements IEditorContribution { // don't listen while inserting the snippet // as that is the inflight state causing cancelation - this._snippetListener = dispose(this._snippetListener); + this._snippetListener.clear(); - if (undoStopBefore) { + if (opts.undoStopBefore) { this._editor.getModel().pushStackElement(); } if (!this._session) { this._modelVersionId = this._editor.getModel().getAlternativeVersionId(); - this._session = new SnippetSession(this._editor, template, overwriteBefore, overwriteAfter, adjustWhitespace); + this._session = new SnippetSession(this._editor, template, opts); this._session.insert(); } else { - this._session.merge(template, overwriteBefore, overwriteAfter, adjustWhitespace); + this._session.merge(template, opts); } - if (undoStopAfter) { + if (opts.undoStopAfter) { this._editor.getModel().pushStackElement(); } this._updateState(); - this._snippetListener = [ - this._editor.onDidChangeModelContent(e => e.isFlush && this.cancel()), - this._editor.onDidChangeModel(() => this.cancel()), - this._editor.onDidChangeCursorSelection(() => this._updateState()) - ]; + this._snippetListener.add(this._editor.onDidChangeModelContent(e => e.isFlush && this.cancel())); + this._snippetListener.add(this._editor.onDidChangeModel(() => this.cancel())); + this._snippetListener.add(this._editor.onDidChangeCursorSelection(() => this._updateState())); } private _updateState(): void { @@ -197,7 +210,7 @@ export class SnippetController2 implements IEditorContribution { this._inSnippet.reset(); this._hasPrevTabstop.reset(); this._hasNextTabstop.reset(); - dispose(this._snippetListener); + this._snippetListener.clear(); dispose(this._session); this._session = undefined; this._modelVersionId = -1; diff --git a/src/vs/editor/contrib/snippet/snippetSession.ts b/src/vs/editor/contrib/snippet/snippetSession.ts index 6eeb1678913..6140e44858a 100644 --- a/src/vs/editor/contrib/snippet/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/snippetSession.ts @@ -22,6 +22,7 @@ import { ClipboardBasedVariableResolver, CompositeSnippetVariableResolver, Model import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import * as colors from 'vs/platform/theme/common/colorRegistry'; import { withNullAsUndefined } from 'vs/base/common/types'; +import { ILabelService } from 'vs/platform/label/common/label'; registerThemingParticipant((theme, collector) => { @@ -315,6 +316,20 @@ export class OneSnippet { } } +export interface ISnippetSessionInsertOptions { + overwriteBefore: number; + overwriteAfter: number; + adjustWhitespace: boolean; + clipboardText: string | undefined; +} + +const _defaultOptions: ISnippetSessionInsertOptions = { + overwriteBefore: 0, + overwriteAfter: 0, + adjustWhitespace: true, + clipboardText: undefined +}; + export class SnippetSession { static adjustWhitespace(model: ITextModel, position: IPosition, snippet: TextmateSnippet): void { @@ -363,7 +378,7 @@ export class SnippetSession { return selection; } - static createEditsAndSnippets(editor: IActiveCodeEditor, template: string, overwriteBefore: number, overwriteAfter: number, enforceFinalTabstop: boolean, adjustWhitespace: boolean): { edits: IIdentifiedSingleEditOperation[], snippets: OneSnippet[] } { + static createEditsAndSnippets(editor: IActiveCodeEditor, template: string, overwriteBefore: number, overwriteAfter: number, enforceFinalTabstop: boolean, adjustWhitespace: boolean, clipboardText: string | undefined): { edits: IIdentifiedSingleEditOperation[], snippets: OneSnippet[] } { const edits: IIdentifiedSingleEditOperation[] = []; const snippets: OneSnippet[] = []; @@ -372,9 +387,11 @@ export class SnippetSession { } const model = editor.getModel(); - const modelBasedVariableResolver = new ModelBasedVariableResolver(model); - const clipboardService = editor.invokeWithinContext(accessor => accessor.get(IClipboardService, optional)); const workspaceService = editor.invokeWithinContext(accessor => accessor.get(IWorkspaceContextService, optional)); + const modelBasedVariableResolver = editor.invokeWithinContext(accessor => new ModelBasedVariableResolver(accessor.get(ILabelService, optional), model)); + + const clipboardService = editor.invokeWithinContext(accessor => accessor.get(IClipboardService, optional)); + clipboardText = clipboardText || clipboardService && clipboardService.readTextSync(); let delta = 0; @@ -427,7 +444,7 @@ export class SnippetSession { snippet.resolveVariables(new CompositeSnippetVariableResolver([ modelBasedVariableResolver, - new ClipboardBasedVariableResolver(clipboardService, idx, indexedSelections.length), + new ClipboardBasedVariableResolver(clipboardText, idx, indexedSelections.length), new SelectionBasedVariableResolver(model, selection), new CommentBasedVariableResolver(model), new TimeBasedVariableResolver, @@ -450,17 +467,13 @@ export class SnippetSession { private readonly _editor: IActiveCodeEditor; private readonly _template: string; private readonly _templateMerges: [number, number, string][] = []; - private readonly _overwriteBefore: number; - private readonly _overwriteAfter: number; - private readonly _adjustWhitespace: boolean; + private readonly _options: ISnippetSessionInsertOptions; private _snippets: OneSnippet[] = []; - constructor(editor: IActiveCodeEditor, template: string, overwriteBefore: number = 0, overwriteAfter: number = 0, adjustWhitespace: boolean = true) { + constructor(editor: IActiveCodeEditor, template: string, options: ISnippetSessionInsertOptions = _defaultOptions) { this._editor = editor; this._template = template; - this._overwriteBefore = overwriteBefore; - this._overwriteAfter = overwriteAfter; - this._adjustWhitespace = adjustWhitespace; + this._options = options; } dispose(): void { @@ -479,7 +492,7 @@ export class SnippetSession { const model = this._editor.getModel(); // make insert edit and start with first selections - const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, this._template, this._overwriteBefore, this._overwriteAfter, false, this._adjustWhitespace); + const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, this._template, this._options.overwriteBefore, this._options.overwriteAfter, false, this._options.adjustWhitespace, this._options.clipboardText); this._snippets = snippets; const selections = model.pushEditOperations(this._editor.getSelections(), edits, undoEdits => { @@ -493,12 +506,12 @@ export class SnippetSession { this._editor.revealRange(selections[0]); } - merge(template: string, overwriteBefore: number = 0, overwriteAfter: number = 0, adjustWhitespace: boolean = true): void { + merge(template: string, options: ISnippetSessionInsertOptions = _defaultOptions): void { if (!this._editor.hasModel()) { return; } this._templateMerges.push([this._snippets[0]._nestingLevel, this._snippets[0]._placeholderGroupsIdx, template]); - const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, template, overwriteBefore, overwriteAfter, true, adjustWhitespace); + const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, template, options.overwriteBefore, options.overwriteAfter, true, options.adjustWhitespace, options.clipboardText); this._editor.setSelections(this._editor.getModel().pushEditOperations(this._editor.getSelections(), edits, undoEdits => { diff --git a/src/vs/editor/contrib/snippet/snippetVariables.ts b/src/vs/editor/contrib/snippet/snippetVariables.ts index 0cca7a56ffe..b56f15882dc 100644 --- a/src/vs/editor/contrib/snippet/snippetVariables.ts +++ b/src/vs/editor/contrib/snippet/snippetVariables.ts @@ -4,17 +4,18 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import { basename, dirname } from 'vs/base/common/path'; +import * as path from 'vs/base/common/path'; +import { dirname } from 'vs/base/common/resources'; import { ITextModel } from 'vs/editor/common/model'; import { Selection } from 'vs/editor/common/core/selection'; import { VariableResolver, Variable, Text } from 'vs/editor/contrib/snippet/snippetParser'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { getLeadingWhitespace, commonPrefixLength, isFalsyOrWhitespace, pad, endsWith } from 'vs/base/common/strings'; -import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { isSingleFolderWorkspaceIdentifier, toWorkspaceIdentifier, WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces'; +import { ILabelService } from 'vs/platform/label/common/label'; -export const KnownSnippetVariableNames = Object.freeze({ +export const KnownSnippetVariableNames: { [key: string]: true } = Object.freeze({ 'CURRENT_YEAR': true, 'CURRENT_YEAR_SHORT': true, 'CURRENT_MONTH': true, @@ -126,6 +127,7 @@ export class SelectionBasedVariableResolver implements VariableResolver { export class ModelBasedVariableResolver implements VariableResolver { constructor( + private readonly _labelService: ILabelService | undefined, private readonly _model: ITextModel ) { // @@ -136,10 +138,10 @@ export class ModelBasedVariableResolver implements VariableResolver { const { name } = variable; if (name === 'TM_FILENAME') { - return basename(this._model.uri.fsPath); + return path.basename(this._model.uri.fsPath); } else if (name === 'TM_FILENAME_BASE') { - const name = basename(this._model.uri.fsPath); + const name = path.basename(this._model.uri.fsPath); const idx = name.lastIndexOf('.'); if (idx <= 0) { return name; @@ -147,12 +149,14 @@ export class ModelBasedVariableResolver implements VariableResolver { return name.slice(0, idx); } - } else if (name === 'TM_DIRECTORY') { - const dir = dirname(this._model.uri.fsPath); - return dir !== '.' ? dir : ''; + } else if (name === 'TM_DIRECTORY' && this._labelService) { + if (path.dirname(this._model.uri.fsPath) === '.') { + return ''; + } + return this._labelService.getUriLabel(dirname(this._model.uri)); - } else if (name === 'TM_FILEPATH') { - return this._model.uri.fsPath; + } else if (name === 'TM_FILEPATH' && this._labelService) { + return this._labelService.getUriLabel(this._model.uri); } return undefined; @@ -162,7 +166,7 @@ export class ModelBasedVariableResolver implements VariableResolver { export class ClipboardBasedVariableResolver implements VariableResolver { constructor( - private readonly _clipboardService: IClipboardService, + private readonly _clipboardText: string | undefined, private readonly _selectionIdx: number, private readonly _selectionCount: number ) { @@ -170,20 +174,19 @@ export class ClipboardBasedVariableResolver implements VariableResolver { } resolve(variable: Variable): string | undefined { - if (variable.name !== 'CLIPBOARD' || !this._clipboardService) { + if (variable.name !== 'CLIPBOARD') { return undefined; } - const text = this._clipboardService.readText(); - if (!text) { + if (!this._clipboardText) { return undefined; } - const lines = text.split(/\r\n|\n|\r/).filter(s => !isFalsyOrWhitespace(s)); + const lines = this._clipboardText.split(/\r\n|\n|\r/).filter(s => !isFalsyOrWhitespace(s)); if (lines.length === this._selectionCount) { return lines[this._selectionIdx]; } else { - return text; + return this._clipboardText; } } } @@ -250,7 +253,7 @@ export class TimeBasedVariableResolver implements VariableResolver { export class WorkspaceBasedVariableResolver implements VariableResolver { constructor( - private readonly _workspaceService: IWorkspaceContextService, + private readonly _workspaceService: IWorkspaceContextService | undefined, ) { // } @@ -266,13 +269,13 @@ export class WorkspaceBasedVariableResolver implements VariableResolver { } if (isSingleFolderWorkspaceIdentifier(workspaceIdentifier)) { - return basename(workspaceIdentifier.path); + return path.basename(workspaceIdentifier.path); } - let filename = basename(workspaceIdentifier.configPath.path); + let filename = path.basename(workspaceIdentifier.configPath.path); if (endsWith(filename, WORKSPACE_EXTENSION)) { filename = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1); } return filename; } -} \ No newline at end of file +} diff --git a/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts b/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts index 9770cb36420..c9751d0504d 100644 --- a/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts @@ -62,7 +62,7 @@ suite('SnippetController', () => { snippetTest((editor, cursor, template, snippetController) => { editor.setPosition({ lineNumber: 4, column: 2 }); - snippetController.insert(template, 0, 0); + snippetController.insert(template); assert.equal(editor.getModel()!.getLineContent(4), '\tfor (var index; index < array.length; index++) {'); assert.equal(editor.getModel()!.getLineContent(5), '\t\tvar element = array[index];'); assert.equal(editor.getModel()!.getLineContent(6), '\t\t'); @@ -98,7 +98,7 @@ suite('SnippetController', () => { snippetTest((editor, cursor, template, snippetController) => { editor.setPosition({ lineNumber: 4, column: 2 }); - snippetController.insert(template, 0, 0); + snippetController.insert(template); assert.equal(editor.getModel()!.getLineContent(4), '\tfor (var index; index < array.length; index++) {'); assert.equal(editor.getModel()!.getLineContent(5), '\t\tvar element = array[index];'); assert.equal(editor.getModel()!.getLineContent(6), '\t\t'); @@ -180,7 +180,7 @@ suite('SnippetController', () => { test('Stops when calling model.setValue()', () => { snippetTest((editor, cursor, codeSnippet, snippetController) => { editor.setPosition({ lineNumber: 4, column: 2 }); - snippetController.insert(codeSnippet, 0, 0); + snippetController.insert(codeSnippet); editor.getModel()!.setValue('goodbye'); @@ -191,7 +191,7 @@ suite('SnippetController', () => { test('Stops when undoing', () => { snippetTest((editor, cursor, codeSnippet, snippetController) => { editor.setPosition({ lineNumber: 4, column: 2 }); - snippetController.insert(codeSnippet, 0, 0); + snippetController.insert(codeSnippet); editor.getModel()!.undo(); @@ -202,7 +202,7 @@ suite('SnippetController', () => { test('Stops when moving cursor outside', () => { snippetTest((editor, cursor, codeSnippet, snippetController) => { editor.setPosition({ lineNumber: 4, column: 2 }); - snippetController.insert(codeSnippet, 0, 0); + snippetController.insert(codeSnippet); editor.setPosition({ lineNumber: 1, column: 1 }); @@ -213,7 +213,7 @@ suite('SnippetController', () => { test('Stops when disconnecting editor model', () => { snippetTest((editor, cursor, codeSnippet, snippetController) => { editor.setPosition({ lineNumber: 4, column: 2 }); - snippetController.insert(codeSnippet, 0, 0); + snippetController.insert(codeSnippet); editor.setModel(null); @@ -224,7 +224,7 @@ suite('SnippetController', () => { test('Stops when disposing editor', () => { snippetTest((editor, cursor, codeSnippet, snippetController) => { editor.setPosition({ lineNumber: 4, column: 2 }); - snippetController.insert(codeSnippet, 0, 0); + snippetController.insert(codeSnippet); snippetController.dispose(); @@ -240,7 +240,7 @@ suite('SnippetController', () => { ]); codeSnippet = 'foo$0'; - snippetController.insert(codeSnippet, 0, 0); + snippetController.insert(codeSnippet); assert.equal(editor.getSelections()!.length, 2); const [first, second] = editor.getSelections()!; @@ -255,7 +255,7 @@ suite('SnippetController', () => { ]); codeSnippet = 'foo$0bar'; - snippetController.insert(codeSnippet, 0, 0); + snippetController.insert(codeSnippet); assert.equal(editor.getSelections()!.length, 2); const [first, second] = editor.getSelections()!; @@ -270,7 +270,7 @@ suite('SnippetController', () => { ]); codeSnippet = 'foo$0bar'; - snippetController.insert(codeSnippet, 0, 0); + snippetController.insert(codeSnippet); assert.equal(editor.getSelections()!.length, 2); const [first, second] = editor.getSelections()!; @@ -285,7 +285,7 @@ suite('SnippetController', () => { ]); codeSnippet = 'foo\n$0\nbar'; - snippetController.insert(codeSnippet, 0, 0); + snippetController.insert(codeSnippet); assert.equal(editor.getSelections()!.length, 2); const [first, second] = editor.getSelections()!; @@ -300,7 +300,7 @@ suite('SnippetController', () => { ]); codeSnippet = 'foo\n$0\nbar'; - snippetController.insert(codeSnippet, 0, 0); + snippetController.insert(codeSnippet); assert.equal(editor.getSelections()!.length, 2); const [first, second] = editor.getSelections()!; @@ -314,7 +314,7 @@ suite('SnippetController', () => { ]); codeSnippet = 'xo$0r'; - snippetController.insert(codeSnippet, 1, 0); + snippetController.insert(codeSnippet, { overwriteBefore: 1 }); assert.equal(editor.getSelections()!.length, 1); assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 2, startColumn: 8, endColumn: 8, endLineNumber: 2 })); @@ -327,7 +327,7 @@ suite('SnippetController', () => { editor.setSelection(new Selection(1, 19, 1, 19)); codeSnippet = '{{% url_**$1** %}}'; - controller.insert(codeSnippet, 2, 0); + controller.insert(codeSnippet, { overwriteBefore: 2 }); assert.equal(editor.getSelections()!.length, 1); assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 1, startColumn: 27, endLineNumber: 1, endColumn: 27 })); @@ -345,7 +345,7 @@ suite('SnippetController', () => { '});' ].join('\n'); - controller.insert(codeSnippet, 2, 0); + controller.insert(codeSnippet, { overwriteBefore: 2 }); assert.equal(editor.getSelections()!.length, 1); assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 2, startColumn: 2, endLineNumber: 2, endColumn: 2 }), editor.getSelection()!.toString()); @@ -363,7 +363,7 @@ suite('SnippetController', () => { '});' ].join('\n'); - controller.insert(codeSnippet, 2, 0); + controller.insert(codeSnippet, { overwriteBefore: 2 }); assert.equal(editor.getSelections()!.length, 1); assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 2, startColumn: 1, endLineNumber: 2, endColumn: 1 }), editor.getSelection()!.toString()); @@ -379,7 +379,7 @@ suite('SnippetController', () => { 'aft${1}er' ].join('\n'); - controller.insert(codeSnippet, 8, 0); + controller.insert(codeSnippet, { overwriteBefore: 8 }); assert.equal(editor.getModel()!.getValue(), 'after'); assert.equal(editor.getSelections()!.length, 1); @@ -403,7 +403,7 @@ suite('SnippetController', () => { '});' ].join('\n'); - controller.insert(codeSnippet, 2, 0); + controller.insert(codeSnippet, { overwriteBefore: 2 }); assert.equal(editor.getSelections()!.length, 2); const [first, second] = editor.getSelections()!; @@ -428,7 +428,7 @@ suite('SnippetController', () => { '});' ].join('\n'); - controller.insert(codeSnippet, 2, 0); + controller.insert(codeSnippet, { overwriteBefore: 2 }); assert.equal(editor.getSelections()!.length, 1); const [first] = editor.getSelections()!; @@ -448,7 +448,7 @@ suite('SnippetController', () => { codeSnippet = 'afterEach'; - controller.insert(codeSnippet, 2, 0); + controller.insert(codeSnippet, { overwriteBefore: 2 }); assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 1, startColumn: 10, endLineNumber: 1, endColumn: 10 })); @@ -465,7 +465,7 @@ suite('SnippetController', () => { ]); codeSnippet = '_foo'; - controller.insert(codeSnippet, 1, 0); + controller.insert(codeSnippet, { overwriteBefore: 1 }); assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc_foo'); }, ['this._', 'abc']); @@ -478,7 +478,7 @@ suite('SnippetController', () => { ]); codeSnippet = 'XX'; - controller.insert(codeSnippet, 1, 0); + controller.insert(codeSnippet, { overwriteBefore: 1 }); assert.equal(editor.getModel()!.getValue(), 'this.XX\nabcXX'); }, ['this._', 'abc']); @@ -492,7 +492,7 @@ suite('SnippetController', () => { ]); codeSnippet = '_foo'; - controller.insert(codeSnippet, 1, 0); + controller.insert(codeSnippet, { overwriteBefore: 1 }); assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc_foo\ndef_foo'); }, ['this._', 'abc', 'def_']); @@ -506,7 +506,7 @@ suite('SnippetController', () => { ]); codeSnippet = '._foo'; - controller.insert(codeSnippet, 2, 0); + controller.insert(codeSnippet, { overwriteBefore: 2 }); assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc._foo\ndef._foo'); }, ['this._', 'abc', 'def._']); @@ -520,7 +520,7 @@ suite('SnippetController', () => { ]); codeSnippet = '._foo'; - controller.insert(codeSnippet, 2, 0); + controller.insert(codeSnippet, { overwriteBefore: 2 }); assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc._foo\ndef._foo'); }, ['this._', 'abc', 'def._']); @@ -534,7 +534,7 @@ suite('SnippetController', () => { ]); codeSnippet = '._foo'; - controller.insert(codeSnippet, 2, 0); + controller.insert(codeSnippet, { overwriteBefore: 2 }); assert.equal(editor.getModel()!.getValue(), 'this._._foo\na._foo\ndef._._foo'); }, ['this._', 'abc', 'def._']); @@ -550,7 +550,7 @@ suite('SnippetController', () => { ]); codeSnippet = 'document'; - controller.insert(codeSnippet, 3, 0); + controller.insert(codeSnippet, { overwriteBefore: 3 }); assert.equal(editor.getModel()!.getValue(), '{document}\n{document && true}'); }, ['{foo}', '{foo && true}']); @@ -565,7 +565,7 @@ suite('SnippetController', () => { ]); codeSnippet = 'for (var ${1:i}=0; ${1:i} { ]); codeSnippet = 'for (let ${1:i}=0; ${1:i} { editor.setSelection(new Selection(2, 5, 2, 5)); - const session = new SnippetSession(editor, 'abc\n foo\n bar\n$0', 0, 0, false); + const session = new SnippetSession(editor, 'abc\n foo\n bar\n$0', { overwriteBefore: 0, overwriteAfter: 0, adjustWhitespace: false, clipboardText: undefined }); session.insert(); assert.equal(editor.getModel()!.getValue(), 'function foo() {\n abc\n foo\n bar\nconsole.log(a);\n}'); }); @@ -648,7 +648,7 @@ suite('SnippetSession', function () { assert.ok(actual.equalsSelection(new Selection(1, 9, 1, 12))); editor.setSelections([new Selection(1, 9, 1, 12)]); - new SnippetSession(editor, 'far', 3, 0).insert(); + new SnippetSession(editor, 'far', { overwriteBefore: 3, overwriteAfter: 0, adjustWhitespace: true, clipboardText: undefined }).insert(); assert.equal(model.getValue(), 'console.far'); }); }); diff --git a/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts b/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts index 0b44a9c6a68..7a5367085e7 100644 --- a/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts @@ -9,11 +9,18 @@ import { Selection } from 'vs/editor/common/core/selection'; import { SelectionBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, ClipboardBasedVariableResolver, TimeBasedVariableResolver, WorkspaceBasedVariableResolver } from 'vs/editor/contrib/snippet/snippetVariables'; import { SnippetParser, Variable, VariableResolver } from 'vs/editor/contrib/snippet/snippetParser'; import { TextModel } from 'vs/editor/common/model/textModel'; -import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { Workspace, toWorkspaceFolders, IWorkspace, IWorkspaceContextService, toWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { ILabelService } from 'vs/platform/label/common/label'; +import { mock } from 'vs/editor/contrib/suggest/test/suggestModel.test'; suite('Snippet Variables Resolver', function () { + const labelService = new class extends mock() { + getUriLabel(uri: URI) { + return uri.fsPath; + } + }; + let model: TextModel; let resolver: VariableResolver; @@ -25,7 +32,7 @@ suite('Snippet Variables Resolver', function () { ].join('\n'), undefined, undefined, URI.parse('file:///foo/files/text.txt')); resolver = new CompositeSnippetVariableResolver([ - new ModelBasedVariableResolver(model), + new ModelBasedVariableResolver(labelService, model), new SelectionBasedVariableResolver(model, new Selection(1, 1, 1, 1)), ]); }); @@ -59,6 +66,7 @@ suite('Snippet Variables Resolver', function () { } resolver = new ModelBasedVariableResolver( + labelService, TextModel.createFromString('', undefined, undefined, URI.parse('http://www.pb.o/abc/def/ghi')) ); assertVariableResolve(resolver, 'TM_FILENAME', 'ghi'); @@ -68,6 +76,7 @@ suite('Snippet Variables Resolver', function () { } resolver = new ModelBasedVariableResolver( + labelService, TextModel.createFromString('', undefined, undefined, URI.parse('mem:fff.ts')) ); assertVariableResolve(resolver, 'TM_DIRECTORY', ''); @@ -75,6 +84,21 @@ suite('Snippet Variables Resolver', function () { }); + test('Path delimiters in code snippet variables aren\'t specific to remote OS #76840', function () { + + const labelService = new class extends mock() { + getUriLabel(uri: URI) { + return uri.fsPath.replace(/\/|\\/g, '|'); + } + }; + + const model = TextModel.createFromString([].join('\n'), undefined, undefined, URI.parse('foo:///foo/files/text.txt')); + + const resolver = new CompositeSnippetVariableResolver([new ModelBasedVariableResolver(labelService, model)]); + + assertVariableResolve(resolver, 'TM_FILEPATH', '|foo|files|text.txt'); + }); + test('editor variables, selection', function () { resolver = new SelectionBasedVariableResolver(model, new Selection(1, 2, 2, 3)); @@ -119,16 +143,19 @@ suite('Snippet Variables Resolver', function () { assertVariableResolve(resolver, 'TM_FILENAME_BASE', 'text'); resolver = new ModelBasedVariableResolver( + labelService, TextModel.createFromString('', undefined, undefined, URI.parse('http://www.pb.o/abc/def/ghi')) ); assertVariableResolve(resolver, 'TM_FILENAME_BASE', 'ghi'); resolver = new ModelBasedVariableResolver( + labelService, TextModel.createFromString('', undefined, undefined, URI.parse('mem:.git')) ); assertVariableResolve(resolver, 'TM_FILENAME_BASE', '.git'); resolver = new ModelBasedVariableResolver( + labelService, TextModel.createFromString('', undefined, undefined, URI.parse('mem:foo.')) ); assertVariableResolve(resolver, 'TM_FILENAME_BASE', 'foo'); @@ -209,63 +236,26 @@ suite('Snippet Variables Resolver', function () { test('Add variable to insert value from clipboard to a snippet #40153', function () { - let readTextResult: string | null | undefined; - const clipboardService = new class implements IClipboardService { - _serviceBrand: any; - readText(): any { return readTextResult; } - _throw = () => { throw new Error(); }; - writeText = this._throw; - readFindText = this._throw; - writeFindText = this._throw; - writeResources = this._throw; - readResources = this._throw; - hasResources = this._throw; - }; - let resolver = new ClipboardBasedVariableResolver(clipboardService, 1, 0); + assertVariableResolve(new ClipboardBasedVariableResolver(undefined, 1, 0), 'CLIPBOARD', undefined); - readTextResult = undefined; - assertVariableResolve(resolver, 'CLIPBOARD', undefined); + assertVariableResolve(new ClipboardBasedVariableResolver(null!, 1, 0), 'CLIPBOARD', undefined); - readTextResult = null; - assertVariableResolve(resolver, 'CLIPBOARD', undefined); + assertVariableResolve(new ClipboardBasedVariableResolver('', 1, 0), 'CLIPBOARD', undefined); - readTextResult = ''; - assertVariableResolve(resolver, 'CLIPBOARD', undefined); + assertVariableResolve(new ClipboardBasedVariableResolver('foo', 1, 0), 'CLIPBOARD', 'foo'); - readTextResult = 'foo'; - assertVariableResolve(resolver, 'CLIPBOARD', 'foo'); - - assertVariableResolve(resolver, 'foo', undefined); - assertVariableResolve(resolver, 'cLIPBOARD', undefined); + assertVariableResolve(new ClipboardBasedVariableResolver('foo', 1, 0), 'foo', undefined); + assertVariableResolve(new ClipboardBasedVariableResolver('foo', 1, 0), 'cLIPBOARD', undefined); }); test('Add variable to insert value from clipboard to a snippet #40153', function () { - let readTextResult: string; - let resolver: VariableResolver; - const clipboardService = new class implements IClipboardService { - _serviceBrand: any; - readText(): string { return readTextResult; } - _throw = () => { throw new Error(); }; - writeText = this._throw; - readFindText = this._throw; - writeFindText = this._throw; - writeResources = this._throw; - readResources = this._throw; - hasResources = this._throw; - }; + assertVariableResolve(new ClipboardBasedVariableResolver('line1', 1, 2), 'CLIPBOARD', 'line1'); + assertVariableResolve(new ClipboardBasedVariableResolver('line1\nline2\nline3', 1, 2), 'CLIPBOARD', 'line1\nline2\nline3'); - resolver = new ClipboardBasedVariableResolver(clipboardService, 1, 2); - readTextResult = 'line1'; - assertVariableResolve(resolver, 'CLIPBOARD', 'line1'); - readTextResult = 'line1\nline2\nline3'; - assertVariableResolve(resolver, 'CLIPBOARD', 'line1\nline2\nline3'); - - readTextResult = 'line1\nline2'; - assertVariableResolve(resolver, 'CLIPBOARD', 'line2'); - readTextResult = 'line1\nline2'; - resolver = new ClipboardBasedVariableResolver(clipboardService, 0, 2); - assertVariableResolve(resolver, 'CLIPBOARD', 'line1'); + assertVariableResolve(new ClipboardBasedVariableResolver('line1\nline2', 1, 2), 'CLIPBOARD', 'line2'); + resolver = new ClipboardBasedVariableResolver('line1\nline2', 0, 2); + assertVariableResolve(new ClipboardBasedVariableResolver('line1\nline2', 0, 2), 'CLIPBOARD', 'line1'); }); @@ -336,4 +326,4 @@ suite('Snippet Variables Resolver', function () { workspace = new Workspace('', toWorkspaceFolders([{ path: 'folderName' }], workspaceConfigPath), workspaceConfigPath); assertVariableResolve(resolver, 'WORKSPACE_NAME', 'testWorkspace'); }); -}); \ No newline at end of file +}); diff --git a/src/vs/editor/contrib/suggest/completionModel.ts b/src/vs/editor/contrib/suggest/completionModel.ts index 63836d21286..29673ee6473 100644 --- a/src/vs/editor/contrib/suggest/completionModel.ts +++ b/src/vs/editor/contrib/suggest/completionModel.ts @@ -4,8 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { fuzzyScore, fuzzyScoreGracefulAggressive, FuzzyScorer, FuzzyScore, anyScore } from 'vs/base/common/filters'; -import { isDisposable } from 'vs/base/common/lifecycle'; -import { CompletionList, CompletionItemProvider, CompletionItemKind } from 'vs/editor/common/modes'; +import { CompletionItemProvider, CompletionItemKind } from 'vs/editor/common/modes'; import { CompletionItem } from './suggest'; import { InternalSuggestOptions, EDITOR_DEFAULTS } from 'vs/editor/common/config/editorOptions'; import { WordDistance } from 'vs/editor/contrib/suggest/wordDistance'; @@ -75,18 +74,6 @@ export class CompletionModel { } } - dispose(): void { - const seen = new Set(); - for (const { container } of this._items) { - if (!seen.has(container)) { - seen.add(container); - if (isDisposable(container)) { - container.dispose(); - } - } - } - } - get lineContext(): LineContext { return this._lineContext; } diff --git a/src/vs/editor/contrib/suggest/media/Class_16x.svg b/src/vs/editor/contrib/suggest/media/Class_16x.svg deleted file mode 100755 index 5ef1c6f80bc..00000000000 --- a/src/vs/editor/contrib/suggest/media/Class_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Class_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/Class_inverse_16x.svg deleted file mode 100755 index c43aad29efd..00000000000 --- a/src/vs/editor/contrib/suggest/media/Class_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/ColorPalette_16x.svg b/src/vs/editor/contrib/suggest/media/ColorPalette_16x.svg deleted file mode 100755 index 2af5cc6faef..00000000000 --- a/src/vs/editor/contrib/suggest/media/ColorPalette_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/ColorPalette_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/ColorPalette_inverse_16x.svg deleted file mode 100755 index 7afb32b895e..00000000000 --- a/src/vs/editor/contrib/suggest/media/ColorPalette_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Constant_16x.svg b/src/vs/editor/contrib/suggest/media/Constant_16x.svg deleted file mode 100644 index ed2a1751005..00000000000 --- a/src/vs/editor/contrib/suggest/media/Constant_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Constant_16x_inverse.svg b/src/vs/editor/contrib/suggest/media/Constant_16x_inverse.svg deleted file mode 100644 index 173e427f964..00000000000 --- a/src/vs/editor/contrib/suggest/media/Constant_16x_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Document_16x.svg b/src/vs/editor/contrib/suggest/media/Document_16x.svg deleted file mode 100755 index 13ded2953eb..00000000000 --- a/src/vs/editor/contrib/suggest/media/Document_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Document_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/Document_inverse_16x.svg deleted file mode 100755 index 949a376216a..00000000000 --- a/src/vs/editor/contrib/suggest/media/Document_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/EnumItem_16x.svg b/src/vs/editor/contrib/suggest/media/EnumItem_16x.svg deleted file mode 100755 index aa901ec1934..00000000000 --- a/src/vs/editor/contrib/suggest/media/EnumItem_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/EnumItem_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/EnumItem_inverse_16x.svg deleted file mode 100755 index 791759092fc..00000000000 --- a/src/vs/editor/contrib/suggest/media/EnumItem_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Enumerator_16x.svg b/src/vs/editor/contrib/suggest/media/Enumerator_16x.svg deleted file mode 100755 index e4a9551fd5a..00000000000 --- a/src/vs/editor/contrib/suggest/media/Enumerator_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Enumerator_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/Enumerator_inverse_16x.svg deleted file mode 100755 index d8e9f4f107a..00000000000 --- a/src/vs/editor/contrib/suggest/media/Enumerator_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Event_16x_vscode.svg b/src/vs/editor/contrib/suggest/media/Event_16x_vscode.svg deleted file mode 100644 index 0e202ec10be..00000000000 --- a/src/vs/editor/contrib/suggest/media/Event_16x_vscode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Event_16x_vscode_inverse.svg b/src/vs/editor/contrib/suggest/media/Event_16x_vscode_inverse.svg deleted file mode 100644 index a508edcd3d6..00000000000 --- a/src/vs/editor/contrib/suggest/media/Event_16x_vscode_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Field_16x.svg b/src/vs/editor/contrib/suggest/media/Field_16x.svg deleted file mode 100755 index c6cb5362b3b..00000000000 --- a/src/vs/editor/contrib/suggest/media/Field_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Field_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/Field_inverse_16x.svg deleted file mode 100755 index 5fc48ceff0f..00000000000 --- a/src/vs/editor/contrib/suggest/media/Field_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Folder_16x.svg b/src/vs/editor/contrib/suggest/media/Folder_16x.svg deleted file mode 100644 index 3d64ae71db4..00000000000 --- a/src/vs/editor/contrib/suggest/media/Folder_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Folder_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/Folder_inverse_16x.svg deleted file mode 100755 index 13b18d18016..00000000000 --- a/src/vs/editor/contrib/suggest/media/Folder_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/ImportFile_16x_vscode.svg b/src/vs/editor/contrib/suggest/media/ImportFile_16x_vscode.svg deleted file mode 100644 index 5511fc9e239..00000000000 --- a/src/vs/editor/contrib/suggest/media/ImportFile_16x_vscode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/ImportFile_16x_vscode_inverse.svg b/src/vs/editor/contrib/suggest/media/ImportFile_16x_vscode_inverse.svg deleted file mode 100644 index 604d994cbd5..00000000000 --- a/src/vs/editor/contrib/suggest/media/ImportFile_16x_vscode_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/IntelliSenseKeyword_16x.svg b/src/vs/editor/contrib/suggest/media/IntelliSenseKeyword_16x.svg deleted file mode 100755 index 4a69c4a038b..00000000000 --- a/src/vs/editor/contrib/suggest/media/IntelliSenseKeyword_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/IntelliSenseKeyword_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/IntelliSenseKeyword_inverse_16x.svg deleted file mode 100755 index decbf2c403e..00000000000 --- a/src/vs/editor/contrib/suggest/media/IntelliSenseKeyword_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Interface_16x.svg b/src/vs/editor/contrib/suggest/media/Interface_16x.svg deleted file mode 100755 index 958a792742a..00000000000 --- a/src/vs/editor/contrib/suggest/media/Interface_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Interface_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/Interface_inverse_16x.svg deleted file mode 100755 index f7c2934a55c..00000000000 --- a/src/vs/editor/contrib/suggest/media/Interface_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/LocalVariable_16x_vscode.svg b/src/vs/editor/contrib/suggest/media/LocalVariable_16x_vscode.svg deleted file mode 100644 index e78894b6c63..00000000000 --- a/src/vs/editor/contrib/suggest/media/LocalVariable_16x_vscode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/LocalVariable_16x_vscode_inverse.svg b/src/vs/editor/contrib/suggest/media/LocalVariable_16x_vscode_inverse.svg deleted file mode 100644 index 44a44b489d1..00000000000 --- a/src/vs/editor/contrib/suggest/media/LocalVariable_16x_vscode_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Method_16x.svg b/src/vs/editor/contrib/suggest/media/Method_16x.svg deleted file mode 100755 index 2be9daa5f5d..00000000000 --- a/src/vs/editor/contrib/suggest/media/Method_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Method_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/Method_inverse_16x.svg deleted file mode 100755 index d3c2c571d98..00000000000 --- a/src/vs/editor/contrib/suggest/media/Method_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Namespace_16x.svg b/src/vs/editor/contrib/suggest/media/Namespace_16x.svg deleted file mode 100755 index dab07dd5ad9..00000000000 --- a/src/vs/editor/contrib/suggest/media/Namespace_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Namespace_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/Namespace_inverse_16x.svg deleted file mode 100755 index 9b9a44c52d2..00000000000 --- a/src/vs/editor/contrib/suggest/media/Namespace_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Operator_16x_vscode.svg b/src/vs/editor/contrib/suggest/media/Operator_16x_vscode.svg deleted file mode 100644 index ba2f2d091cf..00000000000 --- a/src/vs/editor/contrib/suggest/media/Operator_16x_vscode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Operator_16x_vscode_inverse.svg b/src/vs/editor/contrib/suggest/media/Operator_16x_vscode_inverse.svg deleted file mode 100644 index 21e1e814b2e..00000000000 --- a/src/vs/editor/contrib/suggest/media/Operator_16x_vscode_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Property_16x.svg b/src/vs/editor/contrib/suggest/media/Property_16x.svg deleted file mode 100755 index fb1c74cf773..00000000000 --- a/src/vs/editor/contrib/suggest/media/Property_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Property_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/Property_inverse_16x.svg deleted file mode 100755 index f90781897a7..00000000000 --- a/src/vs/editor/contrib/suggest/media/Property_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Ruler_16x.svg b/src/vs/editor/contrib/suggest/media/Ruler_16x.svg deleted file mode 100755 index 2e8e88fef0d..00000000000 --- a/src/vs/editor/contrib/suggest/media/Ruler_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Ruler_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/Ruler_inverse_16x.svg deleted file mode 100755 index 373ab812f92..00000000000 --- a/src/vs/editor/contrib/suggest/media/Ruler_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Snippet_16x.svg b/src/vs/editor/contrib/suggest/media/Snippet_16x.svg deleted file mode 100644 index 8bf3b9f67d6..00000000000 --- a/src/vs/editor/contrib/suggest/media/Snippet_16x.svg +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/src/vs/editor/contrib/suggest/media/Snippet_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/Snippet_inverse_16x.svg deleted file mode 100644 index 501ff9c6177..00000000000 --- a/src/vs/editor/contrib/suggest/media/Snippet_inverse_16x.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/src/vs/editor/contrib/suggest/media/String_16x.svg b/src/vs/editor/contrib/suggest/media/String_16x.svg deleted file mode 100755 index 35e744ce90d..00000000000 --- a/src/vs/editor/contrib/suggest/media/String_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/String_inverse_16x.svg b/src/vs/editor/contrib/suggest/media/String_inverse_16x.svg deleted file mode 100755 index 1ac0cf99ac8..00000000000 --- a/src/vs/editor/contrib/suggest/media/String_inverse_16x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Structure_16x_vscode.svg b/src/vs/editor/contrib/suggest/media/Structure_16x_vscode.svg deleted file mode 100644 index e776cbc5651..00000000000 --- a/src/vs/editor/contrib/suggest/media/Structure_16x_vscode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Structure_16x_vscode_inverse.svg b/src/vs/editor/contrib/suggest/media/Structure_16x_vscode_inverse.svg deleted file mode 100644 index 1b76b62be9a..00000000000 --- a/src/vs/editor/contrib/suggest/media/Structure_16x_vscode_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Template_16x_vscode.svg b/src/vs/editor/contrib/suggest/media/Template_16x_vscode.svg deleted file mode 100644 index 788cc8d6450..00000000000 --- a/src/vs/editor/contrib/suggest/media/Template_16x_vscode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/Template_16x_vscode_inverse.svg b/src/vs/editor/contrib/suggest/media/Template_16x_vscode_inverse.svg deleted file mode 100644 index 6cec71cb033..00000000000 --- a/src/vs/editor/contrib/suggest/media/Template_16x_vscode_inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/boolean-dark.svg b/src/vs/editor/contrib/suggest/media/boolean-dark.svg new file mode 100644 index 00000000000..e009568b131 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/boolean-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/boolean-light.svg b/src/vs/editor/contrib/suggest/media/boolean-light.svg new file mode 100644 index 00000000000..06613f8bedd --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/boolean-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/class-dark.svg b/src/vs/editor/contrib/suggest/media/class-dark.svg new file mode 100644 index 00000000000..a71e221f6bd --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/class-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/class-light.svg b/src/vs/editor/contrib/suggest/media/class-light.svg new file mode 100644 index 00000000000..aa106f18f87 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/class-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/close-dark.svg b/src/vs/editor/contrib/suggest/media/close-dark.svg index 751e89b3b02..556e2e20992 100644 --- a/src/vs/editor/contrib/suggest/media/close-dark.svg +++ b/src/vs/editor/contrib/suggest/media/close-dark.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + diff --git a/src/vs/editor/contrib/suggest/media/close-light.svg b/src/vs/editor/contrib/suggest/media/close-light.svg new file mode 100644 index 00000000000..c84816a0324 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/close-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/close.svg b/src/vs/editor/contrib/suggest/media/close.svg deleted file mode 100644 index fde34404d4e..00000000000 --- a/src/vs/editor/contrib/suggest/media/close.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/browser/media/images/intellisense/color-alt1.svg b/src/vs/editor/contrib/suggest/media/color-dark.svg similarity index 95% rename from src/vs/workbench/browser/media/images/intellisense/color-alt1.svg rename to src/vs/editor/contrib/suggest/media/color-dark.svg index 914bb6f48d5..0914abcdbd3 100644 --- a/src/vs/workbench/browser/media/images/intellisense/color-alt1.svg +++ b/src/vs/editor/contrib/suggest/media/color-dark.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/editor/contrib/suggest/media/color-light.svg b/src/vs/editor/contrib/suggest/media/color-light.svg new file mode 100644 index 00000000000..ca089a1bf2a --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/color-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/constant-dark.svg b/src/vs/editor/contrib/suggest/media/constant-dark.svg new file mode 100644 index 00000000000..0e90ecafcd8 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/constant-dark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/editor/contrib/suggest/media/constant-light.svg b/src/vs/editor/contrib/suggest/media/constant-light.svg new file mode 100644 index 00000000000..1a369c1d8aa --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/constant-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vs/editor/contrib/suggest/media/enumerator-dark.svg b/src/vs/editor/contrib/suggest/media/enumerator-dark.svg new file mode 100644 index 00000000000..82d4ff29c44 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/enumerator-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/enumerator-item-dark.svg b/src/vs/editor/contrib/suggest/media/enumerator-item-dark.svg new file mode 100644 index 00000000000..23c697fdf17 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/enumerator-item-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/enumerator-item-light.svg b/src/vs/editor/contrib/suggest/media/enumerator-item-light.svg new file mode 100644 index 00000000000..a99045d3352 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/enumerator-item-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/enumerator-light.svg b/src/vs/editor/contrib/suggest/media/enumerator-light.svg new file mode 100644 index 00000000000..e2441a0dc16 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/enumerator-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/event-dark.svg b/src/vs/editor/contrib/suggest/media/event-dark.svg new file mode 100644 index 00000000000..712344d1f92 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/event-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/event-light.svg b/src/vs/editor/contrib/suggest/media/event-light.svg new file mode 100644 index 00000000000..712344d1f92 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/event-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/field-dark.svg b/src/vs/editor/contrib/suggest/media/field-dark.svg new file mode 100644 index 00000000000..15623061c5d --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/field-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/field-light.svg b/src/vs/editor/contrib/suggest/media/field-light.svg new file mode 100644 index 00000000000..72dd79504f6 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/field-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/file-dark.svg b/src/vs/editor/contrib/suggest/media/file-dark.svg new file mode 100644 index 00000000000..5ed5762a1f0 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/file-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/file-light.svg b/src/vs/editor/contrib/suggest/media/file-light.svg new file mode 100644 index 00000000000..ad54e13b1b1 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/file-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/folder-dark.svg b/src/vs/editor/contrib/suggest/media/folder-dark.svg new file mode 100644 index 00000000000..43d454e7e5a --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/folder-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/folder-light.svg b/src/vs/editor/contrib/suggest/media/folder-light.svg new file mode 100644 index 00000000000..8daecdac6a3 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/folder-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/indexer-dark.svg b/src/vs/editor/contrib/suggest/media/indexer-dark.svg new file mode 100644 index 00000000000..e92131d3d02 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/indexer-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/indexer-light.svg b/src/vs/editor/contrib/suggest/media/indexer-light.svg new file mode 100644 index 00000000000..207899642c8 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/indexer-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/info-dark.svg b/src/vs/editor/contrib/suggest/media/info-dark.svg new file mode 100644 index 00000000000..3f2d84fa649 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/info-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/info-light.svg b/src/vs/editor/contrib/suggest/media/info-light.svg new file mode 100644 index 00000000000..f25ac7c78d6 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/info-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/info.svg b/src/vs/editor/contrib/suggest/media/info.svg deleted file mode 100644 index 6578b81ea3f..00000000000 --- a/src/vs/editor/contrib/suggest/media/info.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/media/interface-dark.svg b/src/vs/editor/contrib/suggest/media/interface-dark.svg new file mode 100644 index 00000000000..6d482b2abde --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/interface-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/interface-light.svg b/src/vs/editor/contrib/suggest/media/interface-light.svg new file mode 100644 index 00000000000..a397dd00b00 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/interface-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/keyword-dark.svg b/src/vs/editor/contrib/suggest/media/keyword-dark.svg new file mode 100644 index 00000000000..70ba6ea9331 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/keyword-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/keyword-light.svg b/src/vs/editor/contrib/suggest/media/keyword-light.svg new file mode 100644 index 00000000000..fc57528a3ef --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/keyword-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/method-dark.svg b/src/vs/editor/contrib/suggest/media/method-dark.svg new file mode 100644 index 00000000000..970d7b61480 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/method-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/method-light.svg b/src/vs/editor/contrib/suggest/media/method-light.svg new file mode 100644 index 00000000000..403a9b90dd9 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/method-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/namespace-dark.svg b/src/vs/editor/contrib/suggest/media/namespace-dark.svg new file mode 100644 index 00000000000..9a725bb41fd --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/namespace-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/namespace-light.svg b/src/vs/editor/contrib/suggest/media/namespace-light.svg new file mode 100644 index 00000000000..1339da7ce21 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/namespace-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/numeric-dark.svg b/src/vs/editor/contrib/suggest/media/numeric-dark.svg new file mode 100644 index 00000000000..a1573df0107 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/numeric-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/numeric-light.svg b/src/vs/editor/contrib/suggest/media/numeric-light.svg new file mode 100644 index 00000000000..ea0e56e0225 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/numeric-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/operator-dark.svg b/src/vs/editor/contrib/suggest/media/operator-dark.svg new file mode 100644 index 00000000000..957f5f44f17 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/operator-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/operator-light.svg b/src/vs/editor/contrib/suggest/media/operator-light.svg new file mode 100644 index 00000000000..bf6ed57996a --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/operator-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/property-dark.svg b/src/vs/editor/contrib/suggest/media/property-dark.svg new file mode 100644 index 00000000000..23e07ffa19b --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/property-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/property-light.svg b/src/vs/editor/contrib/suggest/media/property-light.svg new file mode 100644 index 00000000000..be642dd152d --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/property-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/reference-dark.svg b/src/vs/editor/contrib/suggest/media/reference-dark.svg new file mode 100644 index 00000000000..ed302ae1398 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/reference-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/reference-light.svg b/src/vs/editor/contrib/suggest/media/reference-light.svg new file mode 100644 index 00000000000..392a840c5ef --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/reference-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/ruler-dark.svg b/src/vs/editor/contrib/suggest/media/ruler-dark.svg new file mode 100644 index 00000000000..1957dbad34e --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/ruler-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/ruler-light.svg b/src/vs/editor/contrib/suggest/media/ruler-light.svg new file mode 100644 index 00000000000..bc321cdffa3 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/ruler-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/snippet-dark.svg b/src/vs/editor/contrib/suggest/media/snippet-dark.svg new file mode 100644 index 00000000000..79799f98c26 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/snippet-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/snippet-light.svg b/src/vs/editor/contrib/suggest/media/snippet-light.svg new file mode 100644 index 00000000000..45fa3a001e8 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/snippet-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/string-dark.svg b/src/vs/editor/contrib/suggest/media/string-dark.svg new file mode 100644 index 00000000000..80fb9d6567d --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/string-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/string-light.svg b/src/vs/editor/contrib/suggest/media/string-light.svg new file mode 100644 index 00000000000..02a0282e906 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/string-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/structure-dark.svg b/src/vs/editor/contrib/suggest/media/structure-dark.svg new file mode 100644 index 00000000000..13766a5dcea --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/structure-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/structure-light.svg b/src/vs/editor/contrib/suggest/media/structure-light.svg new file mode 100644 index 00000000000..c96bcfa61b0 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/structure-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/suggest.css b/src/vs/editor/contrib/suggest/media/suggest.css index b5b3eb956b5..23f9e36ad30 100644 --- a/src/vs/editor/contrib/suggest/media/suggest.css +++ b/src/vs/editor/contrib/suggest/media/suggest.css @@ -109,13 +109,13 @@ } .monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > .header > .close { - background-image: url('./close.svg'); + background-image: url('./close-light.svg'); float: right; margin-right: 5px; } .monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .readMore { - background-image: url('./info.svg'); + background-image: url('./info-light.svg'); } .monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > .header > .close:hover, @@ -187,30 +187,30 @@ .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.method::before, .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.function::before, -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constructor::before { background-image: url('Method_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.field::before { background-image: url('Field_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.event::before { background-image: url('Event_16x_vscode.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.operator::before { background-image: url('Operator_16x_vscode.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.variable::before { background-image: url('LocalVariable_16x_vscode.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.class::before { background-image: url('Class_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.interface::before { background-image: url('Interface_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.struct::before { background-image: url('Structure_16x_vscode.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.type-parameter::before { background-image: url('Template_16x_vscode.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.module::before { background-image: url('Namespace_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.property::before { background-image: url('Property_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.unit::before { background-image: url('Ruler_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constant::before { background-image: url('Constant_16x.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constructor::before { background-image: url('method-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.field::before { background-image: url('field-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.event::before { background-image: url('event-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.operator::before { background-image: url('operator-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.variable::before { background-image: url('variable-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.class::before { background-image: url('class-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.interface::before { background-image: url('interface-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.struct::before { background-image: url('structure-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.type-parameter::before { background-image: url('template-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.module::before { background-image: url('namespace-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.property::before { background-image: url('property-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.unit::before { background-image: url('ruler-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constant::before { background-image: url('constant-light.svg'); } .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.value::before, -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum::before { background-image: url('Enumerator_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum-member::before { background-image: url('EnumItem_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.keyword::before { background-image: url('IntelliSenseKeyword_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.text::before { background-image: url('String_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.color::before { background-image: url('ColorPalette_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.file::before { background-image: url('Document_16x.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.reference::before { background-image: url('ImportFile_16x_vscode.svg'); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.snippet::before { background-image: url('Snippet_16x.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum::before { background-image: url('enumerator-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum-member::before { background-image: url('enumerator-item-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.keyword::before { background-image: url('keyword-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.text::before { background-image: url('string-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.color::before { background-image: url('color-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.file::before { background-image: url('file-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.reference::before { background-image: url('reference-light.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.snippet::before { background-image: url('snippet-light.svg'); } .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.customcolor::before { background-image: none; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.folder::before { background-image: url('Folder_16x.svg'); } +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.folder::before { background-image: url('folder-light.svg'); } .monaco-editor .suggest-widget .monaco-list .monaco-list-row .icon.customcolor .colorspan { margin: 0 0 0 0.3em; @@ -301,6 +301,11 @@ background-image: url('./close-dark.svg'); } +.monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .readMore, +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .readMore { + background-image: url('./info-dark.svg'); +} + .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon::before, .monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon::before { background-image: url('Misc_inverse_16x.svg'); } @@ -309,72 +314,72 @@ .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.function::before, .monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.function::before, .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constructor::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constructor::before { background-image: url('Method_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constructor::before { background-image: url('method-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.field::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.field::before { background-image: url('Field_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.field::before { background-image: url('field-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.event::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.event::before { background-image: url('Event_16x_vscode_inverse.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.event::before { background-image: url('event-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.operator::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.operator::before { background-image: url('Operator_16x_vscode_inverse.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.operator::before { background-image: url('operator-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.variable::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.variable::before { background-image: url('LocalVariable_16x_vscode_inverse.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.variable::before { background-image: url('variable-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.class::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.class::before { background-image: url('Class_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.class::before { background-image: url('class-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.interface::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.interface::before { background-image: url('Interface_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.interface::before { background-image: url('interface-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.struct::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.struct::before { background-image: url('Structure_16x_vscode_inverse.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.struct::before { background-image: url('structure-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.type-parameter::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.type-parameter::before { background-image: url('Template_16x_vscode_inverse.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.type-parameter::before { background-image: url('template-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.module::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.module::before { background-image: url('Namespace_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.module::before { background-image: url('namespace-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.property::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.property::before { background-image: url('Property_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.property::before { background-image: url('property-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.unit::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.unit::before { background-image: url('Ruler_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.unit::before { background-image: url('ruler-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constant::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constant::before { background-image: url('Constant_16x_inverse.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constant::before { background-image: url('constant-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.value::before, .monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.value::before, .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum::before { background-image: url('Enumerator_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum::before { background-image: url('enumerator-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum-member::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum-member::before { background-image: url('EnumItem_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum-member::before { background-image: url('enumerator-item-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.keyword::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.keyword::before { background-image: url('IntelliSenseKeyword_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.keyword::before { background-image: url('keyword-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.text::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.text::before { background-image: url('String_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.text::before { background-image: url('string-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.color::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.color::before { background-image: url('ColorPalette_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.color::before { background-image: url('color-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.file::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.file::before { background-image: url('Document_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.file::before { background-image: url('file-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.reference::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.reference::before { background-image: url('ImportFile_16x_vscode_inverse.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.reference::before { background-image: url('reference-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.snippet::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.snippet::before { background-image: url('Snippet_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.snippet::before { background-image: url('snippet-dark.svg'); } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.customcolor::before, .monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.customcolor::before { background-image: none; } .monaco-editor.vs-dark .suggest-widget .monaco-list .monaco-list-row .suggest-icon.folder::before, -.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.folder::before { background-image: url('Folder_inverse_16x.svg'); } +.monaco-editor.hc-black .suggest-widget .monaco-list .monaco-list-row .suggest-icon.folder::before { background-image: url('folder-dark.svg'); } diff --git a/src/vs/editor/contrib/suggest/media/template-dark.svg b/src/vs/editor/contrib/suggest/media/template-dark.svg new file mode 100644 index 00000000000..425ced36f0e --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/template-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/template-light.svg b/src/vs/editor/contrib/suggest/media/template-light.svg new file mode 100644 index 00000000000..496d8f7c85c --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/template-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/variable-dark.svg b/src/vs/editor/contrib/suggest/media/variable-dark.svg new file mode 100644 index 00000000000..687fcabfff5 --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/variable-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/media/variable-light.svg b/src/vs/editor/contrib/suggest/media/variable-light.svg new file mode 100644 index 00000000000..ede7e9434dd --- /dev/null +++ b/src/vs/editor/contrib/suggest/media/variable-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/editor/contrib/suggest/suggest.ts b/src/vs/editor/contrib/suggest/suggest.ts index e5677eb39f9..241a826a54c 100644 --- a/src/vs/editor/contrib/suggest/suggest.ts +++ b/src/vs/editor/contrib/suggest/suggest.ts @@ -278,7 +278,7 @@ registerDefaultLanguageCommand('_executeCompletionItemProvider', async (model, p await Promise.all(resolving); return result; } finally { - disposables.dispose(); + setTimeout(() => disposables.dispose(), 0); } }); diff --git a/src/vs/editor/contrib/suggest/suggestCommitCharacters.ts b/src/vs/editor/contrib/suggest/suggestCommitCharacters.ts index ba0789bf893..8a6fca72612 100644 --- a/src/vs/editor/contrib/suggest/suggestCommitCharacters.ts +++ b/src/vs/editor/contrib/suggest/suggestCommitCharacters.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import { isNonEmptyArray } from 'vs/base/common/arrays'; -import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ISelectedSuggestion, SuggestWidget } from './suggestWidget'; import { CharacterSet } from 'vs/editor/common/core/characterClassifier'; export class CommitCharacterController { - private _disposables: IDisposable[] = []; + private readonly _disposables = new DisposableStore(); private _active?: { readonly acceptCharacters: CharacterSet; @@ -20,11 +20,11 @@ export class CommitCharacterController { constructor(editor: ICodeEditor, widget: SuggestWidget, accept: (selected: ISelectedSuggestion) => any) { - this._disposables.push(widget.onDidShow(() => this._onItem(widget.getFocusedItem()))); - this._disposables.push(widget.onDidFocus(this._onItem, this)); - this._disposables.push(widget.onDidHide(this.reset, this)); + this._disposables.add(widget.onDidShow(() => this._onItem(widget.getFocusedItem()))); + this._disposables.add(widget.onDidFocus(this._onItem, this)); + this._disposables.add(widget.onDidHide(this.reset, this)); - this._disposables.push(editor.onWillType(text => { + this._disposables.add(editor.onWillType(text => { if (this._active) { const ch = text.charCodeAt(text.length - 1); if (this._active.acceptCharacters.has(ch) && editor.getConfiguration().contribInfo.acceptSuggestionOnCommitCharacter) { @@ -54,6 +54,6 @@ export class CommitCharacterController { } dispose() { - dispose(this._disposables); + this._disposables.dispose(); } } diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index d267a41ca4e..aac58cf801d 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -7,7 +7,7 @@ import { alert } from 'vs/base/browser/ui/aria/aria'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import { onUnexpectedError } from 'vs/base/common/errors'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { dispose, IDisposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, EditorCommand, registerEditorAction, registerEditorCommand, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { EditOperation } from 'vs/editor/common/core/editOperation'; @@ -45,7 +45,7 @@ export class SuggestController implements IEditorContribution { private readonly _model: SuggestModel; private readonly _widget: IdleValue; private readonly _alternatives: IdleValue; - private _toDispose: IDisposable[] = []; + private readonly _toDispose = new DisposableStore(); private readonly _sticky = false; // for development purposes only @@ -63,23 +63,21 @@ export class SuggestController implements IEditorContribution { const widget = this._instantiationService.createInstance(SuggestWidget, this._editor); - this._toDispose.push(widget); - this._toDispose.push(widget.onDidSelect(item => this._insertSuggestion(item, false, true), this)); + this._toDispose.add(widget); + this._toDispose.add(widget.onDidSelect(item => this._insertSuggestion(item, false, true), this)); // Wire up logic to accept a suggestion on certain characters const commitCharacterController = new CommitCharacterController(this._editor, widget, item => this._insertSuggestion(item, false, true)); - this._toDispose.push( - commitCharacterController, - this._model.onDidSuggest(e => { - if (e.completionModel.items.length === 0) { - commitCharacterController.reset(); - } - }) - ); + this._toDispose.add(commitCharacterController); + this._toDispose.add(this._model.onDidSuggest(e => { + if (e.completionModel.items.length === 0) { + commitCharacterController.reset(); + } + })); // Wire up makes text edit context key let makesTextEdit = SuggestContext.MakesTextEdit.bindTo(this._contextKeyService); - this._toDispose.push(widget.onDidFocus(({ item }) => { + this._toDispose.add(widget.onDidFocus(({ item }) => { const position = this._editor.getPosition()!; const startColumn = item.completion.range.startColumn; @@ -103,38 +101,35 @@ export class SuggestController implements IEditorContribution { } makesTextEdit.set(value); })); - this._toDispose.push({ - dispose() { makesTextEdit.reset(); } - }); + this._toDispose.add(toDisposable(() => makesTextEdit.reset())); return widget; }); this._alternatives = new IdleValue(() => { - let res = new SuggestAlternatives(this._editor, this._contextKeyService); - this._toDispose.push(res); - return res; + return this._toDispose.add(new SuggestAlternatives(this._editor, this._contextKeyService)); }); - this._toDispose.push(_instantiationService.createInstance(WordContextKey, _editor)); + this._toDispose.add(_instantiationService.createInstance(WordContextKey, _editor)); - this._toDispose.push(this._model.onDidTrigger(e => { + this._toDispose.add(this._model.onDidTrigger(e => { this._widget.getValue().showTriggered(e.auto, e.shy ? 250 : 50); })); - this._toDispose.push(this._model.onDidSuggest(e => { + this._toDispose.add(this._model.onDidSuggest(e => { if (!e.shy) { let index = this._memoryService.select(this._editor.getModel()!, this._editor.getPosition()!, e.completionModel.items); this._widget.getValue().showSuggestions(e.completionModel, index, e.isFrozen, e.auto); } })); - this._toDispose.push(this._model.onDidCancel(e => { + this._toDispose.add(this._model.onDidCancel(e => { if (this._widget && !e.retrigger) { this._widget.getValue().hideWidget(); } })); - this._toDispose.push(this._editor.onDidBlurEditorWidget(() => { + this._toDispose.add(this._editor.onDidBlurEditorWidget(() => { if (!this._sticky) { this._model.cancel(); + this._model.clear(); } })); @@ -144,7 +139,7 @@ export class SuggestController implements IEditorContribution { const { acceptSuggestionOnEnter } = this._editor.getConfiguration().contribInfo; acceptSuggestionsOnEnter.set(acceptSuggestionOnEnter === 'on' || acceptSuggestionOnEnter === 'smart'); }; - this._toDispose.push(this._editor.onDidChangeConfiguration((e) => updateFromConfig())); + this._toDispose.add(this._editor.onDidChangeConfiguration(() => updateFromConfig())); updateFromConfig(); } @@ -154,17 +149,17 @@ export class SuggestController implements IEditorContribution { } dispose(): void { - this._toDispose = dispose(this._toDispose); + this._alternatives.dispose(); + this._toDispose.dispose(); this._widget.dispose(); - if (this._model) { - this._model.dispose(); - } + this._model.dispose(); } protected _insertSuggestion(event: ISelectedSuggestion | undefined, keepAlternativeSuggestions: boolean, undoStops: boolean): void { if (!event || !event.item) { this._alternatives.getValue().reset(); this._model.cancel(); + this._model.clear(); return; } if (!this._editor.hasModel()) { @@ -198,13 +193,13 @@ export class SuggestController implements IEditorContribution { const overwriteBefore = position.column - suggestion.range.startColumn; const overwriteAfter = suggestion.range.endColumn - position.column; - SnippetController2.get(this._editor).insert( - insertText, - overwriteBefore + columnDelta, + SnippetController2.get(this._editor).insert(insertText, { + overwriteBefore: overwriteBefore + columnDelta, overwriteAfter, - false, false, - !(suggestion.insertTextRules! & CompletionItemInsertTextRule.KeepWhitespace) - ); + undoStopBefore: false, + undoStopAfter: false, + adjustWhitespace: !(suggestion.insertTextRules! & CompletionItemInsertTextRule.KeepWhitespace) + }); if (undoStops) { this._editor.pushUndoStop(); @@ -213,6 +208,7 @@ export class SuggestController implements IEditorContribution { if (!suggestion.command) { // done this._model.cancel(); + this._model.clear(); } else if (suggestion.command.id === TriggerSuggestAction.id) { // retigger @@ -220,7 +216,9 @@ export class SuggestController implements IEditorContribution { } else { // exec command, done - this._commandService.executeCommand(suggestion.command.id, ...(suggestion.command.arguments ? [...suggestion.command.arguments] : [])).catch(onUnexpectedError); + this._commandService.executeCommand(suggestion.command.id, ...(suggestion.command.arguments ? [...suggestion.command.arguments] : [])) + .catch(onUnexpectedError) + .finally(() => this._model.clear()); // <- clear only now, keep commands alive this._model.cancel(); } @@ -340,6 +338,7 @@ export class SuggestController implements IEditorContribution { cancelSuggestWidget(): void { this._model.cancel(); + this._model.clear(); this._widget.getValue().hideWidget(); } diff --git a/src/vs/editor/contrib/suggest/suggestMemory.ts b/src/vs/editor/contrib/suggest/suggestMemory.ts index e99c55af5d5..7e19017b79e 100644 --- a/src/vs/editor/contrib/suggest/suggestMemory.ts +++ b/src/vs/editor/contrib/suggest/suggestMemory.ts @@ -5,7 +5,7 @@ import { LRUCache, TernarySearchTree } from 'vs/base/common/map'; -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { IStorageService, StorageScope, WillSaveStateReason } from 'vs/platform/storage/common/storage'; import { ITextModel } from 'vs/editor/common/model'; import { IPosition } from 'vs/editor/common/core/position'; import { CompletionItemKind, completionKindFromString } from 'vs/editor/common/modes'; @@ -221,7 +221,11 @@ export class SuggestMemoryService extends Disposable implements ISuggestMemorySe }; this._persistSoon = this._register(new RunOnceScheduler(() => this._saveState(), 500)); - this._register(_storageService.onWillSaveState(() => this._saveState())); + this._register(_storageService.onWillSaveState(e => { + if (e.reason === WillSaveStateReason.SHUTDOWN) { + this._saveState(); + } + })); this._register(this._configService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('editor.suggestSelection') || e.affectsConfiguration('editor.suggest.shareSuggestSelections')) { diff --git a/src/vs/editor/contrib/suggest/suggestModel.ts b/src/vs/editor/contrib/suggest/suggestModel.ts index 42991e0a2f8..63de4055d7e 100644 --- a/src/vs/editor/contrib/suggest/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/suggestModel.ts @@ -7,7 +7,7 @@ import { isNonEmptyArray } from 'vs/base/common/arrays'; import { TimeoutTimer } from 'vs/base/common/async'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, DisposableStore, isDisposable } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { CursorChangeReason, ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; import { Position } from 'vs/editor/common/core/position'; @@ -91,7 +91,7 @@ export const enum State { export class SuggestModel implements IDisposable { - private _toDispose: IDisposable[] = []; + private readonly _toDispose = new DisposableStore(); private _quickSuggestDelay: number; private _triggerCharacterListener: IDisposable; private readonly _triggerQuickSuggest = new TimeoutTimer(); @@ -101,7 +101,8 @@ export class SuggestModel implements IDisposable { private _context?: LineContext; private _currentSelection: Selection; - private _completionModel?: CompletionModel; + private _completionModel: CompletionModel | undefined; + private readonly _completionDisposables = new DisposableStore(); private readonly _onDidCancel = new Emitter(); private readonly _onDidTrigger = new Emitter(); private readonly _onDidSuggest = new Emitter(); @@ -117,36 +118,36 @@ export class SuggestModel implements IDisposable { this._currentSelection = this._editor.getSelection() || new Selection(1, 1, 1, 1); // wire up various listeners - this._toDispose.push(this._editor.onDidChangeModel(() => { + this._toDispose.add(this._editor.onDidChangeModel(() => { this._updateTriggerCharacters(); this.cancel(); })); - this._toDispose.push(this._editor.onDidChangeModelLanguage(() => { + this._toDispose.add(this._editor.onDidChangeModelLanguage(() => { this._updateTriggerCharacters(); this.cancel(); })); - this._toDispose.push(this._editor.onDidChangeConfiguration(() => { + this._toDispose.add(this._editor.onDidChangeConfiguration(() => { this._updateTriggerCharacters(); this._updateQuickSuggest(); })); - this._toDispose.push(CompletionProviderRegistry.onDidChange(() => { + this._toDispose.add(CompletionProviderRegistry.onDidChange(() => { this._updateTriggerCharacters(); this._updateActiveSuggestSession(); })); - this._toDispose.push(this._editor.onDidChangeCursorSelection(e => { + this._toDispose.add(this._editor.onDidChangeCursorSelection(e => { this._onCursorChange(e); })); let editorIsComposing = false; - this._toDispose.push(this._editor.onCompositionStart(() => { + this._toDispose.add(this._editor.onCompositionStart(() => { editorIsComposing = true; })); - this._toDispose.push(this._editor.onCompositionEnd(() => { + this._toDispose.add(this._editor.onCompositionEnd(() => { // refilter when composition ends editorIsComposing = false; this._refilterCompletionItems(); })); - this._toDispose.push(this._editor.onDidChangeModelContent(() => { + this._toDispose.add(this._editor.onDidChangeModelContent(() => { // only filter completions when the editor isn't // composing a character, e.g. ¨ + u makes ü but just // ¨ cannot be used for filtering @@ -161,8 +162,8 @@ export class SuggestModel implements IDisposable { dispose(): void { dispose([this._onDidCancel, this._onDidSuggest, this._onDidTrigger, this._triggerCharacterListener, this._triggerQuickSuggest]); - this._toDispose = dispose(this._toDispose); - dispose(this._completionModel); + this._toDispose.dispose(); + this._completionDisposables.dispose(); this.cancel(); } @@ -226,13 +227,16 @@ export class SuggestModel implements IDisposable { this._requestToken = undefined; } this._state = State.Idle; - dispose(this._completionModel); this._completionModel = undefined; this._context = undefined; this._onDidCancel.fire({ retrigger }); } } + clear() { + this._completionDisposables.clear(); + } + private _updateActiveSuggestSession(): void { if (this._state !== State.Idle) { if (!this._editor.hasModel() || !CompletionProviderRegistry.has(this._editor.getModel())) { @@ -289,6 +293,9 @@ export class SuggestModel implements IDisposable { this.cancel(); this._triggerQuickSuggest.cancelAndSet(() => { + if (this._state !== State.Idle) { + return; + } if (!LineContext.shouldAutoTrigger(this._editor)) { return; } @@ -435,7 +442,6 @@ export class SuggestModel implements IDisposable { } const ctx = new LineContext(model, this._editor.getPosition(), auto, context.shy); - dispose(this._completionModel); this._completionModel = new CompletionModel(items, this._context!.column, { leadingLineContent: ctx.leadingLineContent, characterCountDelta: ctx.column - this._context!.column @@ -443,6 +449,14 @@ export class SuggestModel implements IDisposable { wordDistance, this._editor.getConfiguration().contribInfo.suggest ); + + // store containers so that they can be disposed later + for (const item of items) { + if (isDisposable(item.container)) { + this._completionDisposables.add(item.container); + } + } + this._onNewContext(ctx); }).catch(onUnexpectedError); diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 0c0fbb66f0a..9e02b37f673 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -9,7 +9,7 @@ import { createMatches } from 'vs/base/common/filters'; import * as strings from 'vs/base/common/strings'; import { Event, Emitter } from 'vs/base/common/event'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { IDisposable, dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, toDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle'; import { addClass, append, $, hide, removeClass, show, toggleClass, getDomNodePagePosition, hasClass, addDisposableListener } from 'vs/base/browser/dom'; import { IListVirtualDelegate, IListEvent, IListRenderer, IListMouseEvent } from 'vs/base/browser/ui/list/list'; import { List } from 'vs/base/browser/ui/list/listWidget'; @@ -29,7 +29,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag import { MarkdownRenderer } from 'vs/editor/contrib/markdown/markdownRenderer'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { TimeoutTimer, CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; +import { TimeoutTimer, CancelablePromise, createCancelablePromise, disposableTimeout } from 'vs/base/common/async'; import { CompletionItemKind, completionKindToCssClass } from 'vs/editor/common/modes'; import { IconLabel, IIconLabelValueOptions } from 'vs/base/browser/ui/iconLabel/iconLabel'; import { getIconClasses } from 'vs/editor/common/services/getIconClasses'; @@ -37,6 +37,9 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { URI } from 'vs/base/common/uri'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { FileKind } from 'vs/platform/files/common/files'; +import { MarkdownString } from 'vs/base/common/htmlContent'; +import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; const expandSuggestionDocsByDefault = false; @@ -228,6 +231,18 @@ const enum State { Details } + +let _explainMode = false; +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'suggest.toggleExplainMode', + handler() { + _explainMode = !_explainMode; + }, + when: SuggestContext.Visible, + weight: KeybindingWeight.EditorContrib, + primary: KeyMod.CtrlCmd | KeyCode.US_SLASH, +}); + class SuggestionDetails { private el: HTMLElement; @@ -247,7 +262,7 @@ class SuggestionDetails { private readonly widget: SuggestWidget, private readonly editor: ICodeEditor, private readonly markdownRenderer: MarkdownRenderer, - private readonly triggerKeybindingLabel: string + private readonly triggerKeybindingLabel: string, ) { this.disposables = []; @@ -281,10 +296,27 @@ class SuggestionDetails { return this.el; } - render(item: CompletionItem): void { + renderLoading(): void { + this.type.textContent = nls.localize('loading', "Loading..."); + this.docs.textContent = ''; + } + + renderItem(item: CompletionItem): void { this.renderDisposeable = dispose(this.renderDisposeable); - if (!item || !canExpandCompletionItem(item)) { + let { documentation, detail } = item.completion; + // --- documentation + + if (_explainMode) { + let md = ''; + md += `score: ${item.score[0]}${item.word ? `, compared '${item.completion.filterText && (item.completion.filterText + ' (filterText)') || item.completion.label}' with '${item.word}'` : ' (no prefix)'}\n`; + md += `distance: ${item.distance}, see localityBonus-setting\n`; + md += `index: ${item.idx}, based on ${item.completion.sortText && `sortText: "${item.completion.sortText}"` || 'label'}\n`; + documentation = new MarkdownString().appendCodeblock('empty', md); + detail = `Provider: ${item.provider._debugDisplayName}`; + } + + if (!_explainMode && !canExpandCompletionItem(item)) { this.type.textContent = ''; this.docs.textContent = ''; addClass(this.el, 'no-docs'); @@ -292,19 +324,20 @@ class SuggestionDetails { return; } removeClass(this.el, 'no-docs'); - if (typeof item.completion.documentation === 'string') { + if (typeof documentation === 'string') { removeClass(this.docs, 'markdown-docs'); - this.docs.textContent = item.completion.documentation; + this.docs.textContent = documentation; } else { addClass(this.docs, 'markdown-docs'); this.docs.innerHTML = ''; - const renderedContents = this.markdownRenderer.render(item.completion.documentation); + const renderedContents = this.markdownRenderer.render(documentation); this.renderDisposeable = renderedContents; this.docs.appendChild(renderedContents.element); } - if (item.completion.detail) { - this.type.innerText = item.completion.detail; + // --- details + if (detail) { + this.type.innerText = detail; show(this.type); } else { this.type.innerText = ''; @@ -328,8 +361,8 @@ class SuggestionDetails { this.ariaLabel = strings.format( '{0}{1}', - item.completion.detail || '', - item.completion.documentation ? (typeof item.completion.documentation === 'string' ? item.completion.documentation : item.completion.documentation.value) : ''); + detail || '', + documentation ? (typeof documentation === 'string' ? documentation : documentation.value) : ''); } getAriaLabel() { @@ -405,7 +438,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate | null; private focusedItem: CompletionItem | null; private ignoreFocusEvents = false; @@ -423,7 +456,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate(); private onDidFocusEmitter = new Emitter(); @@ -459,14 +492,14 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate { + this.toDispose.add(addDisposableListener(this.element, 'click', e => { if (e.target === this.element) { this.hideWidget(); } @@ -474,7 +507,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate toggleClass(this.element, 'no-icons', !this.editor.getConfiguration().contribInfo.suggest.showIcons); applyIconStyle(); @@ -487,19 +520,18 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate this.onThemeChange(t)), - editor.onDidLayoutChange(() => this.onEditorLayoutChange()), - this.list.onMouseDown(e => this.onListMouseDown(e)), - this.list.onSelectionChange(e => this.onListSelection(e)), - this.list.onFocusChange(e => this.onListFocus(e)), - this.editor.onDidChangeCursorSelection(() => this.onCursorSelectionChanged()), - this.editor.onDidChangeConfiguration(e => e.contribInfo && applyIconStyle()) - ); + this.toDispose.add(attachListStyler(this.list, themeService, { + listInactiveFocusBackground: editorSuggestWidgetSelectedBackground, + listInactiveFocusOutline: activeContrastBorder + })); + this.toDispose.add(themeService.onThemeChange(t => this.onThemeChange(t))); + this.toDispose.add(editor.onDidLayoutChange(() => this.onEditorLayoutChange())); + this.toDispose.add(this.list.onMouseDown(e => this.onListMouseDown(e))); + this.toDispose.add(this.list.onSelectionChange(e => this.onListSelection(e))); + this.toDispose.add(this.list.onFocusChange(e => this.onListFocus(e))); + this.toDispose.add(this.editor.onDidChangeCursorSelection(() => this.onCursorSelectionChanged())); + this.toDispose.add(this.editor.onDidChangeConfiguration(e => e.contribInfo && applyIconStyle())); + this.suggestWidgetVisible = SuggestContext.Visible.bindTo(contextKeyService); this.suggestWidgetMultipleSuggestions = SuggestContext.MultipleSuggestions.bindTo(contextKeyService); @@ -631,7 +663,13 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate item.resolve(token)); + this.currentSuggestionDetails = createCancelablePromise(async token => { + const loading = disposableTimeout(() => this.showDetails(true), 250); + token.onCancellationRequested(() => loading.dispose()); + const result = await item.resolve(token); + loading.dispose(); + return result; + }); this.currentSuggestionDetails.then(() => { if (this.list.length < index) { @@ -645,7 +683,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate { - this.loadingTimeout = null; - this.setState(State.Loading); - }, delay); + this.loadingTimeout = disposableTimeout(() => this.setState(State.Loading), delay); } } @@ -736,10 +771,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate { assert.equal(event.auto, true); assert.equal(event.completionModel.items.length, 2); - assert.equal(disposeA, 1); - assert.equal(disposeB, 0); + + // clean up + model.clear(); + assert.equal(disposeA, 2); // provide got called two times! + assert.equal(disposeB, 1); }); + }); }); }); diff --git a/src/vs/editor/contrib/tokenization/tokenization.ts b/src/vs/editor/contrib/tokenization/tokenization.ts index 96e8d80e052..d24591b4eb9 100644 --- a/src/vs/editor/contrib/tokenization/tokenization.ts +++ b/src/vs/editor/contrib/tokenization/tokenization.ts @@ -7,6 +7,8 @@ import * as nls from 'vs/nls'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, ServicesAccessor, registerEditorAction } from 'vs/editor/browser/editorExtensions'; import { StopWatch } from 'vs/base/common/stopwatch'; +import { StandardTokenType } from 'vs/editor/common/modes'; +import { ITextModel } from 'vs/editor/common/model'; class ForceRetokenizeAction extends EditorAction { constructor() { @@ -23,11 +25,57 @@ class ForceRetokenizeAction extends EditorAction { return; } const model = editor.getModel(); - model.flushTokens(); + model.resetTokenization(); const sw = new StopWatch(true); model.forceTokenization(model.getLineCount()); sw.stop(); console.log(`tokenization took ${sw.elapsed()}`); + + if (!true) { + extractTokenTypes(model); + } + } +} + +function extractTokenTypes(model: ITextModel): void { + const eolLength = model.getEOL().length; + let result: number[] = []; + let resultLen: number = 0; + let lastTokenType: StandardTokenType = StandardTokenType.Other; + let lastEndOffset: number = 0; + let offset = 0; + for (let lineNumber = 1, lineCount = model.getLineCount(); lineNumber <= lineCount; lineNumber++) { + const lineTokens = model.getLineTokens(lineNumber); + + for (let i = 0, len = lineTokens.getCount(); i < len; i++) { + const tokenType = lineTokens.getStandardTokenType(i); + if (tokenType === StandardTokenType.Other) { + continue; + } + + const startOffset = offset + lineTokens.getStartOffset(i); + const endOffset = offset + lineTokens.getEndOffset(i); + const length = endOffset - startOffset; + + if (length === 0) { + continue; + } + + if (lastTokenType === tokenType && lastEndOffset === startOffset) { + result[resultLen - 2] += length; + lastEndOffset += length; + continue; + } + + result[resultLen++] = startOffset; // - lastEndOffset + result[resultLen++] = length; + result[resultLen++] = tokenType; + + lastTokenType = tokenType; + lastEndOffset = endOffset; + } + + offset += lineTokens.getLineContent().length + eolLength; } } diff --git a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts index 6b918096810..0820b22ce51 100644 --- a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts +++ b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts @@ -9,7 +9,7 @@ import { CancelablePromise, createCancelablePromise, first, timeout } from 'vs/b import { CancellationToken } from 'vs/base/common/cancellation'; import { onUnexpectedError, onUnexpectedExternalError } from 'vs/base/common/errors'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IActiveCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, IActionOptions, registerDefaultLanguageCommand, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { CursorChangeReason, ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; @@ -164,7 +164,7 @@ class WordHighlighter { private occurrencesHighlight: boolean; private readonly model: ITextModel; private _decorationIds: string[]; - private toUnhook: IDisposable[]; + private readonly toUnhook = new DisposableStore(); private workerRequestTokenId: number = 0; private workerRequest: IOccurenceAtPositionRequest | null; @@ -183,8 +183,7 @@ class WordHighlighter { this._ignorePositionChangeEvent = false; this.occurrencesHighlight = this.editor.getConfiguration().contribInfo.occurrencesHighlight; this.model = this.editor.getModel(); - this.toUnhook = []; - this.toUnhook.push(editor.onDidChangeCursorPosition((e: ICursorPositionChangedEvent) => { + this.toUnhook.add(editor.onDidChangeCursorPosition((e: ICursorPositionChangedEvent) => { if (this._ignorePositionChangeEvent) { // We are changing the position => ignore this event @@ -199,10 +198,10 @@ class WordHighlighter { this._onPositionChanged(e); })); - this.toUnhook.push(editor.onDidChangeModelContent((e) => { + this.toUnhook.add(editor.onDidChangeModelContent((e) => { this._stopAll(); })); - this.toUnhook.push(editor.onDidChangeConfiguration((e) => { + this.toUnhook.add(editor.onDidChangeConfiguration((e) => { let newValue = this.editor.getConfiguration().contribInfo.occurrencesHighlight; if (this.occurrencesHighlight !== newValue) { this.occurrencesHighlight = newValue; @@ -454,7 +453,7 @@ class WordHighlighter { public dispose(): void { this._stopAll(); - this.toUnhook = dispose(this.toUnhook); + this.toUnhook.dispose(); } } diff --git a/src/vs/editor/editor.worker.ts b/src/vs/editor/editor.worker.ts index 41140026a47..4586cafab31 100644 --- a/src/vs/editor/editor.worker.ts +++ b/src/vs/editor/editor.worker.ts @@ -4,7 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { SimpleWorkerServer } from 'vs/base/common/worker/simpleWorker'; -import { EditorSimpleWorkerImpl } from 'vs/editor/common/services/editorSimpleWorker'; +import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker'; +import { EditorWorkerHost } from 'vs/editor/common/services/editorWorkerServiceImpl'; let initialized = false; @@ -14,10 +15,9 @@ export function initialize(foreignModule: any) { } initialized = true; - const editorWorker = new EditorSimpleWorkerImpl(foreignModule); const simpleWorker = new SimpleWorkerServer((msg) => { (self).postMessage(msg); - }, editorWorker); + }, (host: EditorWorkerHost) => new EditorSimpleWorker(host, foreignModule)); self.onmessage = (e) => { simpleWorker.onmessage(e.data); diff --git a/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts b/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts index 73dfa8d3ac3..22e860f8eb0 100644 --- a/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts +++ b/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts @@ -27,7 +27,7 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { contrastBorder, editorWidgetBackground, widgetShadow } from 'vs/platform/theme/common/colorRegistry'; +import { contrastBorder, editorWidgetBackground, widgetShadow, editorWidgetForeground } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { AccessibilityHelpNLS } from 'vs/editor/common/standaloneStrings'; @@ -371,6 +371,11 @@ registerThemingParticipant((theme, collector) => { if (widgetBackground) { collector.addRule(`.monaco-editor .accessibilityHelpWidget { background-color: ${widgetBackground}; }`); } + const widgetForeground = theme.getColor(editorWidgetForeground); + if (widgetForeground) { + collector.addRule(`.monaco-editor .accessibilityHelpWidget { color: ${widgetForeground}; }`); + } + const widgetShadowColor = theme.getColor(widgetShadow); if (widgetShadowColor) { diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index a699ce708ec..56a0f094d6e 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -38,12 +38,13 @@ import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKe import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding'; import { ILabelService, ResourceLabelFormatter } from 'vs/platform/label/common/label'; import { INotification, INotificationHandle, INotificationService, IPromptChoice, IPromptOptions, NoOpNotification, IStatusMessageOptions } from 'vs/platform/notification/common/notification'; -import { IProgressRunner, ILocalProgressService } from 'vs/platform/progress/common/progress'; +import { IProgressRunner, IEditorProgressService } from 'vs/platform/progress/common/progress'; import { ITelemetryInfo, ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, WorkbenchState, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { ILayoutService, IDimension } from 'vs/platform/layout/browser/layoutService'; import { SimpleServicesNLS } from 'vs/editor/common/standaloneStrings'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; export class SimpleModel implements IResolvedTextEditorModel { @@ -136,7 +137,7 @@ export class SimpleEditorModelResolverService implements ITextModelService { } } -export class SimpleLocalProgressService implements ILocalProgressService { +export class SimpleEditorProgressService implements IEditorProgressService { _serviceBrand: any; private static NULL_PROGRESS_RUNNER: IProgressRunner = { @@ -148,7 +149,7 @@ export class SimpleLocalProgressService implements ILocalProgressService { show(infinite: true, delay?: number): IProgressRunner; show(total: number, delay?: number): IProgressRunner; show(): IProgressRunner { - return SimpleLocalProgressService.NULL_PROGRESS_RUNNER; + return SimpleEditorProgressService.NULL_PROGRESS_RUNNER; } showWhile(promise: Promise, delay?: number): Promise { @@ -390,6 +391,10 @@ export class StandaloneKeybindingService extends AbstractKeybindingService { public _dumpDebugInfo(): string { return ''; } + + public _dumpDebugInfoJSON(): string { + return ''; + } } function isConfigurationOverrides(thing: any): thing is IConfigurationOverrides { @@ -521,6 +526,10 @@ export class StandaloneTelemetryService implements ITelemetryService { return Promise.resolve(undefined); } + publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + return this.publicLog(eventName, data as any); + } + public getTelemetryInfo(): Promise { throw new Error(`Not available`); } diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index b09f41e79f1..8750db8f943 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -352,6 +352,7 @@ export function createMonacoEditorAPI(): typeof monaco.editor { ScrollbarVisibility: standaloneEnums.ScrollbarVisibility, WrappingIndent: standaloneEnums.WrappingIndent, OverviewRulerLane: standaloneEnums.OverviewRulerLane, + MinimapPosition: standaloneEnums.MinimapPosition, EndOfLinePreference: standaloneEnums.EndOfLinePreference, DefaultEndOfLine: standaloneEnums.DefaultEndOfLine, EndOfLineSequence: standaloneEnums.EndOfLineSequence, diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 7c0d721dd7c..cfe1ec119f6 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -290,14 +290,11 @@ export interface EncodedTokensProvider { } function isEncodedTokensProvider(provider: TokensProvider | EncodedTokensProvider): provider is EncodedTokensProvider { - return provider['tokenizeEncoded']; + return 'tokenizeEncoded' in provider; } function isThenable(obj: any): obj is Thenable { - if (typeof obj.then === 'function') { - return true; - } - return false; + return obj && typeof obj.then === 'function'; } /** diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index a9943538a82..894335350e3 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -13,7 +13,7 @@ import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; import { ITextResourceConfigurationService, ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; -import { SimpleBulkEditService, SimpleConfigurationService, SimpleDialogService, SimpleNotificationService, SimpleLocalProgressService, SimpleResourceConfigurationService, SimpleResourcePropertiesService, SimpleUriLabelService, SimpleWorkspaceContextService, StandaloneCommandService, StandaloneKeybindingService, StandaloneTelemetryService, SimpleLayoutService } from 'vs/editor/standalone/browser/simpleServices'; +import { SimpleBulkEditService, SimpleConfigurationService, SimpleDialogService, SimpleNotificationService, SimpleEditorProgressService, SimpleResourceConfigurationService, SimpleResourcePropertiesService, SimpleUriLabelService, SimpleWorkspaceContextService, StandaloneCommandService, StandaloneKeybindingService, StandaloneTelemetryService, SimpleLayoutService } from 'vs/editor/standalone/browser/simpleServices'; import { StandaloneCodeEditorServiceImpl } from 'vs/editor/standalone/browser/standaloneCodeServiceImpl'; import { StandaloneThemeServiceImpl } from 'vs/editor/standalone/browser/standaloneThemeServiceImpl'; import { IStandaloneThemeService } from 'vs/editor/standalone/common/standaloneThemeService'; @@ -36,7 +36,7 @@ import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { MarkerService } from 'vs/platform/markers/common/markerService'; import { IMarkerService } from 'vs/platform/markers/common/markers'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { ILocalProgressService } from 'vs/platform/progress/common/progress'; +import { IEditorProgressService } from 'vs/platform/progress/common/progress'; import { IStorageService, InMemoryStorageService } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; @@ -44,11 +44,10 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { MenuService } from 'vs/platform/actions/common/menuService'; import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService'; import { MarkerDecorationsService } from 'vs/editor/common/services/markerDecorationsServiceImpl'; -import { ISuggestMemoryService, SuggestMemoryService } from 'vs/editor/contrib/suggest/suggestMemory'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { BrowserAccessibilityService } from 'vs/platform/accessibility/common/accessibilityService'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; -import { ICodeLensCache, CodeLensCache } from 'vs/editor/contrib/codelens/codeLensCache'; +import { getSingletonServiceDescriptors } from 'vs/platform/instantiation/common/extensions'; export interface IEditorOverrideServices { [index: string]: any; @@ -100,6 +99,11 @@ export module StaticServices { // Create a fresh service collection let result = new ServiceCollection(); + // make sure to add all services that use `registerSingleton` + for (const [id, descriptor] of getSingletonServiceDescriptors()) { + result.set(id, descriptor); + } + // Initialize the service collection with the overrides for (let serviceId in overrides) { if (overrides.hasOwnProperty(serviceId)) { @@ -150,17 +154,13 @@ export module StaticServices { export const codeEditorService = define(ICodeEditorService, (o) => new StandaloneCodeEditorServiceImpl(standaloneThemeService.get(o))); - export const localProgressService = define(ILocalProgressService, () => new SimpleLocalProgressService()); + export const editorProgressService = define(IEditorProgressService, () => new SimpleEditorProgressService()); export const storageService = define(IStorageService, () => new InMemoryStorageService()); export const logService = define(ILogService, () => new NullLogService()); export const editorWorkerService = define(IEditorWorkerService, (o) => new EditorWorkerServiceImpl(modelService.get(o), resourceConfigurationService.get(o), logService.get(o))); - - export const suggestMemoryService = define(ISuggestMemoryService, (o) => new SuggestMemoryService(storageService.get(o), configurationService.get(o))); - - export const codeLensCacheService = define(ICodeLensCache, (o) => new CodeLensCache(storageService.get(o))); } export class DynamicStandaloneServices extends Disposable { diff --git a/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts b/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts index 5e9074577a3..3f04994e55c 100644 --- a/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts +++ b/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts @@ -27,7 +27,7 @@ class StandaloneTheme implements IStandaloneTheme { public readonly themeName: string; private readonly themeData: IStandaloneThemeData; - private colors: { [colorId: string]: Color } | null; + private colors: Map | null; private readonly defaultColors: { [colorId: string]: Color | undefined; }; private _tokenTheme: TokenTheme | null; @@ -57,19 +57,18 @@ class StandaloneTheme implements IStandaloneTheme { } } - private getColors(): { [colorId: string]: Color } { + private getColors(): Map { if (!this.colors) { - let colors: { [colorId: string]: Color } = Object.create(null); + const colors = new Map(); for (let id in this.themeData.colors) { - colors[id] = Color.fromHex(this.themeData.colors[id]); + colors.set(id, Color.fromHex(this.themeData.colors[id])); } if (this.themeData.inherit) { let baseData = getBuiltinRules(this.themeData.base); for (let id in baseData.colors) { - if (!colors[id]) { - colors[id] = Color.fromHex(baseData.colors[id]); + if (!colors.has(id)) { + colors.set(id, Color.fromHex(baseData.colors[id])); } - } } this.colors = colors; @@ -78,7 +77,7 @@ class StandaloneTheme implements IStandaloneTheme { } public getColor(colorId: ColorIdentifier, useDefault?: boolean): Color | undefined { - const color = this.getColors()[colorId]; + const color = this.getColors().get(colorId); if (color) { return color; } diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index d34c9ff1b1f..aee33dba412 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -2052,7 +2052,7 @@ suite('Editor Controller - Regression tests', () => { getInitialState: () => NULL_STATE, tokenize: undefined!, tokenize2: (line: string, state: IState): TokenizationResult2 => { - return new TokenizationResult2(null!, state); + return new TokenizationResult2(new Uint32Array(0), state); } }; diff --git a/src/vs/editor/test/browser/testCommand.ts b/src/vs/editor/test/browser/testCommand.ts index f0e12dadc69..5b96fde1e00 100644 --- a/src/vs/editor/test/browser/testCommand.ts +++ b/src/vs/editor/test/browser/testCommand.ts @@ -18,7 +18,8 @@ export function testCommand( selection: Selection, commandFactory: (selection: Selection) => editorCommon.ICommand, expectedLines: string[], - expectedSelection: Selection + expectedSelection: Selection, + forceTokenization?: boolean ): void { let model = TextModel.createFromString(lines.join('\n'), undefined, languageIdentifier); withTestCodeEditor('', { model: model }, (_editor, cursor) => { @@ -26,6 +27,10 @@ export function testCommand( return; } + if (forceTokenization) { + model.forceTokenization(model.getLineCount()); + } + cursor.setSelections('tests', [selection]); cursor.trigger('tests', editorCommon.Handler.ExecuteCommand, commandFactory(cursor.getSelection())); diff --git a/src/vs/editor/test/common/model/model.line.test.ts b/src/vs/editor/test/common/model/model.line.test.ts index 19379cd5c2f..be29d6a9657 100644 --- a/src/vs/editor/test/common/model/model.line.test.ts +++ b/src/vs/editor/test/common/model/model.line.test.ts @@ -110,7 +110,9 @@ suite('ModelLinesTokens', () => { for (let lineIndex = 0; lineIndex < initial.length; lineIndex++) { const lineTokens = initial[lineIndex].tokens; const lineTextLength = model.getLineMaxColumn(lineIndex + 1) - 1; - model._tokens._setTokens(0, lineIndex, lineTextLength, TestToken.toTokens(lineTokens)); + const tokens = TestToken.toTokens(lineTokens); + LineTokens.convertToEndOffset(tokens, lineTextLength); + model.setLineTokens(lineIndex + 1, tokens); } model.applyEdits(edits.map((ed) => ({ @@ -441,14 +443,16 @@ suite('ModelLinesTokens', () => { test('insertion on empty line', () => { const model = new TextModel('some text', TextModel.DEFAULT_CREATION_OPTIONS, new LanguageIdentifier('test', 0)); - model._tokens._setTokens(0, 0, model.getLineMaxColumn(1) - 1, TestToken.toTokens([new TestToken(0, 1)])); + const tokens = TestToken.toTokens([new TestToken(0, 1)]); + LineTokens.convertToEndOffset(tokens, model.getLineMaxColumn(1) - 1); + model.setLineTokens(1, tokens); model.applyEdits([{ range: new Range(1, 1, 1, 10), text: '' }]); - model._tokens._setTokens(0, 0, model.getLineMaxColumn(1) - 1, new Uint32Array(0)); + model.setLineTokens(1, new Uint32Array(0)); model.applyEdits([{ range: new Range(1, 1, 1, 1), @@ -660,7 +664,7 @@ suite('ModelLinesTokens', () => { test('updates tokens on insertion 10', () => { testLineEditTokens( '', - null!, + [], [{ startColumn: 1, endColumn: 1, diff --git a/src/vs/editor/test/common/model/model.modes.test.ts b/src/vs/editor/test/common/model/model.modes.test.ts index 3f2a4044f3e..559a6f89f07 100644 --- a/src/vs/editor/test/common/model/model.modes.test.ts +++ b/src/vs/editor/test/common/model/model.modes.test.ts @@ -29,7 +29,7 @@ suite('Editor Model - Model Modes 1', () => { tokenize: undefined!, tokenize2: (line: string, state: modes.IState): TokenizationResult2 => { calledFor.push(line.charAt(0)); - return new TokenizationResult2(null!, state); + return new TokenizationResult2(new Uint32Array(0), state); } }; @@ -170,37 +170,23 @@ suite('Editor Model - Model Modes 2', () => { } } + let calledFor: string[] = []; + + function checkAndClear(arr: string[]): void { + assert.deepEqual(calledFor, arr); + calledFor = []; + } + const tokenizationSupport: modes.ITokenizationSupport = { getInitialState: () => new ModelState2(''), tokenize: undefined!, tokenize2: (line: string, state: modes.IState): TokenizationResult2 => { + calledFor.push(line); (state).prevLineContent = line; - return new TokenizationResult2(null!, state); + return new TokenizationResult2(new Uint32Array(0), state); } }; - function invalidEqual(model: TextModel, expected: number[]): void { - let actual: number[] = []; - for (let i = 0, len = model.getLineCount(); i < len; i++) { - if (model._tokens._isInvalid(i)) { - actual.push(i); - } - } - assert.deepEqual(actual, expected); - } - - function stateEqual(state: modes.IState, content: string): void { - assert.equal((state).prevLineContent, content); - } - - function statesEqual(model: TextModel, states: string[]): void { - let i, len = states.length - 1; - for (i = 0; i < len; i++) { - stateEqual(model._tokens._getState(i)!, states[i]); - } - stateEqual((model)._tokens._lastState, states[len]); - } - let thisModel: TextModel; let languageRegistration: IDisposable; @@ -223,64 +209,54 @@ suite('Editor Model - Model Modes 2', () => { test('getTokensForInvalidLines one text insert', () => { thisModel.forceTokenization(5); - statesEqual(thisModel, ['', 'Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([EditOperation.insert(new Position(1, 6), '-')]); - invalidEqual(thisModel, [0]); - statesEqual(thisModel, ['', 'Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.forceTokenization(5); - statesEqual(thisModel, ['', 'Line1-', 'Line2', 'Line3', 'Line4', 'Line5']); + checkAndClear(['Line1-', 'Line2']); }); test('getTokensForInvalidLines two text insert', () => { thisModel.forceTokenization(5); - statesEqual(thisModel, ['', 'Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([ EditOperation.insert(new Position(1, 6), '-'), EditOperation.insert(new Position(3, 6), '-') ]); - invalidEqual(thisModel, [0, 2]); thisModel.forceTokenization(5); - statesEqual(thisModel, ['', 'Line1-', 'Line2', 'Line3-', 'Line4', 'Line5']); + checkAndClear(['Line1-', 'Line2', 'Line3-', 'Line4']); }); test('getTokensForInvalidLines one multi-line text insert, one small text insert', () => { thisModel.forceTokenization(5); - statesEqual(thisModel, ['', 'Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([EditOperation.insert(new Position(1, 6), '\nNew line\nAnother new line')]); - invalidEqual(thisModel, [0, 1, 2]); thisModel.applyEdits([EditOperation.insert(new Position(5, 6), '-')]); - invalidEqual(thisModel, [0, 1, 2, 4]); thisModel.forceTokenization(7); - statesEqual(thisModel, ['', 'Line1', 'New line', 'Another new line', 'Line2', 'Line3-', 'Line4', 'Line5']); + checkAndClear(['Line1', 'New line', 'Another new line', 'Line2', 'Line3-', 'Line4']); }); test('getTokensForInvalidLines one delete text', () => { thisModel.forceTokenization(5); - statesEqual(thisModel, ['', 'Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 1, 5))]); - invalidEqual(thisModel, [0]); thisModel.forceTokenization(5); - statesEqual(thisModel, ['', '1', 'Line2', 'Line3', 'Line4', 'Line5']); + checkAndClear(['1', 'Line2']); }); test('getTokensForInvalidLines one line delete text', () => { thisModel.forceTokenization(5); - statesEqual(thisModel, ['', 'Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 2, 1))]); - invalidEqual(thisModel, [0]); - statesEqual(thisModel, ['', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.forceTokenization(4); - statesEqual(thisModel, ['', 'Line2', 'Line3', 'Line4', 'Line5']); + checkAndClear(['Line2']); }); test('getTokensForInvalidLines multiple lines delete text', () => { thisModel.forceTokenization(5); - statesEqual(thisModel, ['', 'Line1', 'Line2', 'Line3', 'Line4', 'Line5']); + checkAndClear(['Line1', 'Line2', 'Line3', 'Line4', 'Line5']); thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 3, 3))]); - invalidEqual(thisModel, [0]); - statesEqual(thisModel, ['', 'Line3', 'Line4', 'Line5']); thisModel.forceTokenization(3); - statesEqual(thisModel, ['', 'ne3', 'Line4', 'Line5']); + checkAndClear(['ne3', 'Line4']); }); }); diff --git a/src/vs/editor/test/common/services/editorSimpleWorker.test.ts b/src/vs/editor/test/common/services/editorSimpleWorker.test.ts index 43726f59e04..8ea09048b02 100644 --- a/src/vs/editor/test/common/services/editorSimpleWorker.test.ts +++ b/src/vs/editor/test/common/services/editorSimpleWorker.test.ts @@ -5,11 +5,12 @@ import * as assert from 'assert'; import { Range } from 'vs/editor/common/core/range'; -import { EditorSimpleWorkerImpl, ICommonModel } from 'vs/editor/common/services/editorSimpleWorker'; +import { EditorSimpleWorker, ICommonModel } from 'vs/editor/common/services/editorSimpleWorker'; +import { EditorWorkerHost } from 'vs/editor/common/services/editorWorkerServiceImpl'; suite('EditorSimpleWorker', () => { - class WorkerWithModels extends EditorSimpleWorkerImpl { + class WorkerWithModels extends EditorSimpleWorker { getModel(uri: string) { return this._getModel(uri); @@ -31,7 +32,7 @@ suite('EditorSimpleWorker', () => { let model: ICommonModel; setup(() => { - worker = new WorkerWithModels(null); + worker = new WorkerWithModels(null!, null); model = worker.addModel([ 'This is line one', //16 'and this is line number two', //27 diff --git a/src/vs/loader.js b/src/vs/loader.js index 40b6d2aa327..e3bebe82544 100644 --- a/src/vs/loader.js +++ b/src/vs/loader.js @@ -23,7 +23,7 @@ var _commonjsGlobal = typeof global === 'object' ? global : {}; var AMDLoader; (function (AMDLoader) { AMDLoader.global = _amdLoaderGlobal; - var Environment = (function () { + var Environment = /** @class */ (function () { function Environment() { this._detected = false; this._isWindows = false; @@ -94,7 +94,7 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - var LoaderEvent = (function () { + var LoaderEvent = /** @class */ (function () { function LoaderEvent(type, detail, timestamp) { this.type = type; this.detail = detail; @@ -103,7 +103,7 @@ var AMDLoader; return LoaderEvent; }()); AMDLoader.LoaderEvent = LoaderEvent; - var LoaderEventRecorder = (function () { + var LoaderEventRecorder = /** @class */ (function () { function LoaderEventRecorder(loaderAvailableTimestamp) { this._events = [new LoaderEvent(1 /* LoaderAvailable */, '', loaderAvailableTimestamp)]; } @@ -116,7 +116,7 @@ var AMDLoader; return LoaderEventRecorder; }()); AMDLoader.LoaderEventRecorder = LoaderEventRecorder; - var NullLoaderEventRecorder = (function () { + var NullLoaderEventRecorder = /** @class */ (function () { function NullLoaderEventRecorder() { } NullLoaderEventRecorder.prototype.record = function (type, detail) { @@ -125,9 +125,9 @@ var AMDLoader; NullLoaderEventRecorder.prototype.getEvents = function () { return []; }; + NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); return NullLoaderEventRecorder; }()); - NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); AMDLoader.NullLoaderEventRecorder = NullLoaderEventRecorder; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- @@ -136,7 +136,7 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - var Utilities = (function () { + var Utilities = /** @class */ (function () { function Utilities() { } /** @@ -222,11 +222,11 @@ var AMDLoader; } return (this.HAS_PERFORMANCE_NOW ? AMDLoader.global.performance.now() : Date.now()); }; + Utilities.NEXT_ANONYMOUS_ID = 1; + Utilities.PERFORMANCE_NOW_PROBED = false; + Utilities.HAS_PERFORMANCE_NOW = false; return Utilities; }()); - Utilities.NEXT_ANONYMOUS_ID = 1; - Utilities.PERFORMANCE_NOW_PROBED = false; - Utilities.HAS_PERFORMANCE_NOW = false; AMDLoader.Utilities = Utilities; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- @@ -236,7 +236,7 @@ var AMDLoader; var AMDLoader; (function (AMDLoader) { ; - var ConfigurationOptionsUtil = (function () { + var ConfigurationOptionsUtil = /** @class */ (function () { function ConfigurationOptionsUtil() { } /** @@ -279,13 +279,16 @@ var AMDLoader; if (typeof options.catchError === 'undefined') { options.catchError = false; } + if (typeof options.recordStats === 'undefined') { + options.recordStats = false; + } if (typeof options.urlArgs !== 'string') { options.urlArgs = ''; } if (typeof options.onError !== 'function') { options.onError = defaultOnError; } - if (typeof options.ignoreDuplicateModules !== 'object' || !Array.isArray(options.ignoreDuplicateModules)) { + if (!Array.isArray(options.ignoreDuplicateModules)) { options.ignoreDuplicateModules = []; } if (options.baseUrl.length > 0) { @@ -337,7 +340,7 @@ var AMDLoader; return ConfigurationOptionsUtil; }()); AMDLoader.ConfigurationOptionsUtil = ConfigurationOptionsUtil; - var Configuration = (function () { + var Configuration = /** @class */ (function () { function Configuration(env, options) { this._env = env; this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(options); @@ -548,7 +551,7 @@ var AMDLoader; /** * Load `scriptSrc` only once (avoid multiple + + + + \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js index 2afb9ea3125..1dc234fe681 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -3,41 +3,54 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // @ts-check -'use strict'; /** - * Use polling to track focus of main webview and iframes within the webview - * - * @param {Object} handlers - * @param {() => void} handlers.onFocus - * @param {() => void} handlers.onBlur + * @typedef {{ + * postMessage: (channel: string, data?: any) => void, + * onMessage: (channel: string, handler: any) => void, + * focusIframeOnCreate?: boolean, + * ready?: Promise, + * onIframeLoaded?: (iframe: HTMLIFrameElement) => void, + * fakeLoad: boolean + * }} WebviewHost */ -const trackFocus = ({ onFocus, onBlur }) => { - const interval = 50; - let isFocused = document.hasFocus(); - setInterval(() => { - const isCurrentlyFocused = document.hasFocus(); - if (isCurrentlyFocused === isFocused) { - return; - } - isFocused = isCurrentlyFocused; - if (isCurrentlyFocused) { - onFocus(); - } else { - onBlur(); - } - }, interval); -}; -const getActiveFrame = () => { - return /** @type {HTMLIFrameElement} */ (document.getElementById('active-frame')); -}; +(function () { + 'use strict'; -const getPendingFrame = () => { - return /** @type {HTMLIFrameElement} */ (document.getElementById('pending-frame')); -}; + /** + * Use polling to track focus of main webview and iframes within the webview + * + * @param {Object} handlers + * @param {() => void} handlers.onFocus + * @param {() => void} handlers.onBlur + */ + const trackFocus = ({ onFocus, onBlur }) => { + const interval = 50; + let isFocused = document.hasFocus(); + setInterval(() => { + const isCurrentlyFocused = document.hasFocus(); + if (isCurrentlyFocused === isFocused) { + return; + } + isFocused = isCurrentlyFocused; + if (isCurrentlyFocused) { + onFocus(); + } else { + onBlur(); + } + }, interval); + }; -const defaultCssRules = ` + const getActiveFrame = () => { + return /** @type {HTMLIFrameElement} */ (document.getElementById('active-frame')); + }; + + const getPendingFrame = () => { + return /** @type {HTMLIFrameElement} */ (document.getElementById('pending-frame')); + }; + + const defaultCssRules = ` body { background-color: var(--vscode-editor-background); color: var(--vscode-editor-foreground); @@ -93,151 +106,156 @@ const defaultCssRules = ` background-color: var(--vscode-scrollbarSlider-activeBackground); }`; -/** - * @typedef {{ postMessage: (channel: string, data?: any) => void, onMessage: (channel: string, handler: any) => void }} HostCommunications - */ - -/** - * @param {HostCommunications} host - */ -module.exports = function createWebviewManager(host) { - // state - let firstLoad = true; - let loadTimeout; - let pendingMessages = []; - let isInDevelopmentMode = false; - - const initData = { - initialScrollProgress: undefined - }; - /** - * @param {HTMLDocument?} document - * @param {HTMLElement?} body + * @param {*} [state] + * @return {string} */ - const applyStyles = (document, body) => { - if (!document) { - return; - } + function getVsCodeApiScript(state) { + return ` + const acquireVsCodeApi = (function() { + const originalPostMessage = window.parent.postMessage.bind(window.parent); + const targetOrigin = '*'; + let acquired = false; - if (body) { - body.classList.remove('vscode-light', 'vscode-dark', 'vscode-high-contrast'); - body.classList.add(initData.activeTheme); - } + let state = ${state ? `JSON.parse(${JSON.stringify(state)})` : undefined}; - if (initData.styles) { - for (const variable of Object.keys(initData.styles)) { - document.documentElement.style.setProperty(`--${variable}`, initData.styles[variable]); - } - } - }; - - /** - * @param {MouseEvent} event - */ - const handleInnerClick = (event) => { - if (!event || !event.view || !event.view.document) { - return; - } - - let baseElement = event.view.document.getElementsByTagName('base')[0]; - /** @type {any} */ - let node = event.target; - while (node) { - if (node.tagName && node.tagName.toLowerCase() === 'a' && node.href) { - if (node.getAttribute('href') === '#') { - event.view.scrollTo(0, 0); - } else if (node.hash && (node.getAttribute('href') === node.hash || (baseElement && node.href.indexOf(baseElement.href) >= 0))) { - let scrollTarget = event.view.document.getElementById(node.hash.substr(1, node.hash.length - 1)); - if (scrollTarget) { - scrollTarget.scrollIntoView(); + return () => { + if (acquired) { + throw new Error('An instance of the VS Code API has already been acquired'); } - } else { - host.postMessage('did-click-link', node.href.baseVal || node.href); - } - event.preventDefault(); - break; - } - node = node.parentNode; - } - }; + acquired = true; + return Object.freeze({ + postMessage: function(msg) { + return originalPostMessage({ command: 'onmessage', data: msg }, targetOrigin); + }, + setState: function(newState) { + state = newState; + originalPostMessage({ command: 'do-update-state', data: JSON.stringify(newState) }, targetOrigin); + return newState; + }, + getState: function() { + return state; + } + }); + }; + })(); + delete window.parent; + delete window.top; + delete window.frameElement; + `; + } /** - * @param {KeyboardEvent} e + * @param {WebviewHost} host */ - const handleInnerKeydown = (e) => { - host.postMessage('did-keydown', { - key: e.key, - keyCode: e.keyCode, - code: e.code, - shiftKey: e.shiftKey, - altKey: e.altKey, - ctrlKey: e.ctrlKey, - metaKey: e.metaKey, - repeat: e.repeat - }); - }; + function createWebviewManager(host) { + // state + let firstLoad = true; + let loadTimeout; + let pendingMessages = []; - const onMessage = (message) => { - host.postMessage(message.data.command, message.data.data); - }; + const initData = { + initialScrollProgress: undefined + }; - let isHandlingScroll = false; - const handleInnerScroll = (event) => { - if (!event.target || !event.target.body) { - return; - } - if (isHandlingScroll) { - return; - } - const progress = event.currentTarget.scrollY / event.target.body.clientHeight; - if (isNaN(progress)) { - return; - } - - isHandlingScroll = true; - window.requestAnimationFrame(() => { - try { - host.postMessage('did-scroll', progress); - } catch (e) { - // noop - } - isHandlingScroll = false; - }); - }; - - document.addEventListener('DOMContentLoaded', () => { - if (!document.body) { - return; - } - - host.onMessage('styles', (_event, variables, activeTheme) => { - initData.styles = variables; - initData.activeTheme = activeTheme; - - const target = getActiveFrame(); - if (!target) { + /** + * @param {HTMLDocument?} document + * @param {HTMLElement?} body + */ + const applyStyles = (document, body) => { + if (!document) { return; } - if (target.contentDocument) { - applyStyles(target.contentDocument, target.contentDocument.body); + if (body) { + body.classList.remove('vscode-light', 'vscode-dark', 'vscode-high-contrast'); + body.classList.add(initData.activeTheme); } - }); - // propagate focus - host.onMessage('focus', () => { - const target = getActiveFrame(); - if (target) { - target.contentWindow.focus(); + if (initData.styles) { + for (const variable of Object.keys(initData.styles)) { + document.documentElement.style.setProperty(`--${variable}`, initData.styles[variable]); + } } - }); + }; - // update iframe-contents - host.onMessage('content', (_event, data) => { + /** + * @param {MouseEvent} event + */ + const handleInnerClick = (event) => { + if (!event || !event.view || !event.view.document) { + return; + } + + let baseElement = event.view.document.getElementsByTagName('base')[0]; + /** @type {any} */ + let node = event.target; + while (node) { + if (node.tagName && node.tagName.toLowerCase() === 'a' && node.href) { + if (node.getAttribute('href') === '#') { + event.view.scrollTo(0, 0); + } else if (node.hash && (node.getAttribute('href') === node.hash || (baseElement && node.href.indexOf(baseElement.href) >= 0))) { + let scrollTarget = event.view.document.getElementById(node.hash.substr(1, node.hash.length - 1)); + if (scrollTarget) { + scrollTarget.scrollIntoView(); + } + } else { + host.postMessage('did-click-link', node.href.baseVal || node.href); + } + event.preventDefault(); + break; + } + node = node.parentNode; + } + }; + + /** + * @param {KeyboardEvent} e + */ + const handleInnerKeydown = (e) => { + host.postMessage('did-keydown', { + key: e.key, + keyCode: e.keyCode, + code: e.code, + shiftKey: e.shiftKey, + altKey: e.altKey, + ctrlKey: e.ctrlKey, + metaKey: e.metaKey, + repeat: e.repeat + }); + }; + + let isHandlingScroll = false; + const handleInnerScroll = (event) => { + if (!event.target || !event.target.body) { + return; + } + if (isHandlingScroll) { + return; + } + + const progress = event.currentTarget.scrollY / event.target.body.clientHeight; + if (isNaN(progress)) { + return; + } + + isHandlingScroll = true; + window.requestAnimationFrame(() => { + try { + host.postMessage('did-scroll', progress); + } catch (e) { + // noop + } + isHandlingScroll = false; + }); + }; + + /** + * @return {string} + */ + function toContentHtml(data) { const options = data.options; - const text = data.contents; const newDocument = new DOMParser().parseFromString(text, 'text/html'); @@ -250,38 +268,7 @@ module.exports = function createWebviewManager(host) { // apply default script if (options.allowScripts) { const defaultScript = newDocument.createElement('script'); - defaultScript.textContent = ` - const acquireVsCodeApi = (function() { - const originalPostMessage = window.parent.postMessage.bind(window.parent); - let acquired = false; - - let state = ${data.state ? `JSON.parse(${JSON.stringify(data.state)})` : undefined}; - - return () => { - if (acquired) { - throw new Error('An instance of the VS Code API has already been acquired'); - } - acquired = true; - return Object.freeze({ - postMessage: function(msg) { - return originalPostMessage({ command: 'onmessage', data: msg }, '*'); - }, - setState: function(newState) { - state = newState; - originalPostMessage({ command: 'do-update-state', data: JSON.stringify(newState) }, '*'); - return newState; - }, - getState: function() { - return state; - } - }); - }; - })(); - delete window.parent; - delete window.top; - delete window.frameElement; - `; - + defaultScript.textContent = getVsCodeApiScript(data.state); newDocument.head.prepend(defaultScript); } @@ -293,154 +280,219 @@ module.exports = function createWebviewManager(host) { applyStyles(newDocument, newDocument.body); - const frame = getActiveFrame(); - const wasFirstLoad = firstLoad; - // keep current scrollY around and use later - let setInitialScrollPosition; - if (firstLoad) { - firstLoad = false; - setInitialScrollPosition = (body, window) => { - if (!isNaN(initData.initialScrollProgress)) { - if (window.scrollY === 0) { - window.scroll(0, body.clientHeight * initData.initialScrollProgress); - } - } - }; - } else { - const scrollY = frame && frame.contentDocument && frame.contentDocument.body ? frame.contentWindow.scrollY : 0; - setInitialScrollPosition = (body, window) => { - if (window.scrollY === 0) { - window.scroll(0, scrollY); - } - }; - } - - // Clean up old pending frames and set current one as new one - const previousPendingFrame = getPendingFrame(); - if (previousPendingFrame) { - previousPendingFrame.setAttribute('id', ''); - document.body.removeChild(previousPendingFrame); - } - if (!wasFirstLoad) { - pendingMessages = []; - } - - const newFrame = document.createElement('iframe'); - newFrame.setAttribute('id', 'pending-frame'); - newFrame.setAttribute('frameborder', '0'); - newFrame.setAttribute('sandbox', options.allowScripts ? 'allow-scripts allow-forms allow-same-origin' : 'allow-same-origin'); - newFrame.style.cssText = 'display: block; margin: 0; overflow: hidden; position: absolute; width: 100%; height: 100%; visibility: hidden'; - document.body.appendChild(newFrame); - - // write new content onto iframe - newFrame.contentDocument.open('text/html', 'replace'); - - newFrame.contentWindow.addEventListener('keydown', handleInnerKeydown); - - newFrame.contentWindow.addEventListener('DOMContentLoaded', e => { - const contentDocument = e.target ? (/** @type {HTMLDocument} */ (e.target)) : undefined; - if (contentDocument) { - applyStyles(contentDocument, contentDocument.body); - } - }); - - newFrame.contentWindow.onbeforeunload = () => { - if (isInDevelopmentMode) { // Allow reloads while developing a webview - host.postMessage('do-reload'); - return false; - } - - // Block navigation when not in development mode - console.log('prevented webview navigation'); - return false; - }; - - const onLoad = (contentDocument, contentWindow) => { - if (contentDocument && contentDocument.body) { - // Workaround for https://github.com/Microsoft/vscode/issues/12865 - // check new scrollY and reset if neccessary - setInitialScrollPosition(contentDocument.body, contentWindow); - } - - const newFrame = getPendingFrame(); - if (newFrame && newFrame.contentDocument && newFrame.contentDocument === contentDocument) { - const oldActiveFrame = getActiveFrame(); - if (oldActiveFrame) { - document.body.removeChild(oldActiveFrame); - } - // Styles may have changed since we created the element. Make sure we re-style - applyStyles(newFrame.contentDocument, newFrame.contentDocument.body); - newFrame.setAttribute('id', 'active-frame'); - newFrame.style.visibility = 'visible'; - newFrame.contentWindow.focus(); - - contentWindow.addEventListener('scroll', handleInnerScroll); - - pendingMessages.forEach((data) => { - contentWindow.postMessage(data, '*'); - }); - pendingMessages = []; - } - }; - - clearTimeout(loadTimeout); - loadTimeout = undefined; - loadTimeout = setTimeout(() => { - clearTimeout(loadTimeout); - loadTimeout = undefined; - onLoad(newFrame.contentDocument, newFrame.contentWindow); - }, 200); - - newFrame.contentWindow.addEventListener('load', function (e) { - if (loadTimeout) { - clearTimeout(loadTimeout); - loadTimeout = undefined; - onLoad(e.target, this); - } - }); - - // Bubble out link clicks - newFrame.contentWindow.addEventListener('click', handleInnerClick); - // set DOCTYPE for newDocument explicitly as DOMParser.parseFromString strips it off // and DOCTYPE is needed in the iframe to ensure that the user agent stylesheet is correctly overridden - newFrame.contentDocument.write(''); - newFrame.contentDocument.write(newDocument.documentElement.innerHTML); - newFrame.contentDocument.close(); + return '\n' + newDocument.documentElement.outerHTML; + } - host.postMessage('did-set-content', undefined); - }); + document.addEventListener('DOMContentLoaded', () => { + const idMatch = document.location.search.match(/\bid=([\w-]+)/); + const ID = idMatch ? idMatch[1] : undefined; + if (!document.body) { + return; + } + + host.onMessage('styles', (_event, data) => { + initData.styles = data.styles; + initData.activeTheme = data.activeTheme; - // Forward message to the embedded iframe - host.onMessage('message', (_event, data) => { - const pending = getPendingFrame(); - if (!pending) { const target = getActiveFrame(); - if (target) { - target.contentWindow.postMessage(data, '*'); + if (!target) { return; } - } - pendingMessages.push(data); + + if (target.contentDocument) { + applyStyles(target.contentDocument, target.contentDocument.body); + } + }); + + // propagate focus + host.onMessage('focus', () => { + const target = getActiveFrame(); + if (target) { + target.contentWindow.focus(); + } + }); + + // update iframe-contents + let updateId = 0; + host.onMessage('content', async (_event, data) => { + const currentUpdateId = ++updateId; + await host.ready; + if (currentUpdateId !== updateId) { + return; + } + + const options = data.options; + const newDocument = toContentHtml(data); + + const frame = getActiveFrame(); + const wasFirstLoad = firstLoad; + // keep current scrollY around and use later + let setInitialScrollPosition; + if (firstLoad) { + firstLoad = false; + setInitialScrollPosition = (body, window) => { + if (!isNaN(initData.initialScrollProgress)) { + if (window.scrollY === 0) { + window.scroll(0, body.clientHeight * initData.initialScrollProgress); + } + } + }; + } else { + const scrollY = frame && frame.contentDocument && frame.contentDocument.body ? frame.contentWindow.scrollY : 0; + setInitialScrollPosition = (body, window) => { + if (window.scrollY === 0) { + window.scroll(0, scrollY); + } + }; + } + + // Clean up old pending frames and set current one as new one + const previousPendingFrame = getPendingFrame(); + if (previousPendingFrame) { + previousPendingFrame.setAttribute('id', ''); + document.body.removeChild(previousPendingFrame); + } + if (!wasFirstLoad) { + pendingMessages = []; + } + + const newFrame = document.createElement('iframe'); + newFrame.setAttribute('id', 'pending-frame'); + newFrame.setAttribute('frameborder', '0'); + newFrame.setAttribute('sandbox', options.allowScripts ? 'allow-scripts allow-forms allow-same-origin' : 'allow-same-origin'); + if (host.fakeLoad) { + // We should just be able to use srcdoc, but I wasn't + // seeing the service worker applying properly. + // Fake load an empty on the correct origin and then write real html + // into it to get around this. + newFrame.src = `/fake.html?id=${ID}`; + } + newFrame.style.cssText = 'display: block; margin: 0; overflow: hidden; position: absolute; width: 100%; height: 100%; visibility: hidden'; + document.body.appendChild(newFrame); + + if (!host.fakeLoad) { + // write new content onto iframe + newFrame.contentDocument.open(); + } + + newFrame.contentWindow.addEventListener('keydown', handleInnerKeydown); + + newFrame.contentWindow.addEventListener('DOMContentLoaded', e => { + if (host.fakeLoad) { + newFrame.contentDocument.open(); + newFrame.contentDocument.write(newDocument); + newFrame.contentDocument.close(); + hookupOnLoadHandlers(newFrame); + } + const contentDocument = e.target ? (/** @type {HTMLDocument} */ (e.target)) : undefined; + if (contentDocument) { + applyStyles(contentDocument, contentDocument.body); + } + }); + + const onLoad = (contentDocument, contentWindow) => { + if (contentDocument && contentDocument.body) { + // Workaround for https://github.com/Microsoft/vscode/issues/12865 + // check new scrollY and reset if neccessary + setInitialScrollPosition(contentDocument.body, contentWindow); + } + + const newFrame = getPendingFrame(); + if (newFrame && newFrame.contentDocument && newFrame.contentDocument === contentDocument) { + const oldActiveFrame = getActiveFrame(); + if (oldActiveFrame) { + document.body.removeChild(oldActiveFrame); + } + // Styles may have changed since we created the element. Make sure we re-style + applyStyles(newFrame.contentDocument, newFrame.contentDocument.body); + newFrame.setAttribute('id', 'active-frame'); + newFrame.style.visibility = 'visible'; + if (host.focusIframeOnCreate) { + newFrame.contentWindow.focus(); + } + + contentWindow.addEventListener('scroll', handleInnerScroll); + + pendingMessages.forEach((data) => { + contentWindow.postMessage(data, '*'); + }); + pendingMessages = []; + } + }; + + /** + * @param {HTMLIFrameElement} newFrame + */ + function hookupOnLoadHandlers(newFrame) { + clearTimeout(loadTimeout); + loadTimeout = undefined; + loadTimeout = setTimeout(() => { + clearTimeout(loadTimeout); + loadTimeout = undefined; + onLoad(newFrame.contentDocument, newFrame.contentWindow); + }, 200); + + newFrame.contentWindow.addEventListener('load', function (e) { + if (loadTimeout) { + clearTimeout(loadTimeout); + loadTimeout = undefined; + onLoad(e.target, this); + } + }); + + // Bubble out link clicks + newFrame.contentWindow.addEventListener('click', handleInnerClick); + + if (host.onIframeLoaded) { + host.onIframeLoaded(newFrame); + } + } + + if (!host.fakeLoad) { + hookupOnLoadHandlers(newFrame); + } + + if (!host.fakeLoad) { + newFrame.contentDocument.write(newDocument); + newFrame.contentDocument.close(); + } + + host.postMessage('did-set-content', undefined); + }); + + // Forward message to the embedded iframe + host.onMessage('message', (_event, data) => { + const pending = getPendingFrame(); + if (!pending) { + const target = getActiveFrame(); + if (target) { + target.contentWindow.postMessage(data, '*'); + return; + } + } + pendingMessages.push(data); + }); + + host.onMessage('initial-scroll-position', (_event, progress) => { + initData.initialScrollProgress = progress; + }); + + + trackFocus({ + onFocus: () => host.postMessage('did-focus'), + onBlur: () => host.postMessage('did-blur') + }); + + // signal ready + host.postMessage('webview-ready', {}); }); + } - host.onMessage('initial-scroll-position', (_event, progress) => { - initData.initialScrollProgress = progress; - }); - - host.onMessage('devtools-opened', () => { - isInDevelopmentMode = true; - }); - - trackFocus({ - onFocus: () => host.postMessage('did-focus'), - onBlur: () => host.postMessage('did-blur') - }); - - // Forward messages from the embedded iframe - window.onmessage = onMessage; - - // signal ready - host.postMessage('webview-ready', process.pid); - }); -}; + if (typeof module !== 'undefined') { + module.exports = createWebviewManager; + } else { + window.createWebviewManager = createWebviewManager; + } +}()); diff --git a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js new file mode 100644 index 00000000000..23f08be0281 --- /dev/null +++ b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js @@ -0,0 +1,274 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +const VERSION = 1; + +/** + * Root path for resources + */ +const resourceRoot = '/vscode-resource'; + +const resolveTimeout = 30000; + +/** + * @template T + * @typedef {{ + * resolve: (x: T) => void, + * promise: Promise + * }} RequestStoreEntry + */ + +/** + * @template T + */ +class RequestStore { + constructor() { + /** @type {Map>} */ + this.map = new Map(); + } + + /** + * @param {string} webviewId + * @param {string} path + * @return {Promise | undefined} + */ + get(webviewId, path) { + const entry = this.map.get(this._key(webviewId, path)); + return entry && entry.promise; + } + + /** + * @param {string} webviewId + * @param {string} path + * @returns {Promise} + */ + create(webviewId, path) { + const existing = this.get(webviewId, path); + if (existing) { + return existing; + } + let resolve; + const promise = new Promise(r => resolve = r); + const entry = { resolve, promise }; + const key = this._key(webviewId, path); + this.map.set(key, entry); + + const dispose = () => { + clearTimeout(timeout); + const existingEntry = this.map.get(key); + if (existingEntry === entry) { + return this.map.delete(key); + } + }; + const timeout = setTimeout(dispose, resolveTimeout); + return promise; + } + + /** + * @param {string} webviewId + * @param {string} path + * @param {T} result + * @return {boolean} + */ + resolve(webviewId, path, result) { + const entry = this.map.get(this._key(webviewId, path)); + if (!entry) { + return false; + } + entry.resolve(result); + return true; + } + + /** + * @param {string} webviewId + * @param {string} path + * @return {string} + */ + _key(webviewId, path) { + return `${webviewId}@@@${path}`; + } +} + +/** + * Map of requested paths to responses. + * + * @type {RequestStore<{ body: any, mime: string } | undefined>} + */ +const resourceRequestStore = new RequestStore(); + +/** + * Map of requested localhost origins to optional redirects. + * + * @type {RequestStore} + */ +const localhostRequestStore = new RequestStore(); + +const notFound = () => + new Response('Not Found', { status: 404, }); + +self.addEventListener('message', async (event) => { + switch (event.data.channel) { + case 'version': + { + self.clients.get(event.source.id).then(client => { + if (client) { + client.postMessage({ + channel: 'version', + version: VERSION + }); + } + }); + return; + } + case 'did-load-resource': + { + const webviewId = getWebviewIdForClient(event.source); + const data = event.data.data; + const response = data.status === 200 + ? { body: data.data, mime: data.mime } + : undefined; + + if (!resourceRequestStore.resolve(webviewId, data.path, response)) { + console.log('Could not resolve unknown resource', data.path); + } + return; + } + + case 'did-load-localhost': + { + const webviewId = getWebviewIdForClient(event.source); + const data = event.data.data; + if (!localhostRequestStore.resolve(webviewId, data.origin, data.location)) { + console.log('Could not resolve unknown localhost', data.origin); + } + return; + } + } + + console.log('Unknown message'); +}); + +self.addEventListener('fetch', (event) => { + const requestUrl = new URL(event.request.url); + + // See if it's a resource request + if (requestUrl.origin === self.origin && requestUrl.pathname.startsWith(resourceRoot + '/')) { + return event.respondWith(processResourceRequest(event, requestUrl)); + } + + // See if it's a localhost request + if (requestUrl.origin !== self.origin && requestUrl.host.match(/^localhost:(\d+)$/)) { + return event.respondWith(processLocalhostRequest(event, requestUrl)); + } +}); + +self.addEventListener('install', (event) => { + event.waitUntil(self.skipWaiting()); // Activate worker immediately +}); + +self.addEventListener('activate', (event) => { + event.waitUntil(self.clients.claim()); // Become available to all pages +}); + +async function processResourceRequest(event, requestUrl) { + const client = await self.clients.get(event.clientId); + if (!client) { + console.log('Could not find inner client for request'); + return notFound(); + } + + const webviewId = getWebviewIdForClient(client); + const resourcePath = requestUrl.pathname.replace(resourceRoot, ''); + + function resolveResourceEntry(entry) { + if (!entry) { + return notFound(); + } + return new Response(entry.body, { + status: 200, + headers: { 'Content-Type': entry.mime } + }); + } + + const parentClient = await getOuterIframeClient(webviewId); + if (!parentClient) { + console.log('Could not find parent client for request'); + return notFound(); + } + + // Check if we've already resolved this request + const existing = resourceRequestStore.get(webviewId, resourcePath); + if (existing) { + return existing.then(resolveResourceEntry); + } + + parentClient.postMessage({ + channel: 'load-resource', + path: resourcePath + }); + + return resourceRequestStore.create(webviewId, resourcePath) + .then(resolveResourceEntry); +} + +/** + * @param {*} event + * @param {URL} requestUrl + */ +async function processLocalhostRequest(event, requestUrl) { + const client = await self.clients.get(event.clientId); + if (!client) { + // This is expected when requesting resources on other localhost ports + // that are not spawned by vs code + return undefined; + } + const webviewId = getWebviewIdForClient(client); + const origin = requestUrl.origin; + + const resolveRedirect = redirectOrigin => { + if (!redirectOrigin) { + return fetch(event.request); + } + const location = event.request.url.replace(new RegExp(`^${requestUrl.origin}(/|$)`), `${redirectOrigin}$1`); + return new Response(null, { + status: 302, + headers: { + Location: location + } + }); + }; + + const parentClient = await getOuterIframeClient(webviewId); + if (!parentClient) { + console.log('Could not find parent client for request'); + return notFound(); + } + + // Check if we've already resolved this request + const existing = localhostRequestStore.get(webviewId, origin); + if (existing) { + return existing.then(resolveRedirect); + } + + parentClient.postMessage({ + channel: 'load-localhost', + origin: origin + }); + + return localhostRequestStore.create(webviewId, origin) + .then(resolveRedirect); +} + +function getWebviewIdForClient(client) { + const requesterClientUrl = new URL(client.url); + return requesterClientUrl.search.match(/\bid=([a-z0-9-]+)/i)[1]; +} + +async function getOuterIframeClient(webviewId) { + const allClients = await self.clients.matchAll({ includeUncontrolled: true }); + return allClients.find(client => { + const clientUrl = new URL(client.url); + return clientUrl.pathname === '/' && clientUrl.search.match(new RegExp('\\bid=' + webviewId)); + }); +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/browser/webview.contribution.ts b/src/vs/workbench/contrib/webview/browser/webview.contribution.ts index 61af7e2c34b..40dac14b615 100644 --- a/src/vs/workbench/contrib/webview/browser/webview.contribution.ts +++ b/src/vs/workbench/contrib/webview/browser/webview.contribution.ts @@ -4,11 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { isMacintosh } from 'vs/base/common/platform'; import { localize } from 'vs/nls'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkeys'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; @@ -17,8 +15,8 @@ import { EditorDescriptor, Extensions as EditorExtensions, IEditorRegistry } fro import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; import { Extensions as EditorInputExtensions, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor'; import { WebviewEditorInputFactory } from 'vs/workbench/contrib/webview/browser/webviewEditorInputFactory'; -import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from 'vs/workbench/contrib/webview/common/webview'; -import { CopyWebviewEditorCommand, CutWebviewEditorCommand, HideWebViewEditorFindCommand, OpenWebviewDeveloperToolsAction, PasteWebviewEditorCommand, RedoWebviewEditorCommand, ReloadWebviewAction, SelectAllWebviewEditorCommand, ShowWebViewEditorFindWidgetCommand, UndoWebviewEditorCommand } from '../browser/webviewCommands'; +import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE, webviewDeveloperCategory } from 'vs/workbench/contrib/webview/common/webview'; +import { HideWebViewEditorFindCommand, ReloadWebviewAction, ShowWebViewEditorFindWidgetCommand } from '../browser/webviewCommands'; import { WebviewEditor } from '../browser/webviewEditor'; import { WebviewEditorInput } from '../browser/webviewEditorInput'; import { IWebviewEditorService, WebviewEditorService } from '../browser/webviewEditorService'; @@ -35,12 +33,9 @@ Registry.as(EditorInputExtensions.EditorInputFactor registerSingleton(IWebviewEditorService, WebviewEditorService, true); - -const webviewDeveloperCategory = localize('developer', "Developer"); - const actionRegistry = Registry.as(ActionExtensions.WorkbenchActions); -export function registerWebViewCommands(editorId: string): void { +function registerWebViewCommands(editorId: string): void { const contextKeyExpr = ContextKeyExpr.and(ContextKeyExpr.equals('activeEditor', editorId), ContextKeyExpr.not('editorFocus') /* https://github.com/Microsoft/vscode/issues/58668 */); const showNextFindWidgetCommand = new ShowWebViewEditorFindWidgetCommand({ @@ -63,75 +58,10 @@ export function registerWebViewCommands(editorId: string): void { weight: KeybindingWeight.EditorContrib } })).register(); - - (new SelectAllWebviewEditorCommand({ - id: SelectAllWebviewEditorCommand.ID, - precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), - kbOpts: { - primary: KeyMod.CtrlCmd | KeyCode.KEY_A, - weight: KeybindingWeight.EditorContrib - } - })).register(); - - // These commands are only needed on MacOS where we have to disable the menu bar commands - if (isMacintosh) { - (new CopyWebviewEditorCommand({ - id: CopyWebviewEditorCommand.ID, - precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), - kbOpts: { - primary: KeyMod.CtrlCmd | KeyCode.KEY_C, - weight: KeybindingWeight.EditorContrib - } - })).register(); - - (new PasteWebviewEditorCommand({ - id: PasteWebviewEditorCommand.ID, - precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), - kbOpts: { - primary: KeyMod.CtrlCmd | KeyCode.KEY_V, - weight: KeybindingWeight.EditorContrib - } - })).register(); - - - (new CutWebviewEditorCommand({ - id: CutWebviewEditorCommand.ID, - precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), - kbOpts: { - primary: KeyMod.CtrlCmd | KeyCode.KEY_X, - weight: KeybindingWeight.EditorContrib - } - })).register(); - - (new UndoWebviewEditorCommand({ - id: UndoWebviewEditorCommand.ID, - precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), - kbOpts: { - primary: KeyMod.CtrlCmd | KeyCode.KEY_Z, - weight: KeybindingWeight.EditorContrib - } - })).register(); - - (new RedoWebviewEditorCommand({ - id: RedoWebviewEditorCommand.ID, - precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), - kbOpts: { - primary: KeyMod.CtrlCmd | KeyCode.KEY_Y, - secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z], - mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z }, - weight: KeybindingWeight.EditorContrib - } - })).register(); - } } registerWebViewCommands(WebviewEditor.ID); -actionRegistry.registerWorkbenchAction( - new SyncActionDescriptor(OpenWebviewDeveloperToolsAction, OpenWebviewDeveloperToolsAction.ID, OpenWebviewDeveloperToolsAction.LABEL), - 'Open Webview Developer Tools', - webviewDeveloperCategory); - actionRegistry.registerWorkbenchAction( new SyncActionDescriptor(ReloadWebviewAction, ReloadWebviewAction.ID, ReloadWebviewAction.LABEL), 'Reload Webviews', diff --git a/src/vs/workbench/contrib/webview/browser/webviewCommands.ts b/src/vs/workbench/contrib/webview/browser/webviewCommands.ts index 91b4ad454b9..a5888e3e668 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewCommands.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewCommands.ts @@ -32,96 +32,6 @@ export class HideWebViewEditorFindCommand extends Command { } } -export class SelectAllWebviewEditorCommand extends Command { - public static readonly ID = 'editor.action.webvieweditor.selectAll'; - - public runCommand(accessor: ServicesAccessor, args: any): void { - const webViewEditor = getActiveWebviewEditor(accessor); - if (webViewEditor) { - webViewEditor.selectAll(); - } - } -} - -export class CopyWebviewEditorCommand extends Command { - public static readonly ID = 'editor.action.webvieweditor.copy'; - - public runCommand(accessor: ServicesAccessor, args: any): void { - const webViewEditor = getActiveWebviewEditor(accessor); - if (webViewEditor) { - webViewEditor.copy(); - } - } -} - -export class PasteWebviewEditorCommand extends Command { - public static readonly ID = 'editor.action.webvieweditor.paste'; - - public runCommand(accessor: ServicesAccessor, args: any): void { - const webViewEditor = getActiveWebviewEditor(accessor); - if (webViewEditor) { - webViewEditor.paste(); - } - } -} - -export class CutWebviewEditorCommand extends Command { - public static readonly ID = 'editor.action.webvieweditor.cut'; - - public runCommand(accessor: ServicesAccessor, args: any): void { - const webViewEditor = getActiveWebviewEditor(accessor); - if (webViewEditor) { - webViewEditor.cut(); - } - } -} - -export class UndoWebviewEditorCommand extends Command { - public static readonly ID = 'editor.action.webvieweditor.undo'; - - public runCommand(accessor: ServicesAccessor, args: any): void { - const webViewEditor = getActiveWebviewEditor(accessor); - if (webViewEditor) { - webViewEditor.undo(); - } - } -} - -export class RedoWebviewEditorCommand extends Command { - public static readonly ID = 'editor.action.webvieweditor.redo'; - - public runCommand(accessor: ServicesAccessor, args: any): void { - const webViewEditor = getActiveWebviewEditor(accessor); - if (webViewEditor) { - webViewEditor.redo(); - } - } -} - -export class OpenWebviewDeveloperToolsAction extends Action { - static readonly ID = 'workbench.action.webview.openDeveloperTools'; - static readonly LABEL = nls.localize('openToolsLabel', "Open Webview Developer Tools"); - - public constructor( - id: string, - label: string - ) { - super(id, label); - } - - public run(): Promise { - const elements = document.querySelectorAll('webview.ready'); - for (let i = 0; i < elements.length; i++) { - try { - (elements.item(i) as Electron.WebviewTag).openDevTools(); - } catch (e) { - console.error(e); - } - } - return Promise.resolve(true); - } -} - export class ReloadWebviewAction extends Action { static readonly ID = 'workbench.action.webview.reloadWebviewAction'; static readonly LABEL = nls.localize('refreshWebviewLabel', "Reload Webviews"); diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts index 7c5730e4457..77a8253ff66 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts @@ -17,7 +17,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions } from 'vs/workbench/common/editor'; import { WebviewEditorInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput'; -import { IWebviewService, Webview, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from 'vs/workbench/contrib/webview/common/webview'; +import { IWebviewService, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE, Webview } from 'vs/workbench/contrib/webview/common/webview'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -142,31 +142,7 @@ export class WebviewEditor extends BaseEditor { this.withWebview(webview => webview.focus()); } - public selectAll(): void { - this.withWebview(webview => webview.selectAll()); - } - - public copy(): void { - this.withWebview(webview => webview.copy()); - } - - public paste(): void { - this.withWebview(webview => webview.paste()); - } - - public cut(): void { - this.withWebview(webview => webview.cut()); - } - - public undo(): void { - this.withWebview(webview => webview.undo()); - } - - public redo(): void { - this.withWebview(webview => webview.redo()); - } - - private withWebview(f: (element: Webview) => void): void { + public withWebview(f: (element: Webview) => void): void { if (this._webview) { f(this._webview); } @@ -280,7 +256,7 @@ export class WebviewEditor extends BaseEditor { this._webview.initialScrollProgress = input.scrollYPercentage; } - this._webview.state = input.webviewState; + this._webview.state = input.state ? input.state.state : undefined; this._content!.setAttribute('aria-flowto', this._webviewContent.id); diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts index 6d4d096a9c7..2b114064420 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts @@ -13,7 +13,7 @@ import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/bro import { WebviewEvents, WebviewInputOptions } from './webviewEditorService'; import { Webview, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview'; -export class WebviewEditorInput extends EditorInput { +export class WebviewEditorInput extends EditorInput { private static handlePool = 0; private static _styleElement?: HTMLStyleElement; @@ -39,10 +39,10 @@ export class WebviewEditorInput extends EditorInput { this._icons.forEach((value, key) => { const webviewSelector = `.show-file-icons .webview-${key}-name-file-icon::before`; if (URI.isUri(value)) { - cssRules.push(`${webviewSelector} { content: ""; background-image: url(${value.toString()}); }`); + cssRules.push(`${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value).toString()}); }`); } else { - cssRules.push(`.vs ${webviewSelector} { content: ""; background-image: url(${value.light.toString()}); }`); - cssRules.push(`.vs-dark ${webviewSelector} { content: ""; background-image: url(${value.dark.toString()}); }`); + cssRules.push(`.vs ${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value.light).toString()}); }`); + cssRules.push(`.vs-dark ${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value.dark).toString()}); }`); } }); this._styleElement.innerHTML = cssRules.join('\n'); @@ -62,7 +62,7 @@ export class WebviewEditorInput extends EditorInput { private readonly _webviewDisposables = this._register(new DisposableStore()); private _group?: GroupIdentifier; private _scrollYPercentage: number = 0; - private _state: any; + private _state: State; public readonly extension?: { readonly location: URI; @@ -74,7 +74,7 @@ export class WebviewEditorInput extends EditorInput { public readonly viewType: string, name: string, options: WebviewInputOptions, - state: any, + state: State, events: WebviewEvents, extension: undefined | { readonly location: URI; @@ -175,18 +175,14 @@ export class WebviewEditorInput extends EditorInput { } } - public get state(): any { + public get state(): State { return this._state; } - public set state(value: any) { + public set state(value: State) { this._state = value; } - public get webviewState() { - return this._state.state; - } - public get options(): WebviewInputOptions { return this._options; } @@ -253,7 +249,9 @@ export class WebviewEditorInput extends EditorInput { }, null, this._webviewDisposables); this._webview.onDidUpdateState(newState => { - this._state.state = newState; + if (this._events && this._events.onDidUpdateWebviewState) { + this._events.onDidUpdateWebviewState(newState); + } }, null, this._webviewDisposables); } @@ -262,7 +260,6 @@ export class WebviewEditorInput extends EditorInput { } public claimWebview(owner: any) { - this._webviewOwner = owner; } diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts index b12720c63ff..6064f07dd95 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts @@ -79,6 +79,7 @@ export interface WebviewEvents { onMessage?(message: any): void; onDispose?(): void; onDidClickLink?(link: URI, options: IWebviewOptions): void; + onDidUpdateWebviewState?(newState: any): void; } export interface WebviewInputOptions extends IWebviewOptions, IWebviewPanelOptions { @@ -92,7 +93,7 @@ export function areWebviewInputOptionsEqual(a: WebviewInputOptions, b: WebviewIn && a.retainContextWhenHidden === b.retainContextWhenHidden && a.tryRestoreScrollPosition === b.tryRestoreScrollPosition && (a.localResourceRoots === b.localResourceRoots || (Array.isArray(a.localResourceRoots) && Array.isArray(b.localResourceRoots) && equals(a.localResourceRoots, b.localResourceRoots, (a, b) => a.toString() === b.toString()))) - && (a.portMapping === b.portMapping || (Array.isArray(a.portMapping) && Array.isArray(b.portMapping) && equals(a.portMapping, b.portMapping, (a, b) => a.from === b.from && a.to === b.to))); + && (a.portMapping === b.portMapping || (Array.isArray(a.portMapping) && Array.isArray(b.portMapping) && equals(a.portMapping, b.portMapping, (a, b) => a.extensionHostPort === b.extensionHostPort && a.webviewPort === b.webviewPort))); } function canRevive(reviver: WebviewReviver, webview: WebviewEditorInput): boolean { diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts new file mode 100644 index 00000000000..ed7e22ab84d --- /dev/null +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -0,0 +1,318 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Emitter } from 'vs/base/common/event'; +import { URI } from 'vs/base/common/uri'; +import { Webview, WebviewContentOptions, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview'; +import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IFileService } from 'vs/platform/files/common/files'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { areWebviewInputOptionsEqual } from 'vs/workbench/contrib/webview/browser/webviewEditorService'; +import { addDisposableListener, addClass } from 'vs/base/browser/dom'; +import { getWebviewThemeData } from 'vs/workbench/contrib/webview/common/themeing'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { loadLocalResource } from 'vs/workbench/contrib/webview/common/resourceLoader'; +import { WebviewPortMappingManager } from 'vs/workbench/contrib/webview/common/portMapping'; +import { ITunnelService } from 'vs/platform/remote/common/tunnel'; + +interface WebviewContent { + readonly html: string; + readonly options: WebviewContentOptions; + readonly state: string | undefined; +} + +export class IFrameWebview extends Disposable implements Webview { + private element?: HTMLIFrameElement; + + private readonly _ready: Promise; + + private content: WebviewContent; + private _focused = false; + + private readonly id: string; + + private readonly _portMappingManager: WebviewPortMappingManager; + + constructor( + private _options: WebviewOptions, + contentOptions: WebviewContentOptions, + @IThemeService themeService: IThemeService, + @ITunnelService tunnelService: ITunnelService, + @IEnvironmentService private readonly environmentService: IEnvironmentService, + @IFileService private readonly fileService: IFileService, + @IConfigurationService private readonly _configurationService: IConfigurationService, + ) { + super(); + if (typeof environmentService.webviewEndpoint !== 'string') { + throw new Error('To use iframe based webviews, you must configure `environmentService.webviewEndpoint`'); + } + + this._portMappingManager = this._register(new WebviewPortMappingManager( + this._options.extension ? this._options.extension.location : undefined, + () => this.content.options.portMappings || [], + tunnelService + )); + + this.content = { + html: '', + options: contentOptions, + state: undefined + }; + + this.id = `webview-${Date.now()}`; + + this.element = document.createElement('iframe'); + this.element.sandbox.add('allow-scripts', 'allow-same-origin'); + this.element.setAttribute('src', `${environmentService.webviewEndpoint}?id=${this.id}`); + this.element.style.border = 'none'; + this.element.style.width = '100%'; + this.element.style.height = '100%'; + + this._register(addDisposableListener(window, 'message', e => { + if (!e || !e.data || e.data.target !== this.id) { + return; + } + + switch (e.data.channel) { + case 'onmessage': + if (e.data.data) { + this._onMessage.fire(e.data.data); + } + return; + + case 'did-click-link': + const uri = e.data.data; + this._onDidClickLink.fire(URI.parse(uri)); + return; + + case 'did-scroll': + // if (e.args && typeof e.args[0] === 'number') { + // this._onDidScroll.fire({ scrollYPercentage: e.args[0] }); + // } + return; + + case 'do-reload': + this.reload(); + return; + + case 'do-update-state': + const state = e.data.data; + this.state = state; + this._onDidUpdateState.fire(state); + return; + + case 'did-focus': + this.handleFocusChange(true); + return; + + case 'did-blur': + this.handleFocusChange(false); + return; + + case 'load-resource': + { + const requestPath = e.data.data.path; + const uri = URI.file(decodeURIComponent(requestPath)); + this.loadResource(requestPath, uri); + return; + } + + case 'load-localhost': + { + this.localLocalhost(e.data.data.origin); + return; + } + } + })); + + this._ready = new Promise(resolve => { + const subscription = this._register(addDisposableListener(window, 'message', (e) => { + if (e.data && e.data.target === this.id && e.data.channel === 'webview-ready') { + if (this.element) { + addClass(this.element, 'ready'); + } + subscription.dispose(); + resolve(); + } + })); + }); + + this.style(themeService.getTheme()); + this._register(themeService.onThemeChange(this.style, this)); + } + + public mountTo(parent: HTMLElement) { + if (this.element) { + parent.appendChild(this.element); + } + } + + public set options(options: WebviewContentOptions) { + if (areWebviewInputOptionsEqual(options, this.content.options)) { + return; + } + + this.content = { + html: this.content.html, + options: options, + state: this.content.state, + }; + this.doUpdateContent(); + } + + public set html(value: string) { + this.content = { + html: this.preprocessHtml(value), + options: this.content.options, + state: this.content.state, + }; + this.doUpdateContent(); + } + + private preprocessHtml(value: string): string { + return value.replace(/(["'])vscode-resource:([^\s'"]+?)(["'])/gi, (_, startQuote, path, endQuote) => + `${startQuote}${this.environmentService.webviewEndpoint}/vscode-resource${path}${endQuote}`); + } + + public update(html: string, options: WebviewContentOptions, retainContextWhenHidden: boolean) { + if (retainContextWhenHidden && html === this.content.html && areWebviewInputOptionsEqual(options, this.content.options)) { + return; + } + this.content = { + html: this.preprocessHtml(html), + options: options, + state: this.content.state, + }; + this.doUpdateContent(); + } + + private doUpdateContent() { + this._send('content', { + contents: this.content.html, + options: this.content.options, + state: this.content.state + }); + } + + private handleFocusChange(isFocused: boolean): void { + this._focused = isFocused; + if (this._focused) { + this._onDidFocus.fire(); + } + } + + initialScrollProgress: number; + + private readonly _onDidFocus = this._register(new Emitter()); + public readonly onDidFocus = this._onDidFocus.event; + + private readonly _onDidClickLink = this._register(new Emitter()); + public readonly onDidClickLink = this._onDidClickLink.event; + + private readonly _onDidScroll = this._register(new Emitter<{ scrollYPercentage: number }>()); + public readonly onDidScroll = this._onDidScroll.event; + + private readonly _onDidUpdateState = this._register(new Emitter()); + public readonly onDidUpdateState = this._onDidUpdateState.event; + + private readonly _onMessage = this._register(new Emitter()); + public readonly onMessage = this._onMessage.event; + + sendMessage(data: any): void { + this._send('message', data); + } + + layout(): void { + // noop + } + + focus(): void { + if (this.element) { + this.element.focus(); + } + } + + dispose(): void { + if (this.element) { + if (this.element.parentElement) { + this.element.parentElement.removeChild(this.element); + } + } + + this.element = undefined!; + super.dispose(); + } + + reload(): void { + this.doUpdateContent(); + } + + showFind(): void { + throw new Error('Method not implemented.'); + } + + hideFind(): void { + throw new Error('Method not implemented.'); + } + + public set state(state: string | undefined) { + this.content = { + html: this.content.html, + options: this.content.options, + state, + }; + } + + private _send(channel: string, data: any): void { + this._ready + .then(() => { + if (!this.element) { + return; + } + this.element.contentWindow!.postMessage({ + channel: channel, + args: data + }, '*'); + }) + .catch(err => console.error(err)); + } + + private style(theme: ITheme): void { + const { styles, activeTheme } = getWebviewThemeData(theme, this._configurationService); + this._send('styles', { styles, activeTheme }); + } + + private async loadResource(requestPath: string, uri: URI) { + try { + const result = await loadLocalResource(uri, this.fileService, this._options.extension ? this._options.extension.location : undefined, + () => (this.content.options.localResourceRoots || [])); + + if (result.type === 'success') { + return this._send('did-load-resource', { + status: 200, + path: requestPath, + mime: result.mimeType, + data: result.data.buffer + }); + } + } catch { + // noop + } + + return this._send('did-load-resource', { + status: 404, + path: uri.path + }); + } + + private async localLocalhost(origin: string) { + const redirect = await this._portMappingManager.getRedirect(origin); + return this._send('did-load-localhost', { + origin, + location: redirect + }); + } +} diff --git a/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts b/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts index e33b782bfa8..1f337cbc8e3 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts @@ -44,6 +44,7 @@ export class WebviewFindWidget extends SimpleFindWidget { } else { this._delegate.stopFind(false); } + return false; } protected onFocusTrackerFocus() { } diff --git a/src/vs/workbench/contrib/webview/browser/webviewService.ts b/src/vs/workbench/contrib/webview/browser/webviewService.ts index 00f58a88efb..58448a143cb 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewService.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewService.ts @@ -3,13 +3,23 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IWebviewService, Webview, WebviewContentOptions, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview'; - -export class NullWebviewService implements IWebviewService { +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IFrameWebview as WebviewElement } from 'vs/workbench/contrib/webview/browser/webviewElement'; +import { IWebviewService, WebviewOptions, WebviewContentOptions, Webview } from 'vs/workbench/contrib/webview/common/webview'; +export class WebviewService implements IWebviewService { _serviceBrand: any; - createWebview(_options: WebviewOptions, _contentOptions: WebviewContentOptions): Webview { - throw new Error('not supported'); + constructor( + @IInstantiationService private readonly _instantiationService: IInstantiationService, + ) { } + + createWebview( + options: WebviewOptions, + contentOptions: WebviewContentOptions + ): Webview { + return this._instantiationService.createInstance(WebviewElement, + options, + contentOptions); } -} +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/common/mimeTypes.ts b/src/vs/workbench/contrib/webview/common/mimeTypes.ts new file mode 100644 index 00000000000..0f1f583d451 --- /dev/null +++ b/src/vs/workbench/contrib/webview/common/mimeTypes.ts @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { getMediaMime, MIME_UNKNOWN } from 'vs/base/common/mime'; +import { extname } from 'vs/base/common/path'; +import { URI } from 'vs/base/common/uri'; + +const webviewMimeTypes = new Map([ + ['.svg', 'image/svg+xml'], + ['.txt', 'text/plain'], + ['.css', 'text/css'], + ['.js', 'application/javascript'], + ['.json', 'application/json'], + ['.html', 'text/html'], + ['.htm', 'text/html'], + ['.xhtml', 'application/xhtml+xml'], + ['.oft', 'font/otf'], + ['.xml', 'application/xml'], +]); + +export function getWebviewContentMimeType(normalizedPath: URI): string { + const ext = extname(normalizedPath.fsPath).toLowerCase(); + return webviewMimeTypes.get(ext) || getMediaMime(normalizedPath.fsPath) || MIME_UNKNOWN; +} diff --git a/src/vs/workbench/contrib/webview/common/portMapping.ts b/src/vs/workbench/contrib/webview/common/portMapping.ts new file mode 100644 index 00000000000..964c0ac6da0 --- /dev/null +++ b/src/vs/workbench/contrib/webview/common/portMapping.ts @@ -0,0 +1,87 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from 'vs/base/common/lifecycle'; +import { URI } from 'vs/base/common/uri'; +import * as modes from 'vs/editor/common/modes'; +import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; +import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel'; + +export function extractLocalHostUriMetaDataForPortMapping(uri: URI): { address: string, port: number } | undefined { + if (uri.scheme !== 'http' && uri.scheme !== 'https') { + return undefined; + } + const localhostMatch = /^(localhost|127\.0\.0\.1):(\d+)$/.exec(uri.authority); + if (!localhostMatch) { + return undefined; + } + return { + address: localhostMatch[1], + port: +localhostMatch[2], + }; +} + +export class WebviewPortMappingManager extends Disposable { + + private readonly _tunnels = new Map>(); + + constructor( + private readonly extensionLocation: URI | undefined, + private readonly mappings: () => ReadonlyArray, + private readonly tunnelService: ITunnelService + ) { + super(); + } + + public async getRedirect(url: string): Promise { + const uri = URI.parse(url); + const requestLocalHostInfo = extractLocalHostUriMetaDataForPortMapping(uri); + if (!requestLocalHostInfo) { + return undefined; + } + + for (const mapping of this.mappings()) { + if (mapping.webviewPort === requestLocalHostInfo.port) { + if (this.extensionLocation && this.extensionLocation.scheme === REMOTE_HOST_SCHEME) { + const tunnel = await this.getOrCreateTunnel(mapping.extensionHostPort); + if (tunnel) { + return uri.with({ + authority: `127.0.0.1:${tunnel.tunnelLocalPort}`, + }).toString(); + } + } + + if (mapping.webviewPort !== mapping.extensionHostPort) { + return uri.with({ + authority: `${requestLocalHostInfo.address}:${mapping.extensionHostPort}` + }).toString(); + } + } + } + + return undefined; + } + + dispose() { + super.dispose(); + + for (const tunnel of this._tunnels.values()) { + tunnel.then(tunnel => tunnel.dispose()); + } + this._tunnels.clear(); + } + + private getOrCreateTunnel(remotePort: number): Promise | undefined { + const existing = this._tunnels.get(remotePort); + if (existing) { + return existing; + } + const tunnel = this.tunnelService.openTunnel(remotePort); + if (tunnel) { + this._tunnels.set(remotePort, tunnel); + } + return tunnel; + } +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/common/resourceLoader.ts b/src/vs/workbench/contrib/webview/common/resourceLoader.ts new file mode 100644 index 00000000000..ea33db2e268 --- /dev/null +++ b/src/vs/workbench/contrib/webview/common/resourceLoader.ts @@ -0,0 +1,80 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { VSBuffer } from 'vs/base/common/buffer'; +import { sep } from 'vs/base/common/path'; +import { startsWith, endsWith } from 'vs/base/common/strings'; +import { URI } from 'vs/base/common/uri'; +import { IFileService } from 'vs/platform/files/common/files'; +import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; +import { getWebviewContentMimeType } from 'vs/workbench/contrib/webview/common/mimeTypes'; + +class Success { + readonly type = 'success'; + + constructor( + public readonly data: VSBuffer, + public readonly mimeType: string + ) { } +} + +const Failed = new class { readonly type = 'failed'; }; +const AccessDenied = new class { readonly type = 'access-denied'; }; + +type LocalResourceResponse = Success | typeof Failed | typeof AccessDenied; + +async function resolveContent( + fileService: IFileService, + resource: URI, + mime: string +): Promise { + try { + const contents = await fileService.readFile(resource); + return new Success(contents.value, mime); + } catch (err) { + console.log(err); + return Failed; + } +} + +export async function loadLocalResource( + requestUri: URI, + fileService: IFileService, + extensionLocation: URI | undefined, + getRoots: () => ReadonlyArray +): Promise { + const normalizedPath = requestUri.with({ + scheme: 'file', + fragment: '', + query: '', + }); + + for (const root of getRoots()) { + if (!containsResource(root, normalizedPath)) { + continue; + } + + if (extensionLocation && extensionLocation.scheme === REMOTE_HOST_SCHEME) { + const redirectedUri = URI.from({ + scheme: REMOTE_HOST_SCHEME, + authority: extensionLocation.authority, + path: '/vscode-resource', + query: JSON.stringify({ + requestResourcePath: requestUri.path + }) + }); + return resolveContent(fileService, redirectedUri, getWebviewContentMimeType(requestUri)); + } else { + return resolveContent(fileService, normalizedPath, getWebviewContentMimeType(normalizedPath)); + } + } + + return AccessDenied; +} + +function containsResource(root: URI, resource: URI): boolean { + const rootPath = root.fsPath + (endsWith(root.fsPath, sep) ? '' : sep); + return startsWith(resource.fsPath, rootPath); +} diff --git a/src/vs/workbench/contrib/webview/common/themeing.ts b/src/vs/workbench/contrib/webview/common/themeing.ts new file mode 100644 index 00000000000..5f0649247a8 --- /dev/null +++ b/src/vs/workbench/contrib/webview/common/themeing.ts @@ -0,0 +1,63 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { EDITOR_FONT_DEFAULTS, IEditorOptions } from 'vs/editor/common/config/editorOptions'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import * as colorRegistry from 'vs/platform/theme/common/colorRegistry'; +import { ITheme, LIGHT, DARK } from 'vs/platform/theme/common/themeService'; + +interface WebviewThemeData { + readonly activeTheme: string; + readonly styles: { readonly [key: string]: string | number }; +} + +export function getWebviewThemeData( + theme: ITheme, + configurationService: IConfigurationService +): WebviewThemeData { + const configuration = configurationService.getValue('editor'); + const editorFontFamily = configuration.fontFamily || EDITOR_FONT_DEFAULTS.fontFamily; + const editorFontWeight = configuration.fontWeight || EDITOR_FONT_DEFAULTS.fontWeight; + const editorFontSize = configuration.fontSize || EDITOR_FONT_DEFAULTS.fontSize; + + const exportedColors = colorRegistry.getColorRegistry().getColors().reduce((colors, entry) => { + const color = theme.getColor(entry.id); + if (color) { + colors['vscode-' + entry.id.replace('.', '-')] = color.toString(); + } + return colors; + }, {} as { [key: string]: string }); + + const styles = { + 'vscode-font-family': '-apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", ans-serif', + 'vscode-font-weight': 'normal', + 'vscode-font-size': '13px', + 'vscode-editor-font-family': editorFontFamily, + 'vscode-editor-font-weight': editorFontWeight, + 'vscode-editor-font-size': editorFontSize, + ...exportedColors + }; + + const activeTheme = ApiThemeClassName.fromTheme(theme); + return { styles, activeTheme }; +} + +enum ApiThemeClassName { + light = 'vscode-light', + dark = 'vscode-dark', + highContrast = 'vscode-high-contrast' +} + +namespace ApiThemeClassName { + export function fromTheme(theme: ITheme): ApiThemeClassName { + if (theme.type === LIGHT) { + return ApiThemeClassName.light; + } else if (theme.type === DARK) { + return ApiThemeClassName.dark; + } else { + return ApiThemeClassName.highContrast; + } + } +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/common/webview.ts b/src/vs/workbench/contrib/webview/common/webview.ts index 7aecb55b0af..bf459a3c694 100644 --- a/src/vs/workbench/contrib/webview/common/webview.ts +++ b/src/vs/workbench/contrib/webview/common/webview.ts @@ -4,12 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import { Event } from 'vs/base/common/event'; +import { IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; +import * as modes from 'vs/editor/common/modes'; +import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; -import * as modes from 'vs/editor/common/modes'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import * as nls from 'vs/nls'; /** * Set when the find widget in a webview is visible. @@ -30,6 +31,8 @@ export interface IWebviewService { ): Webview; } +export const WebviewResourceScheme = 'vscode-resource'; + export interface WebviewOptions { readonly allowSvgs?: boolean; readonly extension?: { @@ -69,15 +72,10 @@ export interface Webview extends IDisposable { layout(): void; mountTo(parent: HTMLElement): void; focus(): void; - reload(): void; - selectAll(): void; - copy(): void; - paste(): void; - cut(): void; - undo(): void; - redo(): void; showFind(): void; hideFind(): void; } + +export const webviewDeveloperCategory = nls.localize('developer', "Developer"); diff --git a/src/vs/workbench/contrib/webview/electron-browser/pre/electron-index.js b/src/vs/workbench/contrib/webview/electron-browser/pre/electron-index.js index 21e15e0eedd..6992535ea97 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/pre/electron-index.js +++ b/src/vs/workbench/contrib/webview/electron-browser/pre/electron-index.js @@ -28,16 +28,64 @@ // @ts-ignore const ipcRenderer = require('electron').ipcRenderer; - require('../../browser/pre/main')({ + let isInDevelopmentMode = false; + + /** + * @type {import('../../browser/pre/main').WebviewHost} + */ + const host = { postMessage: (channel, data) => { ipcRenderer.sendToHost(channel, data); }, onMessage: (channel, handler) => { ipcRenderer.on(channel, handler); + }, + focusIframeOnCreate: true, + onIframeLoaded: (newFrame) => { + newFrame.contentWindow.onbeforeunload = () => { + if (isInDevelopmentMode) { // Allow reloads while developing a webview + host.postMessage('do-reload'); + return false; + } + // Block navigation when not in development mode + console.log('prevented webview navigation'); + return false; + }; + + // Electron 4 eats mouseup events from inside webviews + // https://github.com/microsoft/vscode/issues/75090 + // Try to fix this by rebroadcasting mouse moves and mouseups so that we can + // emulate these on the main window + let isMouseDown = false; + newFrame.contentWindow.addEventListener('mousedown', () => { + isMouseDown = true; + }); + + const tryDispatchSyntheticMouseEvent = (e) => { + if (!isMouseDown) { + host.postMessage('synthetic-mouse-event', { type: e.type, screenX: e.screenX, screenY: e.screenY, clientX: e.clientX, clientY: e.clientY }); + } + }; + newFrame.contentWindow.addEventListener('mouseup', e => { + tryDispatchSyntheticMouseEvent(e); + isMouseDown = false; + }); + newFrame.contentWindow.addEventListener('mousemove', tryDispatchSyntheticMouseEvent); } + }; + + host.onMessage('devtools-opened', () => { + isInDevelopmentMode = true; }); document.addEventListener('DOMContentLoaded', () => { registerVscodeResourceScheme(); + + // Forward messages from the embedded iframe + window.onmessage = (message) => { + ipcRenderer.sendToHost(message.data.command, message.data.data); + }; }); + + require('../../browser/pre/main')(host); }()); \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts b/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts index 7b7b2c2dc76..13b7185842a 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts @@ -3,8 +3,90 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; +import { isMacintosh } from 'vs/base/common/platform'; +import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkeys'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IWebviewService } from 'vs/workbench/contrib/webview/common/webview'; +import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; +import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEditor'; +import { IWebviewService, webviewDeveloperCategory } from 'vs/workbench/contrib/webview/common/webview'; +import * as webviewCommands from 'vs/workbench/contrib/webview/electron-browser/webviewCommands'; import { WebviewService } from 'vs/workbench/contrib/webview/electron-browser/webviewService'; registerSingleton(IWebviewService, WebviewService, true); + +const actionRegistry = Registry.as(ActionExtensions.WorkbenchActions); + +actionRegistry.registerWorkbenchAction( + new SyncActionDescriptor(webviewCommands.OpenWebviewDeveloperToolsAction, webviewCommands.OpenWebviewDeveloperToolsAction.ID, webviewCommands.OpenWebviewDeveloperToolsAction.LABEL), + webviewCommands.OpenWebviewDeveloperToolsAction.ALIAS, + webviewDeveloperCategory); + +function registerWebViewCommands(editorId: string): void { + const contextKeyExpr = ContextKeyExpr.and(ContextKeyExpr.equals('activeEditor', editorId), ContextKeyExpr.not('editorFocus') /* https://github.com/Microsoft/vscode/issues/58668 */); + + (new webviewCommands.SelectAllWebviewEditorCommand({ + id: webviewCommands.SelectAllWebviewEditorCommand.ID, + precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), + kbOpts: { + primary: KeyMod.CtrlCmd | KeyCode.KEY_A, + weight: KeybindingWeight.EditorContrib + } + })).register(); + + // These commands are only needed on MacOS where we have to disable the menu bar commands + if (isMacintosh) { + (new webviewCommands.CopyWebviewEditorCommand({ + id: webviewCommands.CopyWebviewEditorCommand.ID, + precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), + kbOpts: { + primary: KeyMod.CtrlCmd | KeyCode.KEY_C, + weight: KeybindingWeight.EditorContrib + } + })).register(); + + (new webviewCommands.PasteWebviewEditorCommand({ + id: webviewCommands.PasteWebviewEditorCommand.ID, + precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), + kbOpts: { + primary: KeyMod.CtrlCmd | KeyCode.KEY_V, + weight: KeybindingWeight.EditorContrib + } + })).register(); + + (new webviewCommands.CutWebviewEditorCommand({ + id: webviewCommands.CutWebviewEditorCommand.ID, + precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), + kbOpts: { + primary: KeyMod.CtrlCmd | KeyCode.KEY_X, + weight: KeybindingWeight.EditorContrib + } + })).register(); + + (new webviewCommands.UndoWebviewEditorCommand({ + id: webviewCommands.UndoWebviewEditorCommand.ID, + precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), + kbOpts: { + primary: KeyMod.CtrlCmd | KeyCode.KEY_Z, + weight: KeybindingWeight.EditorContrib + } + })).register(); + + (new webviewCommands.RedoWebviewEditorCommand({ + id: webviewCommands.RedoWebviewEditorCommand.ID, + precondition: ContextKeyExpr.and(contextKeyExpr, ContextKeyExpr.not(InputFocusedContextKey)), + kbOpts: { + primary: KeyMod.CtrlCmd | KeyCode.KEY_Y, + secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z], + mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z }, + weight: KeybindingWeight.EditorContrib + } + })).register(); + } +} + +registerWebViewCommands(WebviewEditor.ID); \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts new file mode 100644 index 00000000000..15f320ce9f1 --- /dev/null +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts @@ -0,0 +1,98 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Action } from 'vs/base/common/actions'; +import * as nls from 'vs/nls'; +import { Command, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEditor'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { WebviewElement } from 'vs/workbench/contrib/webview/electron-browser/webviewElement'; + +export class OpenWebviewDeveloperToolsAction extends Action { + static readonly ID = 'workbench.action.webview.openDeveloperTools'; + static readonly ALIAS = 'Open Webview Developer Tools'; + static readonly LABEL = nls.localize('openToolsLabel', "Open Webview Developer Tools"); + + public constructor(id: string, label: string) { + super(id, label); + } + + public run(): Promise { + const elements = document.querySelectorAll('webview.ready'); + for (let i = 0; i < elements.length; i++) { + try { + (elements.item(i) as Electron.WebviewTag).openDevTools(); + } catch (e) { + console.error(e); + } + } + return Promise.resolve(true); + } +} + +export class SelectAllWebviewEditorCommand extends Command { + public static readonly ID = 'editor.action.webvieweditor.selectAll'; + + public runCommand(accessor: ServicesAccessor, args: any): void { + withActiveWebviewBasedWebview(accessor, webview => webview.selectAll()); + } +} + +export class CopyWebviewEditorCommand extends Command { + public static readonly ID = 'editor.action.webvieweditor.copy'; + + public runCommand(accessor: ServicesAccessor, _args: any): void { + withActiveWebviewBasedWebview(accessor, webview => webview.copy()); + } +} + +export class PasteWebviewEditorCommand extends Command { + public static readonly ID = 'editor.action.webvieweditor.paste'; + + public runCommand(accessor: ServicesAccessor, _args: any): void { + withActiveWebviewBasedWebview(accessor, webview => webview.paste()); + } +} + +export class CutWebviewEditorCommand extends Command { + public static readonly ID = 'editor.action.webvieweditor.cut'; + + public runCommand(accessor: ServicesAccessor, _args: any): void { + withActiveWebviewBasedWebview(accessor, webview => webview.cut()); + } +} + +export class UndoWebviewEditorCommand extends Command { + public static readonly ID = 'editor.action.webvieweditor.undo'; + + public runCommand(accessor: ServicesAccessor, args: any): void { + withActiveWebviewBasedWebview(accessor, webview => webview.undo()); + } +} + +export class RedoWebviewEditorCommand extends Command { + public static readonly ID = 'editor.action.webvieweditor.redo'; + + public runCommand(accessor: ServicesAccessor, args: any): void { + withActiveWebviewBasedWebview(accessor, webview => webview.redo()); + } +} + +function getActiveWebviewEditor(accessor: ServicesAccessor): WebviewEditor | undefined { + const editorService = accessor.get(IEditorService); + const activeControl = editorService.activeControl as WebviewEditor; + return activeControl.isWebviewEditor ? activeControl : undefined; +} + +function withActiveWebviewBasedWebview(accessor: ServicesAccessor, f: (webview: WebviewElement) => void): void { + const webViewEditor = getActiveWebviewEditor(accessor); + if (webViewEditor) { + webViewEditor.withWebview(webview => { + if (webview instanceof WebviewElement) { + f(webview); + } + }); + } +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index 148b2cb8300..32d4b8d25f0 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -11,20 +11,17 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { isMacintosh } from 'vs/base/common/platform'; import { endsWith } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; -import { EDITOR_FONT_DEFAULTS, IEditorOptions } from 'vs/editor/common/config/editorOptions'; import * as modes from 'vs/editor/common/modes'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; -import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import * as colorRegistry from 'vs/platform/theme/common/colorRegistry'; -import { DARK, ITheme, IThemeService, LIGHT } from 'vs/platform/theme/common/themeService'; -import { Webview, WebviewContentOptions, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview'; -import { registerFileProtocol, WebviewProtocol } from 'vs/workbench/contrib/webview/electron-browser/webviewProtocols'; +import { ITunnelService } from 'vs/platform/remote/common/tunnel'; +import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService'; +import { WebviewPortMappingManager } from 'vs/workbench/contrib/webview/common/portMapping'; +import { getWebviewThemeData } from 'vs/workbench/contrib/webview/common/themeing'; +import { Webview, WebviewContentOptions, WebviewOptions, WebviewResourceScheme } from 'vs/workbench/contrib/webview/common/webview'; +import { registerFileProtocol } from 'vs/workbench/contrib/webview/electron-browser/webviewProtocols'; import { areWebviewInputOptionsEqual } from '../browser/webviewEditorService'; import { WebviewFindWidget } from '../browser/webviewFindWidget'; @@ -117,7 +114,6 @@ class WebviewProtocolProvider extends Disposable { webview: Electron.WebviewTag, private readonly _extensionLocation: URI | undefined, private readonly _getLocalResourceRoots: () => ReadonlyArray, - private readonly _environmentService: IEnvironmentService, private readonly _fileService: IFileService, ) { super(); @@ -135,13 +131,7 @@ class WebviewProtocolProvider extends Disposable { return; } - const appRootUri = URI.file(this._environmentService.appRoot); - - registerFileProtocol(contents, WebviewProtocol.CoreResource, this._fileService, undefined, () => [ - appRootUri - ]); - - registerFileProtocol(contents, WebviewProtocol.VsCodeResource, this._fileService, this._extensionLocation, () => + registerFileProtocol(contents, WebviewResourceScheme, this._fileService, this._extensionLocation, () => this._getLocalResourceRoots() ); } @@ -149,88 +139,22 @@ class WebviewProtocolProvider extends Disposable { class WebviewPortMappingProvider extends Disposable { - private readonly _tunnels = new Map>(); + private readonly _manager: WebviewPortMappingManager; constructor( session: WebviewSession, extensionLocation: URI | undefined, mappings: () => ReadonlyArray, - private readonly tunnelService: ITunnelService, - extensionId: ExtensionIdentifier | undefined, - @ITelemetryService telemetryService: ITelemetryService + tunnelService: ITunnelService, ) { super(); + this._manager = this._register(new WebviewPortMappingManager(extensionLocation, mappings, tunnelService)); - let hasLogged = false; - - session.onBeforeRequest(async (details) => { - const uri = URI.parse(details.url); - if (uri.scheme !== 'http' && uri.scheme !== 'https') { - return undefined; - } - - const localhostMatch = /^localhost:(\d+)$/.exec(uri.authority); - if (localhostMatch) { - if (!hasLogged && extensionId) { - hasLogged = true; - - /* __GDPR__ - "webview.accessLocalhost" : { - "extension" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - telemetryService.publicLog('webview.accessLocalhost', { extension: extensionId.value }); - } - - const port = +localhostMatch[1]; - for (const mapping of mappings()) { - if (mapping.webviewPort === port) { - if (extensionLocation && extensionLocation.scheme === REMOTE_HOST_SCHEME) { - const tunnel = await this.getOrCreateTunnel(mapping.extensionHostPort); - if (tunnel) { - return { - redirectURL: details.url.replace( - new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}/`), - `${uri.scheme}://localhost:${tunnel.tunnelLocalPort}/`) - }; - } - } - - if (mapping.webviewPort !== mapping.extensionHostPort) { - return { - redirectURL: details.url.replace( - new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}/`), - `${uri.scheme}://localhost:${mapping.extensionHostPort}/`) - }; - } - } - } - } - - return undefined; + session.onBeforeRequest(async details => { + const redirect = await this._manager.getRedirect(details.url); + return redirect ? { redirectURL: redirect } : undefined; }); } - - dispose() { - super.dispose(); - - for (const tunnel of this._tunnels.values()) { - tunnel.then(tunnel => tunnel.dispose()); - } - this._tunnels.clear(); - } - - private getOrCreateTunnel(remotePort: number): Promise | undefined { - const existing = this._tunnels.get(remotePort); - if (existing) { - return existing; - } - const tunnel = this.tunnelService.openTunnel(remotePort); - if (tunnel) { - this._tunnels.set(remotePort, tunnel); - } - return tunnel; - } } class SvgBlocker extends Disposable { @@ -257,7 +181,8 @@ class SvgBlocker extends Disposable { }); session.onHeadersReceived((details) => { - const contentType: string[] = details.responseHeaders['content-type'] || details.responseHeaders['Content-Type']; + const headers: any = details.responseHeaders; + const contentType: string[] = headers['content-type'] || headers['Content-Type']; if (contentType && Array.isArray(contentType) && contentType.some(x => x.toLowerCase().indexOf('image/svg') >= 0)) { const uri = URI.parse(details.url); if (uri && !this.isAllowedSvg(uri)) { @@ -378,10 +303,8 @@ export class WebviewElement extends Disposable implements Webview { contentOptions: WebviewContentOptions, @IInstantiationService instantiationService: IInstantiationService, @IThemeService themeService: IThemeService, - @IEnvironmentService environmentService: IEnvironmentService, @IFileService fileService: IFileService, @ITunnelService tunnelService: ITunnelService, - @ITelemetryService telemetryService: ITelemetryService, @IConfigurationService private readonly _configurationService: IConfigurationService, ) { super(); @@ -421,7 +344,6 @@ export class WebviewElement extends Disposable implements Webview { this._webview, this._options.extension ? this._options.extension.location : undefined, () => (this.content.options.localResourceRoots || []), - environmentService, fileService)); this._register(new WebviewPortMappingProvider( @@ -429,8 +351,6 @@ export class WebviewElement extends Disposable implements Webview { _options.extension ? _options.extension.location : undefined, () => (this.content.options.portMappings || []), tunnelService, - _options.extension ? _options.extension.id : undefined, - telemetryService )); if (!this._options.allowSvgs) { @@ -472,6 +392,18 @@ export class WebviewElement extends Disposable implements Webview { this._onDidClickLink.fire(URI.parse(uri)); return; + case 'synthetic-mouse-event': + { + const rawEvent = event.args[0]; + const bounds = this._webview.getBoundingClientRect(); + window.dispatchEvent(new MouseEvent(rawEvent.type, { + ...rawEvent, + clientX: rawEvent.clientX + bounds.left, + clientY: rawEvent.clientY + bounds.top, + })); + return; + } + case 'did-set-content': this._webview.style.flex = ''; this._webview.style.width = '100%'; @@ -554,11 +486,11 @@ export class WebviewElement extends Disposable implements Webview { private readonly _onMessage = this._register(new Emitter()); public readonly onMessage = this._onMessage.event; - private _send(channel: string, ...args: any[]): void { + private _send(channel: string, data?: any): void { this._ready .then(() => { if (this._webview) { - this._webview.send(channel, ...args); + this._webview.send(channel, data); } }) .catch(err => console.error(err)); @@ -647,31 +579,8 @@ export class WebviewElement extends Disposable implements Webview { } private style(theme: ITheme): void { - const configuration = this._configurationService.getValue('editor'); - const editorFontFamily = configuration.fontFamily || EDITOR_FONT_DEFAULTS.fontFamily; - const editorFontWeight = configuration.fontWeight || EDITOR_FONT_DEFAULTS.fontWeight; - const editorFontSize = configuration.fontSize || EDITOR_FONT_DEFAULTS.fontSize; - - const exportedColors = colorRegistry.getColorRegistry().getColors().reduce((colors, entry) => { - const color = theme.getColor(entry.id); - if (color) { - colors['vscode-' + entry.id.replace('.', '-')] = color.toString(); - } - return colors; - }, {} as { [key: string]: string }); - - const styles = { - 'vscode-font-family': '-apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif', - 'vscode-font-weight': 'normal', - 'vscode-font-size': '13px', - 'vscode-editor-font-family': editorFontFamily, - 'vscode-editor-font-weight': editorFontWeight, - 'vscode-editor-font-size': editorFontSize, - ...exportedColors - }; - - const activeTheme = ApiThemeClassName.fromTheme(theme); - this._send('styles', styles, activeTheme); + const { styles, activeTheme } = getWebviewThemeData(theme, this._configurationService); + this._send('styles', { styles, activeTheme }); if (this._webviewFindWidget) { this._webviewFindWidget.updateTheme(theme); @@ -805,22 +714,3 @@ export class WebviewElement extends Disposable implements Webview { } } } - - -enum ApiThemeClassName { - light = 'vscode-light', - dark = 'vscode-dark', - highContrast = 'vscode-high-contrast' -} - -namespace ApiThemeClassName { - export function fromTheme(theme: ITheme): ApiThemeClassName { - if (theme.type === LIGHT) { - return ApiThemeClassName.light; - } else if (theme.type === DARK) { - return ApiThemeClassName.dark; - } else { - return ApiThemeClassName.highContrast; - } - } -} diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewProtocols.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewProtocols.ts index bacc9da1e70..95d41d147cc 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewProtocols.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewProtocols.ts @@ -2,67 +2,36 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { getMediaMime, MIME_UNKNOWN } from 'vs/base/common/mime'; -import { extname, sep } from 'vs/base/common/path'; -import { startsWith } from 'vs/base/common/strings'; -import { URI } from 'vs/base/common/uri'; -import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; -import { IFileService } from 'vs/platform/files/common/files'; import * as electron from 'electron'; - -type BufferProtocolCallback = (buffer?: Buffer | electron.MimeTypedBuffer | { error: number }) => void; - -export const enum WebviewProtocol { - CoreResource = 'vscode-core-resource', - VsCodeResource = 'vscode-resource', -} - -function resolveContent(fileService: IFileService, resource: URI, mime: string, callback: BufferProtocolCallback): void { - fileService.readFile(resource).then(contents => { - callback({ - data: Buffer.from(contents.value.buffer), - mimeType: mime - }); - }, (err) => { - console.log(err); - callback({ error: -2 /* FAILED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); - }); -} +import { URI } from 'vs/base/common/uri'; +import { IFileService } from 'vs/platform/files/common/files'; +import { loadLocalResource } from 'vs/workbench/contrib/webview/common/resourceLoader'; export function registerFileProtocol( contents: electron.WebContents, - protocol: WebviewProtocol, + protocol: string, fileService: IFileService, extensionLocation: URI | undefined, getRoots: () => ReadonlyArray ) { - contents.session.protocol.registerBufferProtocol(protocol, (request, callback: any) => { - const requestPath = URI.parse(request.url).path; - const normalizedPath = URI.file(requestPath); - for (const root of getRoots()) { - if (!startsWith(normalizedPath.fsPath, root.fsPath + sep)) { - continue; - } - - if (extensionLocation && extensionLocation.scheme === REMOTE_HOST_SCHEME) { - const requestUri = URI.parse(request.url); - const redirectedUri = URI.from({ - scheme: REMOTE_HOST_SCHEME, - authority: extensionLocation.authority, - path: '/vscode-resource', - query: JSON.stringify({ - requestResourcePath: requestUri.path - }) + contents.session.protocol.registerBufferProtocol(protocol, async (request, callback: any) => { + try { + const result = await loadLocalResource(URI.parse(request.url), fileService, extensionLocation, getRoots); + if (result.type === 'success') { + return callback({ + data: Buffer.from(result.data.buffer), + mimeType: result.mimeType }); - resolveContent(fileService, redirectedUri, getMimeType(requestUri), callback); - return; - } else { - resolveContent(fileService, normalizedPath, getMimeType(normalizedPath), callback); - return; } + if (result.type === 'access-denied') { + console.error('Webview: Cannot load resource outside of protocol root'); + return callback({ error: -10 /* ACCESS_DENIED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); + } + } catch { + // noop } - console.error('Webview: Cannot load resource outside of protocol root'); - callback({ error: -10 /* ACCESS_DENIED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); + + return callback({ error: -2 /* FAILED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ }); }, (error) => { if (error) { console.error(`Failed to register '${protocol}' protocol`); @@ -70,20 +39,3 @@ export function registerFileProtocol( }); } -const webviewMimeTypes = { - '.svg': 'image/svg+xml', - '.txt': 'text/plain', - '.css': 'text/css', - '.js': 'application/javascript', - '.json': 'application/json', - '.html': 'text/html', - '.htm': 'text/html', - '.xhtml': 'application/xhtml+xml', - '.oft': 'font/otf', - '.xml': 'application/xml', -}; - -function getMimeType(normalizedPath: URI): string { - const ext = extname(normalizedPath.fsPath).toLowerCase(); - return webviewMimeTypes[ext] || getMediaMime(normalizedPath.fsPath) || MIME_UNKNOWN; -} diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts index e341b1864ea..e8ccaee1881 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts @@ -18,10 +18,8 @@ export class WebviewService implements IWebviewService { options: WebviewOptions, contentOptions: WebviewContentOptions ): Webview { - const element = this._instantiationService.createInstance(WebviewElement, + return this._instantiationService.createInstance(WebviewElement, options, contentOptions); - - return element; } } \ No newline at end of file diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts b/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts index 2c31578abdc..99693277ff1 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts @@ -13,7 +13,7 @@ import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; -import { IExperimentService, ExperimentState } from 'vs/workbench/contrib/experiments/node/experimentService'; +import { IExperimentService, ExperimentState } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { language, locale } from 'vs/base/common/platform'; import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -90,13 +90,13 @@ export class TelemetryOptOut implements IWorkbenchContribution { return undefined; } const extensionToFetchTranslationsFrom = tagResult.firstPage.filter(e => e.publisher === 'MS-CEINTL' && e.name.indexOf('vscode-language-pack') === 0)[0] || tagResult.firstPage[0]; - if (!extensionToFetchTranslationsFrom.assets || !extensionToFetchTranslationsFrom.assets.coreTranslations) { + if (!extensionToFetchTranslationsFrom.assets || !extensionToFetchTranslationsFrom.assets.coreTranslations.length) { return undefined; } return this.galleryService.getCoreTranslation(extensionToFetchTranslationsFrom, locale!) .then(translation => { - const translationsFromPack = translation && translation.contents ? translation.contents['vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut'] : {}; + const translationsFromPack: any = translation && translation.contents ? translation.contents['vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut'] : {}; if (!!translationsFromPack[promptMessageKey] && !!translationsFromPack[yesLabelKey] && !!translationsFromPack[noLabelKey]) { promptMessage = translationsFromPack[promptMessageKey].replace('{0}', this.privacyUrl) + ' (Please help Microsoft improve Visual Studio Code by allowing the collection of usage data.)'; yesLabel = translationsFromPack[yesLabelKey] + ' (Yes)'; diff --git a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts index 57ec2510560..64a9afe8fe8 100644 --- a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts +++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts @@ -17,7 +17,7 @@ import { IWindowService, IURIToOpen } from 'vs/platform/windows/common/windows'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { localize } from 'vs/nls'; -import { Action } from 'vs/base/common/actions'; +import { Action, WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { Schemas } from 'vs/base/common/network'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; @@ -151,7 +151,7 @@ const extensionPacks: ExtensionSuggestion[] = [ // { name: localize('welcomePage.go', "Go"), id: 'lukehoban.go' }, { name: localize('welcomePage.php', "PHP"), id: 'felixfbecker.php-pack' }, { name: localize('welcomePage.azure', "Azure"), title: localize('welcomePage.showAzureExtensions', "Show Azure extensions"), id: 'workbench.extensions.action.showAzureExtensions', isCommand: true }, - { name: localize('welcomePage.docker', "Docker"), id: 'peterjausovec.vscode-docker' }, + { name: localize('welcomePage.docker', "Docker"), id: 'ms-azuretools.vscode-docker' }, ]; const keymapExtensions: ExtensionSuggestion[] = [ @@ -360,13 +360,7 @@ class WelcomePage extends Disposable { a.setAttribute('aria-label', localize('welcomePage.openFolderWithPath', "Open folder {0} with path {1}", name, parentPath)); a.href = 'javascript:void(0)'; a.addEventListener('click', e => { - /* __GDPR__ - "workbenchActionExecuted" : { - "id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('workbenchActionExecuted', { + this.telemetryService.publicLog2('workbenchActionExecuted', { id: 'openRecentFolder', from: telemetryFrom }); diff --git a/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts index 2e85c4301fe..7bae52d70b7 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts @@ -129,7 +129,7 @@ export class WalkThroughPart extends BaseEditor { this.disposables.add(this.addEventListener(this.content, 'blur', e => { this.editorFocus.reset(); })); - this.disposables.add(this.addEventListener(this.content, 'focusin', e => { + this.disposables.add(this.addEventListener(this.content, 'focusin', (e: FocusEvent) => { // Work around scrolling as side-effect of setting focus on the offscreen zone widget (#18929) if (e.target instanceof HTMLElement && e.target.classList.contains('zone-widget-container')) { const scrollPosition = this.scrollbar.getScrollPosition(); diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index 811c9ecac13..4da3b429e48 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -6,16 +6,6 @@ import { Action } from 'vs/base/common/actions'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; import * as nls from 'vs/nls'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { domEvent } from 'vs/base/browser/event'; -import { Event } from 'vs/base/common/event'; -import { IDisposable, toDisposable, dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { getDomNodePagePosition, createStyleSheet, createCSSRule, append, $ } from 'vs/base/browser/dom'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { Context } from 'vs/platform/contextkey/browser/contextKeyService'; -import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { timeout } from 'vs/base/common/async'; -import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; export class ToggleDevToolsAction extends Action { @@ -44,176 +34,3 @@ export class ToggleSharedProcessAction extends Action { return this.windowsService.toggleSharedProcess(); } } - -export class InspectContextKeysAction extends Action { - - static readonly ID = 'workbench.action.inspectContextKeys'; - static LABEL = nls.localize('inspect context keys', "Inspect Context Keys"); - - constructor( - id: string, - label: string, - @IContextKeyService private readonly contextKeyService: IContextKeyService, - @IWindowService private readonly windowService: IWindowService, - ) { - super(id, label); - } - - run(): Promise { - const disposables = new DisposableStore(); - - const stylesheet = createStyleSheet(); - disposables.add(toDisposable(() => { - if (stylesheet.parentNode) { - stylesheet.parentNode.removeChild(stylesheet); - } - })); - createCSSRule('*', 'cursor: crosshair !important;', stylesheet); - - const hoverFeedback = document.createElement('div'); - document.body.appendChild(hoverFeedback); - disposables.add(toDisposable(() => document.body.removeChild(hoverFeedback))); - - hoverFeedback.style.position = 'absolute'; - hoverFeedback.style.pointerEvents = 'none'; - hoverFeedback.style.backgroundColor = 'rgba(255, 0, 0, 0.5)'; - hoverFeedback.style.zIndex = '1000'; - - const onMouseMove = domEvent(document.body, 'mousemove', true); - disposables.add(onMouseMove(e => { - const target = e.target as HTMLElement; - const position = getDomNodePagePosition(target); - - hoverFeedback.style.top = `${position.top}px`; - hoverFeedback.style.left = `${position.left}px`; - hoverFeedback.style.width = `${position.width}px`; - hoverFeedback.style.height = `${position.height}px`; - })); - - const onMouseDown = Event.once(domEvent(document.body, 'mousedown', true)); - onMouseDown(e => { e.preventDefault(); e.stopPropagation(); }, null, disposables); - - const onMouseUp = Event.once(domEvent(document.body, 'mouseup', true)); - onMouseUp(e => { - e.preventDefault(); - e.stopPropagation(); - - const context = this.contextKeyService.getContext(e.target as HTMLElement) as Context; - console.log(context.collectAllValues()); - this.windowService.openDevTools(); - - dispose(disposables); - }, null, disposables); - - return Promise.resolve(); - } -} - -export class ToggleScreencastModeAction extends Action { - - static readonly ID = 'workbench.action.toggleScreencastMode'; - static LABEL = nls.localize('toggle screencast mode', "Toggle Screencast Mode"); - - static disposable: IDisposable | undefined; - - constructor( - id: string, - label: string, - @IKeybindingService private readonly keybindingService: IKeybindingService, - @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService - ) { - super(id, label); - } - - async run(): Promise { - if (ToggleScreencastModeAction.disposable) { - ToggleScreencastModeAction.disposable.dispose(); - ToggleScreencastModeAction.disposable = undefined; - return; - } - - const container = this.layoutService.getWorkbenchElement(); - - const mouseMarker = append(container, $('div')); - mouseMarker.style.position = 'absolute'; - mouseMarker.style.border = '2px solid red'; - mouseMarker.style.borderRadius = '20px'; - mouseMarker.style.width = '20px'; - mouseMarker.style.height = '20px'; - mouseMarker.style.top = '0'; - mouseMarker.style.left = '0'; - mouseMarker.style.zIndex = '100000'; - mouseMarker.style.content = ' '; - mouseMarker.style.pointerEvents = 'none'; - mouseMarker.style.display = 'none'; - - const onMouseDown = domEvent(container, 'mousedown', true); - const onMouseUp = domEvent(container, 'mouseup', true); - const onMouseMove = domEvent(container, 'mousemove', true); - - const mouseListener = onMouseDown(e => { - mouseMarker.style.top = `${e.clientY - 10}px`; - mouseMarker.style.left = `${e.clientX - 10}px`; - mouseMarker.style.display = 'block'; - - const mouseMoveListener = onMouseMove(e => { - mouseMarker.style.top = `${e.clientY - 10}px`; - mouseMarker.style.left = `${e.clientX - 10}px`; - }); - - Event.once(onMouseUp)(() => { - mouseMarker.style.display = 'none'; - mouseMoveListener.dispose(); - }); - }); - - const keyboardMarker = append(container, $('div')); - keyboardMarker.style.position = 'absolute'; - keyboardMarker.style.backgroundColor = 'rgba(0, 0, 0 ,0.5)'; - keyboardMarker.style.width = '100%'; - keyboardMarker.style.height = '100px'; - keyboardMarker.style.bottom = '20%'; - keyboardMarker.style.left = '0'; - keyboardMarker.style.zIndex = '100000'; - keyboardMarker.style.pointerEvents = 'none'; - keyboardMarker.style.color = 'white'; - keyboardMarker.style.lineHeight = '100px'; - keyboardMarker.style.textAlign = 'center'; - keyboardMarker.style.fontSize = '56px'; - keyboardMarker.style.display = 'none'; - - const onKeyDown = domEvent(container, 'keydown', true); - let keyboardTimeout: IDisposable = Disposable.None; - - const keyboardListener = onKeyDown(e => { - keyboardTimeout.dispose(); - - const event = new StandardKeyboardEvent(e); - const keybinding = this.keybindingService.resolveKeyboardEvent(event); - const label = keybinding.getLabel(); - - if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { - keyboardMarker.textContent += ' ' + label; - } else { - keyboardMarker.textContent = label; - } - - keyboardMarker.style.display = 'block'; - - const promise = timeout(800); - keyboardTimeout = toDisposable(() => promise.cancel()); - - promise.then(() => { - keyboardMarker.textContent = ''; - keyboardMarker.style.display = 'none'; - }); - }); - - ToggleScreencastModeAction.disposable = toDisposable(() => { - mouseListener.dispose(); - keyboardListener.dispose(); - mouseMarker.remove(); - keyboardMarker.remove(); - }); - } -} diff --git a/src/vs/workbench/electron-browser/actions/media/remove-dark.svg b/src/vs/workbench/electron-browser/actions/media/remove-dark.svg deleted file mode 100644 index 751e89b3b02..00000000000 --- a/src/vs/workbench/electron-browser/actions/media/remove-dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/electron-browser/actions/media/remove.svg b/src/vs/workbench/electron-browser/actions/media/remove.svg deleted file mode 100644 index fde34404d4e..00000000000 --- a/src/vs/workbench/electron-browser/actions/media/remove.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/electron-browser/actions/windowActions.ts b/src/vs/workbench/electron-browser/actions/windowActions.ts index ce3d1279119..7bb652eb2f5 100644 --- a/src/vs/workbench/electron-browser/actions/windowActions.ts +++ b/src/vs/workbench/electron-browser/actions/windowActions.ts @@ -3,29 +3,22 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import 'vs/css!./media/actions'; - import { URI } from 'vs/base/common/uri'; import { Action } from 'vs/base/common/actions'; -import { IWindowService, IWindowsService, IURIToOpen } from 'vs/platform/windows/common/windows'; +import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; import * as nls from 'vs/nls'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { isMacintosh } from 'vs/base/common/platform'; import * as browser from 'vs/base/browser/browser'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { webFrame } from 'electron'; import { FileKind } from 'vs/platform/files/common/files'; -import { ILabelService } from 'vs/platform/label/common/label'; import { IModelService } from 'vs/editor/common/services/modelService'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { IQuickInputService, IQuickInputButton, IQuickPickSeparator, IKeyMods } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickInputButton } from 'vs/platform/quickinput/common/quickInput'; import { getIconClasses } from 'vs/editor/common/services/getIconClasses'; import product from 'vs/platform/product/node/product'; import { ICommandHandler } from 'vs/platform/commands/common/commands'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IRecentFolder, IRecentFile, IRecentWorkspace, IRecent, isRecentFolder, isRecentWorkspace } from 'vs/platform/history/common/history'; -import { splitName } from 'vs/base/common/labels'; export class CloseCurrentWindowAction extends Action { @@ -61,20 +54,6 @@ export class NewWindowAction extends Action { } } -export class ToggleFullScreenAction extends Action { - - static readonly ID = 'workbench.action.toggleFullScreen'; - static LABEL = nls.localize('toggleFullScreen', "Toggle Full Screen"); - - constructor(id: string, label: string, @IWindowService private readonly windowService: IWindowService) { - super(id, label); - } - - run(): Promise { - return this.windowService.toggleFullScreen(); - } -} - export abstract class BaseZoomAction extends Action { private static readonly SETTING_KEY = 'window.zoomLevel'; @@ -164,26 +143,6 @@ export class ZoomResetAction extends BaseZoomAction { } } -export class ReloadWindowAction extends Action { - - static readonly ID = 'workbench.action.reloadWindow'; - static LABEL = nls.localize('reloadWindow', "Reload Window"); - - constructor( - id: string, - label: string, - @IWindowService private readonly windowService: IWindowService - ) { - super(id, label); - } - - async run(): Promise { - await this.windowService.reloadWindow(); - - return true; - } -} - export class ReloadWindowWithExtensionsDisabledAction extends Action { static readonly ID = 'workbench.action.reloadWindowWithExtensionsDisabled'; @@ -308,150 +267,6 @@ export class QuickSwitchWindow extends BaseSwitchWindow { } } -export const inRecentFilesPickerContextKey = 'inRecentFilesPicker'; - -export abstract class BaseOpenRecentAction extends Action { - - private removeFromRecentlyOpened: IQuickInputButton = { - iconClass: 'action-remove-from-recently-opened', - tooltip: nls.localize('remove', "Remove from Recently Opened") - }; - - constructor( - id: string, - label: string, - private windowService: IWindowService, - private windowsService: IWindowsService, - private quickInputService: IQuickInputService, - private contextService: IWorkspaceContextService, - private labelService: ILabelService, - private keybindingService: IKeybindingService, - private modelService: IModelService, - private modeService: IModeService, - ) { - super(id, label); - } - - protected abstract isQuickNavigate(): boolean; - - async run(): Promise { - const { workspaces, files } = await this.windowService.getRecentlyOpened(); - - this.openRecent(workspaces, files); - } - - private async openRecent(recentWorkspaces: Array, recentFiles: IRecentFile[]): Promise { - - const toPick = (recent: IRecent, labelService: ILabelService, buttons: IQuickInputButton[] | undefined) => { - let uriToOpen: IURIToOpen | undefined; - let iconClasses: string[]; - let fullLabel: string | undefined; - let resource: URI | undefined; - if (isRecentFolder(recent)) { - resource = recent.folderUri; - iconClasses = getIconClasses(this.modelService, this.modeService, resource, FileKind.FOLDER); - uriToOpen = { folderUri: resource }; - fullLabel = recent.label || labelService.getWorkspaceLabel(resource, { verbose: true }); - } else if (isRecentWorkspace(recent)) { - resource = recent.workspace.configPath; - iconClasses = getIconClasses(this.modelService, this.modeService, resource, FileKind.ROOT_FOLDER); - uriToOpen = { workspaceUri: resource }; - fullLabel = recent.label || labelService.getWorkspaceLabel(recent.workspace, { verbose: true }); - } else { - resource = recent.fileUri; - iconClasses = getIconClasses(this.modelService, this.modeService, resource, FileKind.FILE); - uriToOpen = { fileUri: resource }; - fullLabel = recent.label || labelService.getUriLabel(resource); - } - const { name, parentPath } = splitName(fullLabel); - return { - iconClasses, - label: name, - description: parentPath, - buttons, - uriToOpen, - resource - }; - }; - const workspacePicks = recentWorkspaces.map(workspace => toPick(workspace, this.labelService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : undefined)); - const filePicks = recentFiles.map(p => toPick(p, this.labelService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : undefined)); - - // focus second entry if the first recent workspace is the current workspace - const firstEntry = recentWorkspaces[0]; - let autoFocusSecondEntry: boolean = firstEntry && this.contextService.isCurrentWorkspace(isRecentWorkspace(firstEntry) ? firstEntry.workspace : firstEntry.folderUri); - - let keyMods: IKeyMods | undefined; - const workspaceSeparator: IQuickPickSeparator = { type: 'separator', label: nls.localize('workspaces', "workspaces") }; - const fileSeparator: IQuickPickSeparator = { type: 'separator', label: nls.localize('files', "files") }; - const picks = [workspaceSeparator, ...workspacePicks, fileSeparator, ...filePicks]; - const pick = await this.quickInputService.pick(picks, { - contextKey: inRecentFilesPickerContextKey, - activeItem: [...workspacePicks, ...filePicks][autoFocusSecondEntry ? 1 : 0], - placeHolder: isMacintosh ? nls.localize('openRecentPlaceHolderMac', "Select to open (hold Cmd-key to open in new window)") : nls.localize('openRecentPlaceHolder', "Select to open (hold Ctrl-key to open in new window)"), - matchOnDescription: true, - onKeyMods: mods => keyMods = mods, - quickNavigate: this.isQuickNavigate() ? { keybindings: this.keybindingService.lookupKeybindings(this.id) } : undefined, - onDidTriggerItemButton: async context => { - await this.windowsService.removeFromRecentlyOpened([context.item.resource]); - context.removeItem(); - } - }); - - if (pick) { - return this.windowService.openWindow([pick.uriToOpen], { forceNewWindow: keyMods && keyMods.ctrlCmd }); - } - } -} - -export class OpenRecentAction extends BaseOpenRecentAction { - - static readonly ID = 'workbench.action.openRecent'; - static readonly LABEL = nls.localize('openRecent', "Open Recent..."); - - constructor( - id: string, - label: string, - @IWindowService windowService: IWindowService, - @IWindowsService windowsService: IWindowsService, - @IQuickInputService quickInputService: IQuickInputService, - @IWorkspaceContextService contextService: IWorkspaceContextService, - @IKeybindingService keybindingService: IKeybindingService, - @IModelService modelService: IModelService, - @IModeService modeService: IModeService, - @ILabelService labelService: ILabelService - ) { - super(id, label, windowService, windowsService, quickInputService, contextService, labelService, keybindingService, modelService, modeService); - } - - protected isQuickNavigate(): boolean { - return false; - } -} - -export class QuickOpenRecentAction extends BaseOpenRecentAction { - - static readonly ID = 'workbench.action.quickOpenRecent'; - static readonly LABEL = nls.localize('quickOpenRecent', "Quick Open Recent..."); - - constructor( - id: string, - label: string, - @IWindowService windowService: IWindowService, - @IWindowsService windowsService: IWindowsService, - @IQuickInputService quickInputService: IQuickInputService, - @IWorkspaceContextService contextService: IWorkspaceContextService, - @IKeybindingService keybindingService: IKeybindingService, - @IModelService modelService: IModelService, - @IModeService modeService: IModeService, - @ILabelService labelService: ILabelService - ) { - super(id, label, windowService, windowsService, quickInputService, contextService, labelService, keybindingService, modelService, modeService); - } - - protected isQuickNavigate(): boolean { - return true; - } -} export class ShowAboutDialogAction extends Action { diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 58f6fbd1090..10557fccab0 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -12,19 +12,17 @@ import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/action import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, OpenNewsletterSignupUrlAction } from 'vs/workbench/electron-browser/actions/helpActions'; -import { ToggleSharedProcessAction, InspectContextKeysAction, ToggleScreencastModeAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions'; -import { ShowAboutDialogAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, OpenRecentAction, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ReloadWindowAction, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions'; -import { AddRootFolderAction, GlobalRemoveRootFolderAction, OpenWorkspaceAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, OpenFileFolderAction, OpenFileAction, OpenFolderAction, CloseWorkspaceAction, OpenLocalFileAction, OpenLocalFolderAction, OpenLocalFileFolderAction } from 'vs/workbench/browser/actions/workspaceActions'; +import { ToggleSharedProcessAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions'; +import { ShowAboutDialogAction, ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions'; +import { AddRootFolderAction, GlobalRemoveRootFolderAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, CloseWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { inQuickOpenContext, getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ADD_ROOT_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands'; -import { SupportsWorkspacesContext, IsMacContext, HasMacNativeTabsContext, IsDevelopmentContext, WorkbenchStateContext, WorkspaceFolderCountContext, RemoteFileDialogContext, IsFullscreenContext } from 'vs/workbench/browser/contextkeys'; +import { SupportsWorkspacesContext, IsMacContext, HasMacNativeTabsContext, IsDevelopmentContext, WorkbenchStateContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys'; import { NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench/common/editor'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; -import { LogStorageAction } from 'vs/platform/storage/node/storageService'; import product from 'vs/platform/product/node/product'; // Actions @@ -35,41 +33,7 @@ import product from 'vs/platform/product/node/product'; (function registerFileActions(): void { const fileCategory = nls.localize('file', "File"); - if (isMacintosh) { - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileFolderAction, OpenFileFolderAction.ID, OpenFileFolderAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open...', fileCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFileFolderAction, OpenLocalFileFolderAction.ID, OpenLocalFileFolderAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }, RemoteFileDialogContext), 'File: Open Local...', fileCategory); - } else { - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileAction, OpenFileAction.ID, OpenFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open File...', fileCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFolderAction, OpenFolderAction.ID, OpenFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }), 'File: Open Folder...', fileCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFileAction, OpenLocalFileAction.ID, OpenLocalFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }, RemoteFileDialogContext), 'File: Open Local File...', fileCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFolderAction, OpenLocalFolderAction.ID, OpenLocalFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }, RemoteFileDialogContext), 'File: Open Local Folder...', fileCategory); - } - - registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenRecentAction, QuickOpenRecentAction.ID, QuickOpenRecentAction.LABEL), 'File: Quick Open Recent...', fileCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenRecentAction, OpenRecentAction.ID, OpenRecentAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_R, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_R } }), 'File: Open Recent...', fileCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(CloseWorkspaceAction, CloseWorkspaceAction.ID, CloseWorkspaceAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'File: Close Workspace', fileCategory); - - const recentFilesPickerContext = ContextKeyExpr.and(inQuickOpenContext, ContextKeyExpr.has(inRecentFilesPickerContextKey)); - - const quickOpenNavigateNextInRecentFilesPickerId = 'workbench.action.quickOpenNavigateNextInRecentFilesPicker'; - KeybindingsRegistry.registerCommandAndKeybindingRule({ - id: quickOpenNavigateNextInRecentFilesPickerId, - weight: KeybindingWeight.WorkbenchContrib + 50, - handler: getQuickNavigateHandler(quickOpenNavigateNextInRecentFilesPickerId, true), - when: recentFilesPickerContext, - primary: KeyMod.CtrlCmd | KeyCode.KEY_R, - mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_R } - }); - - const quickOpenNavigatePreviousInRecentFilesPicker = 'workbench.action.quickOpenNavigatePreviousInRecentFilesPicker'; - KeybindingsRegistry.registerCommandAndKeybindingRule({ - id: quickOpenNavigatePreviousInRecentFilesPicker, - weight: KeybindingWeight.WorkbenchContrib + 50, - handler: getQuickNavigateHandler(quickOpenNavigatePreviousInRecentFilesPicker, false), - when: recentFilesPickerContext, - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_R, - mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KEY_R } - }); })(); // Actions: View @@ -79,7 +43,6 @@ import product from 'vs/platform/product/node/product'; registry.registerWorkbenchAction(new SyncActionDescriptor(ZoomInAction, ZoomInAction.ID, ZoomInAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_EQUAL, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_EQUAL, KeyMod.CtrlCmd | KeyCode.NUMPAD_ADD] }), 'View: Zoom In', viewCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(ZoomOutAction, ZoomOutAction.ID, ZoomOutAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_MINUS, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_MINUS, KeyMod.CtrlCmd | KeyCode.NUMPAD_SUBTRACT], linux: { primary: KeyMod.CtrlCmd | KeyCode.US_MINUS, secondary: [KeyMod.CtrlCmd | KeyCode.NUMPAD_SUBTRACT] } }), 'View: Zoom Out', viewCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(ZoomResetAction, ZoomResetAction.ID, ZoomResetAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.NUMPAD_0 }), 'View: Reset Zoom', viewCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleFullScreenAction, ToggleFullScreenAction.ID, ToggleFullScreenAction.LABEL, { primary: KeyCode.F11, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_F } }), 'View: Toggle Full Screen', viewCategory); })(); // Actions: Window @@ -119,7 +82,6 @@ import product from 'vs/platform/product/node/product'; registry.registerWorkbenchAction(new SyncActionDescriptor(AddRootFolderAction, AddRootFolderAction.ID, AddRootFolderAction.LABEL), 'Workspaces: Add Folder to Workspace...', workspacesCategory, SupportsWorkspacesContext); registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalRemoveRootFolderAction, GlobalRemoveRootFolderAction.ID, GlobalRemoveRootFolderAction.LABEL), 'Workspaces: Remove Folder from Workspace...', workspacesCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenWorkspaceAction, OpenWorkspaceAction.ID, OpenWorkspaceAction.LABEL), 'Workspaces: Open Workspace...', workspacesCategory, SupportsWorkspacesContext); registry.registerWorkbenchAction(new SyncActionDescriptor(SaveWorkspaceAsAction, SaveWorkspaceAsAction.ID, SaveWorkspaceAsAction.LABEL), 'Workspaces: Save Workspace As...', workspacesCategory, SupportsWorkspacesContext); registry.registerWorkbenchAction(new SyncActionDescriptor(DuplicateWorkspaceInNewWindowAction, DuplicateWorkspaceInNewWindowAction.ID, DuplicateWorkspaceInNewWindowAction.LABEL), 'Workspaces: Duplicate Workspace in New Window', workspacesCategory); @@ -161,20 +123,9 @@ import product from 'vs/platform/product/node/product'; (function registerDeveloperActions(): void { const developerCategory = nls.localize('developer', "Developer"); registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleSharedProcessAction, ToggleSharedProcessAction.ID, ToggleSharedProcessAction.LABEL), 'Developer: Toggle Shared Process', developerCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(InspectContextKeysAction, InspectContextKeysAction.ID, InspectContextKeysAction.LABEL), 'Developer: Inspect Context Keys', developerCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleScreencastModeAction, ToggleScreencastModeAction.ID, ToggleScreencastModeAction.LABEL), 'Developer: Toggle Screencast Mode', developerCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(ReloadWindowWithExtensionsDisabledAction, ReloadWindowWithExtensionsDisabledAction.ID, ReloadWindowWithExtensionsDisabledAction.LABEL), 'Developer: Reload Window With Extensions Disabled', developerCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(LogStorageAction, LogStorageAction.ID, LogStorageAction.LABEL), 'Developer: Log Storage Database Contents', developerCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(ReloadWindowAction, ReloadWindowAction.ID, ReloadWindowAction.LABEL), 'Developer: Reload Window', developerCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleDevToolsAction, ToggleDevToolsAction.ID, ToggleDevToolsAction.LABEL), 'Developer: Toggle Developer Tools', developerCategory); - KeybindingsRegistry.registerKeybindingRule({ - id: ReloadWindowAction.ID, - weight: KeybindingWeight.WorkbenchContrib + 50, - when: IsDevelopmentContext, - primary: KeyMod.CtrlCmd | KeyCode.KEY_R - }); - KeybindingsRegistry.registerKeybindingRule({ id: ToggleDevToolsAction.ID, weight: KeybindingWeight.WorkbenchContrib + 50, @@ -227,62 +178,6 @@ import product from 'vs/platform/product/node/product'; order: 2 }); - if (isMacintosh) { - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - group: '2_open', - command: { - id: OpenFileFolderAction.ID, - title: nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...") - }, - order: 1 - }); - } else { - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - group: '2_open', - command: { - id: OpenFileAction.ID, - title: nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File...") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - group: '2_open', - command: { - id: OpenFolderAction.ID, - title: nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder...") - }, - order: 2 - }); - } - - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - group: '2_open', - command: { - id: OpenWorkspaceAction.ID, - title: nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace...") - }, - order: 3, - when: SupportsWorkspacesContext - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - title: nls.localize({ key: 'miOpenRecent', comment: ['&& denotes a mnemonic'] }, "Open &&Recent"), - submenu: MenuId.MenubarRecentMenu, - group: '2_open', - order: 4 - }); - - // More - MenuRegistry.appendMenuItem(MenuId.MenubarRecentMenu, { - group: 'y_more', - command: { - id: OpenRecentAction.ID, - title: nls.localize({ key: 'miMore', comment: ['&& denotes a mnemonic'] }, "&&More...") - }, - order: 1 - }); - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { group: '3_workspace', command: { @@ -303,14 +198,6 @@ import product from 'vs/platform/product/node/product'; when: SupportsWorkspacesContext }); - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - title: nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences"), - submenu: MenuId.MenubarPreferencesMenu, - group: '5_autosave', - order: 2, - when: IsMacContext.toNegated() - }); - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { group: '6_close', command: { @@ -351,24 +238,6 @@ import product from 'vs/platform/product/node/product'; when: IsMacContext.toNegated() }); - // Appereance menu - MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { - group: '2_appearance', - title: nls.localize({ key: 'miAppearance', comment: ['&& denotes a mnemonic'] }, "&&Appearance"), - submenu: MenuId.MenubarAppearanceMenu, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, { - group: '1_toggle_view', - command: { - id: ToggleFullScreenAction.ID, - title: nls.localize({ key: 'miToggleFullScreen', comment: ['&& denotes a mnemonic'] }, "&&Full Screen"), - toggled: IsFullscreenContext - }, - order: 1 - }); - // Zoom MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, { @@ -552,18 +421,6 @@ import product from 'vs/platform/product/node/product'; nls.localize('openFilesInNewWindowMac', "Controls whether files should open in a new window. \nNote that there can still be cases where this setting is ignored (e.g. when using the `--new-window` or `--reuse-window` command line option).") : nls.localize('openFilesInNewWindow', "Controls whether files should open in a new window.\nNote that there can still be cases where this setting is ignored (e.g. when using the `--new-window` or `--reuse-window` command line option).") }, - 'window.openFoldersInNewWindow': { - 'type': 'string', - 'enum': ['on', 'off', 'default'], - 'enumDescriptions': [ - nls.localize('window.openFoldersInNewWindow.on', "Folders will open in a new window."), - nls.localize('window.openFoldersInNewWindow.off', "Folders will replace the last active window."), - nls.localize('window.openFoldersInNewWindow.default', "Folders will open in a new window unless a folder is picked from within the application (e.g. via the File menu).") - ], - 'default': 'default', - 'scope': ConfigurationScope.APPLICATION, - 'markdownDescription': nls.localize('openFoldersInNewWindow', "Controls whether folders should open in a new window or replace the last active window.\nNote that there can still be cases where this setting is ignored (e.g. when using the `--new-window` or `--reuse-window` command line option).") - }, 'window.openWithoutArgumentsInNewWindow': { 'type': 'string', 'enum': ['on', 'off'], @@ -617,27 +474,6 @@ import product from 'vs/platform/product/node/product'; 'default': false, 'description': nls.localize('closeWhenEmpty', "Controls whether closing the last editor should also close the window. This setting only applies for windows that do not show folders.") }, - 'window.menuBarVisibility': { - 'type': 'string', - 'enum': ['default', 'visible', 'toggle', 'hidden'], - 'enumDescriptions': [ - nls.localize('window.menuBarVisibility.default', "Menu is only hidden in full screen mode."), - nls.localize('window.menuBarVisibility.visible', "Menu is always visible even in full screen mode."), - nls.localize('window.menuBarVisibility.toggle', "Menu is hidden but can be displayed via Alt key."), - nls.localize('window.menuBarVisibility.hidden', "Menu is always hidden.") - ], - 'default': 'default', - 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('menuBarVisibility', "Control the visibility of the menu bar. A setting of 'toggle' means that the menu bar is hidden and a single press of the Alt key will show it. By default, the menu bar will be visible, unless the window is full screen."), - 'included': isWindows || isLinux - }, - 'window.enableMenuBarMnemonics': { - 'type': 'boolean', - 'default': true, - 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('enableMenuBarMnemonics', "If enabled, the main menus can be opened via Alt-key shortcuts. Disabling mnemonics allows to bind these Alt-key shortcuts to editor commands instead."), - 'included': isWindows || isLinux - }, 'window.autoDetectHighContrast': { 'type': 'boolean', 'default': true, @@ -670,7 +506,7 @@ import product from 'vs/platform/product/node/product'; 'default': true, 'description': nls.localize('window.nativeFullScreen', "Controls if native full-screen should be used on macOS. Disable this option to prevent macOS from creating a new space when going full-screen."), 'scope': ConfigurationScope.APPLICATION, - 'included': isMacintosh + 'included': false /* isMacintosh */ }, 'window.clickThroughInactive': { 'type': 'boolean', diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 39a00efc7eb..61c920df264 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -19,16 +19,15 @@ import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/n import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { stat } from 'vs/base/node/pfs'; -import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService'; +import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/nativeKeymapService'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { webFrame } from 'electron'; import { ISingleFolderWorkspaceIdentifier, IWorkspaceInitializationPayload, ISingleFolderWorkspaceInitializationPayload, reviveWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { ConsoleLogService, MultiplexLogService, ILogService } from 'vs/platform/log/common/log'; import { StorageService } from 'vs/platform/storage/node/storageService'; -import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/node/logIpc'; +import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/common/logIpc'; import { Schemas } from 'vs/base/common/network'; import { sanitizeFilePath } from 'vs/base/common/extpath'; -import { basename } from 'vs/base/common/path'; import { GlobalStorageDatabaseChannelClient } from 'vs/platform/storage/node/storageIpc'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -40,24 +39,27 @@ import { RemoteAuthorityResolverService } from 'vs/platform/remote/electron-brow import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; -import { FileService } from 'vs/workbench/services/files/common/fileService'; +import { FileService } from 'vs/platform/files/common/fileService'; import { IFileService } from 'vs/platform/files/common/files'; -import { DiskFileSystemProvider } from 'vs/workbench/services/files/electron-browser/diskFileSystemProvider'; +import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { REMOTE_FILE_SYSTEM_CHANNEL_NAME, RemoteExtensionsFileSystemProvider } from 'vs/platform/remote/common/remoteAgentFileSystemChannel'; import { DefaultConfigurationExportHelper } from 'vs/workbench/services/configuration/node/configurationExportHelper'; import { ConfigurationCache } from 'vs/workbench/services/configuration/node/configurationCache'; -import { ConfigurationFileService } from 'vs/workbench/services/configuration/node/configurationFileService'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; import { SignService } from 'vs/platform/sign/node/signService'; import { ISignService } from 'vs/platform/sign/common/sign'; +import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; +import { basename } from 'vs/base/common/resources'; class CodeRendererMain extends Disposable { private workbench: Workbench; + private readonly environmentService: WorkbenchEnvironmentService; - constructor(private readonly configuration: IWindowConfiguration) { + constructor(configuration: IWindowConfiguration) { super(); + this.environmentService = new WorkbenchEnvironmentService(configuration, configuration.execPath); this.init(); } @@ -71,29 +73,29 @@ class CodeRendererMain extends Disposable { this.reviveUris(); // Setup perf - importEntries(this.configuration.perfEntries); + importEntries(this.environmentService.configuration.perfEntries); // Browser config setZoomFactor(webFrame.getZoomFactor()); // Ensure others can listen to zoom level changes setZoomLevel(webFrame.getZoomLevel(), true /* isTrusted */); // Can be trusted because we are not setting it ourselves (https://github.com/Microsoft/vscode/issues/26151) - setFullscreen(!!this.configuration.fullscreen); + setFullscreen(!!this.environmentService.configuration.fullscreen); // Keyboard support KeyboardMapperFactory.INSTANCE._onKeyboardLayoutChanged(); } private reviveUris() { - if (this.configuration.folderUri) { - this.configuration.folderUri = URI.revive(this.configuration.folderUri); + if (this.environmentService.configuration.folderUri) { + this.environmentService.configuration.folderUri = URI.revive(this.environmentService.configuration.folderUri); } - if (this.configuration.workspace) { - this.configuration.workspace = reviveWorkspaceIdentifier(this.configuration.workspace); + if (this.environmentService.configuration.workspace) { + this.environmentService.configuration.workspace = reviveWorkspaceIdentifier(this.environmentService.configuration.workspace); } - const filesToWait = this.configuration.filesToWait; + const filesToWait = this.environmentService.configuration.filesToWait; const filesToWaitPaths = filesToWait && filesToWait.paths; - [filesToWaitPaths, this.configuration.filesToOpenOrCreate, this.configuration.filesToDiff].forEach(paths => { + [filesToWaitPaths, this.environmentService.configuration.filesToOpenOrCreate, this.environmentService.configuration.filesToDiff].forEach(paths => { if (Array.isArray(paths)) { paths.forEach(path => { if (path.fileUri) { @@ -130,17 +132,17 @@ class CodeRendererMain extends Disposable { this._register(instantiationService.createInstance(ElectronWindow)); // Driver - if (this.configuration.driver) { + if (this.environmentService.configuration.driver) { instantiationService.invokeFunction(async accessor => this._register(await registerWindowDriver(accessor))); } // Config Exporter - if (this.configuration['export-default-configuration']) { + if (this.environmentService.configuration['export-default-configuration']) { instantiationService.createInstance(DefaultConfigurationExportHelper); } // Logging - services.logService.trace('workbench configuration', JSON.stringify(this.configuration)); + services.logService.trace('workbench configuration', JSON.stringify(this.environmentService.configuration)); } private onWindowResize(e: Event, retry: boolean): void { @@ -170,15 +172,14 @@ class CodeRendererMain extends Disposable { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Main Process - const mainProcessService = this._register(new MainProcessService(this.configuration.windowId)); + const mainProcessService = this._register(new MainProcessService(this.environmentService.configuration.windowId)); serviceCollection.set(IMainProcessService, mainProcessService); // Environment - const environmentService = new WorkbenchEnvironmentService(this.configuration, this.configuration.execPath); - serviceCollection.set(IWorkbenchEnvironmentService, environmentService); + serviceCollection.set(IWorkbenchEnvironmentService, this.environmentService); // Log - const logService = this._register(this.createLogService(mainProcessService, environmentService)); + const logService = this._register(this.createLogService(mainProcessService, this.environmentService)); serviceCollection.set(ILogService, logService); // Remote @@ -189,7 +190,7 @@ class CodeRendererMain extends Disposable { const signService = new SignService(); serviceCollection.set(ISignService, signService); - const remoteAgentService = this._register(new RemoteAgentService(this.configuration, environmentService, remoteAuthorityResolverService, signService)); + const remoteAgentService = this._register(new RemoteAgentService(this.environmentService.configuration, this.environmentService, remoteAuthorityResolverService, signService)); serviceCollection.set(IRemoteAgentService, remoteAgentService); // Files @@ -199,6 +200,9 @@ class CodeRendererMain extends Disposable { const diskFileSystemProvider = this._register(new DiskFileSystemProvider(logService)); fileService.registerProvider(Schemas.file, diskFileSystemProvider); + // User Data Provider + fileService.registerProvider(Schemas.userData, new FileUserDataProvider(this.environmentService.appSettingsHome, this.environmentService.backupHome, diskFileSystemProvider, this.environmentService)); + const connection = remoteAgentService.getConnection(); if (connection) { const channel = connection.getChannel(REMOTE_FILE_SYSTEM_CHANNEL_NAME); @@ -206,10 +210,10 @@ class CodeRendererMain extends Disposable { fileService.registerProvider(Schemas.vscodeRemote, remoteFileSystemProvider); } - const payload = await this.resolveWorkspaceInitializationPayload(environmentService); + const payload = await this.resolveWorkspaceInitializationPayload(); const services = await Promise.all([ - this.createWorkspaceService(payload, environmentService, fileService, remoteAgentService, logService).then(service => { + this.createWorkspaceService(payload, fileService, remoteAgentService, logService).then(service => { // Workspace serviceCollection.set(IWorkspaceContextService, service); @@ -220,7 +224,7 @@ class CodeRendererMain extends Disposable { return service; }), - this.createStorageService(payload, environmentService, logService, mainProcessService).then(service => { + this.createStorageService(payload, logService, mainProcessService).then(service => { // Storage serviceCollection.set(IStorageService, service); @@ -232,25 +236,25 @@ class CodeRendererMain extends Disposable { return { serviceCollection, logService, storageService: services[1] }; } - private async resolveWorkspaceInitializationPayload(environmentService: IWorkbenchEnvironmentService): Promise { + private async resolveWorkspaceInitializationPayload(): Promise { // Multi-root workspace - if (this.configuration.workspace) { - return this.configuration.workspace; + if (this.environmentService.configuration.workspace) { + return this.environmentService.configuration.workspace; } // Single-folder workspace let workspaceInitializationPayload: IWorkspaceInitializationPayload | undefined; - if (this.configuration.folderUri) { - workspaceInitializationPayload = await this.resolveSingleFolderWorkspaceInitializationPayload(this.configuration.folderUri); + if (this.environmentService.configuration.folderUri) { + workspaceInitializationPayload = await this.resolveSingleFolderWorkspaceInitializationPayload(this.environmentService.configuration.folderUri); } // Fallback to empty workspace if we have no payload yet. if (!workspaceInitializationPayload) { let id: string; - if (this.configuration.backupPath) { - id = basename(this.configuration.backupPath); // we know the backupPath must be a unique path so we leverage its name as workspace ID - } else if (environmentService.isExtensionDevelopment) { + if (this.environmentService.configuration.backupWorkspaceResource) { + id = basename(this.environmentService.configuration.backupWorkspaceResource); // we know the backupPath must be a unique path so we leverage its name as workspace ID + } else if (this.environmentService.isExtensionDevelopment) { id = 'ext-dev'; // extension development window never stores backups and is a singleton } else { throw new Error('Unexpected window configuration without backupPath'); @@ -305,11 +309,8 @@ class CodeRendererMain extends Disposable { return; } - private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; - - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); + private async createWorkspaceService(payload: IWorkspaceInitializationPayload, fileService: FileService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { + const workspaceService = new WorkspaceService({ remoteAuthority: this.environmentService.configuration.remoteAuthority, configurationCache: new ConfigurationCache(this.environmentService) }, this.environmentService, fileService, remoteAgentService); try { await workspaceService.initialize(payload); @@ -323,9 +324,9 @@ class CodeRendererMain extends Disposable { } } - private async createStorageService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, logService: ILogService, mainProcessService: IMainProcessService): Promise { + private async createStorageService(payload: IWorkspaceInitializationPayload, logService: ILogService, mainProcessService: IMainProcessService): Promise { const globalStorageDatabase = new GlobalStorageDatabaseChannelClient(mainProcessService.getChannel('storage')); - const storageService = new StorageService(globalStorageDatabase, logService, environmentService); + const storageService = new StorageService(globalStorageDatabase, logService, this.environmentService); try { await storageService.initialize(payload); @@ -340,8 +341,8 @@ class CodeRendererMain extends Disposable { } private createLogService(mainProcessService: IMainProcessService, environmentService: IWorkbenchEnvironmentService): ILogService { - const spdlogService = new SpdLogService(`renderer${this.configuration.windowId}`, environmentService.logsPath, this.configuration.logLevel); - const consoleLogService = new ConsoleLogService(this.configuration.logLevel); + const spdlogService = new SpdLogService(`renderer${this.environmentService.configuration.windowId}`, environmentService.logsPath, this.environmentService.configuration.logLevel); + const consoleLogService = new ConsoleLogService(this.environmentService.configuration.logLevel); const logService = new MultiplexLogService([consoleLogService, spdlogService]); const logLevelClient = new LogLevelSetterChannelClient(mainProcessService.getChannel('loglevel')); diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index 6b58a8de754..d3c48734060 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -21,12 +21,12 @@ import { IWorkbenchThemeService, VS_HC_THEME } from 'vs/workbench/services/theme import * as browser from 'vs/base/browser/browser'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IResourceInput } from 'vs/platform/editor/common/editor'; -import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService'; +import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/nativeKeymapService'; import { ipcRenderer as ipc, webFrame, crashReporter, Event } from 'electron'; import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; import { IMenuService, MenuId, IMenu, MenuItemAction, ICommandAction } from 'vs/platform/actions/common/actions'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { fillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; +import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { RunOnceScheduler } from 'vs/base/common/async'; import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { LifecyclePhase, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; @@ -369,7 +369,7 @@ export class ElectronWindow extends Disposable { const actions: Array = []; // Fill actions into groups respecting order - fillInActionBarActions(this.touchBarMenu, undefined, actions); + this.touchBarDisposables.add(createAndFillInActionBarActions(this.touchBarMenu, undefined, actions)); // Convert into command action multi array const items: ICommandAction[][] = []; @@ -408,7 +408,7 @@ export class ElectronWindow extends Disposable { const options = { companyName: product.crashReporter.companyName, productName: product.crashReporter.productName, - submitURL: isWindows ? product.hockeyApp[`win32-${process.arch}`] : isLinux ? product.hockeyApp[`linux-${process.arch}`] : product.hockeyApp.darwin, + submitURL: isWindows ? product.hockeyApp[process.arch === 'ia32' ? 'win32-ia32' : 'win32-x64'] : isLinux ? product.hockeyApp[`linux-x64`] : product.hockeyApp.darwin, extra: { vscode_version: pkg.version, vscode_commit: product.commit diff --git a/src/vs/workbench/services/backup/common/backup.ts b/src/vs/workbench/services/backup/common/backup.ts index 9d1b0208434..771cba84a18 100644 --- a/src/vs/workbench/services/backup/common/backup.ts +++ b/src/vs/workbench/services/backup/common/backup.ts @@ -4,8 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import { URI } from 'vs/base/common/uri'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { ITextBufferFactory, ITextSnapshot } from 'vs/editor/common/model'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { joinPath, relativePath } from 'vs/base/common/resources'; export const IBackupFileService = createDecorator('backupFileService'); @@ -18,13 +20,19 @@ export interface IResolvedBackup { * A service that handles any I/O and state associated with the backup system. */ export interface IBackupFileService { - _serviceBrand: any; + + _serviceBrand: ServiceIdentifier; /** * Finds out if there are any backups stored. */ hasBackups(): Promise; + /** + * Finds out if the provided resource with the given version is backed up. + */ + hasBackupSync(resource: URI, versionId?: number): boolean; + /** * Loads the backup resource for a particular resource within the current workspace. * @@ -80,3 +88,7 @@ export interface IBackupFileService { */ discardAllWorkspaceBackups(): Promise; } + +export function toBackupWorkspaceResource(backupWorkspacePath: string, environmentService: IEnvironmentService): URI { + return joinPath(environmentService.userRoamingDataHome, relativePath(URI.file(environmentService.userDataPath), URI.file(backupWorkspacePath))!); +} \ No newline at end of file diff --git a/src/vs/workbench/services/backup/common/backupFileService.ts b/src/vs/workbench/services/backup/common/backupFileService.ts new file mode 100644 index 00000000000..3193fee9594 --- /dev/null +++ b/src/vs/workbench/services/backup/common/backupFileService.ts @@ -0,0 +1,443 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { join } from 'vs/base/common/path'; +import { joinPath } from 'vs/base/common/resources'; +import { URI } from 'vs/base/common/uri'; +import { hash } from 'vs/base/common/hash'; +import { coalesce } from 'vs/base/common/arrays'; +import { equals, deepClone } from 'vs/base/common/objects'; +import { ResourceQueue } from 'vs/base/common/async'; +import { IBackupFileService, IResolvedBackup } from 'vs/workbench/services/backup/common/backup'; +import { IFileService } from 'vs/platform/files/common/files'; +import { ITextSnapshot } from 'vs/editor/common/model'; +import { createTextBufferFactoryFromStream, createTextBufferFactoryFromSnapshot } from 'vs/editor/common/model/textModel'; +import { keys, ResourceMap } from 'vs/base/common/map'; +import { Schemas } from 'vs/base/common/network'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { TextSnapshotReadable } from 'vs/workbench/services/textfile/common/textfiles'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; + +export interface IBackupFilesModel { + resolve(backupRoot: URI): Promise; + + add(resource: URI, versionId?: number, meta?: object): void; + has(resource: URI, versionId?: number, meta?: object): boolean; + get(): URI[]; + remove(resource: URI): void; + count(): number; + clear(): void; +} + +interface IBackupCacheEntry { + versionId?: number; + meta?: object; +} + +export class BackupFilesModel implements IBackupFilesModel { + private cache: ResourceMap = new ResourceMap(); + + constructor(private fileService: IFileService) { } + + async resolve(backupRoot: URI): Promise { + try { + const backupRootStat = await this.fileService.resolve(backupRoot); + if (backupRootStat.children) { + await Promise.all(backupRootStat.children + .filter(child => child.isDirectory) + .map(async backupSchema => { + + // Read backup directory for backups + const backupSchemaStat = await this.fileService.resolve(backupSchema.resource); + + // Remember known backups in our caches + if (backupSchemaStat.children) { + backupSchemaStat.children.forEach(backupHash => this.add(backupHash.resource)); + } + })); + } + } catch (error) { + // ignore any errors + } + + return this; + } + + add(resource: URI, versionId = 0, meta?: object): void { + this.cache.set(resource, { versionId, meta: deepClone(meta) }); // make sure to not store original meta in our cache... + } + + count(): number { + return this.cache.size; + } + + has(resource: URI, versionId?: number, meta?: object): boolean { + const entry = this.cache.get(resource); + if (!entry) { + return false; // unknown resource + } + + if (typeof versionId === 'number' && versionId !== entry.versionId) { + return false; // different versionId + } + + if (meta && !equals(meta, entry.meta)) { + return false; // different metadata + } + + return true; + } + + get(): URI[] { + return this.cache.keys(); + } + + remove(resource: URI): void { + this.cache.delete(resource); + } + + clear(): void { + this.cache.clear(); + } +} + +export class BackupFileService implements IBackupFileService { + + _serviceBrand: ServiceIdentifier; + + private impl: IBackupFileService; + + constructor( + @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, + @IFileService fileService: IFileService + ) { + const backupWorkspaceResource = environmentService.configuration.backupWorkspaceResource; + if (backupWorkspaceResource) { + this.impl = new BackupFileServiceImpl(backupWorkspaceResource, this.hashPath, fileService); + } else { + this.impl = new InMemoryBackupFileService(this.hashPath); + } + } + + protected hashPath(resource: URI): string { + const str = resource.scheme === Schemas.file || resource.scheme === Schemas.untitled ? resource.fsPath : resource.toString(); + + return hash(str).toString(16); + } + + initialize(backupWorkspaceResource: URI): void { + if (this.impl instanceof BackupFileServiceImpl) { + this.impl.initialize(backupWorkspaceResource); + } + } + + hasBackups(): Promise { + return this.impl.hasBackups(); + } + + hasBackupSync(resource: URI, versionId?: number): boolean { + return this.impl.hasBackupSync(resource, versionId); + } + + loadBackupResource(resource: URI): Promise { + return this.impl.loadBackupResource(resource); + } + + backupResource(resource: URI, content: ITextSnapshot, versionId?: number, meta?: T): Promise { + return this.impl.backupResource(resource, content, versionId, meta); + } + + discardResourceBackup(resource: URI): Promise { + return this.impl.discardResourceBackup(resource); + } + + discardAllWorkspaceBackups(): Promise { + return this.impl.discardAllWorkspaceBackups(); + } + + getWorkspaceFileBackups(): Promise { + return this.impl.getWorkspaceFileBackups(); + } + + resolveBackupContent(backup: URI): Promise> { + return this.impl.resolveBackupContent(backup); + } + + toBackupResource(resource: URI): URI { + return this.impl.toBackupResource(resource); + } +} + +class BackupFileServiceImpl implements IBackupFileService { + + private static readonly PREAMBLE_END_MARKER = '\n'; + private static readonly PREAMBLE_META_SEPARATOR = ' '; // using a character that is know to be escaped in a URI as separator + private static readonly PREAMBLE_MAX_LENGTH = 10000; + + _serviceBrand: ServiceIdentifier; + + private backupWorkspacePath: URI; + + private isShuttingDown: boolean; + private ioOperationQueues: ResourceQueue; // queue IO operations to ensure write order + + private ready: Promise; + private model: IBackupFilesModel; + + constructor( + backupWorkspaceResource: URI, + private readonly hashPath: (resource: URI) => string, + @IFileService private readonly fileService: IFileService + ) { + this.isShuttingDown = false; + this.ioOperationQueues = new ResourceQueue(); + + this.initialize(backupWorkspaceResource); + } + + initialize(backupWorkspaceResource: URI): void { + this.backupWorkspacePath = backupWorkspaceResource; + + this.ready = this.init(); + } + + private init(): Promise { + this.model = new BackupFilesModel(this.fileService); + + return this.model.resolve(this.backupWorkspacePath); + } + + async hasBackups(): Promise { + const model = await this.ready; + + return model.count() > 0; + } + + hasBackupSync(resource: URI, versionId?: number): boolean { + const backupResource = this.toBackupResource(resource); + + return this.model.has(backupResource, versionId); + } + + async loadBackupResource(resource: URI): Promise { + const model = await this.ready; + + // Return directly if we have a known backup with that resource + const backupResource = this.toBackupResource(resource); + if (model.has(backupResource)) { + return backupResource; + } + + return undefined; + } + + async backupResource(resource: URI, content: ITextSnapshot, versionId?: number, meta?: T): Promise { + if (this.isShuttingDown) { + return; + } + + const model = await this.ready; + + const backupResource = this.toBackupResource(resource); + if (model.has(backupResource, versionId, meta)) { + return; // return early if backup version id matches requested one + } + + return this.ioOperationQueues.queueFor(backupResource).queue(async () => { + let preamble: string | undefined = undefined; + + // With Metadata: URI + META-START + Meta + END + if (meta) { + const preambleWithMeta = `${resource.toString()}${BackupFileServiceImpl.PREAMBLE_META_SEPARATOR}${JSON.stringify(meta)}${BackupFileServiceImpl.PREAMBLE_END_MARKER}`; + if (preambleWithMeta.length < BackupFileServiceImpl.PREAMBLE_MAX_LENGTH) { + preamble = preambleWithMeta; + } + } + + // Without Metadata: URI + END + if (!preamble) { + preamble = `${resource.toString()}${BackupFileServiceImpl.PREAMBLE_END_MARKER}`; + } + + // Update content with value + await this.fileService.writeFile(backupResource, new TextSnapshotReadable(content, preamble)); + + // Update model + model.add(backupResource, versionId, meta); + }); + } + + async discardResourceBackup(resource: URI): Promise { + const model = await this.ready; + const backupResource = this.toBackupResource(resource); + + return this.ioOperationQueues.queueFor(backupResource).queue(async () => { + await this.fileService.del(backupResource, { recursive: true }); + + model.remove(backupResource); + }); + } + + async discardAllWorkspaceBackups(): Promise { + this.isShuttingDown = true; + + const model = await this.ready; + + await this.fileService.del(this.backupWorkspacePath, { recursive: true }); + + model.clear(); + } + + async getWorkspaceFileBackups(): Promise { + const model = await this.ready; + + const backups = await Promise.all(model.get().map(async fileBackup => { + const backupPreamble = await this.readToMatchingString(fileBackup, BackupFileServiceImpl.PREAMBLE_END_MARKER, BackupFileServiceImpl.PREAMBLE_MAX_LENGTH); + if (!backupPreamble) { + return undefined; + } + + // Preamble with metadata: URI + META-START + Meta + END + const metaStartIndex = backupPreamble.indexOf(BackupFileServiceImpl.PREAMBLE_META_SEPARATOR); + if (metaStartIndex > 0) { + return URI.parse(backupPreamble.substring(0, metaStartIndex)); + } + + // Preamble without metadata: URI + END + else { + return URI.parse(backupPreamble); + } + })); + + return coalesce(backups); + } + + private async readToMatchingString(file: URI, matchingString: string, maximumBytesToRead: number): Promise { + const contents = (await this.fileService.readFile(file, { length: maximumBytesToRead })).value.toString(); + + const newLineIndex = contents.indexOf(matchingString); + if (newLineIndex >= 0) { + return contents.substr(0, newLineIndex); + } + + throw new Error(`Could not find ${JSON.stringify(matchingString)} in first ${maximumBytesToRead} bytes of ${file}`); + } + + async resolveBackupContent(backup: URI): Promise> { + + // Metadata extraction + let metaRaw = ''; + let metaEndFound = false; + + // Add a filter method to filter out everything until the meta end marker + const metaPreambleFilter = (chunk: VSBuffer) => { + const chunkString = chunk.toString(); + + if (!metaEndFound) { + const metaEndIndex = chunkString.indexOf(BackupFileServiceImpl.PREAMBLE_END_MARKER); + if (metaEndIndex === -1) { + metaRaw += chunkString; + + return VSBuffer.fromString(''); // meta not yet found, return empty string + } + + metaEndFound = true; + metaRaw += chunkString.substring(0, metaEndIndex); // ensure to get last chunk from metadata + + return VSBuffer.fromString(chunkString.substr(metaEndIndex + 1)); // meta found, return everything after + } + + return chunk; + }; + + // Read backup into factory + const content = await this.fileService.readFileStream(backup); + const factory = await createTextBufferFactoryFromStream(content.value, metaPreambleFilter); + + // Trigger read for meta data extraction from the filter above + factory.getFirstLineText(1); + + let meta: T | undefined; + const metaStartIndex = metaRaw.indexOf(BackupFileServiceImpl.PREAMBLE_META_SEPARATOR); + if (metaStartIndex !== -1) { + try { + meta = JSON.parse(metaRaw.substr(metaStartIndex + 1)); + } catch (error) { + // ignore JSON parse errors + } + } + + return { value: factory, meta }; + } + + toBackupResource(resource: URI): URI { + return joinPath(this.backupWorkspacePath, resource.scheme, this.hashPath(resource)); + } +} + +export class InMemoryBackupFileService implements IBackupFileService { + + _serviceBrand: ServiceIdentifier; + + private backups: Map = new Map(); + + constructor(private readonly hashPath: (resource: URI) => string) { } + + hasBackups(): Promise { + return Promise.resolve(this.backups.size > 0); + } + + hasBackupSync(resource: URI, versionId?: number): boolean { + const backupResource = this.toBackupResource(resource); + + return this.backups.has(backupResource.toString()); + } + + loadBackupResource(resource: URI): Promise { + const backupResource = this.toBackupResource(resource); + if (this.backups.has(backupResource.toString())) { + return Promise.resolve(backupResource); + } + + return Promise.resolve(undefined); + } + + backupResource(resource: URI, content: ITextSnapshot, versionId?: number, meta?: T): Promise { + const backupResource = this.toBackupResource(resource); + this.backups.set(backupResource.toString(), content); + + return Promise.resolve(); + } + + resolveBackupContent(backupResource: URI): Promise> { + const snapshot = this.backups.get(backupResource.toString()); + if (snapshot) { + return Promise.resolve({ value: createTextBufferFactoryFromSnapshot(snapshot) }); + } + + return Promise.reject('Unexpected backup resource to resolve'); + } + + getWorkspaceFileBackups(): Promise { + return Promise.resolve(keys(this.backups).map(key => URI.parse(key))); + } + + discardResourceBackup(resource: URI): Promise { + this.backups.delete(this.toBackupResource(resource).toString()); + + return Promise.resolve(); + } + + discardAllWorkspaceBackups(): Promise { + this.backups.clear(); + + return Promise.resolve(); + } + + toBackupResource(resource: URI): URI { + return URI.file(join(resource.scheme, this.hashPath(resource))); + } +} \ No newline at end of file diff --git a/src/vs/workbench/services/backup/node/backupFileService.ts b/src/vs/workbench/services/backup/node/backupFileService.ts index 624ec71cad0..30b5c5acf51 100644 --- a/src/vs/workbench/services/backup/node/backupFileService.ts +++ b/src/vs/workbench/services/backup/node/backupFileService.ts @@ -3,407 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { join } from 'vs/base/common/path'; -import { joinPath } from 'vs/base/common/resources'; -import { createHash } from 'crypto'; +import { BackupFileService as CommonBackupFileService } from 'vs/workbench/services/backup/common/backupFileService'; import { URI } from 'vs/base/common/uri'; -import { coalesce } from 'vs/base/common/arrays'; -import { equals, deepClone } from 'vs/base/common/objects'; -import { ResourceQueue } from 'vs/base/common/async'; -import { IBackupFileService, IResolvedBackup } from 'vs/workbench/services/backup/common/backup'; -import { IFileService } from 'vs/platform/files/common/files'; -import { readToMatchingString } from 'vs/base/node/stream'; -import { ITextSnapshot } from 'vs/editor/common/model'; -import { createTextBufferFactoryFromStream, createTextBufferFactoryFromSnapshot } from 'vs/editor/common/model/textModel'; -import { keys, ResourceMap } from 'vs/base/common/map'; import { Schemas } from 'vs/base/common/network'; -import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { VSBuffer } from 'vs/base/common/buffer'; -import { TextSnapshotReadable } from 'vs/workbench/services/textfile/common/textfiles'; -import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import * as crypto from 'crypto'; -export interface IBackupFilesModel { - resolve(backupRoot: URI): Promise; +export class BackupFileService extends CommonBackupFileService { - add(resource: URI, versionId?: number, meta?: object): void; - has(resource: URI, versionId?: number, meta?: object): boolean; - get(): URI[]; - remove(resource: URI): void; - count(): number; - clear(): void; -} - -interface IBackupCacheEntry { - versionId?: number; - meta?: object; -} - -export class BackupFilesModel implements IBackupFilesModel { - private cache: ResourceMap = new ResourceMap(); - - constructor(private fileService: IFileService) { } - - async resolve(backupRoot: URI): Promise { - try { - const backupRootStat = await this.fileService.resolve(backupRoot); - if (backupRootStat.children) { - await Promise.all(backupRootStat.children - .filter(child => child.isDirectory) - .map(async backupSchema => { - - // Read backup directory for backups - const backupSchemaStat = await this.fileService.resolve(backupSchema.resource); - - // Remember known backups in our caches - if (backupSchemaStat.children) { - backupSchemaStat.children.forEach(backupHash => this.add(backupHash.resource)); - } - })); - } - } catch (error) { - // ignore any errors - } - - return this; + protected hashPath(resource: URI): string { + return hashPath(resource); } - add(resource: URI, versionId = 0, meta?: object): void { - this.cache.set(resource, { versionId, meta: deepClone(meta) }); // make sure to not store original meta in our cache... - } - - count(): number { - return this.cache.size; - } - - has(resource: URI, versionId?: number, meta?: object): boolean { - const entry = this.cache.get(resource); - if (!entry) { - return false; // unknown resource - } - - if (typeof versionId === 'number' && versionId !== entry.versionId) { - return false; // different versionId - } - - if (meta && !equals(meta, entry.meta)) { - return false; // different metadata - } - - return true; - } - - get(): URI[] { - return this.cache.keys(); - } - - remove(resource: URI): void { - this.cache.delete(resource); - } - - clear(): void { - this.cache.clear(); - } -} - -export class BackupFileService implements IBackupFileService { - - _serviceBrand: ServiceIdentifier; - - private impl: IBackupFileService; - - constructor( - @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, - @IFileService fileService: IFileService - ) { - const backupWorkspacePath = environmentService.configuration.backupPath; - if (backupWorkspacePath) { - this.impl = new BackupFileServiceImpl(backupWorkspacePath, fileService); - } else { - this.impl = new InMemoryBackupFileService(); - } - } - - initialize(backupWorkspacePath: string): void { - if (this.impl instanceof BackupFileServiceImpl) { - this.impl.initialize(backupWorkspacePath); - } - } - - hasBackups(): Promise { - return this.impl.hasBackups(); - } - - loadBackupResource(resource: URI): Promise { - return this.impl.loadBackupResource(resource); - } - - backupResource(resource: URI, content: ITextSnapshot, versionId?: number, meta?: T): Promise { - return this.impl.backupResource(resource, content, versionId, meta); - } - - discardResourceBackup(resource: URI): Promise { - return this.impl.discardResourceBackup(resource); - } - - discardAllWorkspaceBackups(): Promise { - return this.impl.discardAllWorkspaceBackups(); - } - - getWorkspaceFileBackups(): Promise { - return this.impl.getWorkspaceFileBackups(); - } - - resolveBackupContent(backup: URI): Promise> { - return this.impl.resolveBackupContent(backup); - } - - toBackupResource(resource: URI): URI { - return this.impl.toBackupResource(resource); - } -} - -class BackupFileServiceImpl implements IBackupFileService { - - private static readonly PREAMBLE_END_MARKER = '\n'; - private static readonly PREAMBLE_META_SEPARATOR = ' '; // using a character that is know to be escaped in a URI as separator - private static readonly PREAMBLE_MAX_LENGTH = 10000; - - _serviceBrand: any; - - private backupWorkspacePath: URI; - - private isShuttingDown: boolean; - private ready: Promise; - private ioOperationQueues: ResourceQueue; // queue IO operations to ensure write order - - constructor( - backupWorkspacePath: string, - @IFileService private readonly fileService: IFileService - ) { - this.isShuttingDown = false; - this.ioOperationQueues = new ResourceQueue(); - - this.initialize(backupWorkspacePath); - } - - initialize(backupWorkspacePath: string): void { - this.backupWorkspacePath = URI.file(backupWorkspacePath); - - this.ready = this.init(); - } - - private init(): Promise { - const model = new BackupFilesModel(this.fileService); - - return model.resolve(this.backupWorkspacePath); - } - - async hasBackups(): Promise { - const model = await this.ready; - - return model.count() > 0; - } - - async loadBackupResource(resource: URI): Promise { - const model = await this.ready; - - // Return directly if we have a known backup with that resource - const backupResource = this.toBackupResource(resource); - if (model.has(backupResource)) { - return backupResource; - } - - return undefined; - } - - async backupResource(resource: URI, content: ITextSnapshot, versionId?: number, meta?: T): Promise { - if (this.isShuttingDown) { - return; - } - - const model = await this.ready; - - const backupResource = this.toBackupResource(resource); - if (model.has(backupResource, versionId, meta)) { - return; // return early if backup version id matches requested one - } - - return this.ioOperationQueues.queueFor(backupResource).queue(async () => { - let preamble: string | undefined = undefined; - - // With Metadata: URI + META-START + Meta + END - if (meta) { - const preambleWithMeta = `${resource.toString()}${BackupFileServiceImpl.PREAMBLE_META_SEPARATOR}${JSON.stringify(meta)}${BackupFileServiceImpl.PREAMBLE_END_MARKER}`; - if (preambleWithMeta.length < BackupFileServiceImpl.PREAMBLE_MAX_LENGTH) { - preamble = preambleWithMeta; - } - } - - // Without Metadata: URI + END - if (!preamble) { - preamble = `${resource.toString()}${BackupFileServiceImpl.PREAMBLE_END_MARKER}`; - } - - // Update content with value - await this.fileService.writeFile(backupResource, new TextSnapshotReadable(content, preamble)); - - // Update model - model.add(backupResource, versionId, meta); - }); - } - - async discardResourceBackup(resource: URI): Promise { - const model = await this.ready; - const backupResource = this.toBackupResource(resource); - - return this.ioOperationQueues.queueFor(backupResource).queue(async () => { - await this.fileService.del(backupResource, { recursive: true }); - - model.remove(backupResource); - }); - } - - async discardAllWorkspaceBackups(): Promise { - this.isShuttingDown = true; - - const model = await this.ready; - - await this.fileService.del(this.backupWorkspacePath, { recursive: true }); - - model.clear(); - } - - async getWorkspaceFileBackups(): Promise { - const model = await this.ready; - - const backups = await Promise.all(model.get().map(async fileBackup => { - const backupPreamble = await readToMatchingString(fileBackup.fsPath, BackupFileServiceImpl.PREAMBLE_END_MARKER, BackupFileServiceImpl.PREAMBLE_MAX_LENGTH / 5, BackupFileServiceImpl.PREAMBLE_MAX_LENGTH); - if (!backupPreamble) { - return undefined; - } - - // Preamble with metadata: URI + META-START + Meta + END - const metaStartIndex = backupPreamble.indexOf(BackupFileServiceImpl.PREAMBLE_META_SEPARATOR); - if (metaStartIndex > 0) { - return URI.parse(backupPreamble.substring(0, metaStartIndex)); - } - - // Preamble without metadata: URI + END - else { - return URI.parse(backupPreamble); - } - })); - - return coalesce(backups); - } - - async resolveBackupContent(backup: URI): Promise> { - - // Metadata extraction - let metaRaw = ''; - let metaEndFound = false; - - // Add a filter method to filter out everything until the meta end marker - const metaPreambleFilter = (chunk: VSBuffer) => { - const chunkString = chunk.toString(); - - if (!metaEndFound) { - const metaEndIndex = chunkString.indexOf(BackupFileServiceImpl.PREAMBLE_END_MARKER); - if (metaEndIndex === -1) { - metaRaw += chunkString; - - return VSBuffer.fromString(''); // meta not yet found, return empty string - } - - metaEndFound = true; - metaRaw += chunkString.substring(0, metaEndIndex); // ensure to get last chunk from metadata - - return VSBuffer.fromString(chunkString.substr(metaEndIndex + 1)); // meta found, return everything after - } - - return chunk; - }; - - // Read backup into factory - const content = await this.fileService.readFileStream(backup); - const factory = await createTextBufferFactoryFromStream(content.value, metaPreambleFilter); - - // Trigger read for meta data extraction from the filter above - factory.getFirstLineText(1); - - let meta: T | undefined; - const metaStartIndex = metaRaw.indexOf(BackupFileServiceImpl.PREAMBLE_META_SEPARATOR); - if (metaStartIndex !== -1) { - try { - meta = JSON.parse(metaRaw.substr(metaStartIndex + 1)); - } catch (error) { - // ignore JSON parse errors - } - } - - return { value: factory, meta }; - } - - toBackupResource(resource: URI): URI { - return joinPath(this.backupWorkspacePath, resource.scheme, hashPath(resource)); - } -} - -export class InMemoryBackupFileService implements IBackupFileService { - - _serviceBrand: ServiceIdentifier; - - private backups: Map = new Map(); - - hasBackups(): Promise { - return Promise.resolve(this.backups.size > 0); - } - - loadBackupResource(resource: URI): Promise { - const backupResource = this.toBackupResource(resource); - if (this.backups.has(backupResource.toString())) { - return Promise.resolve(backupResource); - } - - return Promise.resolve(undefined); - } - - backupResource(resource: URI, content: ITextSnapshot, versionId?: number, meta?: T): Promise { - const backupResource = this.toBackupResource(resource); - this.backups.set(backupResource.toString(), content); - - return Promise.resolve(); - } - - resolveBackupContent(backupResource: URI): Promise> { - const snapshot = this.backups.get(backupResource.toString()); - if (snapshot) { - return Promise.resolve({ value: createTextBufferFactoryFromSnapshot(snapshot) }); - } - - return Promise.reject('Unexpected backup resource to resolve'); - } - - getWorkspaceFileBackups(): Promise { - return Promise.resolve(keys(this.backups).map(key => URI.parse(key))); - } - - discardResourceBackup(resource: URI): Promise { - this.backups.delete(this.toBackupResource(resource).toString()); - - return Promise.resolve(); - } - - discardAllWorkspaceBackups(): Promise { - this.backups.clear(); - - return Promise.resolve(); - } - - toBackupResource(resource: URI): URI { - return URI.file(join(resource.scheme, hashPath(resource))); - } } /* @@ -411,7 +21,5 @@ export class InMemoryBackupFileService implements IBackupFileService { */ export function hashPath(resource: URI): string { const str = resource.scheme === Schemas.file || resource.scheme === Schemas.untitled ? resource.fsPath : resource.toString(); - return createHash('md5').update(str).digest('hex'); -} - -registerSingleton(IBackupFileService, BackupFileService); \ No newline at end of file + return crypto.createHash('md5').update(str).digest('hex'); +} \ No newline at end of file diff --git a/src/vs/workbench/services/backup/test/node/backupFileService.test.ts b/src/vs/workbench/services/backup/test/node/backupFileService.test.ts index 52a5bc95d1c..990d688b3cc 100644 --- a/src/vs/workbench/services/backup/test/node/backupFileService.test.ts +++ b/src/vs/workbench/services/backup/test/node/backupFileService.test.ts @@ -11,22 +11,26 @@ import * as fs from 'fs'; import * as path from 'vs/base/common/path'; import * as pfs from 'vs/base/node/pfs'; import { URI } from 'vs/base/common/uri'; -import { BackupFileService, BackupFilesModel, hashPath } from 'vs/workbench/services/backup/node/backupFileService'; +import { BackupFilesModel } from 'vs/workbench/services/backup/common/backupFileService'; import { TextModel, createTextBufferFactory } from 'vs/editor/common/model/textModel'; import { getRandomTestPath } from 'vs/base/test/node/testUtils'; import { DefaultEndOfLine } from 'vs/editor/common/model'; import { Schemas } from 'vs/base/common/network'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; -import { FileService } from 'vs/workbench/services/files/common/fileService'; +import { FileService } from 'vs/platform/files/common/fileService'; import { NullLogService } from 'vs/platform/log/common/log'; -import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFileSystemProvider'; +import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/node/environmentService'; import { parseArgs } from 'vs/platform/environment/node/argv'; import { snapshotToString } from 'vs/workbench/services/textfile/common/textfiles'; import { IFileService } from 'vs/platform/files/common/files'; +import { hashPath, BackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; +import { BACKUPS } from 'vs/platform/environment/common/environment'; +import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; -const parentDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'backupfileservice'); -const backupHome = path.join(parentDir, 'Backups'); +const userdataDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'backupfileservice'); +const appSettingsHome = path.join(userdataDir, 'User'); +const backupHome = path.join(userdataDir, 'Backups'); const workspacesJsonPath = path.join(backupHome, 'workspaces.json'); const workspaceResource = URI.file(platform.isWindows ? 'c:\\workspace' : '/workspace'); @@ -43,18 +47,10 @@ const untitledBackupPath = path.join(workspaceBackupPath, 'untitled', hashPath(u class TestBackupEnvironmentService extends WorkbenchEnvironmentService { - private config: IWindowConfiguration; - - constructor(workspaceBackupPath: string) { - super(parseArgs(process.argv) as IWindowConfiguration, process.execPath); - - this.config = Object.create(null); - this.config.backupPath = workspaceBackupPath; + constructor(backupPath: string) { + super({ ...parseArgs(process.argv), ...{ backupPath, 'user-data-dir': userdataDir } } as IWindowConfiguration, process.execPath); } - get configuration(): IWindowConfiguration { - return this.config; - } } class TestBackupFileService extends BackupFileService { @@ -62,9 +58,11 @@ class TestBackupFileService extends BackupFileService { readonly fileService: IFileService; constructor(workspace: URI, backupHome: string, workspacesJsonPath: string) { - const fileService = new FileService(new NullLogService()); - fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); const environmentService = new TestBackupEnvironmentService(workspaceBackupPath); + const fileService = new FileService(new NullLogService()); + const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, diskFileSystemProvider, environmentService)); super(environmentService, fileService); @@ -124,8 +122,8 @@ suite('BackupFileService', () => { const backupResource = fooFile; const workspaceHash = hashPath(workspaceResource); const filePathHash = hashPath(backupResource); - const expectedPath = URI.file(path.join(backupHome, workspaceHash, 'file', filePathHash)).fsPath; - assert.equal(service.toBackupResource(backupResource).fsPath, expectedPath); + const expectedPath = URI.file(path.join(appSettingsHome, BACKUPS, workspaceHash, Schemas.file, filePathHash)).with({ scheme: Schemas.userData }).toString(); + assert.equal(service.toBackupResource(backupResource).toString(), expectedPath); }); test('should get the correct backup path for untitled files', () => { @@ -133,8 +131,8 @@ suite('BackupFileService', () => { const backupResource = URI.from({ scheme: Schemas.untitled, path: 'Untitled-1' }); const workspaceHash = hashPath(workspaceResource); const filePathHash = hashPath(backupResource); - const expectedPath = URI.file(path.join(backupHome, workspaceHash, 'untitled', filePathHash)).fsPath; - assert.equal(service.toBackupResource(backupResource).fsPath, expectedPath); + const expectedPath = URI.file(path.join(appSettingsHome, BACKUPS, workspaceHash, Schemas.untitled, filePathHash)).with({ scheme: Schemas.userData }).toString(); + assert.equal(service.toBackupResource(backupResource).toString(), expectedPath); }); }); @@ -157,6 +155,16 @@ suite('BackupFileService', () => { assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1); assert.equal(fs.existsSync(fooBackupPath), true); assert.equal(fs.readFileSync(fooBackupPath), `${fooFile.toString()}\ntest`); + assert.ok(service.hasBackupSync(fooFile)); + }); + + test('text file (with version)', async () => { + await service.backupResource(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false), 666); + assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1); + assert.equal(fs.existsSync(fooBackupPath), true); + assert.equal(fs.readFileSync(fooBackupPath), `${fooFile.toString()}\ntest`); + assert.ok(!service.hasBackupSync(fooFile, 555)); + assert.ok(service.hasBackupSync(fooFile, 666)); }); test('text file (with meta)', async () => { @@ -164,6 +172,7 @@ suite('BackupFileService', () => { assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1); assert.equal(fs.existsSync(fooBackupPath), true); assert.equal(fs.readFileSync(fooBackupPath).toString(), `${fooFile.toString()} {"etag":"678","orphaned":true}\ntest`); + assert.ok(service.hasBackupSync(fooFile)); }); test('untitled file', async () => { @@ -171,6 +180,7 @@ suite('BackupFileService', () => { assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 1); assert.equal(fs.existsSync(untitledBackupPath), true); assert.equal(fs.readFileSync(untitledBackupPath), `${untitledFile.toString()}\ntest`); + assert.ok(service.hasBackupSync(untitledFile)); }); test('text file (ITextSnapshot)', async () => { @@ -180,6 +190,8 @@ suite('BackupFileService', () => { assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1); assert.equal(fs.existsSync(fooBackupPath), true); assert.equal(fs.readFileSync(fooBackupPath), `${fooFile.toString()}\ntest`); + assert.ok(service.hasBackupSync(fooFile)); + model.dispose(); }); @@ -190,6 +202,7 @@ suite('BackupFileService', () => { assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 1); assert.equal(fs.existsSync(untitledBackupPath), true); assert.equal(fs.readFileSync(untitledBackupPath), `${untitledFile.toString()}\ntest`); + model.dispose(); }); @@ -201,6 +214,8 @@ suite('BackupFileService', () => { assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1); assert.equal(fs.existsSync(fooBackupPath), true); assert.equal(fs.readFileSync(fooBackupPath), `${fooFile.toString()}\n${largeString}`); + assert.ok(service.hasBackupSync(fooFile)); + model.dispose(); }); @@ -212,6 +227,8 @@ suite('BackupFileService', () => { assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 1); assert.equal(fs.existsSync(untitledBackupPath), true); assert.equal(fs.readFileSync(untitledBackupPath), `${untitledFile.toString()}\n${largeString}`); + assert.ok(service.hasBackupSync(untitledFile)); + model.dispose(); }); }); @@ -220,9 +237,12 @@ suite('BackupFileService', () => { test('text file', async () => { await service.backupResource(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).createSnapshot(false)); assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1); + assert.ok(service.hasBackupSync(fooFile)); + await service.discardResourceBackup(fooFile); assert.equal(fs.existsSync(fooBackupPath), false); assert.equal(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 0); + assert.ok(!service.hasBackupSync(fooFile)); }); test('untitled file', async () => { diff --git a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts index 079e00df824..f698782a600 100644 --- a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts @@ -18,7 +18,7 @@ import { localize } from 'vs/nls'; import { IFileService, FileSystemProviderCapabilities } from 'vs/platform/files/common/files'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ILogService } from 'vs/platform/log/common/log'; -import { emptyProgressRunner, IProgress, IProgressRunner } from 'vs/platform/progress/common/progress'; +import { IProgress, IProgressStep, emptyProgress } from 'vs/platform/progress/common/progress'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { ILabelService } from 'vs/platform/label/common/label'; @@ -231,11 +231,11 @@ export class BulkEdit { private _edits: Edit[] = []; private _editor: ICodeEditor | undefined; - private _progress?: IProgressRunner; + private _progress: IProgress; constructor( editor: ICodeEditor | undefined, - progress: IProgressRunner | undefined, + progress: IProgress | undefined, @ILogService private readonly _logService: ILogService, @ITextModelService private readonly _textModelService: ITextModelService, @IFileService private readonly _fileService: IFileService, @@ -244,7 +244,7 @@ export class BulkEdit { @IConfigurationService private readonly _configurationService: IConfigurationService ) { this._editor = editor; - this._progress = progress || emptyProgressRunner; + this._progress = progress || emptyProgress; } add(edits: Edit[] | Edit): void { @@ -294,10 +294,9 @@ export class BulkEdit { // define total work and progress callback // for child operations - if (this._progress) { - this._progress.total(total); - } - let progress: IProgress = { report: _ => this._progress && this._progress.worked(1) }; + this._progress.report({ total }); + + let progress: IProgress = { report: _ => this._progress.report({ increment: 1 }) }; // do it. for (const group of groups) { diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 02331934375..515c6df2fe3 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -9,10 +9,10 @@ import { Event, Emitter } from 'vs/base/common/event'; import * as errors from 'vs/base/common/errors'; import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; import { RunOnceScheduler } from 'vs/base/common/async'; -import { FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files'; +import { FileChangeType, FileChangesEvent, IFileService } from 'vs/platform/files/common/files'; import { ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels'; import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels'; -import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, IConfigurationFileService, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; import { IStoredWorkspaceFolder, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService'; import { WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -20,15 +20,54 @@ import { ConfigurationScope } from 'vs/platform/configuration/common/configurati import { extname, join } from 'vs/base/common/path'; import { equals } from 'vs/base/common/objects'; import { Schemas } from 'vs/base/common/network'; -import { IConfigurationModel, compare } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { hash } from 'vs/base/common/hash'; +export class UserConfiguration extends Disposable { + + private readonly parser: ConfigurationModelParser; + private readonly reloadConfigurationScheduler: RunOnceScheduler; + protected readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); + readonly onDidChangeConfiguration: Event = this._onDidChangeConfiguration.event; + + constructor( + private readonly userSettingsResource: URI, + private readonly scopes: ConfigurationScope[] | undefined, + private readonly fileService: IFileService + ) { + super(); + + this.parser = new ConfigurationModelParser(this.userSettingsResource.toString(), this.scopes); + this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50)); + this._register(Event.filter(this.fileService.onFileChanges, e => e.contains(this.userSettingsResource))(() => this.reloadConfigurationScheduler.schedule())); + } + + async initialize(): Promise { + return this.reload(); + } + + async reload(): Promise { + try { + const content = await this.fileService.readFile(this.userSettingsResource); + this.parser.parseContent(content.value.toString() || '{}'); + return this.parser.configurationModel; + } catch (e) { + return new ConfigurationModel(); + } + } + + reprocess(): ConfigurationModel { + this.parser.parse(); + return this.parser.configurationModel; + } +} + export class RemoteUserConfiguration extends Disposable { - private readonly _cachedConfiguration: CachedUserConfiguration; - private readonly _configurationFileService: IConfigurationFileService; - private _userConfiguration: UserConfiguration | CachedUserConfiguration; + private readonly _cachedConfiguration: CachedRemoteUserConfiguration; + private readonly _configurationFileService: ConfigurationFileService; + private _userConfiguration: FileServiceBasedRemoteUserConfiguration | CachedRemoteUserConfiguration; private _userConfigurationInitializationPromise: Promise | null = null; private readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); @@ -37,15 +76,15 @@ export class RemoteUserConfiguration extends Disposable { constructor( remoteAuthority: string, configurationCache: IConfigurationCache, - configurationFileService: IConfigurationFileService, + configurationFileService: ConfigurationFileService, remoteAgentService: IRemoteAgentService ) { super(); this._configurationFileService = configurationFileService; - this._userConfiguration = this._cachedConfiguration = new CachedUserConfiguration(remoteAuthority, configurationCache); + this._userConfiguration = this._cachedConfiguration = new CachedRemoteUserConfiguration(remoteAuthority, configurationCache); remoteAgentService.getEnvironment().then(async environment => { if (environment) { - const userConfiguration = this._register(new UserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._configurationFileService)); + const userConfiguration = this._register(new FileServiceBasedRemoteUserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._configurationFileService)); this._register(userConfiguration.onDidChangeConfiguration(configurationModel => this.onDidUserConfigurationChange(configurationModel))); this._userConfigurationInitializationPromise = userConfiguration.initialize(); const configurationModel = await this._userConfigurationInitializationPromise; @@ -57,7 +96,7 @@ export class RemoteUserConfiguration extends Disposable { } async initialize(): Promise { - if (this._userConfiguration instanceof UserConfiguration) { + if (this._userConfiguration instanceof FileServiceBasedRemoteUserConfiguration) { return this._userConfiguration.initialize(); } @@ -90,7 +129,7 @@ export class RemoteUserConfiguration extends Disposable { } } -export class UserConfiguration extends Disposable { +class FileServiceBasedRemoteUserConfiguration extends Disposable { private readonly parser: ConfigurationModelParser; private readonly reloadConfigurationScheduler: RunOnceScheduler; @@ -103,7 +142,7 @@ export class UserConfiguration extends Disposable { constructor( private readonly configurationResource: URI, private readonly scopes: ConfigurationScope[] | undefined, - private readonly configurationFileService: IConfigurationFileService + private readonly configurationFileService: ConfigurationFileService ) { super(); @@ -138,11 +177,7 @@ export class UserConfiguration extends Disposable { async initialize(): Promise { const exists = await this.configurationFileService.exists(this.configurationResource); this.onResourceExists(exists); - const configuraitonModel = await this.reload(); - if (!this.configurationFileService.isWatching) { - this.configurationFileService.whenWatchingStarted.then(() => this.onWatchStarted(configuraitonModel)); - } - return configuraitonModel; + return this.reload(); } async reload(): Promise { @@ -160,14 +195,6 @@ export class UserConfiguration extends Disposable { return this.parser.configurationModel; } - private async onWatchStarted(currentModel: ConfigurationModel): Promise { - const configuraitonModel = await this.reload(); - const { added, removed, updated } = compare(currentModel, configuraitonModel); - if (added.length || removed.length || updated.length) { - this._onDidChangeConfiguration.fire(configuraitonModel); - } - } - private async handleFileEvents(event: FileChangesEvent): Promise { const events = event.changes; @@ -202,7 +229,7 @@ export class UserConfiguration extends Disposable { } } -class CachedUserConfiguration extends Disposable { +class CachedRemoteUserConfiguration extends Disposable { private readonly _onDidChange: Emitter = this._register(new Emitter()); readonly onDidChange: Event = this._onDidChange.event; @@ -252,7 +279,7 @@ class CachedUserConfiguration extends Disposable { export class WorkspaceConfiguration extends Disposable { - private readonly _configurationFileService: IConfigurationFileService; + private readonly _configurationFileService: ConfigurationFileService; private readonly _cachedConfiguration: CachedWorkspaceConfiguration; private _workspaceConfiguration: IWorkspaceConfiguration; private _workspaceConfigurationChangeDisposable: IDisposable = Disposable.None; @@ -266,7 +293,7 @@ export class WorkspaceConfiguration extends Disposable { constructor( configurationCache: IConfigurationCache, - configurationFileService: IConfigurationFileService + configurationFileService: ConfigurationFileService ) { super(); this._configurationFileService = configurationFileService; @@ -369,7 +396,7 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork protected readonly _onDidChange: Emitter = this._register(new Emitter()); readonly onDidChange: Event = this._onDidChange.event; - constructor(private configurationFileService: IConfigurationFileService) { + constructor(private configurationFileService: ConfigurationFileService) { super(); this.workspaceConfigurationModelParser = new WorkspaceConfigurationModelParser(''); @@ -378,10 +405,6 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork this._register(configurationFileService.onFileChanges(e => this.handleWorkspaceFileEvents(e))); this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this._onDidChange.fire(), 50)); this.workspaceConfigWatcher = this._register(this.watchWorkspaceConfigurationFile()); - - if (!this.configurationFileService.isWatching) { - this.configurationFileService.whenWatchingStarted.then(() => this.onWatchStarted()); - } } get workspaceIdentifier(): IWorkspaceIdentifier | null { @@ -426,18 +449,6 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork return this.getWorkspaceSettings(); } - private async onWatchStarted(): Promise { - if (this.workspaceIdentifier) { - const currentModel = this.getConfigurationModel(); - await this.load(this.workspaceIdentifier); - const newModel = this.getConfigurationModel(); - const { added, removed, updated } = compare(currentModel, newModel); - if (added.length || removed.length || updated.length) { - this._onDidChange.fire(); - } - } - } - private consolidate(): void { this.workspaceSettings = this.workspaceConfigurationModelParser.settingsModel.merge(this.workspaceConfigurationModelParser.launchModel); } @@ -546,7 +557,7 @@ class FileServiceBasedFolderConfiguration extends Disposable implements IFolderC protected readonly _onDidChange: Emitter = this._register(new Emitter()); readonly onDidChange: Event = this._onDidChange.event; - constructor(protected readonly configurationFolder: URI, workbenchState: WorkbenchState, private configurationFileService: IConfigurationFileService) { + constructor(protected readonly configurationFolder: URI, workbenchState: WorkbenchState, private configurationFileService: ConfigurationFileService) { super(); this.configurationNames = [FOLDER_SETTINGS_NAME /*First one should be settings */, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY]; @@ -557,9 +568,6 @@ class FileServiceBasedFolderConfiguration extends Disposable implements IFolderC this.changeEventTriggerScheduler = this._register(new RunOnceScheduler(() => this._onDidChange.fire(), 50)); this._register(configurationFileService.onFileChanges(e => this.handleWorkspaceFileEvents(e))); - if (!this.configurationFileService.isWatching) { - this.configurationFileService.whenWatchingStarted.then(() => this.onWatchStarted()); - } } async loadConfiguration(): Promise { @@ -611,15 +619,6 @@ class FileServiceBasedFolderConfiguration extends Disposable implements IFolderC this._cache = this._folderSettingsModelParser.configurationModel.merge(...this._standAloneConfigurations); } - private async onWatchStarted(): Promise { - const currentModel = this._cache; - const newModel = await this.loadConfiguration(); - const { added, removed, updated } = compare(currentModel, newModel); - if (added.length || removed.length || updated.length) { - this._onDidChange.fire(); - } - } - private handleWorkspaceFileEvents(event: FileChangesEvent): void { const events = event.changes; let affectedByChanges = false; @@ -725,7 +724,7 @@ export class FolderConfiguration extends Disposable implements IFolderConfigurat readonly workspaceFolder: IWorkspaceFolder, configFolderRelativePath: string, private readonly workbenchState: WorkbenchState, - configurationFileService: IConfigurationFileService, + configurationFileService: ConfigurationFileService, configurationCache: IConfigurationCache ) { super(); diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 618fb0bc326..a95764ba5ca 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -11,11 +11,10 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { Queue, Barrier } from 'vs/base/common/async'; import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { IWorkspaceContextService, Workspace, WorkbenchState, IWorkspaceFolder, toWorkspaceFolders, IWorkspaceFoldersChangeEvent, WorkspaceFolder, toWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { isLinux } from 'vs/base/common/platform'; import { ConfigurationChangeEvent, ConfigurationModel, DefaultConfigurationModel } from 'vs/platform/configuration/common/configurationModels'; import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Configuration, WorkspaceConfigurationChangeEvent, AllKeysConfigurationChangeEvent } from 'vs/workbench/services/configuration/common/configurationModels'; -import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, IConfigurationFileService, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings } from 'vs/platform/configuration/common/configurationRegistry'; import { IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceInitializationPayload, isSingleFolderWorkspaceInitializationPayload, ISingleFolderWorkspaceInitializationPayload, IEmptyWorkspaceInitializationPayload, useSlashForPath, getStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; @@ -28,6 +27,8 @@ import { localize } from 'vs/nls'; import { isEqual, dirname } from 'vs/base/common/resources'; import { mark } from 'vs/base/common/performance'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; export class WorkspaceService extends Disposable implements IConfigurationService, IWorkspaceContextService { @@ -37,14 +38,16 @@ export class WorkspaceService extends Disposable implements IConfigurationServic private completeWorkspaceBarrier: Barrier; private readonly configurationCache: IConfigurationCache; private _configuration: Configuration; + private initialized: boolean = false; private defaultConfiguration: DefaultConfigurationModel; - private localUserConfiguration: UserConfiguration | null = null; + private localUserConfiguration: UserConfiguration; private remoteUserConfiguration: RemoteUserConfiguration | null = null; private workspaceConfiguration: WorkspaceConfiguration; private cachedFolderConfigs: ResourceMap; - private workspaceEditingQueue: Queue; + private readonly configurationFileService: ConfigurationFileService; + protected readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); public readonly onDidChangeConfiguration: Event = this._onDidChangeConfiguration.event; @@ -64,21 +67,23 @@ export class WorkspaceService extends Disposable implements IConfigurationServic private cyclicDependency = new Promise(resolve => this.cyclicDependencyReady = resolve); constructor( - { userSettingsResource, remoteAuthority, configurationCache }: { userSettingsResource?: URI, remoteAuthority?: string, configurationCache: IConfigurationCache }, - private readonly configurationFileService: IConfigurationFileService, - remoteAgentService: IRemoteAgentService, + { remoteAuthority, configurationCache }: { remoteAuthority?: string, configurationCache: IConfigurationCache }, + environmentService: IWorkbenchEnvironmentService, + fileService: IFileService, + remoteAgentService: IRemoteAgentService ) { super(); this.completeWorkspaceBarrier = new Barrier(); this.defaultConfiguration = new DefaultConfigurationModel(); this.configurationCache = configurationCache; - if (userSettingsResource) { - this.localUserConfiguration = this._register(new UserConfiguration(userSettingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, configurationFileService)); - this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration))); - } + this.configurationFileService = new ConfigurationFileService(fileService); + this._configuration = new Configuration(this.defaultConfiguration, new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ResourceMap(), new ConfigurationModel(), new ResourceMap(), this.workspace); + this.cachedFolderConfigs = new ResourceMap(); + this.localUserConfiguration = this._register(new UserConfiguration(environmentService.settingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, fileService)); + this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration))); if (remoteAuthority) { - this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, configurationFileService, remoteAgentService)); + this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, this.configurationFileService, remoteAgentService)); this._register(this.remoteUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onRemoteUserConfigurationChanged(userConfiguration))); } this.workspaceConfiguration = this._register(new WorkspaceConfiguration(configurationCache, this.configurationFileService)); @@ -225,13 +230,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic } private contains(resources: URI[], toCheck: URI): boolean { - return resources.some(resource => { - if (isLinux) { - return resource.toString() === toCheck.toString(); - } - - return resource.toString().toLowerCase() === toCheck.toString().toLowerCase(); - }); + return resources.some(resource => isEqual(resource, toCheck)); } // Workspace Configuration Service Impl @@ -420,7 +419,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic } private initializeUserConfiguration(): Promise<{ local: ConfigurationModel, remote: ConfigurationModel }> { - return Promise.all([this.localUserConfiguration ? this.localUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel()), this.remoteUserConfiguration ? this.remoteUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel())]) + return Promise.all([this.localUserConfiguration.initialize(), this.remoteUserConfiguration ? this.remoteUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel())]) .then(([local, remote]) => ({ local, remote })); } @@ -429,7 +428,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic } private reloadLocalUserConfiguration(key?: string): Promise { - return this.localUserConfiguration ? this.localUserConfiguration.reload() : Promise.resolve(new ConfigurationModel()); + return this.localUserConfiguration.reload(); } private reloadRemoeUserConfiguration(key?: string): Promise { @@ -466,11 +465,12 @@ export class WorkspaceService extends Disposable implements IConfigurationServic const currentConfiguration = this._configuration; this._configuration = new Configuration(this.defaultConfiguration, userConfigurationModel, remoteUserConfigurationModel, workspaceConfiguration, folderConfigurationModels, new ConfigurationModel(), new ResourceMap(), this.workspace); - if (currentConfiguration) { + if (this.initialized) { const changedKeys = this._configuration.compare(currentConfiguration); this.triggerConfigurationChange(new ConfigurationChangeEvent().change(changedKeys), ConfigurationTarget.WORKSPACE); } else { this._onDidChangeConfiguration.fire(new AllKeysConfigurationChangeEvent(this._configuration, ConfigurationTarget.WORKSPACE, this.getTargetConfiguration(ConfigurationTarget.WORKSPACE))); + this.initialized = true; } }); } @@ -489,7 +489,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic private onDefaultConfigurationChanged(keys: string[]): void { this.defaultConfiguration = new DefaultConfigurationModel(); this.registerConfigurationSchemas(); - if (this.workspace && this._configuration) { + if (this.workspace) { this._configuration.updateDefaultConfiguration(this.defaultConfiguration); if (this.remoteUserConfiguration) { this._configuration.updateRemoteUserConfiguration(this.remoteUserConfiguration.reprocess()); @@ -545,14 +545,12 @@ export class WorkspaceService extends Disposable implements IConfigurationServic } private onRemoteUserConfigurationChanged(userConfiguration: ConfigurationModel): void { - if (this._configuration) { - const keys = this._configuration.compareAndUpdateRemoteUserConfiguration(userConfiguration); - this.triggerConfigurationChange(keys, ConfigurationTarget.USER); - } + const keys = this._configuration.compareAndUpdateRemoteUserConfiguration(userConfiguration); + this.triggerConfigurationChange(keys, ConfigurationTarget.USER); } private onWorkspaceConfigurationChanged(): Promise { - if (this.workspace && this.workspace.configuration && this._configuration) { + if (this.workspace && this.workspace.configuration) { const workspaceConfigurationChangeEvent = this._configuration.compareAndUpdateWorkspaceConfiguration(this.workspaceConfiguration.getConfiguration()); let configuredFolders = toWorkspaceFolders(this.workspaceConfiguration.getFolders(), this.workspace.configuration); const changes = this.compareFolders(this.workspace.folders, configuredFolders); diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index a1185aa3001..ca5948d81a6 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -5,8 +5,7 @@ import { URI } from 'vs/base/common/uri'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { Event } from 'vs/base/common/event'; -import { FileChangesEvent, IFileService } from 'vs/platform/files/common/files'; +import { IFileService } from 'vs/platform/files/common/files'; import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; export const FOLDER_CONFIG_FOLDER_NAME = '.vscode'; @@ -42,24 +41,11 @@ export interface IConfigurationCache { } -export interface IConfigurationFileService { - fileService: IFileService | null; - readonly onFileChanges: Event; - readonly isWatching: boolean; - readonly whenWatchingStarted: Promise; - whenProviderRegistered(scheme: string): Promise; - watch(resource: URI): IDisposable; - exists(resource: URI): Promise; - readFile(resource: URI): Promise; -} +export class ConfigurationFileService { -export class ConfigurationFileService implements IConfigurationFileService { - - constructor(public fileService: IFileService) { } + constructor(private readonly fileService: IFileService) { } get onFileChanges() { return this.fileService.onFileChanges; } - readonly whenWatchingStarted: Promise = Promise.resolve(); - readonly isWatching: boolean = true; whenProviderRegistered(scheme: string): Promise { if (this.fileService.canHandleResource(URI.from({ scheme }))) { diff --git a/src/vs/workbench/services/configuration/node/configurationCache.ts b/src/vs/workbench/services/configuration/node/configurationCache.ts index 67b46a14cb2..432c8ada983 100644 --- a/src/vs/workbench/services/configuration/node/configurationCache.ts +++ b/src/vs/workbench/services/configuration/node/configurationCache.ts @@ -7,12 +7,13 @@ import * as pfs from 'vs/base/node/pfs'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { join } from 'vs/base/common/path'; import { IConfigurationCache, ConfigurationKey } from 'vs/workbench/services/configuration/common/configuration'; +import { IWorkbenchEnvironmentService } from '../../environment/common/environmentService'; export class ConfigurationCache implements IConfigurationCache { private readonly cachedConfigurations: Map = new Map(); - constructor(private readonly environmentService: IEnvironmentService) { + constructor(private readonly environmentService: IWorkbenchEnvironmentService) { } read(key: ConfigurationKey): Promise { diff --git a/src/vs/workbench/services/configuration/node/configurationFileService.ts b/src/vs/workbench/services/configuration/node/configurationFileService.ts deleted file mode 100644 index 18690c44040..00000000000 --- a/src/vs/workbench/services/configuration/node/configurationFileService.ts +++ /dev/null @@ -1,79 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as pfs from 'vs/base/node/pfs'; -import { IConfigurationFileService, ConfigurationFileService as FileServiceBasedConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; -import { URI } from 'vs/base/common/uri'; -import { Event, Emitter } from 'vs/base/common/event'; -import { FileChangesEvent, IFileService } from 'vs/platform/files/common/files'; -import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { Schemas } from 'vs/base/common/network'; - -export class ConfigurationFileService extends Disposable implements IConfigurationFileService { - - private _fileServiceBasedConfigurationFileService: FileServiceBasedConfigurationFileService | null = null; - private _fileServiceBasedConfigurationFileServiceCallback: (fileServiceBasedConfigurationFileService: FileServiceBasedConfigurationFileService) => void; - private _whenFileServiceBasedConfigurationFileServiceAvailable: Promise = new Promise((c) => this._fileServiceBasedConfigurationFileServiceCallback = c); - private _watchResources: { resource: URI, disposable: { disposable: IDisposable | null } }[] = []; - readonly whenWatchingStarted: Promise = this._whenFileServiceBasedConfigurationFileServiceAvailable.then(() => undefined); - - private readonly _onFileChanges: Emitter = this._register(new Emitter()); - readonly onFileChanges: Event = this._onFileChanges.event; - - get isWatching(): boolean { - return this._fileServiceBasedConfigurationFileService ? this._fileServiceBasedConfigurationFileService.isWatching : false; - } - - watch(resource: URI): IDisposable { - if (this._fileServiceBasedConfigurationFileService) { - return this._fileServiceBasedConfigurationFileService.watch(resource); - } - const disposable: { disposable: IDisposable | null } = { disposable: null }; - this._watchResources.push({ resource, disposable }); - return toDisposable(() => { - if (disposable.disposable) { - disposable.disposable.dispose(); - } - }); - } - - whenProviderRegistered(scheme: string): Promise { - if (scheme === Schemas.file) { - return Promise.resolve(); - } - return this._whenFileServiceBasedConfigurationFileServiceAvailable - .then(fileServiceBasedConfigurationFileService => fileServiceBasedConfigurationFileService.whenProviderRegistered(scheme)); - } - - exists(resource: URI): Promise { - return this._fileServiceBasedConfigurationFileService ? this._fileServiceBasedConfigurationFileService.exists(resource) : pfs.exists(resource.fsPath); - } - - async readFile(resource: URI): Promise { - if (this._fileServiceBasedConfigurationFileService) { - return this._fileServiceBasedConfigurationFileService.readFile(resource); - } else { - const contents = await pfs.readFile(resource.fsPath); - return contents.toString(); - } - } - - private _fileService: IFileService | null; - get fileService(): IFileService | null { - return this._fileService; - } - - set fileService(fileService: IFileService | null) { - if (fileService && !this._fileServiceBasedConfigurationFileService) { - this._fileServiceBasedConfigurationFileService = new FileServiceBasedConfigurationFileService(fileService); - this._fileService = fileService; - this._register(this._fileServiceBasedConfigurationFileService.onFileChanges(e => this._onFileChanges.fire(e))); - for (const { resource, disposable } of this._watchResources) { - disposable.disposable = this._fileServiceBasedConfigurationFileService.watch(resource); - } - this._fileServiceBasedConfigurationFileServiceCallback(this._fileServiceBasedConfigurationFileService); - } - } -} diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts index 6634fcb6e04..2a75dca343d 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts @@ -10,10 +10,9 @@ import * as path from 'vs/base/common/path'; import * as fs from 'fs'; import * as json from 'vs/base/common/json'; import { Registry } from 'vs/platform/registry/common/platform'; -import { ParsedArgs, IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { parseArgs } from 'vs/platform/environment/node/argv'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; import { TestTextFileService, workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices'; import * as uuid from 'vs/base/common/uuid'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; @@ -33,21 +32,25 @@ import { URI } from 'vs/base/common/uri'; import { createHash } from 'crypto'; import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; -import { FileService } from 'vs/workbench/services/files/common/fileService'; +import { FileService } from 'vs/platform/files/common/fileService'; import { NullLogService } from 'vs/platform/log/common/log'; import { Schemas } from 'vs/base/common/network'; -import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFileSystemProvider'; +import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; import { IFileService } from 'vs/platform/files/common/files'; import { ConfigurationCache } from 'vs/workbench/services/configuration/node/configurationCache'; -import { ConfigurationFileService } from 'vs/workbench/services/configuration/node/configurationFileService'; +import { KeybindingsEditingService, IKeybindingEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing'; +import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/node/environmentService'; +import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; +import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; -class SettingsTestEnvironmentService extends EnvironmentService { +class TestEnvironmentService extends WorkbenchEnvironmentService { - constructor(args: ParsedArgs, _execPath: string, private customAppSettingsHome: string) { - super(args, _execPath); + constructor(private _appSettingsHome: URI) { + super(parseArgs(process.argv) as IWindowConfiguration, process.execPath); } - get settingsResource(): URI { return URI.file(this.customAppSettingsHome); } + get appSettingsHome() { return this._appSettingsHome; } + } suite('ConfigurationEditingService', () => { @@ -90,7 +93,7 @@ suite('ConfigurationEditingService', () => { const id = uuid.generateUuid(); parentDir = path.join(os.tmpdir(), 'vsctests', id); workspaceDir = path.join(parentDir, 'workspaceconfig', id); - globalSettingsFile = path.join(workspaceDir, 'config.json'); + globalSettingsFile = path.join(workspaceDir, 'settings.json'); workspaceSettingsDir = path.join(workspaceDir, '.vscode'); return await mkdirp(workspaceSettingsDir, 493); @@ -101,17 +104,20 @@ suite('ConfigurationEditingService', () => { clearServices(); instantiationService = workbenchInstantiationService(); - const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); + const environmentService = new TestEnvironmentService(URI.file(workspaceDir)); instantiationService.stub(IEnvironmentService, environmentService); const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {}); + const fileService = new FileService(new NullLogService()); + const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, diskFileSystemProvider, environmentService)); + instantiationService.stub(IFileService, fileService); instantiationService.stub(IRemoteAgentService, remoteAgentService); - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(), remoteAgentService); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); return workspaceService.initialize(noWorkspace ? { id: '' } : { folder: URI.file(workspaceDir), id: createHash('md5').update(URI.file(workspaceDir).toString()).digest('hex') }).then(() => { instantiationService.stub(IConfigurationService, workspaceService); - const fileService = new FileService(new NullLogService()); - fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - instantiationService.stub(IFileService, fileService); + instantiationService.stub(IKeybindingEditingService, instantiationService.createInstance(KeybindingsEditingService)); instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService)); instantiationService.stub(ITextModelService, instantiationService.createInstance(TextModelResolverService)); instantiationService.stub(ICommandService, CommandService); @@ -121,7 +127,10 @@ suite('ConfigurationEditingService', () => { teardown(() => { clearServices(); - return clearWorkspace(); + if (workspaceDir) { + return rimraf(workspaceDir, RimRafMode.MOVE); + } + return undefined; }); function clearServices(): void { @@ -134,16 +143,6 @@ suite('ConfigurationEditingService', () => { } } - function clearWorkspace(): Promise { - return new Promise((c, e) => { - if (parentDir) { - rimraf(parentDir, RimRafMode.MOVE).then(c, c); - } else { - c(undefined); - } - }).then(() => parentDir = null!); - } - test('errors cases - invalid key', () => { return testObject.writeConfiguration(EditableConfigurationTarget.WORKSPACE, { key: 'unknown.key', value: 'value' }) .then(() => assert.fail('Should fail with ERROR_UNKNOWN_KEY'), diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts index 3fd5bf00d75..3c059ad069f 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts @@ -10,8 +10,7 @@ import * as path from 'vs/base/common/path'; import * as os from 'os'; import { URI } from 'vs/base/common/uri'; import { Registry } from 'vs/platform/registry/common/platform'; -import { ParsedArgs, IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { parseArgs } from 'vs/platform/environment/node/argv'; import * as pfs from 'vs/base/node/pfs'; import * as uuid from 'vs/base/common/uuid'; @@ -37,23 +36,27 @@ import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; import { RemoteAuthorityResolverService } from 'vs/platform/remote/electron-browser/remoteAuthorityResolverService'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; -import { FileService } from 'vs/workbench/services/files/common/fileService'; +import { FileService } from 'vs/platform/files/common/fileService'; import { NullLogService } from 'vs/platform/log/common/log'; -import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFileSystemProvider'; +import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; import { ConfigurationCache } from 'vs/workbench/services/configuration/node/configurationCache'; -import { ConfigurationFileService } from 'vs/workbench/services/configuration/node/configurationFileService'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; import { IConfigurationCache } from 'vs/workbench/services/configuration/common/configuration'; -import { VSBuffer } from 'vs/base/common/buffer'; +// import { VSBuffer } from 'vs/base/common/buffer'; import { SignService } from 'vs/platform/sign/browser/signService'; +import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; +import { IKeybindingEditingService, KeybindingsEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing'; +import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/node/environmentService'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -class SettingsTestEnvironmentService extends EnvironmentService { +class TestEnvironmentService extends WorkbenchEnvironmentService { - constructor(args: ParsedArgs, _execPath: string, private customAppSettingsHome: string) { - super(args, _execPath); + constructor(private _appSettingsHome: URI) { + super(parseArgs(process.argv) as IWindowConfiguration, process.execPath); } - get settingsResource(): URI { return URI.file(this.customAppSettingsHome); } + get appSettingsHome() { return this._appSettingsHome; } + } function setUpFolderWorkspace(folderName: string): Promise<{ parentDir: string, folderDir: string }> { @@ -102,9 +105,10 @@ suite('WorkspaceContextService - Folder', () => { .then(({ parentDir, folderDir }) => { parentResource = parentDir; workspaceResource = folderDir; - const globalSettingsFile = path.join(parentDir, 'settings.json'); - const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); - workspaceContextService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(), new RemoteAgentService({}, environmentService, new RemoteAuthorityResolverService(), new SignService())); + const environmentService = new TestEnvironmentService(URI.file(parentDir)); + const fileService = new FileService(new NullLogService()); + fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, new DiskFileSystemProvider(new NullLogService()), environmentService)); + workspaceContextService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, new RemoteAgentService({}, environmentService, new RemoteAuthorityResolverService(), new SignService())); return (workspaceContextService).initialize(convertToWorkspacePayload(URI.file(folderDir))); }); }); @@ -163,10 +167,14 @@ suite('WorkspaceContextService - Workspace', () => { parentResource = parentDir; instantiationService = workbenchInstantiationService(); - const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, path.join(parentDir, 'settings.json')); + const environmentService = new TestEnvironmentService(URI.file(parentDir)); const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {}); instantiationService.stub(IRemoteAgentService, remoteAgentService); - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(), remoteAgentService); + const fileService = new FileService(new NullLogService()); + const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, diskFileSystemProvider, environmentService)); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -219,14 +227,14 @@ suite('WorkspaceContextService - Workspace Editing', () => { parentResource = parentDir; instantiationService = workbenchInstantiationService(); - const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, path.join(parentDir, 'settings.json')); + const environmentService = new TestEnvironmentService(URI.file(parentDir)); const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {}); instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); - fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); + const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, diskFileSystemProvider, environmentService)); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -480,14 +488,14 @@ suite('WorkspaceService - Initialization', () => { globalSettingsFile = path.join(parentDir, 'settings.json'); const instantiationService = workbenchInstantiationService(); - const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); + const environmentService = new TestEnvironmentService(URI.file(parentDir)); const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {}); instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); - fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); + const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, diskFileSystemProvider, environmentService)); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IEnvironmentService, environmentService); @@ -744,20 +752,21 @@ suite('WorkspaceConfigurationService - Folder', () => { globalSettingsFile = path.join(parentDir, 'settings.json'); const instantiationService = workbenchInstantiationService(); - const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); + const environmentService = new TestEnvironmentService(URI.file(parentDir)); const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {}); instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); - fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); + const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, diskFileSystemProvider, environmentService)); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IEnvironmentService, environmentService); return workspaceService.initialize(convertToWorkspacePayload(URI.file(folderDir))).then(() => { instantiationService.stub(IFileService, fileService); + instantiationService.stub(IKeybindingEditingService, instantiationService.createInstance(KeybindingsEditingService)); instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService)); instantiationService.stub(ITextModelService, instantiationService.createInstance(TextModelResolverService)); workspaceService.acquireInstantiationService(instantiationService); @@ -1034,7 +1043,7 @@ suite('WorkspaceConfigurationService - Folder', () => { suite('WorkspaceConfigurationService-Multiroot', () => { - let parentResource: string, workspaceContextService: IWorkspaceContextService, environmentService: IEnvironmentService, jsonEditingServce: IJSONEditingService, testObject: IConfigurationService; + let parentResource: string, workspaceContextService: IWorkspaceContextService, jsonEditingServce: IJSONEditingService, testObject: IConfigurationService, globalSettingsFile: string; const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); suiteSetup(() => { @@ -1070,23 +1079,25 @@ suite('WorkspaceConfigurationService-Multiroot', () => { .then(({ parentDir, configPath }) => { parentResource = parentDir; + globalSettingsFile = path.join(parentDir, 'settings.json'); const instantiationService = workbenchInstantiationService(); - environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, path.join(parentDir, 'settings.json')); + const environmentService = new TestEnvironmentService(URI.file(parentDir)); const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {}); instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); - fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); + const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, diskFileSystemProvider, environmentService)); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); - instantiationService.stub(IEnvironmentService, environmentService); + instantiationService.stub(IWorkbenchEnvironmentService, environmentService); return workspaceService.initialize(getWorkspaceIdentifier(configPath)).then(() => { instantiationService.stub(IFileService, fileService); + instantiationService.stub(IKeybindingEditingService, instantiationService.createInstance(KeybindingsEditingService)); instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService)); instantiationService.stub(ITextModelService, instantiationService.createInstance(TextModelResolverService)); workspaceService.acquireInstantiationService(instantiationService); @@ -1109,21 +1120,21 @@ suite('WorkspaceConfigurationService-Multiroot', () => { }); test('application settings are not read from workspace', () => { - fs.writeFileSync(environmentService.settingsResource.fsPath, '{ "configurationService.workspace.applicationSetting": "userValue" }'); + fs.writeFileSync(globalSettingsFile, '{ "configurationService.workspace.applicationSetting": "userValue" }'); return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'settings', value: { 'configurationService.workspace.applicationSetting': 'workspaceValue' } }, true) .then(() => testObject.reloadConfiguration()) .then(() => assert.equal(testObject.getValue('configurationService.workspace.applicationSetting'), 'userValue')); }); test('machine settings are not read from workspace', () => { - fs.writeFileSync(environmentService.settingsResource.fsPath, '{ "configurationService.workspace.machineSetting": "userValue" }'); + fs.writeFileSync(globalSettingsFile, '{ "configurationService.workspace.machineSetting": "userValue" }'); return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'settings', value: { 'configurationService.workspace.machineSetting': 'workspaceValue' } }, true) .then(() => testObject.reloadConfiguration()) .then(() => assert.equal(testObject.getValue('configurationService.workspace.machineSetting'), 'userValue')); }); test('workspace settings override user settings after defaults are registered ', () => { - fs.writeFileSync(environmentService.settingsResource.fsPath, '{ "configurationService.workspace.newSetting": "userValue" }'); + fs.writeFileSync(globalSettingsFile, '{ "configurationService.workspace.newSetting": "userValue" }'); return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'settings', value: { 'configurationService.workspace.newSetting': 'workspaceValue' } }, true) .then(() => testObject.reloadConfiguration()) .then(() => { @@ -1142,21 +1153,21 @@ suite('WorkspaceConfigurationService-Multiroot', () => { }); test('application settings are not read from workspace folder', () => { - fs.writeFileSync(environmentService.settingsResource.fsPath, '{ "configurationService.workspace.applicationSetting": "userValue" }'); + fs.writeFileSync(globalSettingsFile, '{ "configurationService.workspace.applicationSetting": "userValue" }'); fs.writeFileSync(workspaceContextService.getWorkspace().folders[0].toResource('.vscode/settings.json').fsPath, '{ "configurationService.workspace.applicationSetting": "workspaceFolderValue" }'); return testObject.reloadConfiguration() .then(() => assert.equal(testObject.getValue('configurationService.workspace.applicationSetting'), 'userValue')); }); test('machine settings are not read from workspace folder', () => { - fs.writeFileSync(environmentService.settingsResource.fsPath, '{ "configurationService.workspace.machineSetting": "userValue" }'); + fs.writeFileSync(globalSettingsFile, '{ "configurationService.workspace.machineSetting": "userValue" }'); fs.writeFileSync(workspaceContextService.getWorkspace().folders[0].toResource('.vscode/settings.json').fsPath, '{ "configurationService.workspace.machineSetting": "workspaceFolderValue" }'); return testObject.reloadConfiguration() .then(() => assert.equal(testObject.getValue('configurationService.workspace.machineSetting'), 'userValue')); }); test('application settings are not read from workspace folder after defaults are registered', () => { - fs.writeFileSync(environmentService.settingsResource.fsPath, '{ "configurationService.workspace.testNewApplicationSetting": "userValue" }'); + fs.writeFileSync(globalSettingsFile, '{ "configurationService.workspace.testNewApplicationSetting": "userValue" }'); fs.writeFileSync(workspaceContextService.getWorkspace().folders[0].toResource('.vscode/settings.json').fsPath, '{ "configurationService.workspace.testNewApplicationSetting": "workspaceFolderValue" }'); return testObject.reloadConfiguration() .then(() => { @@ -1176,7 +1187,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => { }); test('application settings are not read from workspace folder after defaults are registered', () => { - fs.writeFileSync(environmentService.settingsResource.fsPath, '{ "configurationService.workspace.testNewMachineSetting": "userValue" }'); + fs.writeFileSync(globalSettingsFile, '{ "configurationService.workspace.testNewMachineSetting": "userValue" }'); fs.writeFileSync(workspaceContextService.getWorkspace().folders[0].toResource('.vscode/settings.json').fsPath, '{ "configurationService.workspace.testNewMachineSetting": "workspaceFolderValue" }'); return testObject.reloadConfiguration() .then(() => { @@ -1230,7 +1241,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => { assert.equal(actual.workspaceFolder, undefined); assert.equal(actual.value, 'isSet'); - fs.writeFileSync(environmentService.settingsResource.fsPath, '{ "configurationService.workspace.testResourceSetting": "userValue" }'); + fs.writeFileSync(globalSettingsFile, '{ "configurationService.workspace.testResourceSetting": "userValue" }'); return testObject.reloadConfiguration() .then(() => { actual = testObject.inspect('configurationService.workspace.testResourceSetting'); @@ -1474,15 +1485,14 @@ suite('WorkspaceConfigurationService - Remote Folder', () => { remoteSettingsFile = path.join(parentDir, 'remote-settings.json'); instantiationService = workbenchInstantiationService(); - const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); + const environmentService = new TestEnvironmentService(URI.file(parentDir)); const remoteEnvironmentPromise = new Promise>(c => resolveRemoteEnvironment = () => c({ settingsPath: URI.file(remoteSettingsFile).with({ scheme: Schemas.vscodeRemote, authority: remoteAuthority }) })); const remoteAgentService = instantiationService.stub(IRemoteAgentService, >{ getEnvironment: () => remoteEnvironmentPromise }); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, diskFileSystemProvider); - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; + fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, diskFileSystemProvider, environmentService)); const configurationCache: IConfigurationCache = { read: () => Promise.resolve(''), write: () => Promise.resolve(), remove: () => Promise.resolve() }; - testObject = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache, remoteAuthority }, configurationFileService, remoteAgentService); + testObject = new WorkspaceService({ configurationCache, remoteAuthority }, environmentService, fileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); instantiationService.stub(IEnvironmentService, environmentService); @@ -1576,26 +1586,26 @@ suite('WorkspaceConfigurationService - Remote Folder', () => { return promise; }); - test('update remote settings', async () => { - registerRemoteFileSystemProvider(); - resolveRemoteEnvironment(); - await initialize(); - assert.equal(testObject.getValue('configurationService.remote.machineSetting'), 'isSet'); - const promise = new Promise((c, e) => { - testObject.onDidChangeConfiguration(event => { - try { - assert.equal(event.source, ConfigurationTarget.USER); - assert.deepEqual(event.affectedKeys, ['configurationService.remote.machineSetting']); - assert.equal(testObject.getValue('configurationService.remote.machineSetting'), 'remoteValue'); - c(); - } catch (error) { - e(error); - } - }); - }); - await instantiationService.get(IFileService).writeFile(URI.file(remoteSettingsFile), VSBuffer.fromString('{ "configurationService.remote.machineSetting": "remoteValue" }')); - return promise; - }); + // test('update remote settings', async () => { + // registerRemoteFileSystemProvider(); + // resolveRemoteEnvironment(); + // await initialize(); + // assert.equal(testObject.getValue('configurationService.remote.machineSetting'), 'isSet'); + // const promise = new Promise((c, e) => { + // testObject.onDidChangeConfiguration(event => { + // try { + // assert.equal(event.source, ConfigurationTarget.USER); + // assert.deepEqual(event.affectedKeys, ['configurationService.remote.machineSetting']); + // assert.equal(testObject.getValue('configurationService.remote.machineSetting'), 'remoteValue'); + // c(); + // } catch (error) { + // e(error); + // } + // }); + // }); + // await instantiationService.get(IFileService).writeFile(URI.file(remoteSettingsFile), VSBuffer.fromString('{ "configurationService.remote.machineSetting": "remoteValue" }')); + // return promise; + // }); test('machine settings in local user settings does not override defaults', async () => { fs.writeFileSync(globalSettingsFile, '{ "configurationService.remote.machineSetting": "globalValue" }'); diff --git a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts index c9a8760aa96..bcf4b31cef9 100644 --- a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts @@ -19,8 +19,9 @@ import { AbstractVariableResolverService } from 'vs/workbench/services/configura import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; import { IQuickInputService, IInputOptions, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput'; -import { ConfiguredInput } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; +import { ConfiguredInput, IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IProcessEnvironment } from 'vs/base/common/platform'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export abstract class BaseConfigurationResolverService extends AbstractVariableResolverService { @@ -304,4 +305,6 @@ export class ConfigurationResolverService extends BaseConfigurationResolverServi ) { super(environmentService.configuration.userEnv, editorService, environmentService, configurationService, commandService, workspaceContextService, quickInputService); } -} \ No newline at end of file +} + +registerSingleton(IConfigurationResolverService, ConfigurationResolverService, true); \ No newline at end of file diff --git a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts index 3d1e2a813c7..43d8013dc31 100644 --- a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts @@ -35,7 +35,7 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe private _context: IVariableResolveContext, private _envVariables: IProcessEnvironment ) { - if (isWindows) { + if (isWindows && _envVariables) { this._envVariables = Object.create(null); Object.keys(_envVariables).forEach(key => { this._envVariables[key.toLowerCase()] = _envVariables[key]; diff --git a/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts b/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts index 8a389cc3c44..f0a715d5868 100644 --- a/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts +++ b/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IAction, IActionRunner, ActionRunner } from 'vs/base/common/actions'; +import { IAction, IActionRunner, ActionRunner, WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import * as dom from 'vs/base/browser/dom'; import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; @@ -173,13 +173,7 @@ class NativeContextMenuService extends Disposable implements IContextMenuService } private async runAction(actionRunner: IActionRunner, actionToRun: IAction, delegate: IContextMenuDelegate, event: IContextMenuEvent): Promise { - /* __GDPR__ - "workbenchActionExecuted" : { - "id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('workbenchActionExecuted', { id: actionToRun.id, from: 'contextMenu' }); + this.telemetryService.publicLog2('workbenchActionExecuted', { id: actionToRun.id, from: 'contextMenu' }); const context = delegate.getActionsContext ? delegate.getActionsContext(event) : event; diff --git a/src/vs/workbench/services/decorations/browser/decorationsService.ts b/src/vs/workbench/services/decorations/browser/decorationsService.ts index b183a2629d8..1a4e587636a 100644 --- a/src/vs/workbench/services/decorations/browser/decorationsService.ts +++ b/src/vs/workbench/services/decorations/browser/decorationsService.ts @@ -7,7 +7,7 @@ import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { IDecorationsService, IDecoration, IResourceDecorationChangeEvent, IDecorationsProvider, IDecorationData } from './decorations'; import { TernarySearchTree } from 'vs/base/common/map'; -import { Disposable, IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { isThenable } from 'vs/base/common/async'; import { LinkedList } from 'vs/base/common/linkedList'; import { createStyleSheet, createCSSRule, removeCSSRulesContainingSelector } from 'vs/base/browser/dom'; @@ -334,15 +334,14 @@ class DecorationProviderWrapper { } } -export class FileDecorationsService implements IDecorationsService { +export class FileDecorationsService extends Disposable implements IDecorationsService { _serviceBrand: any; private readonly _data = new LinkedList(); - private readonly _onDidChangeDecorationsDelayed = new Emitter(); - private readonly _onDidChangeDecorations = new Emitter(); + private readonly _onDidChangeDecorationsDelayed = this._register(new Emitter()); + private readonly _onDidChangeDecorations = this._register(new Emitter()); private readonly _decorationStyles: DecorationStyles; - private readonly _disposables: IDisposable[]; readonly onDidChangeDecorations: Event = Event.any( this._onDidChangeDecorations.event, @@ -356,27 +355,17 @@ export class FileDecorationsService implements IDecorationsService { constructor( @IThemeService themeService: IThemeService ) { - this._decorationStyles = new DecorationStyles(themeService); + super(); + this._decorationStyles = this._register(new DecorationStyles(themeService)); // every so many events we check if there are // css styles that we don't need anymore let count = 0; - let reg = this.onDidChangeDecorations(() => { + this._register(this.onDidChangeDecorations(() => { if (++count % 17 === 0) { this._decorationStyles.cleanUp(this._data.iterator()); } - }); - - this._disposables = [ - reg, - this._decorationStyles - ]; - } - - dispose(): void { - dispose(this._disposables); - dispose(this._onDidChangeDecorations); - dispose(this._onDidChangeDecorationsDelayed); + })); } registerDecorationsProvider(provider: IDecorationsProvider): IDisposable { diff --git a/src/vs/workbench/services/dialogs/browser/fileDialogService.ts b/src/vs/workbench/services/dialogs/browser/fileDialogService.ts index c5792b4a904..8c04023b954 100644 --- a/src/vs/workbench/services/dialogs/browser/fileDialogService.ts +++ b/src/vs/workbench/services/dialogs/browser/fileDialogService.ts @@ -91,7 +91,8 @@ export class FileDialogService implements IFileDialogService { } private ensureFileSchema(schema: string): string[] { - return schema !== Schemas.file ? [schema, Schemas.file] : [schema]; + // Don't allow untitled schema through. + return schema === Schemas.untitled ? [Schemas.file] : (schema !== Schemas.file ? [schema, Schemas.file] : [schema]); } async pickFileFolderAndOpen(options: IPickAndOpenOptions): Promise { @@ -187,7 +188,27 @@ export class FileDialogService implements IFileDialogService { return this.windowService.pickWorkspaceAndOpen(this.toNativeOpenDialogOptions(options)); } + async pickFileToSave(options: ISaveDialogOptions): Promise { + const schema = this.getFileSystemSchema(options); + if (this.shouldUseSimplified(schema)) { + if (!options.availableFileSystems) { + options.availableFileSystems = this.ensureFileSchema(schema); // always allow file as well + } + + options.title = nls.localize('saveFileAs.title', 'Save As'); + return this.saveRemoteResource(options); + } + + const result = await this.windowService.showSaveDialog(this.toNativeSaveDialogOptions(options)); + if (result) { + return URI.file(result); + } + + return; + } + private toNativeSaveDialogOptions(options: ISaveDialogOptions): Electron.SaveDialogOptions { + options.defaultUri = options.defaultUri ? URI.file(options.defaultUri.path) : undefined; return { defaultPath: options.defaultUri && options.defaultUri.fsPath, buttonLabel: options.saveLabel, @@ -267,12 +288,12 @@ export class FileDialogService implements IFileDialogService { return remoteFileDialog.showSaveDialog(options); } - private getSchemeFilterForWindow() { + private getSchemeFilterForWindow(): string { return !this.environmentService.configuration.remoteAuthority ? Schemas.file : REMOTE_HOST_SCHEME; } private getFileSystemSchema(options: { availableFileSystems?: string[], defaultUri?: URI }): string { - return options.availableFileSystems && options.availableFileSystems[0] || options.defaultUri && options.defaultUri.scheme || this.getSchemeFilterForWindow(); + return options.availableFileSystems && options.availableFileSystems[0] || this.getSchemeFilterForWindow(); } } diff --git a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts index f3cdff21d80..7c70bf3fecb 100644 --- a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts @@ -23,13 +23,15 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { equalsIgnoreCase, format, startsWithIgnoreCase } from 'vs/base/common/strings'; -import { OpenLocalFileAction, OpenLocalFileFolderAction, OpenLocalFolderAction } from 'vs/workbench/browser/actions/workspaceActions'; +import { OpenLocalFileCommand, OpenLocalFileFolderCommand, OpenLocalFolderCommand, SaveLocalFileCommand } from 'vs/workbench/browser/actions/workspaceActions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; import { isValidBasename } from 'vs/base/common/extpath'; import { RemoteFileDialogContext } from 'vs/workbench/browser/contextkeys'; import { Emitter } from 'vs/base/common/event'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { createCancelablePromise, CancelablePromise } from 'vs/base/common/async'; +import { CancellationToken } from 'vs/base/common/cancellation'; interface FileQuickPickItem extends IQuickPickItem { uri: URI; @@ -63,6 +65,7 @@ export class RemoteFileDialog { private remoteAgentEnvironment: IRemoteAgentEnvironment | null; private separator: string; private onBusyChangeEmitter = new Emitter(); + private updatingPromise: CancelablePromise | undefined; protected disposables: IDisposable[] = [ this.onBusyChangeEmitter @@ -98,7 +101,7 @@ export class RemoteFileDialog { } public async showOpenDialog(options: IOpenDialogOptions = {}): Promise { - this.scheme = this.getScheme(options.defaultUri, options.availableFileSystems); + this.scheme = this.getScheme(options.availableFileSystems); this.userHome = await this.getUserHome(); const newOptions = await this.getOptions(options); if (!newOptions) { @@ -109,7 +112,7 @@ export class RemoteFileDialog { } public async showSaveDialog(options: ISaveDialogOptions): Promise { - this.scheme = this.getScheme(options.defaultUri, options.availableFileSystems); + this.scheme = this.getScheme(options.availableFileSystems); this.userHome = await this.getUserHome(); this.requiresTrailing = true; const newOptions = await this.getOptions(options, true); @@ -128,9 +131,13 @@ export class RemoteFileDialog { } private getOptions(options: ISaveDialogOptions | IOpenDialogOptions, isSave: boolean = false): IOpenDialogOptions | undefined { - let defaultUri = options.defaultUri; - const filename = (defaultUri && isSave && (resources.dirname(defaultUri).path === '/')) ? resources.basename(defaultUri) : undefined; - if (!defaultUri || filename) { + let defaultUri: URI | undefined = undefined; + let filename: string | undefined = undefined; + if (options.defaultUri) { + defaultUri = (this.scheme === options.defaultUri.scheme) ? options.defaultUri : undefined; + filename = isSave ? resources.basename(options.defaultUri) : undefined; + } + if (!defaultUri) { defaultUri = this.userHome; if (filename) { defaultUri = resources.joinPath(defaultUri, filename); @@ -150,8 +157,8 @@ export class RemoteFileDialog { return resources.toLocalResource(URI.from({ scheme: this.scheme, path }), this.scheme === Schemas.file ? undefined : this.remoteAuthority); } - private getScheme(defaultUri: URI | undefined, available: string[] | undefined): string { - return defaultUri ? defaultUri.scheme : (available ? available[0] : Schemas.file); + private getScheme(available: string[] | undefined): string { + return available ? available[0] : Schemas.file; } private async getRemoteAgentEnvironment(): Promise { @@ -208,10 +215,15 @@ export class RemoteFileDialog { this.filePickBox.autoFocusOnList = false; this.filePickBox.ignoreFocusOut = true; this.filePickBox.ok = true; - if (this.options && this.options.availableFileSystems && (this.options.availableFileSystems.length > 1)) { + if (this.options && this.options.availableFileSystems && (this.options.availableFileSystems.length > 1) && (this.options.availableFileSystems.indexOf(Schemas.file) > -1)) { this.filePickBox.customButton = true; this.filePickBox.customLabel = nls.localize('remoteFileDialog.local', 'Show Local'); - const action = this.allowFileSelection ? (this.allowFolderSelection ? OpenLocalFileFolderAction : OpenLocalFileAction) : OpenLocalFolderAction; + let action; + if (isSave) { + action = SaveLocalFileCommand; + } else { + action = this.allowFileSelection ? (this.allowFolderSelection ? OpenLocalFileFolderCommand : OpenLocalFileCommand) : OpenLocalFolderCommand; + } const keybinding = this.keybindingService.lookupKeybinding(action.ID); if (keybinding) { const label = keybinding.getLabel(); @@ -223,7 +235,7 @@ export class RemoteFileDialog { let isResolving: number = 0; let isAcceptHandled = false; - this.currentFolder = homedir; + this.currentFolder = resources.dirname(homedir); this.userEnteredPathSegment = ''; this.autoCompletePathSegment = ''; @@ -233,6 +245,9 @@ export class RemoteFileDialog { this.filePickBox.items = []; function doResolve(dialog: RemoteFileDialog, uri: URI | undefined) { + if (uri) { + uri = resources.removeTrailingPathSeparator(uri); + } resolve(uri); dialog.contextKey.set(false); dialog.filePickBox.dispose(); @@ -249,9 +264,8 @@ export class RemoteFileDialog { if (this.options.availableFileSystems && (this.options.availableFileSystems.length > 1)) { this.options.availableFileSystems.shift(); } - this.options.defaultUri = undefined; this.filePickBox.hide(); - if (this.requiresTrailing) { + if (isSave) { return this.fileDialogService.showSaveDialog(this.options).then(result => { doResolve(this, result); }); @@ -297,16 +311,21 @@ export class RemoteFileDialog { this.filePickBox.onDidChangeActive(i => { isAcceptHandled = false; // update input box to match the first selected item - if ((i.length === 1) && this.isChangeFromUser()) { + if ((i.length === 1) && this.isSelectionChangeFromUser()) { this.filePickBox.validationMessage = undefined; - this.setAutoComplete(this.constructFullUserPath(), this.userEnteredPathSegment, i[0], true); + const userPath = this.constructFullUserPath(); + if (!equalsIgnoreCase(this.filePickBox.value.substring(0, userPath.length), userPath)) { + this.filePickBox.valueSelection = [0, this.filePickBox.value.length]; + this.insertText(userPath, userPath); + } + this.setAutoComplete(userPath, this.userEnteredPathSegment, i[0], true); } }); this.filePickBox.onDidChangeValue(async value => { try { // onDidChangeValue can also be triggered by the auto complete, so if it looks like the auto complete, don't do anything - if (this.isChangeFromUser()) { + if (this.isValueChangeFromUser()) { // If the user has just entered more bad path, don't change anything if (!equalsIgnoreCase(value, this.constructFullUserPath()) && !this.isBadSubpath(value)) { this.filePickBox.validationMessage = undefined; @@ -320,6 +339,7 @@ export class RemoteFileDialog { } } else { this.filePickBox.activeItems = []; + this.userEnteredPathSegment = ''; } } } catch { @@ -349,16 +369,27 @@ export class RemoteFileDialog { return this.badPath && (value.length > this.badPath.length) && equalsIgnoreCase(value.substring(0, this.badPath.length), this.badPath); } - private isChangeFromUser(): boolean { - if (equalsIgnoreCase(this.filePickBox.value, this.pathAppend(this.currentFolder, this.userEnteredPathSegment + this.autoCompletePathSegment)) - && (this.activeItem === (this.filePickBox.activeItems ? this.filePickBox.activeItems[0] : undefined))) { + private isValueChangeFromUser(): boolean { + if (equalsIgnoreCase(this.filePickBox.value, this.pathAppend(this.currentFolder, this.userEnteredPathSegment + this.autoCompletePathSegment))) { + return false; + } + return true; + } + + private isSelectionChangeFromUser(): boolean { + if (this.activeItem === (this.filePickBox.activeItems ? this.filePickBox.activeItems[0] : undefined)) { return false; } return true; } private constructFullUserPath(): string { - return this.pathAppend(this.currentFolder, this.userEnteredPathSegment); + const currentFolderPath = this.pathFromUri(this.currentFolder); + if (equalsIgnoreCase(this.filePickBox.value.substr(0, this.userEnteredPathSegment.length), this.userEnteredPathSegment) && equalsIgnoreCase(this.filePickBox.value.substr(0, currentFolderPath.length), currentFolderPath)) { + return currentFolderPath; + } else { + return this.pathAppend(this.currentFolder, this.userEnteredPathSegment); + } } private filePickBoxValue(): URI { @@ -372,7 +403,11 @@ export class RemoteFileDialog { const relativePath = resources.relativePath(currentDisplayUri, directUri); const isSameRoot = (this.filePickBox.value.length > 1 && currentPath.length > 1) ? equalsIgnoreCase(this.filePickBox.value.substr(0, 2), currentPath.substr(0, 2)) : false; if (relativePath && isSameRoot) { - const path = resources.joinPath(this.currentFolder, relativePath); + let path = resources.joinPath(this.currentFolder, relativePath); + const directBasename = resources.basename(directUri); + if ((directBasename === '.') || (directBasename === '..')) { + path = this.remoteUriFrom(this.pathAppend(path, directBasename)); + } return resources.hasTrailingPathSeparator(directUri) ? resources.addTrailingPathSeparator(path) : path; } else { return directUri; @@ -463,7 +498,7 @@ export class RemoteFileDialog { } catch (e) { // do nothing } - if (statWithoutTrailing && statWithoutTrailing.isDirectory && (resources.basename(valueUri) !== '.')) { + if (statWithoutTrailing && statWithoutTrailing.isDirectory) { await this.updateItems(inputUriDirname, false, resources.basename(valueUri)); this.badPath = undefined; return UpdateResult.Updated; @@ -481,11 +516,13 @@ export class RemoteFileDialog { const userPath = this.constructFullUserPath(); if (equalsIgnoreCase(userPath, value.substring(0, userPath.length))) { let hasMatch = false; - for (let i = 0; i < this.filePickBox.items.length; i++) { - const item = this.filePickBox.items[i]; - if (this.setAutoComplete(value, inputBasename, item)) { - hasMatch = true; - break; + if (inputBasename.length > this.userEnteredPathSegment.length) { + for (let i = 0; i < this.filePickBox.items.length; i++) { + const item = this.filePickBox.items[i]; + if (this.setAutoComplete(value, inputBasename, item)) { + hasMatch = true; + break; + } } } if (!hasMatch) { @@ -494,11 +531,7 @@ export class RemoteFileDialog { this.filePickBox.activeItems = []; } } else { - if (!equalsIgnoreCase(inputBasename, resources.basename(this.currentFolder))) { - this.userEnteredPathSegment = inputBasename; - } else { - this.userEnteredPathSegment = ''; - } + this.userEnteredPathSegment = inputBasename; this.autoCompletePathSegment = ''; } } @@ -514,7 +547,7 @@ export class RemoteFileDialog { // Either force the autocomplete, or the old value should be one smaller than the new value and match the new value. if (itemBasename === '..') { // Don't match on the up directory item ever. - this.userEnteredPathSegment = startingValue; + this.userEnteredPathSegment = ''; this.autoCompletePathSegment = ''; this.activeItem = quickPickItem; if (force) { @@ -675,27 +708,43 @@ export class RemoteFileDialog { this.busy = true; this.userEnteredPathSegment = trailing ? trailing : ''; this.autoCompletePathSegment = ''; - const newValue = trailing ? this.pathFromUri(resources.joinPath(newFolder, trailing)) : this.pathFromUri(newFolder, true); + const newValue = trailing ? this.pathAppend(newFolder, trailing) : this.pathFromUri(newFolder, true); this.currentFolder = resources.addTrailingPathSeparator(newFolder, this.separator); - return this.createItems(this.currentFolder).then(items => { - this.filePickBox.items = items; - if (this.allowFolderSelection) { - this.filePickBox.activeItems = []; - } - // the user might have continued typing while we were updating. Only update the input box if it doesn't match the directory. - if (!equalsIgnoreCase(this.filePickBox.value, newValue) && force) { - this.filePickBox.valueSelection = [0, this.filePickBox.value.length]; - this.insertText(newValue, newValue); - } - if (force && trailing) { - // Keep the cursor position in front of the save as name. - this.filePickBox.valueSelection = [this.filePickBox.value.length - trailing.length, this.filePickBox.value.length - trailing.length]; - } else if (!trailing) { - // If there is trailing, we don't move the cursor. If there is no trailing, cursor goes at the end. - this.filePickBox.valueSelection = [this.filePickBox.value.length, this.filePickBox.value.length]; - } - this.busy = false; + + const updatingPromise = createCancelablePromise(async token => { + return this.createItems(this.currentFolder, token).then(items => { + if (token.isCancellationRequested) { + this.busy = false; + return; + } + + this.filePickBox.items = items; + if (this.allowFolderSelection) { + this.filePickBox.activeItems = []; + } + // the user might have continued typing while we were updating. Only update the input box if it doesn't matche directory. + if (!equalsIgnoreCase(this.filePickBox.value, newValue) && force) { + this.filePickBox.valueSelection = [0, this.filePickBox.value.length]; + this.insertText(newValue, newValue); + } + if (force && trailing) { + // Keep the cursor position in front of the save as name. + this.filePickBox.valueSelection = [this.filePickBox.value.length - trailing.length, this.filePickBox.value.length - trailing.length]; + } else if (!trailing) { + // If there is trailing, we don't move the cursor. If there is no trailing, cursor goes at the end. + this.filePickBox.valueSelection = [this.filePickBox.value.length, this.filePickBox.value.length]; + } + this.busy = false; + this.updatingPromise = undefined; + }); }); + + if (this.updatingPromise !== undefined) { + this.updatingPromise.cancel(); + } + this.updatingPromise = updatingPromise; + + return updatingPromise; } private pathFromUri(uri: URI, endWithSeparator: boolean = false): string { @@ -714,7 +763,7 @@ export class RemoteFileDialog { private pathAppend(uri: URI, additional: string): string { if ((additional === '..') || (additional === '.')) { const basePath = this.pathFromUri(uri); - return basePath + (this.endsWithSlash(basePath) ? '' : this.separator) + additional; + return basePath + this.separator + additional; } else { return this.pathFromUri(resources.joinPath(uri, additional)); } @@ -747,14 +796,14 @@ export class RemoteFileDialog { return null; } - private async createItems(currentFolder: URI): Promise { + private async createItems(currentFolder: URI, token: CancellationToken): Promise { const result: FileQuickPickItem[] = []; const backDir = this.createBackItem(currentFolder); try { const folder = await this.fileService.resolve(currentFolder); const fileNames = folder.children ? folder.children.map(child => child.name) : []; - const items = await Promise.all(fileNames.map(fileName => this.createItem(fileName, currentFolder))); + const items = await Promise.all(fileNames.map(fileName => this.createItem(fileName, currentFolder, token))); for (let item of items) { if (item) { result.push(item); @@ -764,6 +813,9 @@ export class RemoteFileDialog { // ignore console.log(e); } + if (token.isCancellationRequested) { + return []; + } const sorted = result.sort((i1, i2) => { if (i1.isFolder !== i2.isFolder) { return i1.isFolder ? -1 : 1; @@ -794,7 +846,10 @@ export class RemoteFileDialog { return true; } - private async createItem(filename: string, parent: URI): Promise { + private async createItem(filename: string, parent: URI, token: CancellationToken): Promise { + if (token.isCancellationRequested) { + return undefined; + } let fullPath = resources.joinPath(parent, filename); try { const stat = await this.fileService.resolve(fullPath); diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 683b344b9dd..3211d6adeb4 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -21,7 +21,7 @@ import { localize } from 'vs/nls'; import { IEditorGroupsService, IEditorGroup, GroupsOrder, IEditorReplacement, GroupChangeKind, preferredSideBySideGroupDirection } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IResourceEditor, ACTIVE_GROUP_TYPE, SIDE_GROUP_TYPE, SIDE_GROUP, IResourceEditorReplacement, IOpenEditorOverrideHandler, IVisibleEditor, IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { coalesce } from 'vs/base/common/arrays'; import { isCodeEditor, isDiffEditor, ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { IEditorGroupView, IEditorOpeningEvent, EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor'; @@ -118,29 +118,29 @@ export class EditorService extends Disposable implements EditorServiceImpl { } private registerGroupListeners(group: IEditorGroupView): void { - const groupDisposeables: IDisposable[] = []; + const groupDisposables = new DisposableStore(); - groupDisposeables.push(group.onDidGroupChange(e => { + groupDisposables.add(group.onDidGroupChange(e => { if (e.kind === GroupChangeKind.EDITOR_ACTIVE) { this.handleActiveEditorChange(group); this._onDidVisibleEditorsChange.fire(); } })); - groupDisposeables.push(group.onDidCloseEditor(event => { + groupDisposables.add(group.onDidCloseEditor(event => { this._onDidCloseEditor.fire(event); })); - groupDisposeables.push(group.onWillOpenEditor(event => { + groupDisposables.add(group.onWillOpenEditor(event => { this.onGroupWillOpenEditor(group, event); })); - groupDisposeables.push(group.onDidOpenEditorFail(editor => { + groupDisposables.add(group.onDidOpenEditorFail(editor => { this._onDidOpenEditorFail.fire({ editor, groupId: group.id }); })); Event.once(group.onWillDispose)(() => { - dispose(groupDisposeables); + dispose(groupDisposables); }); } diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index 91b2ea587f3..ac6ff2b537c 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -232,12 +232,12 @@ export interface IEditorGroupsService { /** * Returns the size of a group. */ - getSize(group: IEditorGroup | GroupIdentifier): number; + getSize(group: IEditorGroup | GroupIdentifier): { width: number, height: number }; /** * Sets the size of a group. */ - setSize(group: IEditorGroup | GroupIdentifier, size: number): void; + setSize(group: IEditorGroup | GroupIdentifier, size: { width: number, height: number }): void; /** * Arrange all groups according to the provided arrangement. diff --git a/src/vs/workbench/services/editor/test/browser/editorService.test.ts b/src/vs/workbench/services/editor/test/browser/editorService.test.ts index 658a4a84e77..81cbc839a9b 100644 --- a/src/vs/workbench/services/editor/test/browser/editorService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorService.test.ts @@ -8,7 +8,7 @@ import { IEditorModel } from 'vs/platform/editor/common/editor'; import { URI } from 'vs/base/common/uri'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorInput, EditorOptions, IFileEditorInput, IEditorInput } from 'vs/workbench/common/editor'; -import { workbenchInstantiationService, TestStorageService, NullFileSystemProvider } from 'vs/workbench/test/workbenchTestServices'; +import { workbenchInstantiationService, TestStorageService } from 'vs/workbench/test/workbenchTestServices'; import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { EditorService, DelegatingEditorService } from 'vs/workbench/services/editor/browser/editorService'; @@ -31,6 +31,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { Disposable } from 'vs/base/common/lifecycle'; import { ModesRegistry } from 'vs/editor/common/modes/modesRegistry'; import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel'; +import { NullFileSystemProvider } from 'vs/platform/files/test/common/nullFileSystemProvider'; export class TestEditorControl extends BaseEditor { diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts new file mode 100644 index 00000000000..6ee56a1d50e --- /dev/null +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -0,0 +1,154 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IWindowConfiguration, IPath, IPathsToWaitFor } from 'vs/platform/windows/common/windows'; +import { IEnvironmentService, IExtensionHostDebugParams, IDebugParams, BACKUPS } from 'vs/platform/environment/common/environment'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { URI } from 'vs/base/common/uri'; +import { IProcessEnvironment } from 'vs/base/common/platform'; +import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { ExportData } from 'vs/base/common/performance'; +import { LogLevel } from 'vs/platform/log/common/log'; +import { joinPath } from 'vs/base/common/resources'; +import { Schemas } from 'vs/base/common/network'; + +export class BrowserWindowConfiguration implements IWindowConfiguration { + + _: any[]; + + machineId: string; + windowId: number; + logLevel: LogLevel; + + mainPid: number; + + appRoot: string; + execPath: string; + isInitialStartup?: boolean; + + userEnv: IProcessEnvironment; + nodeCachedDataDir?: string; + + backupPath?: string; + + workspace?: IWorkspaceIdentifier; + folderUri?: ISingleFolderWorkspaceIdentifier; + + remoteAuthority: string; + + zoomLevel?: number; + fullscreen?: boolean; + maximized?: boolean; + highContrast?: boolean; + frameless?: boolean; + accessibilitySupport?: boolean; + partsSplashPath?: string; + + perfStartTime?: number; + perfAppReady?: number; + perfWindowLoadTime?: number; + perfEntries: ExportData; + + filesToOpenOrCreate?: IPath[]; + filesToDiff?: IPath[]; + filesToWait?: IPathsToWaitFor; + termProgram?: string; +} + +export interface IBrowserWindowConfiguration { + workspaceId: string; + remoteAuthority?: string; + webviewEndpoint?: string; +} + +export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { + _serviceBrand: ServiceIdentifier; + + readonly configuration: IWindowConfiguration = new BrowserWindowConfiguration(); + + constructor(configuration: IBrowserWindowConfiguration) { + this.args = { _: [] }; + this.appRoot = '/web/'; + this.appNameLong = 'Visual Studio Code - Web'; + + this.configuration.remoteAuthority = configuration.remoteAuthority; + this.userRoamingDataHome = URI.file('/User').with({ scheme: Schemas.userData }); + this.settingsResource = joinPath(this.userRoamingDataHome, 'settings.json'); + this.keybindingsResource = joinPath(this.userRoamingDataHome, 'keybindings.json'); + this.keyboardLayoutResource = joinPath(this.userRoamingDataHome, 'keyboardLayout.json'); + this.localeResource = joinPath(this.userRoamingDataHome, 'locale.json'); + this.backupHome = joinPath(this.userRoamingDataHome, BACKUPS); + this.configuration.backupWorkspaceResource = joinPath(this.backupHome, configuration.workspaceId); + + this.logsPath = '/web/logs'; + + this.debugExtensionHost = { + port: null, + break: false + }; + + this.webviewEndpoint = configuration.webviewEndpoint; + this.untitledWorkspacesHome = URI.from({ scheme: Schemas.untitled, path: 'Workspaces' }); + } + + untitledWorkspacesHome: URI; + extensionTestsLocationURI?: URI; + args: any; + execPath: string; + cliPath: string; + appRoot: string; + userHome: string; + userDataPath: string; + appNameLong: string; + appQuality?: string; + appSettingsHome: URI; + userRoamingDataHome: URI; + settingsResource: URI; + keybindingsResource: URI; + keyboardLayoutResource: URI; + localeResource: URI; + machineSettingsHome: URI; + machineSettingsResource: URI; + globalStorageHome: string; + workspaceStorageHome: string; + backupHome: URI; + backupWorkspacesPath: string; + workspacesHome: string; + isExtensionDevelopment: boolean; + disableExtensions: boolean | string[]; + builtinExtensionsPath: string; + extensionsPath: string; + extensionDevelopmentLocationURI?: URI[]; + extensionTestsPath?: string; + debugExtensionHost: IExtensionHostDebugParams; + debugSearch: IDebugParams; + logExtensionHostCommunication: boolean; + isBuilt: boolean; + wait: boolean; + status: boolean; + log?: string; + logsPath: string; + verbose: boolean; + skipGettingStarted: boolean; + skipReleaseNotes: boolean; + skipAddToRecentlyOpened: boolean; + mainIPCHandle: string; + sharedIPCHandle: string; + nodeCachedDataDir?: string; + installSourcePath: string; + disableUpdates: boolean; + disableCrashReporter: boolean; + driverHandle?: string; + driverVerbose: boolean; + webviewEndpoint?: string; + + get webviewResourceRoot(): string { + return this.webviewEndpoint ? this.webviewEndpoint + '/vscode-resource{{resource}}' : 'vscode-resource:{{resource}}'; + } + + get webviewCspSource(): string { + return this.webviewEndpoint ? this.webviewEndpoint : 'vscode-resource:'; + } +} diff --git a/src/vs/workbench/services/environment/common/environmentService.ts b/src/vs/workbench/services/environment/common/environmentService.ts index 84c501ee1ea..fd4beaf134d 100644 --- a/src/vs/workbench/services/environment/common/environmentService.ts +++ b/src/vs/workbench/services/environment/common/environmentService.ts @@ -3,14 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; export const IWorkbenchEnvironmentService = createDecorator('environmentService'); export interface IWorkbenchEnvironmentService extends IEnvironmentService { - _serviceBrand: any; + + _serviceBrand: ServiceIdentifier; readonly configuration: IWindowConfiguration; } diff --git a/src/vs/workbench/services/environment/node/environmentService.ts b/src/vs/workbench/services/environment/node/environmentService.ts index db2a229c03b..8b8b9354b63 100644 --- a/src/vs/workbench/services/environment/node/environmentService.ts +++ b/src/vs/workbench/services/environment/node/environmentService.ts @@ -6,6 +6,10 @@ import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { memoize } from 'vs/base/common/decorators'; +import { URI } from 'vs/base/common/uri'; +import { Schemas } from 'vs/base/common/network'; +import { toBackupWorkspaceResource } from 'vs/workbench/services/backup/common/backup'; export class WorkbenchEnvironmentService extends EnvironmentService implements IWorkbenchEnvironmentService { @@ -16,9 +20,13 @@ export class WorkbenchEnvironmentService extends EnvironmentService implements I execPath: string ) { super(_configuration, execPath); + this._configuration.backupWorkspaceResource = this._configuration.backupPath ? toBackupWorkspaceResource(this._configuration.backupPath, this) : undefined; } get configuration(): IWindowConfiguration { return this._configuration; } + + @memoize + get userRoamingDataHome(): URI { return this.appSettingsHome.with({ scheme: Schemas.userData }); } } diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index 80418f5fad8..d57fa8b1801 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -231,14 +231,12 @@ export abstract class AbstractExtensionService extends Disposable implements IEx public readExtensionPointContributions(extPoint: IExtensionPoint): Promise[]> { return this._installedExtensionsReady.wait().then(() => { - let availableExtensions = this._registry.getAllExtensionDescriptions(); - - let result: ExtensionPointContribution[] = [], resultLen = 0; - for (let i = 0, len = availableExtensions.length; i < len; i++) { - let desc = availableExtensions[i]; + const availableExtensions = this._registry.getAllExtensionDescriptions(); + const result: ExtensionPointContribution[] = []; + for (const desc of availableExtensions) { if (desc.contributes && hasOwnProperty.call(desc.contributes, extPoint.name)) { - result[resultLen++] = new ExtensionPointContribution(desc, desc.contributes[extPoint.name]); + result.push(new ExtensionPointContribution(desc, desc.contributes[extPoint.name as keyof typeof desc.contributes])); } } @@ -320,9 +318,9 @@ export abstract class AbstractExtensionService extends Disposable implements IEx const messageHandler = (msg: IMessage) => this._handleExtensionPointMessage(msg); const availableExtensions = this._registry.getAllExtensionDescriptions(); const extensionPoints = ExtensionsRegistry.getExtensionPoints(); - for (let i = 0, len = extensionPoints.length; i < len; i++) { - if (affectedExtensionPoints[extensionPoints[i].name]) { - AbstractExtensionService._handleExtensionPoint(extensionPoints[i], availableExtensions, messageHandler); + for (const extensionPoint of extensionPoints) { + if (affectedExtensionPoints[extensionPoint.name]) { + AbstractExtensionService._handleExtensionPoint(extensionPoint, availableExtensions, messageHandler); } } } @@ -346,35 +344,38 @@ export abstract class AbstractExtensionService extends Disposable implements IEx if (!this._isDev && msg.extensionId) { const { type, extensionId, extensionPointId, message } = msg; - /* __GDPR__ - "extensionsMessage" : { - "type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "extensionId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "extensionPointId": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "message": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } - } - */ - this._telemetryService.publicLog('extensionsMessage', { + type ExtensionsMessageClassification = { + type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + extensionId: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + extensionPointId: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + message: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + }; + type ExtensionsMessageEvent = { + type: Severity; + extensionId: string; + extensionPointId: string; + message: string; + }; + this._telemetryService.publicLog2('extensionsMessage', { type, extensionId: extensionId.value, extensionPointId, message }); } } private static _handleExtensionPoint(extensionPoint: ExtensionPoint, availableExtensions: IExtensionDescription[], messageHandler: (msg: IMessage) => void): void { - let users: IExtensionPointUser[] = [], usersLen = 0; - for (let i = 0, len = availableExtensions.length; i < len; i++) { - let desc = availableExtensions[i]; - + const users: IExtensionPointUser[] = []; + for (const desc of availableExtensions) { if (desc.contributes && hasOwnProperty.call(desc.contributes, extensionPoint.name)) { - users[usersLen++] = { + users.push({ description: desc, - value: desc.contributes[extensionPoint.name], + value: desc.contributes[extensionPoint.name as keyof typeof desc.contributes], collector: new ExtensionMessageCollector(messageHandler, desc, extensionPoint.name) - }; + }); } } - + perf.mark(`willHandleExtensionPoint/${extensionPoint.name}`); extensionPoint.acceptUsers(users); + perf.mark(`didHandleExtensionPoint/${extensionPoint.name}`); } private _showMessageToUser(severity: Severity, msg: string): void { diff --git a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts index 577cc633360..9776a42da6a 100644 --- a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts +++ b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts @@ -206,7 +206,7 @@ export const schema = { type: 'object', properties: { // extensions will fill in - }, + } as { [key: string]: any }, default: {} }, preview: { diff --git a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts index 75ca5ef552a..9dc5b940cf1 100644 --- a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts +++ b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts @@ -189,13 +189,19 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, globalStorageHome: remoteExtensionHostData.globalStorageHome, - userHome: remoteExtensionHostData.userHome + userHome: remoteExtensionHostData.userHome, + webviewResourceRoot: this._environmentService.webviewResourceRoot, + webviewCspSource: this._environmentService.webviewCspSource, }, workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : { configuration: workspace.configuration, id: workspace.id, name: this._labelService.getWorkspaceLabel(workspace) }, + remote: { + isRemote: true, + authority: this._initDataProvider.remoteAuthority + }, resolvedExtensions: resolvedExtensions, hostExtensions: hostExtensions, extensions: remoteExtensionHostData.extensions, @@ -203,7 +209,6 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH logLevel: this._logService.getLevel(), logsLocation: remoteExtensionHostData.extensionHostLogsPath, autoStart: true, - remoteAuthority: this._initDataProvider.remoteAuthority, }; return r; }); diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 0a153bff244..7b8225ca6ac 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -57,7 +57,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { // Resources, in order they get acquired/created when .start() is called: private _namedPipeServer: Server | null; - private _inspectPort: number; + private _inspectPort: number | null; private _extensionHostProcess: ChildProcess | null; private _extensionHostConnection: Socket | null; private _messageProtocol: Promise | null; @@ -123,7 +123,10 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { } if (!this._messageProtocol) { - this._messageProtocol = Promise.all([this._tryListenOnPipe(), this._tryFindDebugPort()]).then(data => { + this._messageProtocol = Promise.all([ + this._tryListenOnPipe(), + !this._environmentService.args['disable-inspect'] ? this._tryFindDebugPort() : Promise.resolve(null) + ]).then(data => { const pipeName = data[0]; const portData = data[1]; @@ -146,7 +149,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { silent: true }; - if (portData.actual) { + if (portData && portData.actual) { opts.execArgv = [ '--nolazy', (this._isExtensionDevDebugBrk ? '--inspect-brk=' : '--inspect=') + portData.actual @@ -213,10 +216,12 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { this._extensionHostProcess.on('exit', (code: number, signal: string) => this._onExtHostProcessExit(code, signal)); // Notify debugger that we are ready to attach to the process if we run a development extension - if (this._isExtensionDevHost && portData.actual && this._isExtensionDevDebug && this._environmentService.debugExtensionHost.debugId) { - this._extensionHostDebugService.attachSession(this._environmentService.debugExtensionHost.debugId, portData.actual); + if (portData) { + if (this._isExtensionDevHost && portData.actual && this._isExtensionDevDebug && this._environmentService.debugExtensionHost.debugId) { + this._extensionHostDebugService.attachSession(this._environmentService.debugExtensionHost.debugId, portData.actual); + } + this._inspectPort = portData.actual; } - this._inspectPort = portData.actual; // Help in case we fail to start it let startupTimeoutHandle: any; @@ -394,7 +399,9 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, globalStorageHome: URI.file(this._environmentService.globalStorageHome), - userHome: URI.file(this._environmentService.userHome) + userHome: URI.file(this._environmentService.userHome), + webviewResourceRoot: this._environmentService.webviewResourceRoot, + webviewCspSource: this._environmentService.webviewCspSource, }, workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? undefined : { configuration: withNullAsUndefined(workspace.configuration), @@ -402,6 +409,10 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { name: this._labelService.getWorkspaceLabel(workspace), isUntitled: workspace.configuration ? isEqualOrParent(workspace.configuration, this._environmentService.untitledWorkspacesHome) : false }, + remote: { + authority: this._environmentService.configuration.remoteAuthority, + isRemote: false + }, resolvedExtensions: [], hostExtensions: [], extensions: extensionDescriptions, @@ -452,20 +463,8 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { this._onExit.fire([code, signal]); } - public enableInspector(): Promise { - if (this._inspectPort) { - return Promise.resolve(); - } - // send SIGUSR1 and wait a little the actual port is read from the process stdout which we - // scan here: https://github.com/Microsoft/vscode/blob/67ffab8dcd1a6752d8b62bcd13d7020101eef568/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts#L225-L240 - if (this._extensionHostProcess) { - this._extensionHostProcess.kill('SIGUSR1'); - } - return timeout(1000); - } - - public getInspectPort(): number { - return this._inspectPort; + public getInspectPort(): number | undefined { + return withNullAsUndefined(this._inspectPort); } public terminate(): void { diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionManagementServerService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionManagementServerService.ts index 64343563a11..611ab9aec95 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionManagementServerService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionManagementServerService.ts @@ -6,13 +6,17 @@ import { localize } from 'vs/nls'; import { Schemas } from 'vs/base/common/network'; import { URI } from 'vs/base/common/uri'; -import { IExtensionManagementServer, IExtensionManagementServerService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionManagementServer, IExtensionManagementServerService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/node/extensionManagementIpc'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ILogService } from 'vs/platform/log/common/log'; +import { RemoteExtensionManagementChannelClient } from 'vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IProductService } from 'vs/platform/product/common/product'; const localExtensionManagementServerAuthority: string = 'vscode-local'; @@ -25,14 +29,18 @@ export class ExtensionManagementServerService implements IExtensionManagementSer constructor( @ISharedProcessService sharedProcessService: ISharedProcessService, - @IRemoteAgentService remoteAgentService: IRemoteAgentService + @IRemoteAgentService remoteAgentService: IRemoteAgentService, + @IExtensionGalleryService galleryService: IExtensionGalleryService, + @IConfigurationService configurationService: IConfigurationService, + @IProductService productService: IProductService, + @ILogService logService: ILogService ) { const localExtensionManagementService = new ExtensionManagementChannelClient(sharedProcessService.getChannel('extensions')); this.localExtensionManagementServer = { extensionManagementService: localExtensionManagementService, authority: localExtensionManagementServerAuthority, label: localize('local', "Local") }; const remoteAgentConnection = remoteAgentService.getConnection(); if (remoteAgentConnection) { - const extensionManagementService = new ExtensionManagementChannelClient(remoteAgentConnection.getChannel('extensions')); + const extensionManagementService = new RemoteExtensionManagementChannelClient(remoteAgentConnection.getChannel('extensions'), this.localExtensionManagementServer.extensionManagementService, galleryService, logService, configurationService, productService); this.remoteExtensionManagementServer = { authority: remoteAgentConnection.remoteAuthority, extensionManagementService, label: localize('remote', "Remote") }; } } diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index be2007b0449..98b5cf01ba1 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -26,7 +26,7 @@ import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/ import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { IExtensionService, toExtension } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionHostProcessManager } from 'vs/workbench/services/extensions/common/extensionHostProcessManager'; import { ExtensionIdentifier, IExtension, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { Schemas } from 'vs/base/common/network'; @@ -166,13 +166,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten for (let i = 0, len = _toAdd.length; i < len; i++) { const extension = _toAdd[i]; - if (extension.location.scheme !== Schemas.file) { - continue; - } - - const existingExtensionDescription = this._registry.getExtensionDescription(extension.identifier.id); - if (existingExtensionDescription) { - // this extension is already running (most likely at a different version) + if (!this._canAddExtension(extension)) { continue; } @@ -213,6 +207,9 @@ export class ExtensionService extends AbstractExtensionService implements IExten this._logOrShowMessage(Severity.Error, nls.localize('looping', "The following extensions contain dependency loops and have been disabled: {0}", result.removedDueToLooping.map(e => `'${e.identifier.value}'`).join(', '))); } + // enable or disable proposed API per extension + this._checkEnableProposedApi(toAdd); + // Update extension points this._rehandleExtensionPoints(([]).concat(toAdd).concat(toRemove)); @@ -232,21 +229,28 @@ export class ExtensionService extends AbstractExtensionService implements IExten this._doHandleExtensionPoints(extensionDescriptions); } - public canAddExtension(extension: IExtensionDescription): boolean { + public canAddExtension(extensionDescription: IExtensionDescription): boolean { + return this._canAddExtension(toExtension(extensionDescription)); + } + + public _canAddExtension(extension: IExtension): boolean { if (this._environmentService.configuration.remoteAuthority) { return false; } - if (extension.extensionLocation.scheme !== Schemas.file) { + if (extension.location.scheme !== Schemas.file) { return false; } - const extensionDescription = this._registry.getExtensionDescription(extension.identifier); + const extensionDescription = this._registry.getExtensionDescription(extension.identifier.id); if (extensionDescription) { - // ignore adding an extension which is already running and cannot be removed - if (!this._canRemoveExtension(extensionDescription)) { - return false; - } + // this extension is already running (most likely at a different version) + return false; + } + + // Check if extension is renamed + if (extension.identifier.uuid && this._registry.getAllExtensionDescriptions().some(e => e.uuid === extension.identifier.uuid)) { + return false; } return true; @@ -337,7 +341,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten let extensions: Promise; if (isInitialStart) { autoStart = false; - extensions = this._extensionScanner.scannedExtensions; + extensions = this._extensionScanner.scannedExtensions.then(extensions => extensions.filter(extension => this._isEnabled(extension))); // remove disabled extensions } else { // restart case autoStart = true; diff --git a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts new file mode 100644 index 00000000000..6fd6dc821e8 --- /dev/null +++ b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts @@ -0,0 +1,142 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IExtensionManagementService, ILocalExtension, IGalleryExtension, IExtensionGalleryService, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { URI } from 'vs/base/common/uri'; +import { ExtensionType, IExtensionManifest } from 'vs/platform/extensions/common/extensions'; +import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; +import { ILogService } from 'vs/platform/log/common/log'; +import { toErrorMessage } from 'vs/base/common/errorMessage'; +import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil'; +import { isNonEmptyArray } from 'vs/base/common/arrays'; +import { values } from 'vs/base/common/map'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { localize } from 'vs/nls'; +import { IProductService } from 'vs/platform/product/common/product'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/node/extensionManagementIpc'; + +export class RemoteExtensionManagementChannelClient extends ExtensionManagementChannelClient { + + _serviceBrand: any; + + constructor( + channel: IChannel, + private readonly localExtensionManagementService: IExtensionManagementService, + private readonly galleryService: IExtensionGalleryService, + private readonly logService: ILogService, + private readonly configurationService: IConfigurationService, + private readonly productService: IProductService + ) { + super(channel); + } + + async install(vsix: URI): Promise { + const local = await super.install(vsix); + await this.installUIDependenciesAndPackedExtensions(local); + return local; + } + + async installFromGallery(extension: IGalleryExtension): Promise { + const local = await this.doInstallFromGallery(extension); + await this.installUIDependenciesAndPackedExtensions(local); + return local; + } + + private async doInstallFromGallery(extension: IGalleryExtension): Promise { + try { + const local = await super.installFromGallery(extension); + return local; + } catch (error) { + try { + this.logService.error(`Error while installing '${extension.identifier.id}' extension in the remote server.`, toErrorMessage(error)); + this.logService.info(`Trying to download '${extension.identifier.id}' extension locally and install`); + const local = await this.downloadCompatibleAndInstall(extension); + this.logService.info(`Successfully installed '${extension.identifier.id}' extension`); + return local; + } catch (e) { + this.logService.error(e); + throw error; + } + } + } + + private async downloadCompatibleAndInstall(extension: IGalleryExtension): Promise { + const installed = await this.getInstalled(ExtensionType.User); + const compatible = await this.galleryService.getCompatibleExtension(extension); + if (!compatible) { + return Promise.reject(new Error(localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", extension.identifier.id, this.productService.version))); + } + const manifest = await this.galleryService.getManifest(compatible, CancellationToken.None); + if (manifest) { + const workspaceExtensions = await this.getAllWorkspaceDependenciesAndPackedExtensions(manifest, CancellationToken.None); + await Promise.all(workspaceExtensions.map(e => this.downloadAndInstall(e, installed))); + } + return this.downloadAndInstall(extension, installed); + } + + private async downloadAndInstall(extension: IGalleryExtension, installed: ILocalExtension[]): Promise { + const location = await this.galleryService.download(extension, installed.filter(i => areSameExtensions(i.identifier, extension.identifier))[0] ? InstallOperation.Update : InstallOperation.Install); + return super.install(URI.file(location)); + } + + private async installUIDependenciesAndPackedExtensions(local: ILocalExtension): Promise { + const uiExtensions = await this.getAllUIDependenciesAndPackedExtensions(local.manifest, CancellationToken.None); + const installed = await this.localExtensionManagementService.getInstalled(); + const toInstall = uiExtensions.filter(e => installed.every(i => !areSameExtensions(i.identifier, e.identifier))); + await Promise.all(toInstall.map(d => this.localExtensionManagementService.installFromGallery(d))); + } + + private async getAllUIDependenciesAndPackedExtensions(manifest: IExtensionManifest, token: CancellationToken): Promise { + const result = new Map(); + const extensions = [...(manifest.extensionPack || []), ...(manifest.extensionDependencies || [])]; + await this.getDependenciesAndPackedExtensionsRecursively(extensions, result, true, token); + return values(result); + } + + private async getAllWorkspaceDependenciesAndPackedExtensions(manifest: IExtensionManifest, token: CancellationToken): Promise { + const result = new Map(); + const extensions = [...(manifest.extensionPack || []), ...(manifest.extensionDependencies || [])]; + await this.getDependenciesAndPackedExtensionsRecursively(extensions, result, false, token); + return values(result); + } + + private async getDependenciesAndPackedExtensionsRecursively(toGet: string[], result: Map, uiExtension: boolean, token: CancellationToken): Promise { + if (toGet.length === 0) { + return Promise.resolve(); + } + + const extensions = (await this.galleryService.query({ names: toGet, pageSize: toGet.length }, token)).firstPage; + const manifests = await Promise.all(extensions.map(e => this.galleryService.getManifest(e, token))); + const extensionsManifests: IExtensionManifest[] = []; + for (let idx = 0; idx < extensions.length; idx++) { + const extension = extensions[idx]; + const manifest = manifests[idx]; + if (manifest && isUIExtension(manifest, this.productService, this.configurationService) === uiExtension) { + result.set(extension.identifier.id.toLowerCase(), extension); + extensionsManifests.push(manifest); + } + } + toGet = []; + for (const extensionManifest of extensionsManifests) { + if (isNonEmptyArray(extensionManifest.extensionDependencies)) { + for (const id of extensionManifest.extensionDependencies) { + if (!result.has(id.toLowerCase())) { + toGet.push(id); + } + } + } + if (isNonEmptyArray(extensionManifest.extensionPack)) { + for (const id of extensionManifest.extensionPack) { + if (!result.has(id.toLowerCase())) { + toGet.push(id); + } + } + } + } + return this.getDependenciesAndPackedExtensionsRecursively(toGet, result, uiExtension, token); + } +} \ No newline at end of file diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts index d7b8965f8ac..1a5822e645f 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts @@ -319,10 +319,10 @@ export async function startExtensionHostProcess(): Promise { // Attempt to load uri transformer let uriTransformer: IURITransformer | null = null; - if (initData.remoteAuthority && args.uriTransformerPath) { + if (initData.remote.authority && args.uriTransformerPath) { try { const rawURITransformerFactory = require.__$__nodeRequire(args.uriTransformerPath); - const rawURITransformer = rawURITransformerFactory(initData.remoteAuthority); + const rawURITransformer = rawURITransformerFactory(initData.remote.authority); uriTransformer = new URITransformer(rawURITransformer); } catch (e) { console.error(e); diff --git a/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts b/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts index e27a2a7ed46..1760b4d5fc3 100644 --- a/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts +++ b/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts @@ -8,7 +8,7 @@ import { IExtensionManagementService, ILocalExtension, IGalleryExtension, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata, IExtensionManagementServerService, IExtensionManagementServer, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { ExtensionType, IExtensionManifest, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; +import { ExtensionType, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; import { URI } from 'vs/base/common/uri'; import { Disposable } from 'vs/base/common/lifecycle'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -18,8 +18,6 @@ import { areSameExtensions } from 'vs/platform/extensionManagement/common/extens import { localize } from 'vs/nls'; import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { isNonEmptyArray } from 'vs/base/common/arrays'; -import { values } from 'vs/base/common/map'; import { IProductService } from 'vs/platform/product/common/product'; export class MultiExtensionManagementService extends Disposable implements IExtensionManagementService { @@ -134,44 +132,38 @@ export class MultiExtensionManagementService extends Disposable implements IExte return Promise.all(this.servers.map(({ extensionManagementService }) => extensionManagementService.unzip(zipLocation, type))).then(([extensionIdentifier]) => extensionIdentifier); } - async install(vsix: URI): Promise { + async install(vsix: URI): Promise { if (this.extensionManagementServerService.remoteExtensionManagementServer) { const manifest = await getManifest(vsix.fsPath); if (isLanguagePackExtension(manifest)) { // Install on both servers - const [extensionIdentifier] = await Promise.all(this.servers.map(server => server.extensionManagementService.install(vsix))); - return extensionIdentifier; + const [local] = await Promise.all(this.servers.map(server => server.extensionManagementService.install(vsix))); + return local; } if (isUIExtension(manifest, this.productService, this.configurationService)) { // Install only on local server return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.install(vsix); } // Install only on remote server - const promise = this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.install(vsix); - // Install UI Dependencies on local server - await this.installUIDependenciesAndPackedExtensions(manifest); - return promise; + return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.install(vsix); } return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.install(vsix); } - async installFromGallery(gallery: IGalleryExtension): Promise { + async installFromGallery(gallery: IGalleryExtension): Promise { if (this.extensionManagementServerService.remoteExtensionManagementServer) { const manifest = await this.extensionGalleryService.getManifest(gallery, CancellationToken.None); if (manifest) { if (isLanguagePackExtension(manifest)) { // Install on both servers - return Promise.all(this.servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(() => undefined); + return Promise.all(this.servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(([local]) => local); } if (isUIExtension(manifest, this.productService, this.configurationService)) { // Install only on local server return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(gallery); } // Install only on remote server - const promise = this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.installFromGallery(gallery); - // Install UI dependencies and packed extensions on local server - await this.installUIDependenciesAndPackedExtensions(manifest); - return promise; + return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.installFromGallery(gallery); } else { return Promise.reject(localize('Manifest is not found', "Installing Extension {0} failed: Manifest is not found.", gallery.displayName || gallery.name)); } @@ -179,13 +171,6 @@ export class MultiExtensionManagementService extends Disposable implements IExte return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(gallery); } - private async installUIDependenciesAndPackedExtensions(manifest: IExtensionManifest): Promise { - const uiExtensions = await this.getAllUIDependenciesAndPackedExtensions(manifest, CancellationToken.None); - const installed = await this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.getInstalled(); - const toInstall = uiExtensions.filter(e => installed.every(i => !areSameExtensions(i.identifier, e.identifier))); - await Promise.all(toInstall.map(d => this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(d))); - } - getExtensionsReport(): Promise { return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.getExtensionsReport(); } @@ -193,49 +178,6 @@ export class MultiExtensionManagementService extends Disposable implements IExte private getServer(extension: ILocalExtension): IExtensionManagementServer | null { return this.extensionManagementServerService.getExtensionManagementServer(extension.location); } - - private async getAllUIDependenciesAndPackedExtensions(manifest: IExtensionManifest, token: CancellationToken): Promise { - const result = new Map(); - const extensions = [...(manifest.extensionPack || []), ...(manifest.extensionDependencies || [])]; - await this.getAllUIDependenciesAndPackedExtensionsRecursively(extensions, result, token); - return values(result); - } - - private async getAllUIDependenciesAndPackedExtensionsRecursively(toGet: string[], result: Map, token: CancellationToken): Promise { - if (toGet.length === 0) { - return Promise.resolve(); - } - - const extensions = (await this.extensionGalleryService.query({ names: toGet, pageSize: toGet.length }, token)).firstPage; - const manifests = await Promise.all(extensions.map(e => this.extensionGalleryService.getManifest(e, token))); - const uiExtensionsManifests: IExtensionManifest[] = []; - for (let idx = 0; idx < extensions.length; idx++) { - const extension = extensions[idx]; - const manifest = manifests[idx]; - if (manifest && isUIExtension(manifest, this.productService, this.configurationService)) { - result.set(extension.identifier.id.toLowerCase(), extension); - uiExtensionsManifests.push(manifest); - } - } - toGet = []; - for (const uiExtensionManifest of uiExtensionsManifests) { - if (isNonEmptyArray(uiExtensionManifest.extensionDependencies)) { - for (const id of uiExtensionManifest.extensionDependencies) { - if (!result.has(id.toLowerCase())) { - toGet.push(id); - } - } - } - if (isNonEmptyArray(uiExtensionManifest.extensionPack)) { - for (const id of uiExtensionManifest.extensionPack) { - if (!result.has(id.toLowerCase())) { - toGet.push(id); - } - } - } - } - return this.getAllUIDependenciesAndPackedExtensionsRecursively(toGet, result, token); - } } registerSingleton(IExtensionManagementService, MultiExtensionManagementService); \ No newline at end of file diff --git a/src/vs/workbench/services/extensions/node/proxyResolver.ts b/src/vs/workbench/services/extensions/node/proxyResolver.ts index 5480a882d78..6aa6ba1e617 100644 --- a/src/vs/workbench/services/extensions/node/proxyResolver.ts +++ b/src/vs/workbench/services/extensions/node/proxyResolver.ts @@ -103,22 +103,33 @@ function setupProxyResolution( let results: ConnectionResult[] = []; function logEvent() { timeout = undefined; - /* __GDPR__ - "resolveProxy" : { - "count": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "duration": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "errorCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cacheCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cacheSize": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cacheRolls": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "envCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "settingsCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "localhostCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "envNoProxyCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "results": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } - } - */ - mainThreadTelemetry.$publicLog('resolveProxy', { count, duration, errorCount, cacheCount, cacheSize: cache.size, cacheRolls, envCount, settingsCount, localhostCount, envNoProxyCount, results }); + type ResolveProxyClassification = { + count: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + duration: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + errorCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + cacheCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + cacheSize: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + cacheRolls: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + envCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + settingsCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + localhostCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + envNoProxyCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + results: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + }; + type ResolveProxyEvent = { + count: number; + duration: number; + errorCount: number; + cacheCount: number; + cacheSize: number; + cacheRolls: number; + envCount: number; + settingsCount: number; + localhostCount: number; + envNoProxyCount: number; + results: ConnectionResult[]; + }; + mainThreadTelemetry.$publicLog2('resolveProxy', { count, duration, errorCount, cacheCount, cacheSize: cache.size, cacheRolls, envCount, settingsCount, localhostCount, envNoProxyCount, results }); count = duration = errorCount = cacheCount = envCount = settingsCount = localhostCount = envNoProxyCount = 0; results = []; } @@ -403,7 +414,7 @@ function configureModuleLoading(extensionService: ExtHostExtensionService, looku const modules = lookup[request]; const ext = extensionPaths.findSubstr(URI.file(parent.filename).fsPath); if (ext && ext.enableProposedApi) { - return modules[(ext).proxySupport] || modules.onRequest; + return (modules as any)[(ext).proxySupport] || modules.onRequest; } return modules.default; }; @@ -471,11 +482,9 @@ async function readWindowsCaCertificates() { store.done(); } - const seen = {}; - const certs = ders.map(derToPem) - .filter(pem => !seen[pem] && (seen[pem] = true)); + const certs = new Set(ders.map(derToPem)); return { - certs, + certs: Array.from(certs), append: true }; } @@ -489,11 +498,10 @@ async function readMacCaCertificates() { child.on('error', reject); child.on('exit', code => code ? reject(code) : resolve(stdout.join(''))); }); - const seen = {}; - const certs = stdout.split(/(?=-----BEGIN CERTIFICATE-----)/g) - .filter(pem => !!pem.length && !seen[pem] && (seen[pem] = true)); + const certs = new Set(stdout.split(/(?=-----BEGIN CERTIFICATE-----)/g) + .filter(pem => !!pem.length)); return { - certs, + certs: Array.from(certs), append: true }; } @@ -507,11 +515,10 @@ async function readLinuxCaCertificates() { for (const certPath of linuxCaCertificatePaths) { try { const content = await promisify(fs.readFile)(certPath, { encoding: 'utf8' }); - const seen = {}; - const certs = content.split(/(?=-----BEGIN CERTIFICATE-----)/g) - .filter(pem => !!pem.length && !seen[pem] && (seen[pem] = true)); + const certs = new Set(content.split(/(?=-----BEGIN CERTIFICATE-----)/g) + .filter(pem => !!pem.length)); return { - certs, + certs: Array.from(certs), append: false }; } catch (err) { diff --git a/src/vs/workbench/services/files/common/workspaceWatcher.ts b/src/vs/workbench/services/files/common/workspaceWatcher.ts index a16c82e3594..7aa7ef157f6 100644 --- a/src/vs/workbench/services/files/common/workspaceWatcher.ts +++ b/src/vs/workbench/services/files/common/workspaceWatcher.ts @@ -16,7 +16,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { localize } from 'vs/nls'; -import { FileService } from 'vs/workbench/services/files/common/fileService'; +import { FileService } from 'vs/platform/files/common/fileService'; export class WorkspaceWatcher extends Disposable { diff --git a/src/vs/workbench/services/heap/common/heap.ts b/src/vs/workbench/services/heap/common/heap.ts deleted file mode 100644 index 4aa4cc0ec78..00000000000 --- a/src/vs/workbench/services/heap/common/heap.ts +++ /dev/null @@ -1,33 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - - -import { Event } from 'vs/base/common/event'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; - -export const IHeapService = createDecorator('heapService'); - -export interface ObjectIdentifier { - $ident?: number; -} - -export interface IHeapService { - _serviceBrand: any; - - readonly onGarbageCollection: Event; - - /** - * Track gc-collection for the given object - */ - trackObject(obj: ObjectIdentifier | undefined): void; -} - - - -export class NullHeapService implements IHeapService { - _serviceBrand: any; - onGarbageCollection = Event.None; - trackObject() { } -} diff --git a/src/vs/workbench/services/heap/node/heap.ts b/src/vs/workbench/services/heap/node/heap.ts deleted file mode 100644 index 8f627bacea1..00000000000 --- a/src/vs/workbench/services/heap/node/heap.ts +++ /dev/null @@ -1,80 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { Event, Emitter } from 'vs/base/common/event'; -import { GCSignal } from 'gc-signals'; -import { IHeapService, ObjectIdentifier } from 'vs/workbench/services/heap/common/heap'; - -export class HeapService implements IHeapService { - - _serviceBrand: any; - - private readonly _onGarbageCollection: Emitter = new Emitter(); - public readonly onGarbageCollection: Event = this._onGarbageCollection.event; - - private _activeSignals = new WeakMap(); - private _activeIds = new Set(); - - private _consumeHandle: any; - private _ctor: { new(id: number): GCSignal }; - private _ctorInit: Promise; - - constructor() { - // - } - - dispose() { - clearInterval(this._consumeHandle); - } - - trackObject(obj: ObjectIdentifier | undefined | null): void { - if (!obj) { - return; - } - - const ident = obj.$ident; - if (typeof ident !== 'number') { - return; - } - - if (this._activeIds.has(ident)) { - return; - } - - if (this._ctor) { - // track and leave - this._activeIds.add(ident); - this._activeSignals.set(obj, new this._ctor(ident)); - - } else { - // make sure to load gc-signals, then track and leave - if (!this._ctorInit) { - this._ctorInit = import('gc-signals').then(({ GCSignal, consumeSignals }) => { - this._ctor = GCSignal; - this._consumeHandle = setInterval(() => { - const ids = consumeSignals(); - - if (ids.length > 0) { - // local book-keeping - for (const id of ids) { - this._activeIds.delete(id); - } - // fire event - this._onGarbageCollection.fire(ids); - } - }, 15 * 1000); - }); - } - - this._ctorInit.then(() => { - this._activeIds.add(ident); - this._activeSignals.set(obj, new this._ctor(ident)); - }); - } - } -} - -registerSingleton(IHeapService, HeapService, true); diff --git a/src/vs/workbench/services/history/browser/history.ts b/src/vs/workbench/services/history/browser/history.ts index 192ab79c021..91e3136b50e 100644 --- a/src/vs/workbench/services/history/browser/history.ts +++ b/src/vs/workbench/services/history/browser/history.ts @@ -13,13 +13,13 @@ import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { FileChangesEvent, IFileService, FileChangeType, FILES_EXCLUDE_CONFIG } from 'vs/platform/files/common/files'; import { Selection } from 'vs/editor/common/core/selection'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IDisposable, dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { Registry } from 'vs/platform/registry/common/platform'; import { Event } from 'vs/base/common/event'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { IWindowsService } from 'vs/platform/windows/common/windows'; +import { IWindowService } from 'vs/platform/windows/common/windows'; import { getCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { getExcludes, ISearchConfiguration } from 'vs/workbench/services/search/common/search'; import { IExpression } from 'vs/base/common/glob'; @@ -32,6 +32,7 @@ import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/cont import { coalesce } from 'vs/base/common/arrays'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { withNullAsUndefined } from 'vs/base/common/types'; +import { addDisposableListener, EventType, EventHelper } from 'vs/base/browser/dom'; /** * Stores the selection & view state of an editor and allows to compare it to other selection states. @@ -108,8 +109,8 @@ export class HistoryService extends Disposable implements IHistoryService { private readonly activeEditorListeners = this._register(new DisposableStore()); private lastActiveEditor?: IEditorIdentifier; - private readonly editorHistoryListeners: Map = new Map(); - private readonly editorStackListeners: Map = new Map(); + private readonly editorHistoryListeners: Map = new Map(); + private readonly editorStackListeners: Map = new Map(); private stack: IStackEntry[]; private index: number; @@ -137,10 +138,10 @@ export class HistoryService extends Disposable implements IHistoryService { @IStorageService private readonly storageService: IStorageService, @IConfigurationService private readonly configurationService: IConfigurationService, @IFileService private readonly fileService: IFileService, - @IWindowsService private readonly windowService: IWindowsService, + @IWindowService private readonly windowService: IWindowService, @IInstantiationService private readonly instantiationService: IInstantiationService, @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, - @IContextKeyService private readonly contextKeyService: IContextKeyService + @IContextKeyService private readonly contextKeyService: IContextKeyService, ) { super(); @@ -184,6 +185,39 @@ export class HistoryService extends Disposable implements IHistoryService { if (this.editorService.activeControl) { this.onActiveEditorChanged(); } + + // Mouse back/forward support + const mouseBackForwardSupportListener = this._register(new DisposableStore()); + const handleMouseBackForwardSupport = () => { + mouseBackForwardSupportListener.clear(); + + if (this.configurationService.getValue('workbench.editor.mouseBackForwardToNavigate')) { + mouseBackForwardSupportListener.add(addDisposableListener(this.layoutService.getWorkbenchElement(), EventType.MOUSE_DOWN, e => this.onMouseDown(e))); + } + }; + + this._register(this.configurationService.onDidChangeConfiguration(event => { + if (event.affectsConfiguration('workbench.editor.mouseBackForwardToNavigate')) { + handleMouseBackForwardSupport(); + } + })); + + handleMouseBackForwardSupport(); + } + + private onMouseDown(e: MouseEvent): void { + + // Support to navigate in history when mouse buttons 4/5 are pressed + switch (e.button) { + case 3: + EventHelper.stop(e); + this.back(); + break; + case 4: + EventHelper.stop(e); + this.forward(); + break; + } } private onActiveEditorChanged(): void { @@ -475,19 +509,19 @@ export class HistoryService extends Disposable implements IHistoryService { } } - private onEditorDispose(editor: EditorInput, listener: Function, mapEditorToDispose: Map): void { + private onEditorDispose(editor: EditorInput, listener: Function, mapEditorToDispose: Map): void { const toDispose = Event.once(editor.onDispose)(() => listener()); let disposables = mapEditorToDispose.get(editor); if (!disposables) { - disposables = []; + disposables = new DisposableStore(); mapEditorToDispose.set(editor, disposables); } - disposables.push(toDispose); + disposables.add(toDispose); } - private clearOnEditorDispose(editor: IEditorInput | IResourceInput | FileChangesEvent, mapEditorToDispose: Map): void { + private clearOnEditorDispose(editor: IEditorInput | IResourceInput | FileChangesEvent, mapEditorToDispose: Map): void { if (editor instanceof EditorInput) { const disposables = mapEditorToDispose.get(editor); if (disposables) { diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts similarity index 70% rename from src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts rename to src/vs/workbench/services/keybinding/browser/keybindingService.ts index 99d5f9cad60..4e64ebdc0c6 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -4,15 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import * as nativeKeymap from 'native-keymap'; -import { release } from 'os'; +import * as browser from 'vs/base/browser/browser'; import * as dom from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { Emitter, Event } from 'vs/base/common/event'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; -import { Keybinding, ResolvedKeybinding } from 'vs/base/common/keyCodes'; +import { Keybinding, ResolvedKeybinding, KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { KeybindingParser } from 'vs/base/common/keybindingParser'; -import { OS, OperatingSystem } from 'vs/base/common/platform'; +import { OS, OperatingSystem, isWeb } from 'vs/base/common/platform'; import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Extensions as ConfigExtensions, IConfigurationNode, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; @@ -20,7 +19,7 @@ import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/commo import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService'; -import { IKeybindingEvent, IKeyboardEvent, IUserFriendlyKeybinding, KeybindingSource, IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IKeyboardEvent, IUserFriendlyKeybinding, KeybindingSource, IKeybindingService, IKeybindingEvent } from 'vs/platform/keybinding/common/keybinding'; import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver'; import { IKeybindingItem, IKeybindingRule2, KeybindingWeight, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem'; @@ -30,137 +29,24 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { keybindingsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; import { ExtensionMessageCollector, ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import { IUserKeybindingItem, KeybindingIO, OutputBuilder } from 'vs/workbench/services/keybinding/common/keybindingIO'; -import { CachedKeyboardMapper, IKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; -import { MacLinuxFallbackKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxFallbackKeyboardMapper'; -import { IMacLinuxKeyboardMapping, MacLinuxKeyboardMapper, macLinuxKeyboardMappingEquals } from 'vs/workbench/services/keybinding/common/macLinuxKeyboardMapper'; -import { IWindowsKeyboardMapping, WindowsKeyboardMapper, windowsKeyboardMappingEquals } from 'vs/workbench/services/keybinding/common/windowsKeyboardMapper'; +import { IKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { MenuRegistry } from 'vs/platform/actions/common/actions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +// tslint:disable-next-line: import-patterns import { commandsExtensionPoint } from 'vs/workbench/api/common/menusExtensionPoint'; -import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { RunOnceScheduler } from 'vs/base/common/async'; import { URI } from 'vs/base/common/uri'; -import { IFileService, FileChangesEvent, FileChangeType } from 'vs/platform/files/common/files'; -import { dirname, isEqual } from 'vs/base/common/resources'; +import { IFileService } from 'vs/platform/files/common/files'; import { parse } from 'vs/base/common/json'; import * as objects from 'vs/base/common/objects'; - -export class KeyboardMapperFactory { - public static readonly INSTANCE = new KeyboardMapperFactory(); - - private _layoutInfo: nativeKeymap.IKeyboardLayoutInfo | null; - private _rawMapping: nativeKeymap.IKeyboardMapping | null; - private _keyboardMapper: IKeyboardMapper | null; - private _initialized: boolean; - - private readonly _onDidChangeKeyboardMapper = new Emitter(); - public readonly onDidChangeKeyboardMapper: Event = this._onDidChangeKeyboardMapper.event; - - private constructor() { - this._layoutInfo = null; - this._rawMapping = null; - this._keyboardMapper = null; - this._initialized = false; - } - - public _onKeyboardLayoutChanged(): void { - if (this._initialized) { - this._setKeyboardData(nativeKeymap.getCurrentKeyboardLayout(), nativeKeymap.getKeyMap()); - } - } - - public getKeyboardMapper(dispatchConfig: DispatchConfig): IKeyboardMapper { - if (!this._initialized) { - this._setKeyboardData(nativeKeymap.getCurrentKeyboardLayout(), nativeKeymap.getKeyMap()); - } - if (dispatchConfig === DispatchConfig.KeyCode) { - // Forcefully set to use keyCode - return new MacLinuxFallbackKeyboardMapper(OS); - } - return this._keyboardMapper!; - } - - public getCurrentKeyboardLayout(): nativeKeymap.IKeyboardLayoutInfo | null { - if (!this._initialized) { - this._setKeyboardData(nativeKeymap.getCurrentKeyboardLayout(), nativeKeymap.getKeyMap()); - } - return this._layoutInfo; - } - - private static _isUSStandard(_kbInfo: nativeKeymap.IKeyboardLayoutInfo): boolean { - if (OS === OperatingSystem.Linux) { - const kbInfo = _kbInfo; - return (kbInfo && kbInfo.layout === 'us'); - } - - if (OS === OperatingSystem.Macintosh) { - const kbInfo = _kbInfo; - return (kbInfo && kbInfo.id === 'com.apple.keylayout.US'); - } - - if (OS === OperatingSystem.Windows) { - const kbInfo = _kbInfo; - return (kbInfo && kbInfo.name === '00000409'); - } - - return false; - } - - public getRawKeyboardMapping(): nativeKeymap.IKeyboardMapping | null { - if (!this._initialized) { - this._setKeyboardData(nativeKeymap.getCurrentKeyboardLayout(), nativeKeymap.getKeyMap()); - } - return this._rawMapping; - } - - private _setKeyboardData(layoutInfo: nativeKeymap.IKeyboardLayoutInfo, rawMapping: nativeKeymap.IKeyboardMapping): void { - this._layoutInfo = layoutInfo; - - if (this._initialized && KeyboardMapperFactory._equals(this._rawMapping, rawMapping)) { - // nothing to do... - return; - } - - this._initialized = true; - this._rawMapping = rawMapping; - this._keyboardMapper = new CachedKeyboardMapper( - KeyboardMapperFactory._createKeyboardMapper(this._layoutInfo, this._rawMapping) - ); - this._onDidChangeKeyboardMapper.fire(); - } - - private static _createKeyboardMapper(layoutInfo: nativeKeymap.IKeyboardLayoutInfo, rawMapping: nativeKeymap.IKeyboardMapping): IKeyboardMapper { - const isUSStandard = KeyboardMapperFactory._isUSStandard(layoutInfo); - if (OS === OperatingSystem.Windows) { - return new WindowsKeyboardMapper(isUSStandard, rawMapping); - } - - if (Object.keys(rawMapping).length === 0) { - // Looks like reading the mappings failed (most likely Mac + Japanese/Chinese keyboard layouts) - return new MacLinuxFallbackKeyboardMapper(OS); - } - - if (OS === OperatingSystem.Macintosh) { - const kbInfo = layoutInfo; - if (kbInfo.id === 'com.apple.keylayout.DVORAK-QWERTYCMD') { - // Use keyCode based dispatching for DVORAK - QWERTY ⌘ - return new MacLinuxFallbackKeyboardMapper(OS); - } - } - - return new MacLinuxKeyboardMapper(isUSStandard, rawMapping, OS); - } - - private static _equals(a: nativeKeymap.IKeyboardMapping | null, b: nativeKeymap.IKeyboardMapping | null): boolean { - if (OS === OperatingSystem.Windows) { - return windowsKeyboardMappingEquals(a, b); - } - - return macLinuxKeyboardMappingEquals(a, b); - } -} +import { IKeymapService } from 'vs/workbench/services/keybinding/common/keymapInfo'; +import { getDispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; +import { isArray } from 'vs/base/common/types'; +import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; +import { ScanCodeUtils, IMMUTABLE_CODE_TO_KEY_CODE } from 'vs/base/common/scanCode'; interface ContributedKeyBinding { command: string; @@ -257,17 +143,6 @@ const keybindingsExtPoint = ExtensionsRegistry.registerExtensionPointkeyboard).dispatch : null); - return (r === 'keyCode' ? DispatchConfig.KeyCode : DispatchConfig.Code); -} - export class WorkbenchKeybindingService extends AbstractKeybindingService { private _keyboardMapper: IKeyboardMapper; @@ -283,7 +158,8 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { @IConfigurationService configurationService: IConfigurationService, @IWindowService private readonly windowService: IWindowService, @IExtensionService extensionService: IExtensionService, - @IFileService fileService: IFileService + @IFileService fileService: IFileService, + @IKeymapService private readonly keymapService: IKeymapService ) { super(contextKeyService, commandService, telemetryService, notificationService); @@ -297,13 +173,13 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { } dispatchConfig = newDispatchConfig; - this._keyboardMapper = KeyboardMapperFactory.INSTANCE.getKeyboardMapper(dispatchConfig); + this._keyboardMapper = this.keymapService.getKeyboardMapper(dispatchConfig); this.updateResolver({ source: KeybindingSource.Default }); }); - this._keyboardMapper = KeyboardMapperFactory.INSTANCE.getKeyboardMapper(dispatchConfig); - KeyboardMapperFactory.INSTANCE.onDidChangeKeyboardMapper(() => { - this._keyboardMapper = KeyboardMapperFactory.INSTANCE.getKeyboardMapper(dispatchConfig); + this._keyboardMapper = this.keymapService.getKeyboardMapper(dispatchConfig); + this.keymapService.onDidChangeKeyboardMapper(() => { + this._keyboardMapper = this.keymapService.getKeyboardMapper(dispatchConfig); this.updateResolver({ source: KeybindingSource.Default }); }); @@ -316,12 +192,11 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { } }); this._register(this.userKeybindings.onDidChange(() => { - /* __GDPR__ - "customKeybindingsChanged" : { - "keyCount" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - } - */ - this._telemetryService.publicLog('customKeybindingsChanged', { + type CustomKeybindingsChangedClassification = { + keyCount: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true } + }; + + this._telemetryService.publicLog2<{ keyCount: number }, CustomKeybindingsChangedClassification>('customKeybindingsChanged', { keyCount: this.userKeybindings.keybindings.length }); this.updateResolver({ @@ -353,7 +228,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { })); keybindingsTelemetry(telemetryService, this); - let data = KeyboardMapperFactory.INSTANCE.getCurrentKeyboardLayout(); + let data = this.keymapService.getCurrentKeyboardLayout(); /* __GDPR__ "keyboardLayout" : { "currentKeyboardLayout": { "${inline}": [ "${IKeyboardLayoutInfo}" ] } @@ -362,15 +237,41 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { telemetryService.publicLog('keyboardLayout', { currentKeyboardLayout: data }); + + this._register(browser.onDidChangeFullscreen(() => { + const keyboard = (navigator).keyboard; + + if (!keyboard) { + return; + } + + if (browser.isFullscreen()) { + keyboard.lock(['Escape']); + } else { + keyboard.unlock(); + } + + // update resolver which will bring back all unbound keyboard shortcuts + this._cachedResolver = null; + this._onDidUpdateKeybindings.fire({ source: KeybindingSource.User }); + })); } public _dumpDebugInfo(): string { - const layoutInfo = JSON.stringify(KeyboardMapperFactory.INSTANCE.getCurrentKeyboardLayout(), null, '\t'); + const layoutInfo = JSON.stringify(this.keymapService.getCurrentKeyboardLayout(), null, '\t'); const mapperInfo = this._keyboardMapper.dumpDebugInfo(); - const rawMapping = JSON.stringify(KeyboardMapperFactory.INSTANCE.getRawKeyboardMapping(), null, '\t'); + const rawMapping = JSON.stringify(this.keymapService.getRawKeyboardMapping(), null, '\t'); return `Layout info:\n${layoutInfo}\n${mapperInfo}\n\nRaw mapping:\n${rawMapping}`; } + public _dumpDebugInfoJSON(): string { + const info = { + layout: this.keymapService.getCurrentKeyboardLayout(), + rawMapping: this.keymapService.getRawKeyboardMapping() + }; + return JSON.stringify(info, null, '\t'); + } + public customKeybindingsCount(): number { return this.userKeybindings.keybindings.length; } @@ -405,6 +306,10 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { // This might be a removal keybinding item in user settings => accept it result[resultLen++] = new ResolvedKeybindingItem(undefined, item.command, item.commandArgs, when, isDefault); } else { + if (this._assertBrowserConflicts(keybinding, item.command)) { + continue; + } + const resolvedKeybindings = this.resolveKeybinding(keybinding); for (const resolvedKeybinding of resolvedKeybindings) { result[resultLen++] = new ResolvedKeybindingItem(resolvedKeybinding, item.command, item.commandArgs, when, isDefault); @@ -434,11 +339,83 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { return result; } + private _assertBrowserConflicts(kb: Keybinding, commandId: string): boolean { + if (!isWeb) { + return false; + } + + if (browser.isStandalone) { + return false; + } + + if (browser.isFullscreen() && (navigator).keyboard) { + return false; + } + + for (let part of kb.parts) { + if (!part.metaKey && !part.altKey && !part.ctrlKey && !part.shiftKey) { + continue; + } + + const modifiersMask = KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.Shift; + + let partModifiersMask = 0; + if (part.metaKey) { + partModifiersMask |= KeyMod.CtrlCmd; + } + + if (part.shiftKey) { + partModifiersMask |= KeyMod.Shift; + } + + if (part.altKey) { + partModifiersMask |= KeyMod.Alt; + } + + if (part.ctrlKey && OS === OperatingSystem.Macintosh) { + partModifiersMask |= KeyMod.WinCtrl; + } + + if ((partModifiersMask & modifiersMask) === KeyMod.CtrlCmd && part.keyCode === KeyCode.KEY_W) { + // console.warn('Ctrl/Cmd+W keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); + + return true; + } + + if ((partModifiersMask & modifiersMask) === KeyMod.CtrlCmd && part.keyCode === KeyCode.KEY_N) { + // console.warn('Ctrl/Cmd+N keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); + + return true; + } + + if ((partModifiersMask & modifiersMask) === KeyMod.CtrlCmd && part.keyCode === KeyCode.KEY_T) { + // console.warn('Ctrl/Cmd+T keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); + + return true; + } + + if ((partModifiersMask & modifiersMask) === (KeyMod.CtrlCmd | KeyMod.Alt) && (part.keyCode === KeyCode.LeftArrow || part.keyCode === KeyCode.RightArrow)) { + // console.warn('Ctrl/Cmd+Arrow keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); + + return true; + } + + if ((partModifiersMask & modifiersMask) === KeyMod.CtrlCmd && part.keyCode >= KeyCode.KEY_0 && part.keyCode <= KeyCode.KEY_9) { + // console.warn('Ctrl/Cmd+Num keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); + + return true; + } + } + + return false; + } + public resolveKeybinding(kb: Keybinding): ResolvedKeybinding[] { return this._keyboardMapper.resolveKeybinding(kb); } public resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): ResolvedKeybinding { + this.keymapService.validateCurrentKeyboardMapping(keyboardEvent); return this._keyboardMapper.resolveKeyboardEvent(keyboardEvent); } @@ -553,13 +530,19 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { } mightProducePrintableCharacter(event: IKeyboardEvent): boolean { - if (event.ctrlKey || event.metaKey) { - // ignore ctrl/cmd-combination but not shift/alt-combinatios + if (event.ctrlKey || event.metaKey || event.altKey) { + // ignore ctrl/cmd/alt-combination but not shift-combinatios + return false; + } + const code = ScanCodeUtils.toEnum(event.code); + const keycode = IMMUTABLE_CODE_TO_KEY_CODE[code]; + if (keycode !== -1) { + // https://github.com/microsoft/vscode/issues/74934 return false; } // consult the KeyboardMapperFactory to check the given event for // a printable value. - const mapping = KeyboardMapperFactory.INSTANCE.getRawKeyboardMapping(); + const mapping = this.keymapService.getRawKeyboardMapping(); if (!mapping) { return false; } @@ -578,12 +561,11 @@ class UserKeybindings extends Disposable { private _keybindings: IUserFriendlyKeybinding[] = []; get keybindings(): IUserFriendlyKeybinding[] { return this._keybindings; } - private readonly reloadConfigurationScheduler: RunOnceScheduler; - protected readonly _onDidChange: Emitter = this._register(new Emitter()); - readonly onDidChange: Event = this._onDidChange.event; - private fileWatcherDisposable: IDisposable = Disposable.None; - private directoryWatcherDisposable: IDisposable = Disposable.None; + private readonly reloadConfigurationScheduler: RunOnceScheduler; + + private readonly _onDidChange: Emitter = this._register(new Emitter()); + readonly onDidChange: Event = this._onDidChange.event; constructor( private readonly keybindingsResource: URI, @@ -591,40 +573,15 @@ class UserKeybindings extends Disposable { ) { super(); - this._register(fileService.onFileChanges(e => this.handleFileEvents(e))); this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(changed => { if (changed) { this._onDidChange.fire(); } }), 50)); - this._register(toDisposable(() => { - this.stopWatchingResource(); - this.stopWatchingDirectory(); - })); - } - - private watchResource(): void { - this.fileWatcherDisposable = this.fileService.watch(this.keybindingsResource); - } - - private stopWatchingResource(): void { - this.fileWatcherDisposable.dispose(); - this.fileWatcherDisposable = Disposable.None; - } - - private watchDirectory(): void { - const directory = dirname(this.keybindingsResource); - this.directoryWatcherDisposable = this.fileService.watch(directory); - } - - private stopWatchingDirectory(): void { - this.directoryWatcherDisposable.dispose(); - this.directoryWatcherDisposable = Disposable.None; + this._register(Event.filter(this.fileService.onFileChanges, e => e.contains(this.keybindingsResource))(() => this.reloadConfigurationScheduler.schedule())); } async initialize(): Promise { - const exists = await this.fileService.exists(this.keybindingsResource); - this.onResourceExists(exists); await this.reload(); } @@ -632,45 +589,13 @@ class UserKeybindings extends Disposable { const existing = this._keybindings; try { const content = await this.fileService.readFile(this.keybindingsResource); - this._keybindings = parse(content.value.toString()); + const value = parse(content.value.toString()); + this._keybindings = isArray(value) ? value : []; } catch (e) { this._keybindings = []; } return existing ? !objects.equals(existing, this._keybindings) : true; } - - private async handleFileEvents(event: FileChangesEvent): Promise { - const events = event.changes; - - let affectedByChanges = false; - - // Find changes that affect the resource - for (const event of events) { - affectedByChanges = isEqual(this.keybindingsResource, event.resource); - if (affectedByChanges) { - if (event.type === FileChangeType.ADDED) { - this.onResourceExists(true); - } else if (event.type === FileChangeType.DELETED) { - this.onResourceExists(false); - } - break; - } - } - - if (affectedByChanges) { - this.reloadConfigurationScheduler.schedule(); - } - } - - private onResourceExists(exists: boolean): void { - if (exists) { - this.stopWatchingDirectory(); - this.watchResource(); - } else { - this.stopWatchingResource(); - this.watchDirectory(); - } - } } let schemaId = 'vscode://schemas/keybindings'; @@ -751,8 +676,8 @@ function updateSchema() { }; const allCommands = CommandsRegistry.getCommands(); - for (let commandId in allCommands) { - const commandDescription = allCommands[commandId].description; + for (const [commandId, command] of allCommands) { + const commandDescription = command.description; addKnownCommand(commandId, commandDescription ? commandDescription.description : undefined); @@ -780,7 +705,7 @@ function updateSchema() { } const menuCommands = MenuRegistry.getCommands(); - for (let commandId in menuCommands) { + for (const commandId of menuCommands.keys()) { addKnownCommand(commandId); } } @@ -799,13 +724,8 @@ const keyboardConfiguration: IConfigurationNode = { 'default': 'code', 'markdownDescription': nls.localize('dispatch', "Controls the dispatching logic for key presses to use either `code` (recommended) or `keyCode`."), 'included': OS === OperatingSystem.Macintosh || OS === OperatingSystem.Linux - }, - 'keyboard.touchbar.enabled': { - 'type': 'boolean', - 'default': true, - 'description': nls.localize('touchbar.enabled', "Enables the macOS touchbar buttons on the keyboard if available."), - 'included': OS === OperatingSystem.Macintosh && parseFloat(release()) >= 16 // Minimum: macOS Sierra (10.12.x = darwin 16.x) } + // no touch bar support } }; diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts new file mode 100644 index 00000000000..89ef892047a --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts @@ -0,0 +1,23 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IKeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; + +export class KeyboardLayoutContribution { + public static readonly INSTANCE: KeyboardLayoutContribution = new KeyboardLayoutContribution(); + + private _layoutInfos: IKeymapInfo[] = []; + + get layoutInfos() { + return this._layoutInfos; + } + + private constructor() { + } + + registerKeyboardLayout(layout: IKeymapInfo) { + this._layoutInfos.push(layout); + } +} \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts new file mode 100644 index 00000000000..c187c923cec --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts @@ -0,0 +1,168 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000405', id: '', text: 'Czech' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '{', '', 0, 'VK_B'], + KeyC: ['c', 'C', '&', '', 0, 'VK_C'], + KeyD: ['d', 'D', 'Đ', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '[', '', 0, 'VK_F'], + KeyG: ['g', 'G', ']', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', 'ł', '', 0, 'VK_K'], + KeyL: ['l', 'L', 'Ł', '', 0, 'VK_L'], + KeyM: ['m', 'M', '', '', 0, 'VK_M'], + KeyN: ['n', 'N', '}', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '\\', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', 'đ', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '@', '', 0, 'VK_V'], + KeyW: ['w', 'W', '|', '', 0, 'VK_W'], + KeyX: ['x', 'X', '#', '', 0, 'VK_X'], + KeyY: ['z', 'Z', '', '', 0, 'VK_Z'], + KeyZ: ['y', 'Y', '', '', 0, 'VK_Y'], + Digit1: ['+', '1', '~', '', 0, 'VK_1'], + Digit2: ['ě', '2', 'ˇ', '', 0, 'VK_2'], + Digit3: ['š', '3', '^', '', 0, 'VK_3'], + Digit4: ['č', '4', '˘', '', 0, 'VK_4'], + Digit5: ['ř', '5', '°', '', 0, 'VK_5'], + Digit6: ['ž', '6', '˛', '', 0, 'VK_6'], + Digit7: ['ý', '7', '`', '', 0, 'VK_7'], + Digit8: ['á', '8', '˙', '', 0, 'VK_8'], + Digit9: ['í', '9', '´', '', 0, 'VK_9'], + Digit0: ['é', '0', '˝', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['=', '%', '¨', '', 0, 'VK_OEM_PLUS'], + Equal: ['´', 'ˇ', '¸', '', 0, 'VK_OEM_2'], + BracketLeft: ['ú', '/', '÷', '', 0, 'VK_OEM_4'], + BracketRight: [')', '(', '×', '', 0, 'VK_OEM_6'], + Backslash: ['¨', '\'', '¤', '', 0, 'VK_OEM_5'], + Semicolon: ['ů', '"', '$', '', 0, 'VK_OEM_1'], + Quote: ['§', '!', 'ß', '', 0, 'VK_OEM_7'], + Backquote: [';', '°', '', '', 0, 'VK_OEM_3'], + Comma: [',', '?', '<', '', 0, 'VK_OEM_COMMA'], + Period: ['.', ':', '>', '', 0, 'VK_OEM_PERIOD'], + Slash: ['-', '_', '*', '', 0, 'VK_OEM_MINUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['\\', '|', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts new file mode 100644 index 00000000000..b19d2935e66 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000807', id: '', text: 'Swiss German' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', '', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['z', 'Z', '', '', 0, 'VK_Z'], + KeyZ: ['y', 'Y', '', '', 0, 'VK_Y'], + Digit1: ['1', '+', '¦', '', 0, 'VK_1'], + Digit2: ['2', '"', '@', '', 0, 'VK_2'], + Digit3: ['3', '*', '#', '', 0, 'VK_3'], + Digit4: ['4', 'ç', '°', '', 0, 'VK_4'], + Digit5: ['5', '%', '§', '', 0, 'VK_5'], + Digit6: ['6', '&', '¬', '', 0, 'VK_6'], + Digit7: ['7', '/', '|', '', 0, 'VK_7'], + Digit8: ['8', '(', '¢', '', 0, 'VK_8'], + Digit9: ['9', ')', '', '', 0, 'VK_9'], + Digit0: ['0', '=', '', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['\'', '?', '´', '', 0, 'VK_OEM_4'], + Equal: ['^', '`', '~', '', 0, 'VK_OEM_6'], + BracketLeft: ['ü', 'è', '[', '', 0, 'VK_OEM_1'], + BracketRight: ['¨', '!', ']', '', 0, 'VK_OEM_3'], + Backslash: ['$', '£', '}', '', 0, 'VK_OEM_8'], + Semicolon: ['ö', 'é', '', '', 0, 'VK_OEM_7'], + Quote: ['ä', 'à', '{', '', 0, 'VK_OEM_5'], + Backquote: ['§', '°', '', '', 0, 'VK_OEM_2'], + Comma: [',', ';', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', ':', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '\\', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts new file mode 100644 index 00000000000..33d2f5d5e32 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.German', lang: 'de', localizedName: 'German' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', 'å', 'Å', 0], + KeyB: ['b', 'B', '∫', '‹', 0], + KeyC: ['c', 'C', 'ç', 'Ç', 0], + KeyD: ['d', 'D', '∂', '™', 0], + KeyE: ['e', 'E', '€', '‰', 0], + KeyF: ['f', 'F', 'ƒ', 'Ï', 0], + KeyG: ['g', 'G', '©', 'Ì', 0], + KeyH: ['h', 'H', 'ª', 'Ó', 0], + KeyI: ['i', 'I', '⁄', 'Û', 0], + KeyJ: ['j', 'J', 'º', 'ı', 0], + KeyK: ['k', 'K', '∆', 'ˆ', 0], + KeyL: ['l', 'L', '@', 'fl', 0], + KeyM: ['m', 'M', 'µ', '˘', 0], + KeyN: ['n', 'N', '~', '›', 4], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'π', '∏', 0], + KeyQ: ['q', 'Q', '«', '»', 0], + KeyR: ['r', 'R', '®', '¸', 0], + KeyS: ['s', 'S', '‚', 'Í', 0], + KeyT: ['t', 'T', '†', '˝', 0], + KeyU: ['u', 'U', '¨', 'Á', 4], + KeyV: ['v', 'V', '√', '◊', 0], + KeyW: ['w', 'W', '∑', '„', 0], + KeyX: ['x', 'X', '≈', 'Ù', 0], + KeyY: ['z', 'Z', 'Ω', 'ˇ', 0], + KeyZ: ['y', 'Y', '¥', '‡', 0], + Digit1: ['1', '!', '¡', '¬', 0], + Digit2: ['2', '"', '“', '”', 0], + Digit3: ['3', '§', '¶', '#', 0], + Digit4: ['4', '$', '¢', '£', 0], + Digit5: ['5', '%', '[', 'fi', 0], + Digit6: ['6', '&', ']', '^', 8], + Digit7: ['7', '/', '|', '\\', 0], + Digit8: ['8', '(', '{', '˜', 0], + Digit9: ['9', ')', '}', '·', 0], + Digit0: ['0', '=', '≠', '¯', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['ß', '?', '¿', '˙', 0], + Equal: ['´', '`', '\'', '˚', 3], + BracketLeft: ['ü', 'Ü', '•', '°', 0], + BracketRight: ['+', '*', '±', '', 0], + Backslash: ['#', '\'', '‘', '’', 0], + Semicolon: ['ö', 'Ö', 'œ', 'Œ', 0], + Quote: ['ä', 'Ä', 'æ', 'Æ', 0], + Backquote: ['<', '>', '≤', '≥', 0], + Comma: [',', ';', '∞', '˛', 0], + Period: ['.', ':', '…', '÷', 0], + Slash: ['-', '_', '–', '—', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: [',', ',', '.', '.', 0], + IntlBackslash: ['^', '°', '„', '“', 1], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts new file mode 100644 index 00000000000..b4675240ef0 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts @@ -0,0 +1,187 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { model: 'pc104', layout: 'de', variant: '', options: '', rules: 'base' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', 'æ', 'Æ', 0], + KeyB: ['b', 'B', '“', '‘', 0], + KeyC: ['c', 'C', '¢', '©', 0], + KeyD: ['d', 'D', 'ð', 'Ð', 0], + KeyE: ['e', 'E', '€', '€', 0], + KeyF: ['f', 'F', 'đ', 'ª', 0], + KeyG: ['g', 'G', 'ŋ', 'Ŋ', 0], + KeyH: ['h', 'H', 'ħ', 'Ħ', 0], + KeyI: ['i', 'I', '→', 'ı', 0], + KeyJ: ['j', 'J', '̣', '̇', 0], + KeyK: ['k', 'K', 'ĸ', '&', 0], + KeyL: ['l', 'L', 'ł', 'Ł', 0], + KeyM: ['m', 'M', 'µ', 'º', 0], + KeyN: ['n', 'N', '”', '’', 0], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'þ', 'Þ', 0], + KeyQ: ['q', 'Q', '@', 'Ω', 0], + KeyR: ['r', 'R', '¶', '®', 0], + KeyS: ['s', 'S', 'ſ', 'ẞ', 0], + KeyT: ['t', 'T', 'ŧ', 'Ŧ', 0], + KeyU: ['u', 'U', '↓', '↑', 0], + KeyV: ['v', 'V', '„', '‚', 0], + KeyW: ['w', 'W', 'ł', 'Ł', 0], + KeyX: ['x', 'X', '«', '‹', 0], + KeyY: ['z', 'Z', '←', '¥', 0], + KeyZ: ['y', 'Y', '»', '›', 0], + Digit1: ['1', '!', '¹', '¡', 0], + Digit2: ['2', '"', '²', '⅛', 0], + Digit3: ['3', '§', '³', '£', 0], + Digit4: ['4', '$', '¼', '¤', 0], + Digit5: ['5', '%', '½', '⅜', 0], + Digit6: ['6', '&', '¬', '⅝', 0], + Digit7: ['7', '/', '{', '⅞', 0], + Digit8: ['8', '(', '[', '™', 0], + Digit9: ['9', ')', ']', '±', 0], + Digit0: ['0', '=', '}', '°', 0], + Enter: ['\r', '\r', '\r', '\r', 0], + Escape: ['\u001b', '\u001b', '\u001b', '\u001b', 0], + Backspace: ['\b', '\b', '\b', '\b', 0], + Tab: ['\t', '', '\t', '', 0], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['ß', '?', '\\', '¿', 0], + Equal: ['́', '̀', '̧', '̨', 0], + BracketLeft: ['ü', 'Ü', '̈', '̊', 0], + BracketRight: ['+', '*', '~', '¯', 0], + Backslash: ['#', '\'', '’', '̆', 0], + Semicolon: ['ö', 'Ö', '̋', '̣', 0], + Quote: ['ä', 'Ä', '̂', '̌', 0], + Backquote: ['̂', '°', '′', '″', 0], + Comma: [',', ';', '·', '×', 0], + Period: ['.', ':', '…', '÷', 0], + Slash: ['-', '_', '–', '—', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: ['', '', '', '', 0], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: ['/', '/', '/', '/', 0], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: [], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['', '1', '', '1', 0], + Numpad2: ['', '2', '', '2', 0], + Numpad3: ['', '3', '', '3', 0], + Numpad4: ['', '4', '', '4', 0], + Numpad5: ['', '5', '', '5', 0], + Numpad6: ['', '6', '', '6', 0], + Numpad7: ['', '7', '', '7', 0], + Numpad8: ['', '8', '', '8', 0], + Numpad9: ['', '9', '', '9', 0], + Numpad0: ['', '0', '', '0', 0], + NumpadDecimal: ['', ',', '', ',', 0], + IntlBackslash: ['<', '>', '|', '̱', 0], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Open: [], + Help: [], + Select: [], + Again: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + Find: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + Lang5: [], + NumpadParenLeft: [], + NumpadParenRight: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: ['\r', '\r', '\r', '\r', 0], + MetaRight: ['.', '.', '.', '.', 0], + BrightnessUp: [], + BrightnessDown: [], + MediaPlay: [], + MediaRecord: [], + MediaFastForward: [], + MediaRewind: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + SelectTask: [], + LaunchScreenSaver: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [], + MailReply: [], + MailForward: [], + MailSend: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts new file mode 100644 index 00000000000..46bf5981a68 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000407', id: '', text: 'German' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', 'µ', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '@', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['z', 'Z', '', '', 0, 'VK_Z'], + KeyZ: ['y', 'Y', '', '', 0, 'VK_Y'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '"', '²', '', 0, 'VK_2'], + Digit3: ['3', '§', '³', '', 0, 'VK_3'], + Digit4: ['4', '$', '', '', 0, 'VK_4'], + Digit5: ['5', '%', '', '', 0, 'VK_5'], + Digit6: ['6', '&', '', '', 0, 'VK_6'], + Digit7: ['7', '/', '{', '', 0, 'VK_7'], + Digit8: ['8', '(', '[', '', 0, 'VK_8'], + Digit9: ['9', ')', ']', '', 0, 'VK_9'], + Digit0: ['0', '=', '}', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['ß', '?', '\\', 'ẞ', 0, 'VK_OEM_4'], + Equal: ['´', '`', '', '', 0, 'VK_OEM_6'], + BracketLeft: ['ü', 'Ü', '', '', 0, 'VK_OEM_1'], + BracketRight: ['+', '*', '~', '', 0, 'VK_OEM_PLUS'], + Backslash: ['#', '\'', '', '', 0, 'VK_OEM_2'], + Semicolon: ['ö', 'Ö', '', '', 0, 'VK_OEM_3'], + Quote: ['ä', 'Ä', '', '', 0, 'VK_OEM_7'], + Backquote: ['^', '°', '', '', 0, 'VK_OEM_5'], + Comma: [',', ';', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', ':', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '|', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts new file mode 100644 index 00000000000..b774622699c --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts @@ -0,0 +1,170 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000406', id: '', text: 'Danish' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', 'µ', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '"', '@', '', 0, 'VK_2'], + Digit3: ['3', '#', '£', '', 0, 'VK_3'], + Digit4: ['4', '¤', '$', '', 0, 'VK_4'], + Digit5: ['5', '%', '€', '', 0, 'VK_5'], + Digit6: ['6', '&', '', '', 0, 'VK_6'], + Digit7: ['7', '/', '{', '', 0, 'VK_7'], + Digit8: ['8', '(', '[', '', 0, 'VK_8'], + Digit9: ['9', ')', ']', '', 0, 'VK_9'], + Digit0: ['0', '=', '}', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['+', '?', '', '', 0, 'VK_OEM_PLUS'], + Equal: ['´', '`', '|', '', 0, 'VK_OEM_4'], + BracketLeft: ['å', 'Å', '', '', 0, 'VK_OEM_6'], + BracketRight: ['¨', '^', '~', '', 0, 'VK_OEM_1'], + Backslash: ['\'', '*', '', '', 0, 'VK_OEM_2'], + Semicolon: ['æ', 'Æ', '', '', 0, 'VK_OEM_3'], + Quote: ['ø', 'Ø', '', '', 0, 'VK_OEM_7'], + Backquote: ['½', '§', '', '', 0, 'VK_OEM_5'], + Comma: [',', ';', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', ':', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '\\', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } + +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts new file mode 100644 index 00000000000..89e3a27892a --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000813', id: '', text: 'Belgian (Period)' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: [',', '?', '', '', 0, 'VK_OEM_COMMA'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['a', 'A', '', '', 0, 'VK_A'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['z', 'Z', '', '', 0, 'VK_Z'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['w', 'W', '', '', 0, 'VK_W'], + Digit1: ['&', '1', '|', '', 0, 'VK_1'], + Digit2: ['é', '2', '@', '', 0, 'VK_2'], + Digit3: ['"', '3', '#', '', 0, 'VK_3'], + Digit4: ['\'', '4', '{', '', 0, 'VK_4'], + Digit5: ['(', '5', '[', '', 0, 'VK_5'], + Digit6: ['§', '6', '^', '', 0, 'VK_6'], + Digit7: ['è', '7', '', '', 0, 'VK_7'], + Digit8: ['!', '8', '', '', 0, 'VK_8'], + Digit9: ['ç', '9', '{', '', 0, 'VK_9'], + Digit0: ['à', '0', '}', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: [')', '°', '', '', 0, 'VK_OEM_4'], + Equal: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + BracketLeft: ['^', '¨', '[', '', 0, 'VK_OEM_6'], + BracketRight: ['$', '*', ']', '', 0, 'VK_OEM_1'], + Backslash: ['µ', '£', '`', '`', 0, 'VK_OEM_5'], + Semicolon: ['m', 'M', '', '', 0, 'VK_M'], + Quote: ['ù', '%', '´', '´', 0, 'VK_OEM_3'], + Backquote: ['²', '³', '', '', 0, 'VK_OEM_7'], + Comma: [';', '.', '', '', 0, 'VK_OEM_PERIOD'], + Period: [':', '/', '', '', 0, 'VK_OEM_2'], + Slash: ['=', '+', '~', '~', 0, 'VK_OEM_PLUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '\\', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts new file mode 100644 index 00000000000..a12a2338bff --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.USExtended', lang: 'en', localizedName: 'ABC - Extended' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', '¯', '̄', 4], + KeyB: ['b', 'B', '˘', '̆', 4], + KeyC: ['c', 'C', '¸', '̧', 4], + KeyD: ['d', 'D', 'ð', 'Ð', 0], + KeyE: ['e', 'E', '´', '́', 4], + KeyF: ['f', 'F', 'ƒ', '', 0], + KeyG: ['g', 'G', '©', '‸', 8], + KeyH: ['h', 'H', 'ˍ', '̱', 4], + KeyI: ['i', 'I', 'ʼ', '̛', 4], + KeyJ: ['j', 'J', '˝', '̋', 4], + KeyK: ['k', 'K', '˚', '̊', 4], + KeyL: ['l', 'L', '-', '̵', 4], + KeyM: ['m', 'M', '˛', '̨', 4], + KeyN: ['n', 'N', '˜', '̃', 4], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', ',', '̦', 4], + KeyQ: ['q', 'Q', 'œ', 'Œ', 0], + KeyR: ['r', 'R', '®', '‰', 0], + KeyS: ['s', 'S', 'ß', '', 0], + KeyT: ['t', 'T', 'þ', 'Þ', 0], + KeyU: ['u', 'U', '¨', '̈', 4], + KeyV: ['v', 'V', 'ˇ', '̌', 4], + KeyW: ['w', 'W', '˙', '̇', 4], + KeyX: ['x', 'X', '.', '̣', 4], + KeyY: ['y', 'Y', '¥', '', 0], + KeyZ: ['z', 'Z', 'ˀ', '̉', 4], + Digit1: ['1', '!', '¡', '⁄', 0], + Digit2: ['2', '@', '™', '€', 0], + Digit3: ['3', '#', '£', '‹', 0], + Digit4: ['4', '$', '¢', '›', 0], + Digit5: ['5', '%', '§', '†', 0], + Digit6: ['6', '^', 'ˆ', '̂', 4], + Digit7: ['7', '&', '¶', '‡', 0], + Digit8: ['8', '*', '•', '°', 0], + Digit9: ['9', '(', 'ª', '·', 0], + Digit0: ['0', ')', 'º', '‚', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '–', '—', 0], + Equal: ['=', '+', '≠', '±', 0], + BracketLeft: ['[', '{', '“', '”', 0], + BracketRight: [']', '}', '‘', '’', 0], + Backslash: ['\\', '|', '«', '»', 0], + Semicolon: [';', ':', '…', '№', 8], + Quote: ['\'', '"', 'æ', 'Æ', 0], + Backquote: ['`', '~', '`', '̀', 4], + Comma: [',', '<', '≤', '„', 0], + Period: ['.', '>', '≥', 'ʔ', 8], + Slash: ['/', '?', '÷', '¿', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: ['.', '.', '.', '.', 0], + IntlBackslash: ['§', '±', '§', '±', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts new file mode 100644 index 00000000000..a1786f42061 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00004009', id: '', text: 'India' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', 'ā', 'Ā', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', 'ḍ', 'Ḍ', 0, 'VK_D'], + KeyE: ['e', 'E', 'ē', 'Ē', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', 'ṅ', 'Ṅ', 0, 'VK_G'], + KeyH: ['h', 'H', 'ḥ', 'Ḥ', 0, 'VK_H'], + KeyI: ['i', 'I', 'ī', 'Ī', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', 'l̥', 'L̥', 0, 'VK_L'], + KeyM: ['m', 'M', 'ṁ', 'Ṁ', 0, 'VK_M'], + KeyN: ['n', 'N', 'ṇ', 'Ṇ', 0, 'VK_N'], + KeyO: ['o', 'O', 'ō', 'Ō', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', 'æ', 'Æ', 0, 'VK_Q'], + KeyR: ['r', 'R', 'r̥', 'R̥', 0, 'VK_R'], + KeyS: ['s', 'S', 'ś', 'Ś', 0, 'VK_S'], + KeyT: ['t', 'T', 'ṭ', 'Ṭ', 0, 'VK_T'], + KeyU: ['u', 'U', 'ū', 'Ū', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', 'ṣ', 'Ṣ', 0, 'VK_X'], + KeyY: ['y', 'Y', 'ñ', 'Ñ', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '@', '', '', 0, 'VK_2'], + Digit3: ['3', '#', '', '', 0, 'VK_3'], + Digit4: ['4', '$', '₹', '', 0, 'VK_4'], + Digit5: ['5', '%', '', '', 0, 'VK_5'], + Digit6: ['6', '^', '', 'ˆ', 0, 'VK_6'], + Digit7: ['7', '&', '', '', 0, 'VK_7'], + Digit8: ['8', '*', '', '', 0, 'VK_8'], + Digit9: ['9', '(', '', '˘', 0, 'VK_9'], + Digit0: ['0', ')', '', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['-', '_', '-', 'ˍ', 0, 'VK_OEM_MINUS'], + Equal: ['=', '+', '', '', 0, 'VK_OEM_PLUS'], + BracketLeft: ['[', '{', '', '', 0, 'VK_OEM_4'], + BracketRight: [']', '}', '', '', 0, 'VK_OEM_6'], + Backslash: ['\\', '|', '', '', 0, 'VK_OEM_5'], + Semicolon: [';', ':', '', '', 0, 'VK_OEM_1'], + Quote: ['\'', '"', '', '', 0, 'VK_OEM_7'], + Backquote: ['`', '~', '', '~', 0, 'VK_OEM_3'], + Comma: [',', '<', ',', '<', 0, 'VK_OEM_COMMA'], + Period: ['.', '>', '.', '', 0, 'VK_OEM_PERIOD'], + Slash: ['/', '?', '', '', 0, 'VK_OEM_2'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['\\', '|', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts new file mode 100644 index 00000000000..ceb7b67a878 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.USInternational-PC', lang: 'en', localizedName: 'U.S. International - PC' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', 'å', 'Å', 0], + KeyB: ['b', 'B', '∫', 'ı', 0], + KeyC: ['c', 'C', 'ç', 'Ç', 0], + KeyD: ['d', 'D', '∂', 'Î', 0], + KeyE: ['e', 'E', '´', '´', 4], + KeyF: ['f', 'F', 'ƒ', 'Ï', 0], + KeyG: ['g', 'G', '©', '˝', 0], + KeyH: ['h', 'H', '˙', 'Ó', 0], + KeyI: ['i', 'I', 'ˆ', 'ˆ', 4], + KeyJ: ['j', 'J', '∆', 'Ô', 0], + KeyK: ['k', 'K', '˚', '', 0], + KeyL: ['l', 'L', '¬', 'Ò', 0], + KeyM: ['m', 'M', 'µ', 'Â', 0], + KeyN: ['n', 'N', '˜', '˜', 4], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'π', '∏', 0], + KeyQ: ['q', 'Q', 'œ', 'Œ', 0], + KeyR: ['r', 'R', '®', '‰', 0], + KeyS: ['s', 'S', 'ß', 'Í', 0], + KeyT: ['t', 'T', '†', 'ˇ', 0], + KeyU: ['u', 'U', '¨', '¨', 4], + KeyV: ['v', 'V', '√', '◊', 0], + KeyW: ['w', 'W', '∑', '„', 0], + KeyX: ['x', 'X', '≈', '˛', 0], + KeyY: ['y', 'Y', '¥', 'Á', 0], + KeyZ: ['z', 'Z', 'Ω', '¸', 0], + Digit1: ['1', '!', '¡', '⁄', 0], + Digit2: ['2', '@', '™', '€', 0], + Digit3: ['3', '#', '£', '‹', 0], + Digit4: ['4', '$', '¢', '›', 0], + Digit5: ['5', '%', '∞', 'fi', 0], + Digit6: ['6', 'ˆ', '§', 'fl', 2], + Digit7: ['7', '&', '¶', '‡', 0], + Digit8: ['8', '*', '•', '°', 0], + Digit9: ['9', '(', 'ª', '·', 0], + Digit0: ['0', ')', 'º', '‚', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '–', '—', 0], + Equal: ['=', '+', '≠', '±', 0], + BracketLeft: ['[', '{', '“', '”', 0], + BracketRight: [']', '}', '‘', '’', 0], + Backslash: ['\\', '|', '«', '»', 0], + Semicolon: [';', ':', '…', 'Ú', 0], + Quote: ['\'', '"', 'æ', 'Æ', 3], + Backquote: ['`', '˜', '`', '`', 7], + Comma: [',', '<', '≤', '¯', 0], + Period: ['.', '>', '≥', '˘', 0], + Slash: ['/', '?', '÷', '¿', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: ['.', '.', '.', '.', 0], + IntlBackslash: ['§', '±', '§', '±', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts new file mode 100644 index 00000000000..75a2a40b805 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00020409', id: '0001', text: 'United States-International' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', 'á', 'Á', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '©', '¢', 0, 'VK_C'], + KeyD: ['d', 'D', 'ð', 'Ð', 0, 'VK_D'], + KeyE: ['e', 'E', 'é', 'É', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', 'í', 'Í', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', 'ø', 'Ø', 0, 'VK_L'], + KeyM: ['m', 'M', 'µ', '', 0, 'VK_M'], + KeyN: ['n', 'N', 'ñ', 'Ñ', 0, 'VK_N'], + KeyO: ['o', 'O', 'ó', 'Ó', 0, 'VK_O'], + KeyP: ['p', 'P', 'ö', 'Ö', 0, 'VK_P'], + KeyQ: ['q', 'Q', 'ä', 'Ä', 0, 'VK_Q'], + KeyR: ['r', 'R', '®', '', 0, 'VK_R'], + KeyS: ['s', 'S', 'ß', '§', 0, 'VK_S'], + KeyT: ['t', 'T', 'þ', 'Þ', 0, 'VK_T'], + KeyU: ['u', 'U', 'ú', 'Ú', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', 'å', 'Å', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', 'ü', 'Ü', 0, 'VK_Y'], + KeyZ: ['z', 'Z', 'æ', 'Æ', 0, 'VK_Z'], + Digit1: ['1', '!', '¡', '¹', 0, 'VK_1'], + Digit2: ['2', '@', '²', '', 0, 'VK_2'], + Digit3: ['3', '#', '³', '', 0, 'VK_3'], + Digit4: ['4', '$', '¤', '£', 0, 'VK_4'], + Digit5: ['5', '%', '€', '', 0, 'VK_5'], + Digit6: ['6', '^', '¼', '', 0, 'VK_6'], + Digit7: ['7', '&', '½', '', 0, 'VK_7'], + Digit8: ['8', '*', '¾', '', 0, 'VK_8'], + Digit9: ['9', '(', '‘', '', 0, 'VK_9'], + Digit0: ['0', ')', '’', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['-', '_', '¥', '', 0, 'VK_OEM_MINUS'], + Equal: ['=', '+', '×', '÷', 0, 'VK_OEM_PLUS'], + BracketLeft: ['[', '{', '«', '', 0, 'VK_OEM_4'], + BracketRight: [']', '}', '»', '', 0, 'VK_OEM_6'], + Backslash: ['\\', '|', '¬', '¦', 0, 'VK_OEM_5'], + Semicolon: [';', ':', '¶', '°', 0, 'VK_OEM_1'], + Quote: ['\'', '"', '´', '¨', 0, 'VK_OEM_7'], + Backquote: ['`', '~', '', '', 0, 'VK_OEM_3'], + Comma: [',', '<', 'ç', 'Ç', 0, 'VK_OEM_COMMA'], + Period: ['.', '>', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['/', '?', '¿', '', 0, 'VK_OEM_2'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['\\', '|', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts new file mode 100644 index 00000000000..89236337707 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts @@ -0,0 +1,131 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.British', lang: 'en', localizedName: 'British' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', 'å', 'Å', 0], + KeyB: ['b', 'B', '∫', 'ı', 0], + KeyC: ['c', 'C', 'ç', 'Ç', 0], + KeyD: ['d', 'D', '∂', 'Î', 0], + KeyE: ['e', 'E', '´', '‰', 4], + KeyF: ['f', 'F', 'ƒ', 'Ï', 0], + KeyG: ['g', 'G', '©', 'Ì', 0], + KeyH: ['h', 'H', '˙', 'Ó', 0], + KeyI: ['i', 'I', '^', 'È', 4], + KeyJ: ['j', 'J', '∆', 'Ô', 0], + KeyK: ['k', 'K', '˚', '', 0], + KeyL: ['l', 'L', '¬', 'Ò', 0], + KeyM: ['m', 'M', 'µ', '˜', 0], + KeyN: ['n', 'N', '~', 'ˆ', 4], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'π', '∏', 0], + KeyQ: ['q', 'Q', 'œ', 'Œ', 0], + KeyR: ['r', 'R', '®', 'Â', 0], + KeyS: ['s', 'S', 'ß', 'Í', 0], + KeyT: ['t', 'T', '†', 'Ê', 0], + KeyU: ['u', 'U', '¨', 'Ë', 4], + KeyV: ['v', 'V', '√', '◊', 0], + KeyW: ['w', 'W', '∑', '„', 0], + KeyX: ['x', 'X', '≈', 'Ù', 0], + KeyY: ['y', 'Y', '¥', 'Á', 0], + KeyZ: ['z', 'Z', 'Ω', 'Û', 0], + Digit1: ['1', '!', '¡', '⁄', 0], + Digit2: ['2', '@', '€', '™', 0], + Digit3: ['3', '£', '#', '‹', 0], + Digit4: ['4', '$', '¢', '›', 0], + Digit5: ['5', '%', '∞', 'fi', 0], + Digit6: ['6', '^', '§', 'fl', 0], + Digit7: ['7', '&', '¶', '‡', 0], + Digit8: ['8', '*', '•', '°', 0], + Digit9: ['9', '(', 'ª', '·', 0], + Digit0: ['0', ')', 'º', '‚', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '–', '—', 0], + Equal: ['=', '+', '≠', '±', 0], + BracketLeft: ['[', '{', '“', '”', 0], + BracketRight: [']', '}', '‘', '’', 0], + Backslash: ['\\', '|', '«', '»', 0], + Semicolon: [';', ':', '…', 'Ú', 0], + Quote: ['\'', '"', 'æ', 'Æ', 0], + Backquote: ['`', '~', '`', 'Ÿ', 4], + Comma: [',', '<', '≤', '¯', 0], + Period: ['.', '>', '≥', '˘', 0], + Slash: ['/', '?', '÷', '¿', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: ['.', '.', '.', '.', 0], + IntlBackslash: ['§', '±', '', '', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts new file mode 100644 index 00000000000..0b07025fa88 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts @@ -0,0 +1,170 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000809', id: '', text: 'United Kingdom' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', 'á', 'Á', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', 'é', 'É', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', 'í', 'Í', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', '', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', 'ó', 'Ó', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', 'ú', 'Ú', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '"', '', '', 0, 'VK_2'], + Digit3: ['3', '£', '', '', 0, 'VK_3'], + Digit4: ['4', '$', '€', '', 0, 'VK_4'], + Digit5: ['5', '%', '', '', 0, 'VK_5'], + Digit6: ['6', '^', '', '', 0, 'VK_6'], + Digit7: ['7', '&', '', '', 0, 'VK_7'], + Digit8: ['8', '*', '', '', 0, 'VK_8'], + Digit9: ['9', '(', '', '', 0, 'VK_9'], + Digit0: ['0', ')', '', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + Equal: ['=', '+', '', '', 0, 'VK_OEM_PLUS'], + BracketLeft: ['[', '{', '', '', 0, 'VK_OEM_4'], + BracketRight: [']', '}', '', '', 0, 'VK_OEM_6'], + Backslash: ['#', '~', '\\', '|', 0, 'VK_OEM_7'], + Semicolon: [';', ':', '', '', 0, 'VK_OEM_1'], + Quote: ['\'', '@', '', '', 0, 'VK_OEM_3'], + Backquote: ['`', '¬', '¦', '', 0, 'VK_OEM_8'], + Comma: [',', '<', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', '>', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['/', '?', '', '', 0, 'VK_OEM_2'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['\\', '|', '', '', 0, 'VK_OEM_5'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } + +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts new file mode 100644 index 00000000000..f0fca4a9d74 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts @@ -0,0 +1,140 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.US', lang: 'en', localizedName: 'U.S.', isUSStandard: true }, + secondaryLayouts: [ + { id: 'com.apple.keylayout.ABC', lang: 'en', localizedName: 'ABC' }, + { id: 'com.sogou.inputmethod.sogou.pinyin', lang: 'zh-Hans', localizedName: 'Pinyin - Simplified' }, + { id: 'com.apple.inputmethod.Kotoeri.Roman', lang: 'en', localizedName: 'Romaji' }, + { id: 'com.apple.inputmethod.Kotoeri.Japanese', lang: 'ja', localizedName: 'Hiragana' }, + { id: 'com.apple.keylayout.Australian', lang: 'en', localizedName: 'Australian' }, + { id: 'com.apple.keylayout.Canadian', lang: 'en', localizedName: 'Canadian English' }, + { id: 'com.apple.keylayout.Brazilian', lang: 'pt', localizedName: 'Brazilian' }, + ], + mapping: { + KeyA: ['a', 'A', 'å', 'Å', 0], + KeyB: ['b', 'B', '∫', 'ı', 0], + KeyC: ['c', 'C', 'ç', 'Ç', 0], + KeyD: ['d', 'D', '∂', 'Î', 0], + KeyE: ['e', 'E', '´', '´', 4], + KeyF: ['f', 'F', 'ƒ', 'Ï', 0], + KeyG: ['g', 'G', '©', '˝', 0], + KeyH: ['h', 'H', '˙', 'Ó', 0], + KeyI: ['i', 'I', 'ˆ', 'ˆ', 4], + KeyJ: ['j', 'J', '∆', 'Ô', 0], + KeyK: ['k', 'K', '˚', '', 0], + KeyL: ['l', 'L', '¬', 'Ò', 0], + KeyM: ['m', 'M', 'µ', 'Â', 0], + KeyN: ['n', 'N', '˜', '˜', 4], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'π', '∏', 0], + KeyQ: ['q', 'Q', 'œ', 'Œ', 0], + KeyR: ['r', 'R', '®', '‰', 0], + KeyS: ['s', 'S', 'ß', 'Í', 0], + KeyT: ['t', 'T', '†', 'ˇ', 0], + KeyU: ['u', 'U', '¨', '¨', 4], + KeyV: ['v', 'V', '√', '◊', 0], + KeyW: ['w', 'W', '∑', '„', 0], + KeyX: ['x', 'X', '≈', '˛', 0], + KeyY: ['y', 'Y', '¥', 'Á', 0], + KeyZ: ['z', 'Z', 'Ω', '¸', 0], + Digit1: ['1', '!', '¡', '⁄', 0], + Digit2: ['2', '@', '™', '€', 0], + Digit3: ['3', '#', '£', '‹', 0], + Digit4: ['4', '$', '¢', '›', 0], + Digit5: ['5', '%', '∞', 'fi', 0], + Digit6: ['6', '^', '§', 'fl', 0], + Digit7: ['7', '&', '¶', '‡', 0], + Digit8: ['8', '*', '•', '°', 0], + Digit9: ['9', '(', 'ª', '·', 0], + Digit0: ['0', ')', 'º', '‚', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '–', '—', 0], + Equal: ['=', '+', '≠', '±', 0], + BracketLeft: ['[', '{', '“', '”', 0], + BracketRight: [']', '}', '‘', '’', 0], + Backslash: ['\\', '|', '«', '»', 0], + Semicolon: [';', ':', '…', 'Ú', 0], + Quote: ['\'', '"', 'æ', 'Æ', 0], + Backquote: ['`', '~', '`', '`', 4], + Comma: [',', '<', '≤', '¯', 0], + Period: ['.', '>', '≥', '˘', 0], + Slash: ['/', '?', '÷', '¿', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: ['.', '.', '.', '.', 0], + IntlBackslash: ['§', '±', '§', '±', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts new file mode 100644 index 00000000000..571e9164e15 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts @@ -0,0 +1,190 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { model: 'pc105', layout: 'us', variant: '', options: '', rules: 'evdev', isUSStandard: true }, + secondaryLayouts: [ + { model: 'pc105', layout: 'cn', variant: '', options: '', rules: 'evdev' }, + ], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', 'a', 'A', 0], + KeyB: ['b', 'B', 'b', 'B', 0], + KeyC: ['c', 'C', 'c', 'C', 0], + KeyD: ['d', 'D', 'd', 'D', 0], + KeyE: ['e', 'E', 'e', 'E', 0], + KeyF: ['f', 'F', 'f', 'F', 0], + KeyG: ['g', 'G', 'g', 'G', 0], + KeyH: ['h', 'H', 'h', 'H', 0], + KeyI: ['i', 'I', 'i', 'I', 0], + KeyJ: ['j', 'J', 'j', 'J', 0], + KeyK: ['k', 'K', 'k', 'K', 0], + KeyL: ['l', 'L', 'l', 'L', 0], + KeyM: ['m', 'M', 'm', 'M', 0], + KeyN: ['n', 'N', 'n', 'N', 0], + KeyO: ['o', 'O', 'o', 'O', 0], + KeyP: ['p', 'P', 'p', 'P', 0], + KeyQ: ['q', 'Q', 'q', 'Q', 0], + KeyR: ['r', 'R', 'r', 'R', 0], + KeyS: ['s', 'S', 's', 'S', 0], + KeyT: ['t', 'T', 't', 'T', 0], + KeyU: ['u', 'U', 'u', 'U', 0], + KeyV: ['v', 'V', 'v', 'V', 0], + KeyW: ['w', 'W', 'w', 'W', 0], + KeyX: ['x', 'X', 'x', 'X', 0], + KeyY: ['y', 'Y', 'y', 'Y', 0], + KeyZ: ['z', 'Z', 'z', 'Z', 0], + Digit1: ['1', '!', '1', '!', 0], + Digit2: ['2', '@', '2', '@', 0], + Digit3: ['3', '#', '3', '#', 0], + Digit4: ['4', '$', '4', '$', 0], + Digit5: ['5', '%', '5', '%', 0], + Digit6: ['6', '^', '6', '^', 0], + Digit7: ['7', '&', '7', '&', 0], + Digit8: ['8', '*', '8', '*', 0], + Digit9: ['9', '(', '9', '(', 0], + Digit0: ['0', ')', '0', ')', 0], + Enter: ['\r', '\r', '\r', '\r', 0], + Escape: ['\u001b', '\u001b', '\u001b', '\u001b', 0], + Backspace: ['\b', '\b', '\b', '\b', 0], + Tab: ['\t', '', '\t', '', 0], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '-', '_', 0], + Equal: ['=', '+', '=', '+', 0], + BracketLeft: ['[', '{', '[', '{', 0], + BracketRight: [']', '}', ']', '}', 0], + Backslash: ['\\', '|', '\\', '|', 0], + Semicolon: [';', ':', ';', ':', 0], + Quote: ['\'', '"', '\'', '"', 0], + Backquote: ['`', '~', '`', '~', 0], + Comma: [',', '<', ',', '<', 0], + Period: ['.', '>', '.', '>', 0], + Slash: ['/', '?', '/', '?', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: ['', '', '', '', 0], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: ['\r', '\r', '\r', '\r', 0], + Numpad1: ['', '1', '', '1', 0], + Numpad2: ['', '2', '', '2', 0], + Numpad3: ['', '3', '', '3', 0], + Numpad4: ['', '4', '', '4', 0], + Numpad5: ['', '5', '', '5', 0], + Numpad6: ['', '6', '', '6', 0], + Numpad7: ['', '7', '', '7', 0], + Numpad8: ['', '8', '', '8', 0], + Numpad9: ['', '9', '', '9', 0], + Numpad0: ['', '0', '', '0', 0], + NumpadDecimal: ['', '.', '', '.', 0], + IntlBackslash: ['<', '>', '|', '¦', 0], + ContextMenu: [], + Power: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Open: [], + Help: [], + Select: [], + Again: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + Find: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: ['.', '.', '.', '.', 0], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + Lang5: [], + NumpadParenLeft: ['(', '(', '(', '(', 0], + NumpadParenRight: [')', ')', ')', ')', 0], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + BrightnessUp: [], + BrightnessDown: [], + MediaPlay: [], + MediaRecord: [], + MediaFastForward: [], + MediaRewind: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + SelectTask: [], + LaunchScreenSaver: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [], + MailReply: [], + MailForward: [], + MailSend: [] + } + +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts new file mode 100644 index 00000000000..3d6845dc053 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts @@ -0,0 +1,174 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000409', id: '', text: 'US', isUSStandard: true }, + secondaryLayouts: [ + { name: '00000804', id: '', text: 'Chinese (Simplified) - US Keyboard' }, + { name: '00000411', id: '', text: 'Japanese' }, + { name: '00000412', id: '', text: 'Korean' }, + { name: '00000404', id: '', text: 'Chinese (Traditional) - US Keyboard' } + ], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', '', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '@', '', '', 0, 'VK_2'], + Digit3: ['3', '#', '', '', 0, 'VK_3'], + Digit4: ['4', '$', '', '', 0, 'VK_4'], + Digit5: ['5', '%', '', '', 0, 'VK_5'], + Digit6: ['6', '^', '', '', 0, 'VK_6'], + Digit7: ['7', '&', '', '', 0, 'VK_7'], + Digit8: ['8', '*', '', '', 0, 'VK_8'], + Digit9: ['9', '(', '', '', 0, 'VK_9'], + Digit0: ['0', ')', '', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + Equal: ['=', '+', '', '', 0, 'VK_OEM_PLUS'], + BracketLeft: ['[', '{', '', '', 0, 'VK_OEM_4'], + BracketRight: [']', '}', '', '', 0, 'VK_OEM_6'], + Backslash: ['\\', '|', '', '', 0, 'VK_OEM_5'], + Semicolon: [';', ':', '', '', 0, 'VK_OEM_1'], + Quote: ['\'', '"', '', '', 0, 'VK_OEM_7'], + Backquote: ['`', '~', '', '', 0, 'VK_OEM_3'], + Comma: [',', '<', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', '>', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['/', '?', '', '', 0, 'VK_OEM_2'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['\\', '|', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts new file mode 100644 index 00000000000..16531eda212 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts @@ -0,0 +1,170 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000080A', id: '', text: 'Latin American' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', '', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '@', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '"', '', '', 0, 'VK_2'], + Digit3: ['3', '#', '', '', 0, 'VK_3'], + Digit4: ['4', '$', '', '', 0, 'VK_4'], + Digit5: ['5', '%', '', '', 0, 'VK_5'], + Digit6: ['6', '&', '', '', 0, 'VK_6'], + Digit7: ['7', '/', '', '', 0, 'VK_7'], + Digit8: ['8', '(', '', '', 0, 'VK_8'], + Digit9: ['9', ')', '', '', 0, 'VK_9'], + Digit0: ['0', '=', '', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['\'', '?', '\\', '', 0, 'VK_OEM_4'], + Equal: ['¿', '¡', '', '', 0, 'VK_OEM_6'], + BracketLeft: ['´', '¨', '', '', 0, 'VK_OEM_1'], + BracketRight: ['+', '*', '~', '', 0, 'VK_OEM_PLUS'], + Backslash: ['}', ']', '`', '', 0, 'VK_OEM_2'], + Semicolon: ['ñ', 'Ñ', '', '', 0, 'VK_OEM_3'], + Quote: ['{', '[', '^', '', 0, 'VK_OEM_7'], + Backquote: ['|', '°', '¬', '', 0, 'VK_OEM_5'], + Comma: [',', ';', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', ':', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } + +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts new file mode 100644 index 00000000000..679dfb36d08 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.Spanish-ISO', lang: 'es', localizedName: 'Spanish - ISO' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', 'å', 'Å', 0], + KeyB: ['b', 'B', 'ß', '', 0], + KeyC: ['c', 'C', '©', ' ', 0], + KeyD: ['d', 'D', '∂', '∆', 0], + KeyE: ['e', 'E', '€', '€', 0], + KeyF: ['f', 'F', 'ƒ', 'fi', 0], + KeyG: ['g', 'G', '', 'fl', 0], + KeyH: ['h', 'H', '™', ' ', 0], + KeyI: ['i', 'I', ' ', ' ', 0], + KeyJ: ['j', 'J', '¶', '¯', 0], + KeyK: ['k', 'K', '§', 'ˇ', 0], + KeyL: ['l', 'L', ' ', '˘', 0], + KeyM: ['m', 'M', 'µ', '˚', 0], + KeyN: ['n', 'N', ' ', '˙', 0], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'π', '∏', 0], + KeyQ: ['q', 'Q', 'œ', 'Œ', 0], + KeyR: ['r', 'R', '®', ' ', 0], + KeyS: ['s', 'S', '∫', ' ', 0], + KeyT: ['t', 'T', '†', '‡', 0], + KeyU: ['u', 'U', ' ', ' ', 0], + KeyV: ['v', 'V', '√', '◊', 0], + KeyW: ['w', 'W', 'æ', 'Æ', 0], + KeyX: ['x', 'X', '∑', '›', 0], + KeyY: ['y', 'Y', '¥', ' ', 0], + KeyZ: ['z', 'Z', 'Ω', '‹', 0], + Digit1: ['1', '!', '|', 'ı', 0], + Digit2: ['2', '"', '@', '˝', 0], + Digit3: ['3', '·', '#', '•', 0], + Digit4: ['4', '$', '¢', '£', 0], + Digit5: ['5', '%', '∞', '‰', 0], + Digit6: ['6', '&', '¬', ' ', 0], + Digit7: ['7', '/', '÷', '⁄', 0], + Digit8: ['8', '(', '“', '‘', 0], + Digit9: ['9', ')', '”', '’', 0], + Digit0: ['0', '=', '≠', '≈', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['\'', '?', '´', '¸', 0], + Equal: ['¡', '¿', '‚', '˛', 0], + BracketLeft: ['`', '^', '[', 'ˆ', 3], + BracketRight: ['+', '*', ']', '±', 0], + Backslash: ['ç', 'Ç', '}', '»', 0], + Semicolon: ['ñ', 'Ñ', '~', '˜', 4], + Quote: ['´', '¨', '{', '«', 3], + Backquote: ['<', '>', '≤', '≥', 0], + Comma: [',', ';', '„', '', 0], + Period: ['.', ':', '…', '…', 0], + Slash: ['-', '_', '–', '—', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: [',', ',', ',', ',', 0], + IntlBackslash: ['º', 'ª', '\\', '°', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts new file mode 100644 index 00000000000..8fcff46f8d6 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts @@ -0,0 +1,187 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { model: 'pc105', layout: 'es', variant: '', options: '', rules: 'evdev' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', 'æ', 'Æ', 0], + KeyB: ['b', 'B', '”', '’', 0], + KeyC: ['c', 'C', '¢', '©', 0], + KeyD: ['d', 'D', 'ð', 'Ð', 0], + KeyE: ['e', 'E', '€', '¢', 0], + KeyF: ['f', 'F', 'đ', 'ª', 0], + KeyG: ['g', 'G', 'ŋ', 'Ŋ', 0], + KeyH: ['h', 'H', 'ħ', 'Ħ', 0], + KeyI: ['i', 'I', '→', 'ı', 0], + KeyJ: ['j', 'J', '̉', '̛', 0], + KeyK: ['k', 'K', 'ĸ', '&', 0], + KeyL: ['l', 'L', 'ł', 'Ł', 0], + KeyM: ['m', 'M', 'µ', 'º', 0], + KeyN: ['n', 'N', 'n', 'N', 0], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'þ', 'Þ', 0], + KeyQ: ['q', 'Q', '@', 'Ω', 0], + KeyR: ['r', 'R', '¶', '®', 0], + KeyS: ['s', 'S', 'ß', '§', 0], + KeyT: ['t', 'T', 'ŧ', 'Ŧ', 0], + KeyU: ['u', 'U', '↓', '↑', 0], + KeyV: ['v', 'V', '“', '‘', 0], + KeyW: ['w', 'W', 'ł', 'Ł', 0], + KeyX: ['x', 'X', '»', '>', 0], + KeyY: ['y', 'Y', '←', '¥', 0], + KeyZ: ['z', 'Z', '«', '<', 0], + Digit1: ['1', '!', '|', '¡', 0], + Digit2: ['2', '"', '@', '⅛', 0], + Digit3: ['3', '·', '#', '£', 0], + Digit4: ['4', '$', '~', '$', 0], + Digit5: ['5', '%', '½', '⅜', 0], + Digit6: ['6', '&', '¬', '⅝', 0], + Digit7: ['7', '/', '{', '⅞', 0], + Digit8: ['8', '(', '[', '™', 0], + Digit9: ['9', ')', ']', '±', 0], + Digit0: ['0', '=', '}', '°', 0], + Enter: ['\r', '\r', '\r', '\r', 0], + Escape: ['\u001b', '\u001b', '\u001b', '\u001b', 0], + Backspace: ['\b', '\b', '\b', '\b', 0], + Tab: ['\t', '', '\t', '', 0], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['\'', '?', '\\', '¿', 0], + Equal: ['¡', '¿', '̃', '~', 0], + BracketLeft: ['̀', '̂', '[', '̊', 0], + BracketRight: ['+', '*', ']', '̄', 0], + Backslash: ['ç', 'Ç', '}', '̆', 0], + Semicolon: ['ñ', 'Ñ', '~', '̋', 0], + Quote: ['́', '̈', '{', '{', 0], + Backquote: ['º', 'ª', '\\', '\\', 0], + Comma: [',', ';', '─', '×', 0], + Period: ['.', ':', '·', '÷', 0], + Slash: ['-', '_', '̣', '̇', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: ['', '', '', '', 0], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: ['\r', '\r', '\r', '\r', 0], + Numpad1: ['', '1', '', '1', 0], + Numpad2: ['', '2', '', '2', 0], + Numpad3: ['', '3', '', '3', 0], + Numpad4: ['', '4', '', '4', 0], + Numpad5: ['', '5', '', '5', 0], + Numpad6: ['', '6', '', '6', 0], + Numpad7: ['', '7', '', '7', 0], + Numpad8: ['', '8', '', '8', 0], + Numpad9: ['', '9', '', '9', 0], + Numpad0: ['', '0', '', '0', 0], + NumpadDecimal: ['', '.', '', '.', 0], + IntlBackslash: ['<', '>', '|', '¦', 0], + ContextMenu: [], + Power: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Open: [], + Help: [], + Select: [], + Again: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + Find: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: ['.', '.', '.', '.', 0], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + Lang5: [], + NumpadParenLeft: ['(', '(', '(', '(', 0], + NumpadParenRight: [')', ')', ')', ')', 0], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + BrightnessUp: [], + BrightnessDown: [], + MediaPlay: [], + MediaRecord: [], + MediaFastForward: [], + MediaRewind: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + SelectTask: [], + LaunchScreenSaver: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [], + MailReply: [], + MailForward: [], + MailSend: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts new file mode 100644 index 00000000000..3ac96a5dc59 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000040A', id: '', text: 'Spanish' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', '', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '|', '', 0, 'VK_1'], + Digit2: ['2', '"', '@', '', 0, 'VK_2'], + Digit3: ['3', '·', '#', '', 0, 'VK_3'], + Digit4: ['4', '$', '~', '', 0, 'VK_4'], + Digit5: ['5', '%', '€', '', 0, 'VK_5'], + Digit6: ['6', '&', '¬', '', 0, 'VK_6'], + Digit7: ['7', '/', '', '', 0, 'VK_7'], + Digit8: ['8', '(', '', '', 0, 'VK_8'], + Digit9: ['9', ')', '', '', 0, 'VK_9'], + Digit0: ['0', '=', '', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['\'', '?', '', '', 0, 'VK_OEM_4'], + Equal: ['¡', '¿', '', '', 0, 'VK_OEM_6'], + BracketLeft: ['`', '^', '[', '', 0, 'VK_OEM_1'], + BracketRight: ['+', '*', ']', '', 0, 'VK_OEM_PLUS'], + Backslash: ['ç', 'Ç', '}', '', 0, 'VK_OEM_2'], + Semicolon: ['ñ', 'Ñ', '', '', 0, 'VK_OEM_3'], + Quote: ['´', '¨', '{', '', 0, 'VK_OEM_7'], + Backquote: ['º', 'ª', '\\', '', 0, 'VK_OEM_5'], + Comma: [',', ';', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', ':', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts new file mode 100644 index 00000000000..fa9198b64a0 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.French', lang: 'fr', localizedName: 'French' }, + secondaryLayouts: [], + mapping: { + KeyA: ['q', 'Q', '‡', 'Ω', 0], + KeyB: ['b', 'B', 'ß', '∫', 0], + KeyC: ['c', 'C', '©', '¢', 0], + KeyD: ['d', 'D', '∂', '∆', 0], + KeyE: ['e', 'E', 'ê', 'Ê', 0], + KeyF: ['f', 'F', 'ƒ', '·', 0], + KeyG: ['g', 'G', 'fi', 'fl', 0], + KeyH: ['h', 'H', 'Ì', 'Î', 0], + KeyI: ['i', 'I', 'î', 'ï', 0], + KeyJ: ['j', 'J', 'Ï', 'Í', 0], + KeyK: ['k', 'K', 'È', 'Ë', 0], + KeyL: ['l', 'L', '¬', '|', 0], + KeyM: [',', '?', '∞', '¿', 0], + KeyN: ['n', 'N', '~', 'ı', 4], + KeyO: ['o', 'O', 'œ', 'Œ', 0], + KeyP: ['p', 'P', 'π', '∏', 0], + KeyQ: ['a', 'A', 'æ', 'Æ', 0], + KeyR: ['r', 'R', '®', '‚', 0], + KeyS: ['s', 'S', 'Ò', '∑', 0], + KeyT: ['t', 'T', '†', '™', 0], + KeyU: ['u', 'U', 'º', 'ª', 0], + KeyV: ['v', 'V', '◊', '√', 0], + KeyW: ['z', 'Z', 'Â', 'Å', 0], + KeyX: ['x', 'X', '≈', '⁄', 0], + KeyY: ['y', 'Y', 'Ú', 'Ÿ', 0], + KeyZ: ['w', 'W', '‹', '›', 0], + Digit1: ['&', '1', '', '´', 8], + Digit2: ['é', '2', 'ë', '„', 0], + Digit3: ['"', '3', '“', '”', 0], + Digit4: ['\'', '4', '‘', '’', 0], + Digit5: ['(', '5', '{', '[', 0], + Digit6: ['§', '6', '¶', 'å', 0], + Digit7: ['è', '7', '«', '»', 0], + Digit8: ['!', '8', '¡', 'Û', 0], + Digit9: ['ç', '9', 'Ç', 'Á', 0], + Digit0: ['à', '0', 'ø', 'Ø', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: [')', '°', '}', ']', 0], + Equal: ['-', '_', '—', '–', 0], + BracketLeft: ['^', '¨', 'ô', 'Ô', 3], + BracketRight: ['$', '*', '€', '¥', 0], + Backslash: ['`', '£', '@', '#', 1], + Semicolon: ['m', 'M', 'µ', 'Ó', 0], + Quote: ['ù', '%', 'Ù', '‰', 0], + Backquote: ['<', '>', '≤', '≥', 0], + Comma: [';', '.', '…', '•', 0], + Period: [':', '/', '÷', '\\', 0], + Slash: ['=', '+', '≠', '±', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: [',', '.', ',', '.', 0], + IntlBackslash: ['@', '#', '•', 'Ÿ', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts new file mode 100644 index 00000000000..dc9488f28c3 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts @@ -0,0 +1,187 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { model: 'pc104', layout: 'fr', variant: '', options: '', rules: 'base' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['q', 'Q', '@', 'Ω', 0], + KeyB: ['b', 'B', '”', '’', 0], + KeyC: ['c', 'C', '¢', '©', 0], + KeyD: ['d', 'D', 'ð', 'Ð', 0], + KeyE: ['e', 'E', '€', '¢', 0], + KeyF: ['f', 'F', 'đ', 'ª', 0], + KeyG: ['g', 'G', 'ŋ', 'Ŋ', 0], + KeyH: ['h', 'H', 'ħ', 'Ħ', 0], + KeyI: ['i', 'I', '→', 'ı', 0], + KeyJ: ['j', 'J', '̉', '̛', 0], + KeyK: ['k', 'K', 'ĸ', '&', 0], + KeyL: ['l', 'L', 'ł', 'Ł', 0], + KeyM: [',', '?', '́', '̋', 0], + KeyN: ['n', 'N', 'n', 'N', 0], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'þ', 'Þ', 0], + KeyQ: ['a', 'A', 'æ', 'Æ', 0], + KeyR: ['r', 'R', '¶', '®', 0], + KeyS: ['s', 'S', 'ß', '§', 0], + KeyT: ['t', 'T', 'ŧ', 'Ŧ', 0], + KeyU: ['u', 'U', '↓', '↑', 0], + KeyV: ['v', 'V', '“', '‘', 0], + KeyW: ['z', 'Z', '«', '<', 0], + KeyX: ['x', 'X', '»', '>', 0], + KeyY: ['y', 'Y', '←', '¥', 0], + KeyZ: ['w', 'W', 'ł', 'Ł', 0], + Digit1: ['&', '1', '¹', '¡', 0], + Digit2: ['é', '2', '~', '⅛', 0], + Digit3: ['"', '3', '#', '£', 0], + Digit4: ['\'', '4', '{', '$', 0], + Digit5: ['(', '5', '[', '⅜', 0], + Digit6: ['-', '6', '|', '⅝', 0], + Digit7: ['è', '7', '`', '⅞', 0], + Digit8: ['_', '8', '\\', '™', 0], + Digit9: ['ç', '9', '^', '±', 0], + Digit0: ['à', '0', '@', '°', 0], + Enter: ['\r', '\r', '\r', '\r', 0], + Escape: ['\u001b', '\u001b', '\u001b', '\u001b', 0], + Backspace: ['\b', '\b', '\b', '\b', 0], + Tab: ['\t', '', '\t', '', 0], + Space: [' ', ' ', ' ', ' ', 0], + Minus: [')', '°', ']', '¿', 0], + Equal: ['=', '+', '}', '̨', 0], + BracketLeft: ['̂', '̈', '̈', '̊', 0], + BracketRight: ['$', '£', '¤', '̄', 0], + Backslash: ['*', 'µ', '̀', '̆', 0], + Semicolon: ['m', 'M', 'µ', 'º', 0], + Quote: ['ù', '%', '̂', '̌', 0], + Backquote: ['²', '~', '¬', '¬', 0], + Comma: [';', '.', '─', '×', 0], + Period: [':', '/', '·', '÷', 0], + Slash: ['!', '§', '̣', '̇', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: ['', '', '', '', 0], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: ['/', '/', '/', '/', 0], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: [], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['', '1', '', '1', 0], + Numpad2: ['', '2', '', '2', 0], + Numpad3: ['', '3', '', '3', 0], + Numpad4: ['', '4', '', '4', 0], + Numpad5: ['', '5', '', '5', 0], + Numpad6: ['', '6', '', '6', 0], + Numpad7: ['', '7', '', '7', 0], + Numpad8: ['', '8', '', '8', 0], + Numpad9: ['', '9', '', '9', 0], + Numpad0: ['', '0', '', '0', 0], + NumpadDecimal: ['', '.', '', '.', 0], + IntlBackslash: ['<', '>', '|', '¦', 0], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Open: [], + Help: [], + Select: [], + Again: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + Find: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + Lang5: [], + NumpadParenLeft: [], + NumpadParenRight: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: ['\r', '\r', '\r', '\r', 0], + MetaRight: ['.', '.', '.', '.', 0], + BrightnessUp: [], + BrightnessDown: [], + MediaPlay: [], + MediaRecord: [], + MediaFastForward: [], + MediaRewind: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + SelectTask: [], + LaunchScreenSaver: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [], + MailReply: [], + MailForward: [], + MailSend: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts new file mode 100644 index 00000000000..c9f032d7bee --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000040C', id: '', text: 'French' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: [',', '?', '', '', 0, 'VK_OEM_COMMA'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['a', 'A', '', '', 0, 'VK_A'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['z', 'Z', '', '', 0, 'VK_Z'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['w', 'W', '', '', 0, 'VK_W'], + Digit1: ['&', '1', '', '', 0, 'VK_1'], + Digit2: ['é', '2', '~', '', 0, 'VK_2'], + Digit3: ['"', '3', '#', '', 0, 'VK_3'], + Digit4: ['\'', '4', '{', '', 0, 'VK_4'], + Digit5: ['(', '5', '[', '', 0, 'VK_5'], + Digit6: ['-', '6', '|', '', 0, 'VK_6'], + Digit7: ['è', '7', '`', '', 0, 'VK_7'], + Digit8: ['_', '8', '\\', '', 0, 'VK_8'], + Digit9: ['ç', '9', '^', '', 0, 'VK_9'], + Digit0: ['à', '0', '@', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: [')', '°', ']', '', 0, 'VK_OEM_4'], + Equal: ['=', '+', '}', '', 0, 'VK_OEM_PLUS'], + BracketLeft: ['^', '¨', '', '', 0, 'VK_OEM_6'], + BracketRight: ['$', '£', '¤', '', 0, 'VK_OEM_1'], + Backslash: ['*', 'µ', '', '', 0, 'VK_OEM_5'], + Semicolon: ['m', 'M', '', '', 0, 'VK_M'], + Quote: ['ù', '%', '', '', 0, 'VK_OEM_3'], + Backquote: ['²', '', '', '', 0, 'VK_OEM_7'], + Comma: [';', '.', '', '', 0, 'VK_OEM_PERIOD'], + Period: [':', '/', '', '', 0, 'VK_OEM_2'], + Slash: ['!', '§', '', '', 0, 'VK_OEM_8'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts new file mode 100644 index 00000000000..d6b5a4dac06 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000040E', id: '', text: 'Hungarian' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', 'ä', '', 0, 'VK_A'], + KeyB: ['b', 'B', '{', '', 0, 'VK_B'], + KeyC: ['c', 'C', '&', '', 0, 'VK_C'], + KeyD: ['d', 'D', 'Đ', '', 0, 'VK_D'], + KeyE: ['e', 'E', 'Ä', '', 0, 'VK_E'], + KeyF: ['f', 'F', '[', '', 0, 'VK_F'], + KeyG: ['g', 'G', ']', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', 'Í', '', 0, 'VK_I'], + KeyJ: ['j', 'J', 'í', '', 0, 'VK_J'], + KeyK: ['k', 'K', 'ł', '', 0, 'VK_K'], + KeyL: ['l', 'L', 'Ł', '', 0, 'VK_L'], + KeyM: ['m', 'M', '<', '', 0, 'VK_M'], + KeyN: ['n', 'N', '}', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '\\', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', 'đ', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '€', '', 0, 'VK_U'], + KeyV: ['v', 'V', '@', '', 0, 'VK_V'], + KeyW: ['w', 'W', '|', '', 0, 'VK_W'], + KeyX: ['x', 'X', '#', '', 0, 'VK_X'], + KeyY: ['z', 'Z', '', '', 0, 'VK_Z'], + KeyZ: ['y', 'Y', '>', '', 0, 'VK_Y'], + Digit1: ['1', '\'', '~', '', 0, 'VK_1'], + Digit2: ['2', '"', 'ˇ', '', 0, 'VK_2'], + Digit3: ['3', '+', '^', '', 0, 'VK_3'], + Digit4: ['4', '!', '˘', '', 0, 'VK_4'], + Digit5: ['5', '%', '°', '', 0, 'VK_5'], + Digit6: ['6', '/', '˛', '', 0, 'VK_6'], + Digit7: ['7', '=', '`', '', 0, 'VK_7'], + Digit8: ['8', '(', '˙', '', 0, 'VK_8'], + Digit9: ['9', ')', '´', '', 0, 'VK_9'], + Digit0: ['ö', 'Ö', '˝', '', 0, 'VK_OEM_3'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['ü', 'Ü', '¨', '', 0, 'VK_OEM_2'], + Equal: ['ó', 'Ó', '¸', '', 0, 'VK_OEM_PLUS'], + BracketLeft: ['ő', 'Ő', '÷', '', 0, 'VK_OEM_4'], + BracketRight: ['ú', 'Ú', '×', '', 0, 'VK_OEM_6'], + Backslash: ['ű', 'Ű', '¤', '', 0, 'VK_OEM_5'], + Semicolon: ['é', 'É', '$', '', 0, 'VK_OEM_1'], + Quote: ['á', 'Á', 'ß', '', 0, 'VK_OEM_7'], + Backquote: ['0', '§', '', '', 0, 'VK_0'], + Comma: [',', '?', ';', '', 0, 'VK_OEM_COMMA'], + Period: ['.', ':', '>', '', 0, 'VK_OEM_PERIOD'], + Slash: ['-', '_', '*', '', 0, 'VK_OEM_MINUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['í', 'Í', '<', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts new file mode 100644 index 00000000000..1dc97d9903f --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.Italian-Pro', lang: 'it', localizedName: 'Italian' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', 'å', 'Å', 0], + KeyB: ['b', 'B', '∫', 'Í', 0], + KeyC: ['c', 'C', '©', 'Á', 0], + KeyD: ['d', 'D', '∂', '˘', 0], + KeyE: ['e', 'E', '€', 'È', 0], + KeyF: ['f', 'F', 'ƒ', '˙', 0], + KeyG: ['g', 'G', '∞', '˚', 0], + KeyH: ['h', 'H', '∆', '¸', 0], + KeyI: ['i', 'I', 'œ', 'Œ', 0], + KeyJ: ['j', 'J', 'ª', '˝', 0], + KeyK: ['k', 'K', 'º', '˛', 0], + KeyL: ['l', 'L', '¬', 'ˇ', 0], + KeyM: ['m', 'M', 'µ', 'Ú', 0], + KeyN: ['n', 'N', '˜', 'Ó', 4], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'π', '∏', 0], + KeyQ: ['q', 'Q', '„', '‚', 0], + KeyR: ['r', 'R', '®', 'Ì', 0], + KeyS: ['s', 'S', 'ß', '¯', 0], + KeyT: ['t', 'T', '™', 'Ò', 0], + KeyU: ['u', 'U', '¨', 'Ù', 4], + KeyV: ['v', 'V', '√', 'É', 0], + KeyW: ['w', 'W', 'Ω', 'À', 0], + KeyX: ['x', 'X', '†', '‡', 0], + KeyY: ['y', 'Y', 'æ', 'Æ', 0], + KeyZ: ['z', 'Z', '∑', ' ', 0], + Digit1: ['1', '!', '«', '»', 0], + Digit2: ['2', '"', '“', '”', 0], + Digit3: ['3', '£', '‘', '’', 0], + Digit4: ['4', '$', '¥', '¢', 0], + Digit5: ['5', '%', '~', '‰', 0], + Digit6: ['6', '&', '‹', '›', 0], + Digit7: ['7', '/', '÷', '⁄', 0], + Digit8: ['8', '(', '´', '', 4], + Digit9: ['9', ')', '`', ' ', 4], + Digit0: ['0', '=', '≠', '≈', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['\'', '?', '¡', '¿', 0], + Equal: ['ì', '^', 'ˆ', '±', 4], + BracketLeft: ['è', 'é', '[', '{', 0], + BracketRight: ['+', '*', ']', '}', 0], + Backslash: ['ù', '§', '¶', '◊', 0], + Semicolon: ['ò', 'ç', '@', 'Ç', 0], + Quote: ['à', '°', '#', '∞', 0], + Backquote: ['<', '>', '≤', '≥', 0], + Comma: [',', ';', '…', ' ', 0], + Period: ['.', ':', '•', '·', 0], + Slash: ['-', '_', '–', '—', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: [',', '.', ',', '.', 0], + IntlBackslash: ['\\', '|', '`', 'ı', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts new file mode 100644 index 00000000000..573b7b0c6c3 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000410', id: '', text: 'Italian' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', '', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '"', '', '', 0, 'VK_2'], + Digit3: ['3', '£', '', '', 0, 'VK_3'], + Digit4: ['4', '$', '', '', 0, 'VK_4'], + Digit5: ['5', '%', '€', '', 0, 'VK_5'], + Digit6: ['6', '&', '', '', 0, 'VK_6'], + Digit7: ['7', '/', '', '', 0, 'VK_7'], + Digit8: ['8', '(', '', '', 0, 'VK_8'], + Digit9: ['9', ')', '', '', 0, 'VK_9'], + Digit0: ['0', '=', '', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['\'', '?', '', '', 0, 'VK_OEM_4'], + Equal: ['ì', '^', '', '', 0, 'VK_OEM_6'], + BracketLeft: ['è', 'é', '[', '{', 0, 'VK_OEM_1'], + BracketRight: ['+', '*', ']', '}', 0, 'VK_OEM_PLUS'], + Backslash: ['ù', '§', '', '', 0, 'VK_OEM_2'], + Semicolon: ['ò', 'ç', '@', '', 0, 'VK_OEM_3'], + Quote: ['à', '°', '#', '', 0, 'VK_OEM_7'], + Backquote: ['\\', '|', '', '', 0, 'VK_OEM_5'], + Comma: [',', ';', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', ':', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts new file mode 100644 index 00000000000..27328f3d87b --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.google.inputmethod.Japanese.Roman', lang: 'en', localizedName: 'Alphanumeric (Google)' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', '¯', '̄', 4], + KeyB: ['b', 'B', '˘', '̆', 4], + KeyC: ['c', 'C', '¸', '̧', 4], + KeyD: ['d', 'D', 'ð', 'Ð', 0], + KeyE: ['e', 'E', '´', '́', 4], + KeyF: ['f', 'F', 'ƒ', '', 0], + KeyG: ['g', 'G', '©', '‸', 8], + KeyH: ['h', 'H', 'ˍ', '̱', 4], + KeyI: ['i', 'I', 'ʼ', '̛', 4], + KeyJ: ['j', 'J', '˝', '̋', 4], + KeyK: ['k', 'K', '˚', '̊', 4], + KeyL: ['l', 'L', '-', '̵', 4], + KeyM: ['m', 'M', '˛', '̨', 4], + KeyN: ['n', 'N', '˜', '̃', 4], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', ',', '̦', 4], + KeyQ: ['q', 'Q', 'œ', 'Œ', 0], + KeyR: ['r', 'R', '®', '‰', 0], + KeyS: ['s', 'S', 'ß', '', 0], + KeyT: ['t', 'T', 'þ', 'Þ', 0], + KeyU: ['u', 'U', '¨', '̈', 4], + KeyV: ['v', 'V', 'ˇ', '̌', 4], + KeyW: ['w', 'W', '˙', '̇', 4], + KeyX: ['x', 'X', '.', '̣', 4], + KeyY: ['y', 'Y', '¥', '', 0], + KeyZ: ['z', 'Z', 'ˀ', '̉', 4], + Digit1: ['1', '!', '¡', '⁄', 0], + Digit2: ['2', '@', '™', '€', 0], + Digit3: ['3', '#', '£', '‹', 0], + Digit4: ['4', '$', '¢', '›', 0], + Digit5: ['5', '%', '§', '†', 0], + Digit6: ['6', '^', 'ˆ', '̂', 4], + Digit7: ['7', '&', '¶', '‡', 0], + Digit8: ['8', '*', '•', '°', 0], + Digit9: ['9', '(', 'ª', '·', 0], + Digit0: ['0', ')', 'º', '‚', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '–', '—', 0], + Equal: ['=', '+', '≠', '±', 0], + BracketLeft: ['[', '{', '“', '”', 0], + BracketRight: [']', '}', '‘', '’', 0], + Backslash: ['\\', '|', '«', '»', 0], + Semicolon: [';', ':', '…', '№', 8], + Quote: ['\'', '"', 'æ', 'Æ', 0], + Backquote: ['`', '~', '`', '̀', 4], + Comma: [',', '<', '≤', '„', 0], + Period: ['.', '>', '≥', 'ʔ', 8], + Slash: ['/', '?', '÷', '¿', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: ['.', '.', '.', '.', 0], + IntlBackslash: ['§', '±', '§', '±', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts new file mode 100644 index 00000000000..819f96ba5ca --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.inputmethod.Kotoeri.Japanese', lang: 'ja', localizedName: 'Hiragana' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', 'å', 'Å', 0], + KeyB: ['b', 'B', '∫', 'ı', 0], + KeyC: ['c', 'C', 'ç', 'Ç', 0], + KeyD: ['d', 'D', '∂', 'Î', 0], + KeyE: ['e', 'E', '´', '´', 4], + KeyF: ['f', 'F', 'ƒ', 'Ï', 0], + KeyG: ['g', 'G', '©', '˝', 0], + KeyH: ['h', 'H', '˙', 'Ó', 0], + KeyI: ['i', 'I', 'ˆ', 'ˆ', 4], + KeyJ: ['j', 'J', '∆', 'Ô', 0], + KeyK: ['k', 'K', '˚', '', 0], + KeyL: ['l', 'L', '¬', 'Ò', 0], + KeyM: ['m', 'M', 'µ', 'Â', 0], + KeyN: ['n', 'N', '˜', '˜', 4], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'π', '∏', 0], + KeyQ: ['q', 'Q', 'œ', 'Œ', 0], + KeyR: ['r', 'R', '®', '‰', 0], + KeyS: ['s', 'S', 'ß', 'Í', 0], + KeyT: ['t', 'T', '†', 'ˇ', 0], + KeyU: ['u', 'U', '¨', '¨', 4], + KeyV: ['v', 'V', '√', '◊', 0], + KeyW: ['w', 'W', '∑', '„', 0], + KeyX: ['x', 'X', '≈', '˛', 0], + KeyY: ['y', 'Y', '¥', 'Á', 0], + KeyZ: ['z', 'Z', 'Ω', '¸', 0], + Digit1: ['1', '!', '¡', '⁄', 0], + Digit2: ['2', '@', '™', '€', 0], + Digit3: ['3', '#', '£', '‹', 0], + Digit4: ['4', '$', '¢', '›', 0], + Digit5: ['5', '%', '∞', 'fi', 0], + Digit6: ['6', '^', '§', 'fl', 0], + Digit7: ['7', '&', '¶', '‡', 0], + Digit8: ['8', '*', '•', '°', 0], + Digit9: ['9', '(', 'ª', '·', 0], + Digit0: ['0', ')', 'º', '‚', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '–', '—', 0], + Equal: ['=', '+', '≠', '±', 0], + BracketLeft: ['[', '{', '“', '”', 0], + BracketRight: [']', '}', '‘', '’', 0], + Backslash: ['\\', '|', '«', '»', 0], + Semicolon: [';', ':', '…', 'Ú', 0], + Quote: ['\'', '"', 'æ', 'Æ', 0], + Backquote: ['`', '~', '`', '`', 4], + Comma: [',', '<', '≤', '¯', 0], + Period: ['.', '>', '≥', '˘', 0], + Slash: ['/', '?', '÷', '¿', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: ['.', '.', '.', '.', 0], + IntlBackslash: ['§', '±', '§', '±', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts new file mode 100644 index 00000000000..4219a7bd62f --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.inputmethod.Korean.2SetKorean', lang: 'ko', localizedName: '2-Set Korean' }, + secondaryLayouts: [], + mapping: { + KeyA: ['ㅁ', 'ㅁ', 'a', 'A', 0], + KeyB: ['ㅠ', 'ㅠ', 'b', 'B', 0], + KeyC: ['ㅊ', 'ㅊ', 'c', 'C', 0], + KeyD: ['ㅇ', 'ㅇ', 'd', 'D', 0], + KeyE: ['ㄷ', 'ㄸ', 'e', 'E', 0], + KeyF: ['ㄹ', 'ㄹ', 'f', 'F', 0], + KeyG: ['ㅎ', 'ㅎ', 'g', 'G', 0], + KeyH: ['ㅗ', 'ㅗ', 'h', 'H', 0], + KeyI: ['ㅑ', 'ㅑ', 'i', 'I', 0], + KeyJ: ['ㅓ', 'ㅓ', 'j', 'J', 0], + KeyK: ['ㅏ', 'ㅏ', 'k', 'K', 0], + KeyL: ['ㅣ', 'ㅣ', 'l', 'L', 0], + KeyM: ['ㅡ', 'ㅡ', 'm', 'M', 0], + KeyN: ['ㅜ', 'ㅜ', 'n', 'N', 0], + KeyO: ['ㅐ', 'ㅒ', 'o', 'O', 0], + KeyP: ['ㅔ', 'ㅖ', 'p', 'P', 0], + KeyQ: ['ㅂ', 'ㅃ', 'q', 'Q', 0], + KeyR: ['ㄱ', 'ㄲ', 'r', 'R', 0], + KeyS: ['ㄴ', 'ㄴ', 's', 'S', 0], + KeyT: ['ㅅ', 'ㅆ', 't', 'T', 0], + KeyU: ['ㅕ', 'ㅕ', 'u', 'U', 0], + KeyV: ['ㅍ', 'ㅍ', 'v', 'V', 0], + KeyW: ['ㅈ', 'ㅉ', 'w', 'W', 0], + KeyX: ['ㅌ', 'ㅌ', 'x', 'X', 0], + KeyY: ['ㅛ', 'ㅛ', 'y', 'Y', 0], + KeyZ: ['ㅋ', 'ㅋ', 'z', 'Z', 0], + Digit1: ['1', '!', '1', '!', 0], + Digit2: ['2', '@', '2', '@', 0], + Digit3: ['3', '#', '3', '#', 0], + Digit4: ['4', '$', '4', '$', 0], + Digit5: ['5', '%', '5', '%', 0], + Digit6: ['6', '^', '6', '^', 0], + Digit7: ['7', '&', '7', '&', 0], + Digit8: ['8', '*', '8', '*', 0], + Digit9: ['9', '(', '9', '(', 0], + Digit0: ['0', ')', '0', ')', 0], + Enter: [], + Escape: ['', '', '', '‌', 0], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '-', '_', 0], + Equal: ['=', '+', '=', '+', 0], + BracketLeft: ['[', '{', '[', '{', 0], + BracketRight: [']', '}', ']', '}', 0], + Backslash: ['\\', '|', '\\', '|', 0], + Semicolon: [';', ':', ';', ':', 0], + Quote: ['\'', '"', '\'', '"', 0], + Backquote: ['₩', '~', '`', '~', 0], + Comma: [',', '<', ',', '<', 0], + Period: ['.', '>', '.', '>', 0], + Slash: ['/', '?', '/', '?', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: ['.', '.', '.', '.', 0], + IntlBackslash: ['§', '±', '§', '±', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin.ts new file mode 100644 index 00000000000..8de0fa205a3 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin'; // 15% +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin'; + +export { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts new file mode 100644 index 00000000000..6561501fce4 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux'; + +export { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win.ts new file mode 100644 index 00000000000..bb85b252f90 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win.ts @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en.win'; // 40% +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/es.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/it.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/no.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win'; + +export { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts new file mode 100644 index 00000000000..2c415e8ebff --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000414', id: '', text: 'Norwegian' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', 'µ', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '"', '@', '', 0, 'VK_2'], + Digit3: ['3', '#', '£', '', 0, 'VK_3'], + Digit4: ['4', '¤', '$', '', 0, 'VK_4'], + Digit5: ['5', '%', '€', '', 0, 'VK_5'], + Digit6: ['6', '&', '', '', 0, 'VK_6'], + Digit7: ['7', '/', '{', '', 0, 'VK_7'], + Digit8: ['8', '(', '[', '', 0, 'VK_8'], + Digit9: ['9', ')', ']', '', 0, 'VK_9'], + Digit0: ['0', '=', '}', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['+', '?', '', '', 0, 'VK_OEM_PLUS'], + Equal: ['\\', '`', '´', '', 0, 'VK_OEM_4'], + BracketLeft: ['å', 'Å', '', '', 0, 'VK_OEM_6'], + BracketRight: ['¨', '^', '~', '', 0, 'VK_OEM_1'], + Backslash: ['\'', '*', '', '', 0, 'VK_OEM_2'], + Semicolon: ['ø', 'Ø', '', '', 0, 'VK_OEM_3'], + Quote: ['æ', 'Æ', '', '', 0, 'VK_OEM_7'], + Backquote: ['|', '§', '', '', 0, 'VK_OEM_5'], + Comma: [',', ';', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', ':', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts new file mode 100644 index 00000000000..57577ba513c --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.PolishPro', lang: 'pl', localizedName: 'Polish - Pro' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', 'ą', 'Ą', 0], + KeyB: ['b', 'B', 'ļ', 'ű', 0], + KeyC: ['c', 'C', 'ć', 'Ć', 0], + KeyD: ['d', 'D', '∂', 'Ž', 0], + KeyE: ['e', 'E', 'ę', 'Ę', 0], + KeyF: ['f', 'F', 'ń', 'ž', 0], + KeyG: ['g', 'G', '©', 'Ū', 0], + KeyH: ['h', 'H', 'ķ', 'Ó', 0], + KeyI: ['i', 'I', '^', 'ť', 4], + KeyJ: ['j', 'J', '∆', 'Ô', 0], + KeyK: ['k', 'K', 'Ż', 'ū', 0], + KeyL: ['l', 'L', 'ł', 'Ł', 0], + KeyM: ['m', 'M', 'Ķ', 'ų', 0], + KeyN: ['n', 'N', 'ń', 'Ń', 0], + KeyO: ['o', 'O', 'ó', 'Ó', 0], + KeyP: ['p', 'P', 'Ļ', 'ł', 0], + KeyQ: ['q', 'Q', 'Ō', 'ő', 0], + KeyR: ['r', 'R', '®', '£', 0], + KeyS: ['s', 'S', 'ś', 'Ś', 0], + KeyT: ['t', 'T', '†', 'ś', 0], + KeyU: ['u', 'U', '¨', 'Ť', 4], + KeyV: ['v', 'V', '√', '◊', 0], + KeyW: ['w', 'W', '∑', '„', 0], + KeyX: ['x', 'X', 'ź', 'Ź', 0], + KeyY: ['y', 'Y', 'ī', 'Á', 0], + KeyZ: ['z', 'Z', 'ż', 'Ż', 0], + Digit1: ['1', '!', 'Ń', 'ŕ', 0], + Digit2: ['2', '@', '™', 'Ř', 0], + Digit3: ['3', '#', '€', '‹', 0], + Digit4: ['4', '$', 'ß', '›', 0], + Digit5: ['5', '%', 'į', 'ř', 0], + Digit6: ['6', '^', '§', 'Ŗ', 0], + Digit7: ['7', '&', '¶', 'ŗ', 0], + Digit8: ['8', '*', '•', '°', 0], + Digit9: ['9', '(', 'Ľ', 'Š', 0], + Digit0: ['0', ')', 'ľ', '‚', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '–', '—', 0], + Equal: ['=', '+', '≠', 'Ī', 0], + BracketLeft: ['[', '{', '„', '”', 0], + BracketRight: [']', '}', '‚', '’', 0], + Backslash: ['\\', '|', '«', '»', 0], + Semicolon: [';', ':', '…', 'Ú', 0], + Quote: ['\'', '"', 'ĺ', 'ģ', 0], + Backquote: ['`', '~', '`', 'Ŕ', 4], + Comma: [',', '<', '≤', 'Ý', 0], + Period: ['.', '>', '≥', 'ý', 0], + Slash: ['/', '?', '÷', 'ņ', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: ['.', '.', '.', '.', 0], + IntlBackslash: ['§', '£', '¬', '¬', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts new file mode 100644 index 00000000000..a110111a83f --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000415', id: '', text: 'Polish (Programmers)' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', 'ą', 'Ą', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', 'ć', 'Ć', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', 'ę', 'Ę', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', 'ł', 'Ł', 0, 'VK_L'], + KeyM: ['m', 'M', '', '', 0, 'VK_M'], + KeyN: ['n', 'N', 'ń', 'Ń', 0, 'VK_N'], + KeyO: ['o', 'O', 'ó', 'Ó', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', 'ś', 'Ś', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '€', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', 'ź', 'Ź', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', 'ż', 'Ż', 0, 'VK_Z'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '@', '', '', 0, 'VK_2'], + Digit3: ['3', '#', '', '', 0, 'VK_3'], + Digit4: ['4', '$', '', '', 0, 'VK_4'], + Digit5: ['5', '%', '', '', 0, 'VK_5'], + Digit6: ['6', '^', '', '', 0, 'VK_6'], + Digit7: ['7', '&', '', '', 0, 'VK_7'], + Digit8: ['8', '*', '', '', 0, 'VK_8'], + Digit9: ['9', '(', '', '', 0, 'VK_9'], + Digit0: ['0', ')', '', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + Equal: ['=', '+', '', '', 0, 'VK_OEM_PLUS'], + BracketLeft: ['[', '{', '', '', 0, 'VK_OEM_4'], + BracketRight: [']', '}', '', '', 0, 'VK_OEM_6'], + Backslash: ['\\', '|', '', '', 0, 'VK_OEM_5'], + Semicolon: [';', ':', '', '', 0, 'VK_OEM_1'], + Quote: ['\'', '"', '', '', 0, 'VK_OEM_7'], + Backquote: ['`', '~', '', '', 0, 'VK_OEM_3'], + Comma: [',', '<', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', '>', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['/', '?', '', '', 0, 'VK_OEM_2'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['\\', '|', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts new file mode 100644 index 00000000000..9bb82448a7c --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts @@ -0,0 +1,170 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000416', id: '', text: 'Portuguese (Brazilian ABNT)' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '₢', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '°', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', '', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '/', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '?', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '¹', '', 0, 'VK_1'], + Digit2: ['2', '@', '²', '', 0, 'VK_2'], + Digit3: ['3', '#', '³', '', 0, 'VK_3'], + Digit4: ['4', '$', '£', '', 0, 'VK_4'], + Digit5: ['5', '%', '¢', '', 0, 'VK_5'], + Digit6: ['6', '¨', '¬', '', 0, 'VK_6'], + Digit7: ['7', '&', '', '', 0, 'VK_7'], + Digit8: ['8', '*', '', '', 0, 'VK_8'], + Digit9: ['9', '(', '', '', 0, 'VK_9'], + Digit0: ['0', ')', '', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + Equal: ['=', '+', '§', '', 0, 'VK_OEM_PLUS'], + BracketLeft: ['´', '`', '', '', 0, 'VK_OEM_4'], + BracketRight: ['[', '{', 'ª', '', 0, 'VK_OEM_6'], + Backslash: [']', '}', 'º', '', 0, 'VK_OEM_5'], + Semicolon: ['ç', 'Ç', '', '', 0, 'VK_OEM_1'], + Quote: ['~', '^', '', '', 0, 'VK_OEM_7'], + Backquote: ['\'', '"', '', '', 0, 'VK_OEM_3'], + Comma: [',', '<', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', '>', '', '', 0, 'VK_OEM_PERIOD'], + Slash: [';', ':', '', '', 0, 'VK_OEM_2'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['\\', '|', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: ['.', '.', '', '', 0, 'VK_ABNT_C2'], + IntlRo: ['/', '?', '°', '', 0, 'VK_ABNT_C1'], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts new file mode 100644 index 00000000000..87435fdc0ea --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.Brazilian-Pro', lang: 'pt' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', 'å', 'Å', 0], + KeyB: ['b', 'B', '∫', 'ı', 0], + KeyC: ['c', 'C', 'ç', 'Ç', 0], + KeyD: ['d', 'D', '∂', 'Î', 0], + KeyE: ['e', 'E', '´', '´', 4], + KeyF: ['f', 'F', 'ƒ', 'Ï', 0], + KeyG: ['g', 'G', '©', '˝', 0], + KeyH: ['h', 'H', '˙', 'Ó', 0], + KeyI: ['i', 'I', 'ˆ', 'ˆ', 4], + KeyJ: ['j', 'J', '∆', 'Ô', 0], + KeyK: ['k', 'K', '˚', '', 0], + KeyL: ['l', 'L', '¬', 'Ò', 0], + KeyM: ['m', 'M', 'µ', 'Â', 0], + KeyN: ['n', 'N', '˜', '˜', 4], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'π', '∏', 0], + KeyQ: ['q', 'Q', 'œ', 'Œ', 0], + KeyR: ['r', 'R', '®', '‰', 0], + KeyS: ['s', 'S', 'ß', 'Í', 0], + KeyT: ['t', 'T', '†', 'ˇ', 0], + KeyU: ['u', 'U', '¨', '¨', 4], + KeyV: ['v', 'V', '√', '◊', 0], + KeyW: ['w', 'W', '∑', '„', 0], + KeyX: ['x', 'X', '≈', '˛', 0], + KeyY: ['y', 'Y', '¥', 'Á', 0], + KeyZ: ['z', 'Z', 'Ω', '¸', 0], + Digit1: ['1', '!', '¡', '⁄', 0], + Digit2: ['2', '@', '™', '€', 0], + Digit3: ['3', '#', '£', '‹', 0], + Digit4: ['4', '$', '¢', '›', 0], + Digit5: ['5', '%', '∞', 'fi', 0], + Digit6: ['6', 'ˆ', '§', 'fl', 2], + Digit7: ['7', '&', '¶', '‡', 0], + Digit8: ['8', '*', '•', '°', 0], + Digit9: ['9', '(', 'ª', '·', 0], + Digit0: ['0', ')', 'º', '‚', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '–', '—', 0], + Equal: ['=', '+', '≠', '±', 0], + BracketLeft: ['[', '{', '“', '”', 0], + BracketRight: [']', '}', '‘', '’', 0], + Backslash: ['\\', '|', '«', '»', 0], + Semicolon: [';', ':', '…', 'Ú', 0], + Quote: ['\'', '"', 'æ', 'Æ', 3], + Backquote: ['`', '˜', '`', '`', 7], + Comma: [',', '<', '≤', '¯', 0], + Period: ['.', '>', '≥', '˘', 0], + Slash: ['/', '?', '÷', '¿', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: ['.', '.', '.', '.', 0], + IntlBackslash: ['§', '±', '§', '±', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts new file mode 100644 index 00000000000..456a537654b --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts @@ -0,0 +1,170 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000816', id: '', text: 'Portuguese' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', '', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '"', '@', '', 0, 'VK_2'], + Digit3: ['3', '#', '£', '', 0, 'VK_3'], + Digit4: ['4', '$', '§', '', 0, 'VK_4'], + Digit5: ['5', '%', '€', '', 0, 'VK_5'], + Digit6: ['6', '&', '', '', 0, 'VK_6'], + Digit7: ['7', '/', '{', '', 0, 'VK_7'], + Digit8: ['8', '(', '[', '', 0, 'VK_8'], + Digit9: ['9', ')', ']', '', 0, 'VK_9'], + Digit0: ['0', '=', '}', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['\'', '?', '', '', 0, 'VK_OEM_4'], + Equal: ['«', '»', '', '', 0, 'VK_OEM_6'], + BracketLeft: ['+', '*', '¨', '', 0, 'VK_OEM_PLUS'], + BracketRight: ['´', '`', ']', '', 0, 'VK_OEM_1'], + Backslash: ['~', '^', '', '', 0, 'VK_OEM_2'], + Semicolon: ['ç', 'Ç', '', '', 0, 'VK_OEM_3'], + Quote: ['º', 'ª', '', '', 0, 'VK_OEM_7'], + Backquote: ['\\', '|', '', '', 0, 'VK_OEM_5'], + Comma: [',', ';', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', ':', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } + +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts new file mode 100644 index 00000000000..5eea5ac38f5 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.Russian', lang: 'ru', localizedName: 'Russian' }, + secondaryLayouts: [], + mapping: { + KeyA: ['ф', 'Ф', 'ƒ', 'ƒ', 0], + KeyB: ['и', 'И', 'и', 'И', 0], + KeyC: ['с', 'С', '≠', '≠', 0], + KeyD: ['в', 'В', 'ћ', 'Ћ', 0], + KeyE: ['у', 'У', 'ќ', 'Ќ', 0], + KeyF: ['а', 'А', '÷', '÷', 0], + KeyG: ['п', 'П', '©', '©', 0], + KeyH: ['р', 'Р', '₽', '₽', 0], + KeyI: ['ш', 'Ш', 'ѕ', 'Ѕ', 0], + KeyJ: ['о', 'О', '°', '•', 0], + KeyK: ['л', 'Л', 'љ', 'Љ', 0], + KeyL: ['д', 'Д', '∆', '∆', 0], + KeyM: ['ь', 'Ь', '~', '~', 0], + KeyN: ['т', 'Т', '™', '™', 0], + KeyO: ['щ', 'Щ', 'ў', 'Ў', 0], + KeyP: ['з', 'З', '‘', '’', 0], + KeyQ: ['й', 'Й', 'ј', 'Ј', 0], + KeyR: ['к', 'К', '®', '®', 0], + KeyS: ['ы', 'Ы', 'ы', 'Ы', 0], + KeyT: ['е', 'Е', '†', '†', 0], + KeyU: ['г', 'Г', 'ѓ', 'Ѓ', 0], + KeyV: ['м', 'М', 'µ', 'µ', 0], + KeyW: ['ц', 'Ц', 'џ', 'Џ', 0], + KeyX: ['ч', 'Ч', '≈', '≈', 0], + KeyY: ['н', 'Н', 'њ', 'Њ', 0], + KeyZ: ['я', 'Я', 'ђ', 'Ђ', 0], + Digit1: ['1', '!', '!', '|', 0], + Digit2: ['2', '"', '@', '"', 0], + Digit3: ['3', '№', '#', '£', 0], + Digit4: ['4', '%', '$', '€', 0], + Digit5: ['5', ':', '%', '∞', 0], + Digit6: ['6', ',', '^', '¬', 0], + Digit7: ['7', '.', '&', '¶', 0], + Digit8: ['8', ';', '*', '√', 0], + Digit9: ['9', '(', '{', '\'', 0], + Digit0: ['0', ')', '}', '`', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '–', '—', 0], + Equal: ['=', '+', '»', '«', 0], + BracketLeft: ['х', 'Х', '“', '”', 0], + BracketRight: ['ъ', 'Ъ', 'ъ', 'Ъ', 0], + Backslash: ['ё', 'Ё', 'ё', 'Ё', 0], + Semicolon: ['ж', 'Ж', '…', '…', 0], + Quote: ['э', 'Э', 'э', 'Э', 0], + Backquote: [']', '[', ']', '[', 0], + Comma: ['б', 'Б', '≤', '<', 0], + Period: ['ю', 'Ю', '≥', '>', 0], + Slash: ['/', '?', '“', '„', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: [',', '.', ',', ',', 0], + IntlBackslash: ['>', '<', '§', '±', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts new file mode 100644 index 00000000000..b13adb0d9ac --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts @@ -0,0 +1,187 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { model: 'pc104', layout: 'ru', variant: ',', options: '', rules: 'base' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['ф', 'Ф', 'ф', 'Ф', 0], + KeyB: ['и', 'И', 'и', 'И', 0], + KeyC: ['с', 'С', 'с', 'С', 0], + KeyD: ['в', 'В', 'в', 'В', 0], + KeyE: ['у', 'У', 'у', 'У', 0], + KeyF: ['а', 'А', 'а', 'А', 0], + KeyG: ['п', 'П', 'п', 'П', 0], + KeyH: ['р', 'Р', 'р', 'Р', 0], + KeyI: ['ш', 'Ш', 'ш', 'Ш', 0], + KeyJ: ['о', 'О', 'о', 'О', 0], + KeyK: ['л', 'Л', 'л', 'Л', 0], + KeyL: ['д', 'Д', 'д', 'Д', 0], + KeyM: ['ь', 'Ь', 'ь', 'Ь', 0], + KeyN: ['т', 'Т', 'т', 'Т', 0], + KeyO: ['щ', 'Щ', 'щ', 'Щ', 0], + KeyP: ['з', 'З', 'з', 'З', 0], + KeyQ: ['й', 'Й', 'й', 'Й', 0], + KeyR: ['к', 'К', 'к', 'К', 0], + KeyS: ['ы', 'Ы', 'ы', 'Ы', 0], + KeyT: ['е', 'Е', 'е', 'Е', 0], + KeyU: ['г', 'Г', 'г', 'Г', 0], + KeyV: ['м', 'М', 'м', 'М', 0], + KeyW: ['ц', 'Ц', 'ц', 'Ц', 0], + KeyX: ['ч', 'Ч', 'ч', 'Ч', 0], + KeyY: ['н', 'Н', 'н', 'Н', 0], + KeyZ: ['я', 'Я', 'я', 'Я', 0], + Digit1: ['1', '!', '1', '!', 0], + Digit2: ['2', '"', '2', '"', 0], + Digit3: ['3', '№', '3', '№', 0], + Digit4: ['4', ';', '4', ';', 0], + Digit5: ['5', '%', '5', '%', 0], + Digit6: ['6', ':', '6', ':', 0], + Digit7: ['7', '?', '7', '?', 0], + Digit8: ['8', '*', '₽', '', 0], + Digit9: ['9', '(', '9', '(', 0], + Digit0: ['0', ')', '0', ')', 0], + Enter: ['\r', '\r', '\r', '\r', 0], + Escape: ['\u001b', '\u001b', '\u001b', '\u001b', 0], + Backspace: ['\b', '\b', '\b', '\b', 0], + Tab: ['\t', '', '\t', '', 0], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '_', '-', '_', 0], + Equal: ['=', '+', '=', '+', 0], + BracketLeft: ['х', 'Х', 'х', 'Х', 0], + BracketRight: ['ъ', 'Ъ', 'ъ', 'Ъ', 0], + Backslash: ['\\', '/', '\\', '/', 0], + Semicolon: ['ж', 'Ж', 'ж', 'Ж', 0], + Quote: ['э', 'Э', 'э', 'Э', 0], + Backquote: ['ё', 'Ё', 'ё', 'Ё', 0], + Comma: ['б', 'Б', 'б', 'Б', 0], + Period: ['ю', 'Ю', 'ю', 'Ю', 0], + Slash: ['.', ',', '.', ',', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: ['', '', '', '', 0], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: ['/', '/', '/', '/', 0], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: [], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['', '1', '', '1', 0], + Numpad2: ['', '2', '', '2', 0], + Numpad3: ['', '3', '', '3', 0], + Numpad4: ['', '4', '', '4', 0], + Numpad5: ['', '5', '', '5', 0], + Numpad6: ['', '6', '', '6', 0], + Numpad7: ['', '7', '', '7', 0], + Numpad8: ['', '8', '', '8', 0], + Numpad9: ['', '9', '', '9', 0], + Numpad0: ['', '0', '', '0', 0], + NumpadDecimal: ['', ',', '', ',', 0], + IntlBackslash: ['/', '|', '|', '¦', 0], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Open: [], + Help: [], + Select: [], + Again: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + Find: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + Lang5: [], + NumpadParenLeft: [], + NumpadParenRight: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: ['\r', '\r', '\r', '\r', 0], + MetaRight: ['.', '.', '.', '.', 0], + BrightnessUp: [], + BrightnessDown: [], + MediaPlay: [], + MediaRecord: [], + MediaFastForward: [], + MediaRewind: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + SelectTask: [], + LaunchScreenSaver: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [], + MailReply: [], + MailForward: [], + MailSend: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts new file mode 100644 index 00000000000..0da492a10ac --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000419', id: '', text: 'Russian' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['ф', 'Ф', '', '', 0, 'VK_A'], + KeyB: ['и', 'И', '', '', 0, 'VK_B'], + KeyC: ['с', 'С', '', '', 0, 'VK_C'], + KeyD: ['в', 'В', '', '', 0, 'VK_D'], + KeyE: ['у', 'У', '', '', 0, 'VK_E'], + KeyF: ['а', 'А', '', '', 0, 'VK_F'], + KeyG: ['п', 'П', '', '', 0, 'VK_G'], + KeyH: ['р', 'Р', '', '', 0, 'VK_H'], + KeyI: ['ш', 'Ш', '', '', 0, 'VK_I'], + KeyJ: ['о', 'О', '', '', 0, 'VK_J'], + KeyK: ['л', 'Л', '', '', 0, 'VK_K'], + KeyL: ['д', 'Д', '', '', 0, 'VK_L'], + KeyM: ['ь', 'Ь', '', '', 0, 'VK_M'], + KeyN: ['т', 'Т', '', '', 0, 'VK_N'], + KeyO: ['щ', 'Щ', '', '', 0, 'VK_O'], + KeyP: ['з', 'З', '', '', 0, 'VK_P'], + KeyQ: ['й', 'Й', '', '', 0, 'VK_Q'], + KeyR: ['к', 'К', '', '', 0, 'VK_R'], + KeyS: ['ы', 'Ы', '', '', 0, 'VK_S'], + KeyT: ['е', 'Е', '', '', 0, 'VK_T'], + KeyU: ['г', 'Г', '', '', 0, 'VK_U'], + KeyV: ['м', 'М', '', '', 0, 'VK_V'], + KeyW: ['ц', 'Ц', '', '', 0, 'VK_W'], + KeyX: ['ч', 'Ч', '', '', 0, 'VK_X'], + KeyY: ['н', 'Н', '', '', 0, 'VK_Y'], + KeyZ: ['я', 'Я', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '"', '', '', 0, 'VK_2'], + Digit3: ['3', '№', '', '', 0, 'VK_3'], + Digit4: ['4', ';', '', '', 0, 'VK_4'], + Digit5: ['5', '%', '', '', 0, 'VK_5'], + Digit6: ['6', ':', '', '', 0, 'VK_6'], + Digit7: ['7', '?', '', '', 0, 'VK_7'], + Digit8: ['8', '*', '₽', '', 0, 'VK_8'], + Digit9: ['9', '(', '', '', 0, 'VK_9'], + Digit0: ['0', ')', '', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + Equal: ['=', '+', '', '', 0, 'VK_OEM_PLUS'], + BracketLeft: ['х', 'Х', '', '', 0, 'VK_OEM_4'], + BracketRight: ['ъ', 'Ъ', '', '', 0, 'VK_OEM_6'], + Backslash: ['\\', '/', '', '', 0, 'VK_OEM_5'], + Semicolon: ['ж', 'Ж', '', '', 0, 'VK_OEM_1'], + Quote: ['э', 'Э', '', '', 0, 'VK_OEM_7'], + Backquote: ['ё', 'Ё', '', '', 0, 'VK_OEM_3'], + Comma: ['б', 'Б', '', '', 0, 'VK_OEM_COMMA'], + Period: ['ю', 'Ю', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['.', ',', '', '', 0, 'VK_OEM_2'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['\\', '/', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts new file mode 100644 index 00000000000..6d80477a689 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.Swedish-Pro', lang: 'sv', localizedName: 'Swedish - Pro' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', '', '◊', 0], + KeyB: ['b', 'B', '›', '»', 0], + KeyC: ['c', 'C', 'ç', 'Ç', 0], + KeyD: ['d', 'D', '∂', '∆', 0], + KeyE: ['e', 'E', 'é', 'É', 0], + KeyF: ['f', 'F', 'ƒ', '∫', 0], + KeyG: ['g', 'G', '¸', '¯', 0], + KeyH: ['h', 'H', '˛', '˘', 0], + KeyI: ['i', 'I', 'ı', 'ˆ', 0], + KeyJ: ['j', 'J', '√', '¬', 0], + KeyK: ['k', 'K', 'ª', 'º', 0], + KeyL: ['l', 'L', 'fi', 'fl', 0], + KeyM: ['m', 'M', '’', '”', 0], + KeyN: ['n', 'N', '‘', '“', 0], + KeyO: ['o', 'O', 'œ', 'Œ', 0], + KeyP: ['p', 'P', 'π', '∏', 0], + KeyQ: ['q', 'Q', '•', '°', 0], + KeyR: ['r', 'R', '®', '√', 0], + KeyS: ['s', 'S', 'ß', '∑', 0], + KeyT: ['t', 'T', '†', '‡', 0], + KeyU: ['u', 'U', 'ü', 'Ü', 0], + KeyV: ['v', 'V', '‹', '«', 0], + KeyW: ['w', 'W', 'Ω', '˝', 0], + KeyX: ['x', 'X', '≈', 'ˇ', 0], + KeyY: ['y', 'Y', 'µ', '˜', 0], + KeyZ: ['z', 'Z', '÷', '⁄', 0], + Digit1: ['1', '!', '©', '¡', 0], + Digit2: ['2', '"', '@', '”', 0], + Digit3: ['3', '#', '£', '¥', 0], + Digit4: ['4', '€', '$', '¢', 0], + Digit5: ['5', '%', '∞', '‰', 0], + Digit6: ['6', '&', '§', '¶', 0], + Digit7: ['7', '/', '|', '\\', 0], + Digit8: ['8', '(', '[', '{', 0], + Digit9: ['9', ')', ']', '}', 0], + Digit0: ['0', '=', '≈', '≠', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['+', '?', '±', '¿', 0], + Equal: ['´', '`', '´', '`', 3], + BracketLeft: ['å', 'Å', '˙', '˚', 0], + BracketRight: ['¨', '^', '~', '^', 7], + Backslash: ['\'', '*', '™', '’', 0], + Semicolon: ['ö', 'Ö', 'ø', 'Ø', 0], + Quote: ['ä', 'Ä', 'æ', 'Æ', 0], + Backquote: ['<', '>', '≤', '≥', 0], + Comma: [',', ';', '‚', '„', 0], + Period: ['.', ':', '…', '·', 0], + Slash: ['-', '_', '–', '—', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: [',', '.', ',', '.', 0], + IntlBackslash: ['§', '°', '¶', '•', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts new file mode 100644 index 00000000000..c7128b5c929 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts @@ -0,0 +1,171 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000041D', id: '', text: 'Swedish' }, + secondaryLayouts: [ + { name: '0000040B', id: '', text: 'Finnish' } + ], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', '', '', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['i', 'I', '', '', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', 'µ', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', '', '', 0, 'VK_S'], + KeyT: ['t', 'T', '', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '', '', 0, 'VK_1'], + Digit2: ['2', '"', '@', '', 0, 'VK_2'], + Digit3: ['3', '#', '£', '', 0, 'VK_3'], + Digit4: ['4', '¤', '$', '', 0, 'VK_4'], + Digit5: ['5', '%', '€', '', 0, 'VK_5'], + Digit6: ['6', '&', '', '', 0, 'VK_6'], + Digit7: ['7', '/', '{', '', 0, 'VK_7'], + Digit8: ['8', '(', '[', '', 0, 'VK_8'], + Digit9: ['9', ')', ']', '', 0, 'VK_9'], + Digit0: ['0', '=', '}', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['+', '?', '\\', '', 0, 'VK_OEM_PLUS'], + Equal: ['´', '`', '', '', 0, 'VK_OEM_4'], + BracketLeft: ['å', 'Å', '', '', 0, 'VK_OEM_6'], + BracketRight: ['¨', '^', '~', '', 0, 'VK_OEM_1'], + Backslash: ['\'', '*', '', '', 0, 'VK_OEM_2'], + Semicolon: ['ö', 'Ö', '', '', 0, 'VK_OEM_3'], + Quote: ['ä', 'Ä', '', '', 0, 'VK_OEM_7'], + Backquote: ['§', '½', '', '', 0, 'VK_OEM_5'], + Comma: [',', ';', '', '', 0, 'VK_OEM_COMMA'], + Period: ['.', ':', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['-', '_', '', '', 0, 'VK_OEM_MINUS'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '|', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts new file mode 100644 index 00000000000..be85bfedd9e --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts @@ -0,0 +1,168 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000041E', id: '', text: 'Thai Kedmanee' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['ฟ', 'ฤ', '', '', 0, 'VK_A'], + KeyB: ['ิ', 'ฺ', '', '', 0, 'VK_B'], + KeyC: ['แ', 'ฉ', '', '', 0, 'VK_C'], + KeyD: ['ก', 'ฏ', '', '', 0, 'VK_D'], + KeyE: ['ำ', 'ฎ', '', '', 0, 'VK_E'], + KeyF: ['ด', 'โ', '', '', 0, 'VK_F'], + KeyG: ['เ', 'ฌ', '', '', 0, 'VK_G'], + KeyH: ['้', '็', '', '', 0, 'VK_H'], + KeyI: ['ร', 'ณ', '', '', 0, 'VK_I'], + KeyJ: ['่', '๋', '', '', 0, 'VK_J'], + KeyK: ['า', 'ษ', '', '', 0, 'VK_K'], + KeyL: ['ส', 'ศ', '', '', 0, 'VK_L'], + KeyM: ['ท', '?', '', '', 0, 'VK_M'], + KeyN: ['ื', '์', '', '', 0, 'VK_N'], + KeyO: ['น', 'ฯ', '', '', 0, 'VK_O'], + KeyP: ['ย', 'ญ', '', '', 0, 'VK_P'], + KeyQ: ['ๆ', '๐', '', '', 0, 'VK_Q'], + KeyR: ['พ', 'ฑ', '', '', 0, 'VK_R'], + KeyS: ['ห', 'ฆ', '', '', 0, 'VK_S'], + KeyT: ['ะ', 'ธ', '', '', 0, 'VK_T'], + KeyU: ['ี', '๊', '', '', 0, 'VK_U'], + KeyV: ['อ', 'ฮ', '', '', 0, 'VK_V'], + KeyW: ['ไ', '"', '', '', 0, 'VK_W'], + KeyX: ['ป', ')', '', '', 0, 'VK_X'], + KeyY: ['ั', 'ํ', '', '', 0, 'VK_Y'], + KeyZ: ['ผ', '(', '', '', 0, 'VK_Z'], + Digit1: ['ๅ', '+', '', '', 0, 'VK_1'], + Digit2: ['/', '๑', '', '', 0, 'VK_2'], + Digit3: ['-', '๒', '', '', 0, 'VK_3'], + Digit4: ['ภ', '๓', '', '', 0, 'VK_4'], + Digit5: ['ถ', '๔', '', '', 0, 'VK_5'], + Digit6: ['ุ', 'ู', '', '', 0, 'VK_6'], + Digit7: ['ึ', '฿', '', '', 0, 'VK_7'], + Digit8: ['ค', '๕', '', '', 0, 'VK_8'], + Digit9: ['ต', '๖', '', '', 0, 'VK_9'], + Digit0: ['จ', '๗', '', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['ข', '๘', '', '', 0, 'VK_OEM_MINUS'], + Equal: ['ช', '๙', '', '', 0, 'VK_OEM_PLUS'], + BracketLeft: ['บ', 'ฐ', '', '', 0, 'VK_OEM_4'], + BracketRight: ['ล', ',', '', '', 0, 'VK_OEM_6'], + Backslash: ['ฃ', 'ฅ', '', '', 0, 'VK_OEM_5'], + Semicolon: ['ว', 'ซ', '', '', 0, 'VK_OEM_1'], + Quote: ['ง', '.', '', '', 0, 'VK_OEM_7'], + Backquote: ['_', '%', '', '', 0, 'VK_OEM_3'], + Comma: ['ม', 'ฒ', '', '', 0, 'VK_OEM_COMMA'], + Period: ['ใ', 'ฬ', '', '', 0, 'VK_OEM_PERIOD'], + Slash: ['ฝ', 'ฦ', '', '', 0, 'VK_OEM_2'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['ฃ', 'ฅ', '', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts new file mode 100644 index 00000000000..955b03f5fc0 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts @@ -0,0 +1,168 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000041F', id: '', text: 'Turkish Q' }, + secondaryLayouts: [], + mapping: { + Sleep: [], + WakeUp: [], + KeyA: ['a', 'A', 'æ', 'Æ', 0, 'VK_A'], + KeyB: ['b', 'B', '', '', 0, 'VK_B'], + KeyC: ['c', 'C', '', '', 0, 'VK_C'], + KeyD: ['d', 'D', '', '', 0, 'VK_D'], + KeyE: ['e', 'E', '€', '', 0, 'VK_E'], + KeyF: ['f', 'F', '', '', 0, 'VK_F'], + KeyG: ['g', 'G', '', '', 0, 'VK_G'], + KeyH: ['h', 'H', '', '', 0, 'VK_H'], + KeyI: ['ı', 'I', 'i', 'İ', 0, 'VK_I'], + KeyJ: ['j', 'J', '', '', 0, 'VK_J'], + KeyK: ['k', 'K', '', '', 0, 'VK_K'], + KeyL: ['l', 'L', '', '', 0, 'VK_L'], + KeyM: ['m', 'M', '', '', 0, 'VK_M'], + KeyN: ['n', 'N', '', '', 0, 'VK_N'], + KeyO: ['o', 'O', '', '', 0, 'VK_O'], + KeyP: ['p', 'P', '', '', 0, 'VK_P'], + KeyQ: ['q', 'Q', '@', '', 0, 'VK_Q'], + KeyR: ['r', 'R', '', '', 0, 'VK_R'], + KeyS: ['s', 'S', 'ß', '', 0, 'VK_S'], + KeyT: ['t', 'T', '₺', '', 0, 'VK_T'], + KeyU: ['u', 'U', '', '', 0, 'VK_U'], + KeyV: ['v', 'V', '', '', 0, 'VK_V'], + KeyW: ['w', 'W', '', '', 0, 'VK_W'], + KeyX: ['x', 'X', '', '', 0, 'VK_X'], + KeyY: ['y', 'Y', '', '', 0, 'VK_Y'], + KeyZ: ['z', 'Z', '', '', 0, 'VK_Z'], + Digit1: ['1', '!', '>', '', 0, 'VK_1'], + Digit2: ['2', '\'', '£', '', 0, 'VK_2'], + Digit3: ['3', '^', '#', '', 0, 'VK_3'], + Digit4: ['4', '+', '$', '', 0, 'VK_4'], + Digit5: ['5', '%', '½', '', 0, 'VK_5'], + Digit6: ['6', '&', '', '', 0, 'VK_6'], + Digit7: ['7', '/', '{', '', 0, 'VK_7'], + Digit8: ['8', '(', '[', '', 0, 'VK_8'], + Digit9: ['9', ')', ']', '', 0, 'VK_9'], + Digit0: ['0', '=', '}', '', 0, 'VK_0'], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', '', '', 0, 'VK_SPACE'], + Minus: ['*', '?', '\\', '', 0, 'VK_OEM_8'], + Equal: ['-', '_', '|', '', 0, 'VK_OEM_MINUS'], + BracketLeft: ['ğ', 'Ğ', '¨', '', 0, 'VK_OEM_4'], + BracketRight: ['ü', 'Ü', '~', '', 0, 'VK_OEM_6'], + Backslash: [',', ';', '`', '', 0, 'VK_OEM_COMMA'], + Semicolon: ['ş', 'Ş', '´', '', 0, 'VK_OEM_1'], + Quote: ['i', 'İ', '', '', 0, 'VK_OEM_7'], + Backquote: ['"', 'é', '<', '', 0, 'VK_OEM_3'], + Comma: ['ö', 'Ö', '', '', 0, 'VK_OEM_2'], + Period: ['ç', 'Ç', '', '', 0, 'VK_OEM_5'], + Slash: ['.', ':', '', '', 0, 'VK_OEM_PERIOD'], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + PrintScreen: [], + ScrollLock: [], + Pause: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '', '', 0, 'VK_DIVIDE'], + NumpadMultiply: ['*', '*', '', '', 0, 'VK_MULTIPLY'], + NumpadSubtract: ['-', '-', '', '', 0, 'VK_SUBTRACT'], + NumpadAdd: ['+', '+', '', '', 0, 'VK_ADD'], + NumpadEnter: [], + Numpad1: [], + Numpad2: [], + Numpad3: [], + Numpad4: [], + Numpad5: [], + Numpad6: [], + Numpad7: [], + Numpad8: [], + Numpad9: [], + Numpad0: [], + NumpadDecimal: [], + IntlBackslash: ['<', '>', '|', '', 0, 'VK_OEM_102'], + ContextMenu: [], + Power: [], + NumpadEqual: [], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + F21: [], + F22: [], + F23: [], + F24: [], + Help: [], + Undo: [], + Cut: [], + Copy: [], + Paste: [], + AudioVolumeMute: [], + AudioVolumeUp: [], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + Convert: [], + NonConvert: [], + Lang1: [], + Lang2: [], + Lang3: [], + Lang4: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [], + MediaTrackNext: [], + MediaTrackPrevious: [], + MediaStop: [], + Eject: [], + MediaPlayPause: [], + MediaSelect: [], + LaunchMail: [], + LaunchApp2: [], + LaunchApp1: [], + BrowserSearch: [], + BrowserHome: [], + BrowserBack: [], + BrowserForward: [], + BrowserStop: [], + BrowserRefresh: [], + BrowserFavorites: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts new file mode 100644 index 00000000000..49d1f60ae0d --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts @@ -0,0 +1,131 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.inputmethod.SCIM.ITABC', lang: 'zh-Hans', localizedName: '搜狗拼音' }, + secondaryLayouts: [], + mapping: { + KeyA: ['a', 'A', 'å', 'Å', 0], + KeyB: ['b', 'B', '∫', 'ı', 0], + KeyC: ['c', 'C', 'ç', 'Ç', 0], + KeyD: ['d', 'D', '∂', 'Î', 0], + KeyE: ['e', 'E', '´', '´', 4], + KeyF: ['f', 'F', 'ƒ', 'Ï', 0], + KeyG: ['g', 'G', '©', '˝', 0], + KeyH: ['h', 'H', '˙', 'Ó', 0], + KeyI: ['i', 'I', 'ˆ', 'ˆ', 4], + KeyJ: ['j', 'J', '∆', 'Ô', 0], + KeyK: ['k', 'K', '˚', '', 0], + KeyL: ['l', 'L', '¬', 'Ò', 0], + KeyM: ['m', 'M', 'µ', 'Â', 0], + KeyN: ['n', 'N', '˜', '˜', 4], + KeyO: ['o', 'O', 'ø', 'Ø', 0], + KeyP: ['p', 'P', 'π', '∏', 0], + KeyQ: ['q', 'Q', 'œ', 'Œ', 0], + KeyR: ['r', 'R', '®', '‰', 0], + KeyS: ['s', 'S', 'ß', 'Í', 0], + KeyT: ['t', 'T', '†', 'ˇ', 0], + KeyU: ['u', 'U', '¨', '¨', 4], + KeyV: ['v', 'V', '√', '◊', 0], + KeyW: ['w', 'W', '∑', '„', 0], + KeyX: ['x', 'X', '≈', '˛', 0], + KeyY: ['y', 'Y', '¥', 'Á', 0], + KeyZ: ['z', 'Z', 'Ω', '¸', 0], + Digit1: ['1', '!', '¡', '⁄', 0], + Digit2: ['2', '@', '™', '€', 0], + Digit3: ['3', '#', '£', '‹', 0], + Digit4: ['4', '¥', '¢', '›', 0], + Digit5: ['5', '%', '∞', 'fi', 0], + Digit6: ['6', '', '§', 'fl', 0], + Digit7: ['7', '&', '¶', '‡', 0], + Digit8: ['8', '*', '•', '°', 0], + Digit9: ['9', '(', 'ª', '·', 0], + Digit0: ['0', ')', 'º', '‚', 0], + Enter: [], + Escape: [], + Backspace: [], + Tab: [], + Space: [' ', ' ', ' ', ' ', 0], + Minus: ['-', '', '–', '—', 0], + Equal: ['=', '+', '≠', '±', 0], + BracketLeft: ['【', '「', '“', '”', 0], + BracketRight: ['】', '」', '‘', '’', 0], + Backslash: ['、', '|', '«', '»', 0], + Semicolon: [';', ':', '…', 'Ú', 0], + Quote: ['\'', '"', 'æ', 'Æ', 0], + Backquote: ['·', '~', '`', '`', 4], + Comma: [',', '《', '≤', '¯', 0], + Period: ['。', '》', '≥', '˘', 0], + Slash: ['/', '?', '÷', '¿', 0], + CapsLock: [], + F1: [], + F2: [], + F3: [], + F4: [], + F5: [], + F6: [], + F7: [], + F8: [], + F9: [], + F10: [], + F11: [], + F12: [], + Insert: [], + Home: [], + PageUp: [], + Delete: [], + End: [], + PageDown: [], + ArrowRight: [], + ArrowLeft: [], + ArrowDown: [], + ArrowUp: [], + NumLock: [], + NumpadDivide: ['/', '/', '/', '/', 0], + NumpadMultiply: ['*', '*', '*', '*', 0], + NumpadSubtract: ['-', '-', '-', '-', 0], + NumpadAdd: ['+', '+', '+', '+', 0], + NumpadEnter: [], + Numpad1: ['1', '1', '1', '1', 0], + Numpad2: ['2', '2', '2', '2', 0], + Numpad3: ['3', '3', '3', '3', 0], + Numpad4: ['4', '4', '4', '4', 0], + Numpad5: ['5', '5', '5', '5', 0], + Numpad6: ['6', '6', '6', '6', 0], + Numpad7: ['7', '7', '7', '7', 0], + Numpad8: ['8', '8', '8', '8', 0], + Numpad9: ['9', '9', '9', '9', 0], + Numpad0: ['0', '0', '0', '0', 0], + NumpadDecimal: ['.', '.', '.', '.', 0], + IntlBackslash: ['§', '±', '§', '±', 0], + ContextMenu: [], + NumpadEqual: ['=', '=', '=', '=', 0], + F13: [], + F14: [], + F15: [], + F16: [], + F17: [], + F18: [], + F19: [], + F20: [], + AudioVolumeMute: [], + AudioVolumeUp: ['', '=', '', '=', 0], + AudioVolumeDown: [], + NumpadComma: [], + IntlRo: [], + KanaMode: [], + IntlYen: [], + ControlLeft: [], + ShiftLeft: [], + AltLeft: [], + MetaLeft: [], + ControlRight: [], + ShiftRight: [], + AltRight: [], + MetaRight: [] + } +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts new file mode 100644 index 00000000000..401dede8db9 --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -0,0 +1,622 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vs/nls'; +import { Emitter, Event } from 'vs/base/common/event'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping, IWindowsKeyboardMapping, KeymapInfo, IRawMixedKeyboardMapping, getKeyboardLayoutId, IKeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { DispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; +import { IKeyboardMapper, CachedKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; +import { OS, OperatingSystem, isMacintosh, isWindows } from 'vs/base/common/platform'; +import { WindowsKeyboardMapper } from 'vs/workbench/services/keybinding/common/windowsKeyboardMapper'; +import { MacLinuxFallbackKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxFallbackKeyboardMapper'; +import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; +import { IMacLinuxKeyboardMapping, MacLinuxKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxKeyboardMapper'; +import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { URI } from 'vs/base/common/uri'; +import { IFileService } from 'vs/platform/files/common/files'; +import { RunOnceScheduler } from 'vs/base/common/async'; +import { parse } from 'vs/base/common/json'; +import * as objects from 'vs/base/common/objects'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions as ConfigExtensions, IConfigurationRegistry, IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; +import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage'; + +export class BrowserKeyboardMapperFactoryBase { + // keyboard mapper + protected _initialized: boolean; + protected _keyboardMapper: IKeyboardMapper | null; + private readonly _onDidChangeKeyboardMapper = new Emitter(); + public readonly onDidChangeKeyboardMapper: Event = this._onDidChangeKeyboardMapper.event; + + // keymap infos + protected _keymapInfos: KeymapInfo[]; + protected _mru: KeymapInfo[]; + private _activeKeymapInfo: KeymapInfo | null; + + get activeKeymap(): KeymapInfo | null { + return this._activeKeymapInfo; + } + + get keymapInfos(): KeymapInfo[] { + return this._keymapInfos; + } + + get activeKeyboardLayout(): IKeyboardLayoutInfo | null { + if (!this._initialized) { + return null; + } + + return this._activeKeymapInfo && this._activeKeymapInfo.layout; + } + + get activeKeyMapping(): IKeyboardMapping | null { + if (!this._initialized) { + return null; + } + + return this._activeKeymapInfo && this._activeKeymapInfo.mapping; + } + + get keyboardLayouts(): IKeyboardLayoutInfo[] { + return this._keymapInfos.map(keymapInfo => keymapInfo.layout); + } + + protected constructor( + private _notificationService: INotificationService, + private _storageService: IStorageService, + private _commandService: ICommandService + ) { + this._keyboardMapper = null; + this._initialized = false; + this._keymapInfos = []; + this._mru = []; + this._activeKeymapInfo = null; + + if ((navigator).keyboard && (navigator).keyboard.addEventListener) { + (navigator).keyboard.addEventListener!('layoutchange', () => { + // Update user keyboard map settings + this._getBrowserKeyMapping().then((mapping: IKeyboardMapping | null) => { + if (this.isKeyMappingActive(mapping)) { + return; + } + + this.onKeyboardLayoutChanged(); + }); + }); + } + } + + registerKeyboardLayout(layout: KeymapInfo) { + this._keymapInfos.push(layout); + this._mru = this._keymapInfos; + } + + removeKeyboardLayout(layout: KeymapInfo): void { + let index = this._mru.indexOf(layout); + this._mru.splice(index, 1); + index = this._keymapInfos.indexOf(layout); + this._keymapInfos.splice(index, 1); + } + + getMatchedKeymapInfo(keyMapping: IKeyboardMapping | null): { result: KeymapInfo, score: number } | null { + if (!keyMapping) { + return null; + } + + let usStandard = this.getUSStandardLayout(); + + if (usStandard) { + let maxScore = usStandard.getScore(keyMapping); + if (maxScore === 0) { + return { + result: usStandard, + score: 0 + }; + } + + let result = usStandard; + for (let i = 0; i < this._mru.length; i++) { + let score = this._mru[i].getScore(keyMapping); + if (score > maxScore) { + if (score === 0) { + return { + result: this._mru[i], + score: 0 + }; + } + + maxScore = score; + result = this._mru[i]; + } + } + + return { + result, + score: maxScore + }; + } + + for (let i = 0; i < this._mru.length; i++) { + if (this._mru[i].fuzzyEqual(keyMapping)) { + return { + result: this._mru[i], + score: 0 + }; + } + } + + return null; + } + + getUSStandardLayout() { + const usStandardLayouts = this._mru.filter(layout => layout.layout.isUSStandard); + + if (usStandardLayouts.length) { + return usStandardLayouts[0]; + } + + return null; + } + + isKeyMappingActive(keymap: IKeyboardMapping | null) { + return this._activeKeymapInfo && keymap && this._activeKeymapInfo.fuzzyEqual(keymap); + } + + setUSKeyboardLayout() { + this._activeKeymapInfo = this.getUSStandardLayout(); + } + + setActiveKeyMapping(keymap: IKeyboardMapping | null) { + let matchedKeyboardLayout = this.getMatchedKeymapInfo(keymap); + if (matchedKeyboardLayout) { + let score = matchedKeyboardLayout.score; + + if (keymap && score < 0) { + const donotAskUpdateKey = 'missing.keyboardlayout.donotask'; + if (this._storageService.getBoolean(donotAskUpdateKey, StorageScope.GLOBAL)) { + return; + } + + // the keyboard layout doesn't actually match the key event or the keymap from chromium + this._notificationService.prompt( + Severity.Info, + nls.localize('missing.keyboardlayout', 'Fail to find matching keyboard layout'), + [{ + label: nls.localize('keyboardLayoutMissing.configure', "Configure"), + run: () => this._commandService.executeCommand('workbench.action.openKeyboardLayoutPicker') + }, { + label: nls.localize('neverAgain', "Don't Show Again"), + isSecondary: true, + run: () => this._storageService.store(donotAskUpdateKey, true, StorageScope.GLOBAL) + }] + ); + + return; + } + + if (!this._activeKeymapInfo) { + this._activeKeymapInfo = matchedKeyboardLayout.result; + } else if (keymap) { + if (matchedKeyboardLayout.result.getScore(keymap) > this._activeKeymapInfo.getScore(keymap)) { + this._activeKeymapInfo = matchedKeyboardLayout.result; + } + } + } + + if (!this._activeKeymapInfo) { + this._activeKeymapInfo = this.getUSStandardLayout(); + } + + if (!this._activeKeymapInfo) { + return; + } + + const index = this._mru.indexOf(this._activeKeymapInfo); + + this._mru.splice(index, 1); + this._mru.unshift(this._activeKeymapInfo); + + this._setKeyboardData(this._activeKeymapInfo); + } + + setActiveKeymapInfo(keymapInfo: KeymapInfo) { + this._activeKeymapInfo = keymapInfo; + + const index = this._mru.indexOf(this._activeKeymapInfo); + + if (index === 0) { + return; + } + + this._mru.splice(index, 1); + this._mru.unshift(this._activeKeymapInfo); + + this._setKeyboardData(this._activeKeymapInfo); + } + + public onKeyboardLayoutChanged(): void { + this._updateKeyboardLayoutAsync(this._initialized); + } + + private _updateKeyboardLayoutAsync(initialized: boolean, keyboardEvent?: IKeyboardEvent) { + if (!initialized) { + return; + } + + this._getBrowserKeyMapping(keyboardEvent).then(keyMap => { + // might be false positive + if (this.isKeyMappingActive(keyMap)) { + return; + } + this.setActiveKeyMapping(keyMap); + }); + } + + public getKeyboardMapper(dispatchConfig: DispatchConfig): IKeyboardMapper { + if (!this._initialized) { + return new MacLinuxFallbackKeyboardMapper(OS); + } + if (dispatchConfig === DispatchConfig.KeyCode) { + // Forcefully set to use keyCode + return new MacLinuxFallbackKeyboardMapper(OS); + } + return this._keyboardMapper!; + } + + public validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): void { + if (!this._initialized) { + return; + } + + let isCurrentKeyboard = this._validateCurrentKeyboardMapping(keyboardEvent); + + if (isCurrentKeyboard) { + return; + } + + this._updateKeyboardLayoutAsync(true, keyboardEvent); + } + + public setKeyboardLayout(layoutName: string) { + let matchedLayouts: KeymapInfo[] = this.keymapInfos.filter(keymapInfo => getKeyboardLayoutId(keymapInfo.layout) === layoutName); + + if (matchedLayouts.length > 0) { + this.setActiveKeymapInfo(matchedLayouts[0]); + } + } + + private _setKeyboardData(keymapInfo: KeymapInfo): void { + this._initialized = true; + + this._keyboardMapper = new CachedKeyboardMapper(BrowserKeyboardMapperFactory._createKeyboardMapper(keymapInfo)); + this._onDidChangeKeyboardMapper.fire(); + } + + private static _createKeyboardMapper(keymapInfo: KeymapInfo): IKeyboardMapper { + let rawMapping = keymapInfo.mapping; + const isUSStandard = !!keymapInfo.layout.isUSStandard; + if (OS === OperatingSystem.Windows) { + return new WindowsKeyboardMapper(isUSStandard, rawMapping); + } + if (Object.keys(rawMapping).length === 0) { + // Looks like reading the mappings failed (most likely Mac + Japanese/Chinese keyboard layouts) + return new MacLinuxFallbackKeyboardMapper(OS); + } + + return new MacLinuxKeyboardMapper(isUSStandard, rawMapping, OS); + } + + //#region Browser API + private _validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): boolean { + if (!this._initialized) { + return true; + } + + const standardKeyboardEvent = keyboardEvent as StandardKeyboardEvent; + const currentKeymap = this._activeKeymapInfo; + if (!currentKeymap) { + return true; + } + + const mapping = currentKeymap.mapping[standardKeyboardEvent.code]; + + if (!mapping) { + return false; + } + + if (mapping.value === '') { + // we don't undetstand + if (keyboardEvent.ctrlKey || keyboardEvent.metaKey) { + setTimeout(() => { + this._getBrowserKeyMapping().then((keymap: IKeyboardMapping) => { + if (this.isKeyMappingActive(keymap)) { + return; + } + + this.onKeyboardLayoutChanged(); + }); + }, 350); + } + return true; + } + + const expectedValue = standardKeyboardEvent.altKey && standardKeyboardEvent.shiftKey ? mapping.withShiftAltGr : + standardKeyboardEvent.altKey ? mapping.withAltGr : + standardKeyboardEvent.shiftKey ? mapping.withShift : mapping.value; + + const isDead = (standardKeyboardEvent.altKey && standardKeyboardEvent.shiftKey && mapping.withShiftAltGrIsDeadKey) || + (standardKeyboardEvent.altKey && mapping.withAltGrIsDeadKey) || + (standardKeyboardEvent.shiftKey && mapping.withShiftIsDeadKey) || + mapping.valueIsDeadKey; + + if (isDead && standardKeyboardEvent.browserEvent.key !== 'Dead') { + return false; + } + + // TODO, this assumption is wrong as `browserEvent.key` doesn't necessarily equal expectedValue from real keymap + if (!isDead && standardKeyboardEvent.browserEvent.key !== expectedValue) { + return false; + } + + return true; + } + + private async _getBrowserKeyMapping(keyboardEvent?: IKeyboardEvent): Promise { + if ((navigator as any).keyboard) { + try { + return (navigator as any).keyboard.getLayoutMap().then((e: any) => { + let ret: IKeyboardMapping = {}; + for (let key of e) { + ret[key[0]] = { + 'value': key[1], + 'withShift': '', + 'withAltGr': '', + 'withShiftAltGr': '' + }; + } + + return ret; + + // const matchedKeyboardLayout = this.getMatchedKeymapInfo(ret); + + // if (matchedKeyboardLayout) { + // return matchedKeyboardLayout.result.mapping; + // } + + // return null; + }); + } catch { + // getLayoutMap can throw if invoked from a nested browsing context + } + } else if (keyboardEvent && !keyboardEvent.shiftKey && !keyboardEvent.altKey && !keyboardEvent.metaKey && !keyboardEvent.metaKey) { + let ret: IKeyboardMapping = {}; + const standardKeyboardEvent = keyboardEvent as StandardKeyboardEvent; + ret[standardKeyboardEvent.browserEvent.code] = { + 'value': standardKeyboardEvent.browserEvent.key, + 'withShift': '', + 'withAltGr': '', + 'withShiftAltGr': '' + }; + + const matchedKeyboardLayout = this.getMatchedKeymapInfo(ret); + + if (matchedKeyboardLayout) { + return ret; + } + + return null; + } + + return null; + } + + //#endregion +} + +export class BrowserKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase { + constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) { + super(notificationService, storageService, commandService); + + const platform = isWindows ? 'win' : isMacintosh ? 'darwin' : 'linux'; + + import('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.' + platform).then((m) => { + let keymapInfos: IKeymapInfo[] = m.KeyboardLayoutContribution.INSTANCE.layoutInfos; + this._keymapInfos.push(...keymapInfos.map(info => (new KeymapInfo(info.layout, info.secondaryLayouts, info.mapping, info.isUserKeyboardLayout)))); + this._mru = this._keymapInfos; + this._initialized = true; + this.onKeyboardLayoutChanged(); + }); + } +} + +class UserKeyboardLayout extends Disposable { + + private readonly reloadConfigurationScheduler: RunOnceScheduler; + protected readonly _onDidChange: Emitter = this._register(new Emitter()); + readonly onDidChange: Event = this._onDidChange.event; + + private _keyboardLayout: KeymapInfo | null; + get keyboardLayout(): KeymapInfo | null { return this._keyboardLayout; } + + constructor( + private readonly keyboardLayoutResource: URI, + private readonly fileService: IFileService + ) { + super(); + + this._keyboardLayout = null; + + this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(changed => { + if (changed) { + this._onDidChange.fire(); + } + }), 50)); + + this._register(Event.filter(this.fileService.onFileChanges, e => e.contains(this.keyboardLayoutResource))(() => this.reloadConfigurationScheduler.schedule())); + } + + async initialize(): Promise { + await this.reload(); + } + + private async reload(): Promise { + const existing = this._keyboardLayout; + try { + const content = await this.fileService.readFile(this.keyboardLayoutResource); + const value = parse(content.value.toString()); + const layoutInfo = value.layout; + const mappings = value.rawMapping; + this._keyboardLayout = KeymapInfo.createKeyboardLayoutFromDebugInfo(layoutInfo, mappings, true); + } catch (e) { + this._keyboardLayout = null; + } + + return existing ? !objects.equals(existing, this._keyboardLayout) : true; + } + +} + +class BrowserKeymapService extends Disposable implements IKeymapService { + public _serviceBrand: any; + + private readonly _onDidChangeKeyboardMapper = new Emitter(); + public readonly onDidChangeKeyboardMapper: Event = this._onDidChangeKeyboardMapper.event; + + private _userKeyboardLayout: UserKeyboardLayout; + + private readonly layoutChangeListener = this._register(new MutableDisposable()); + private readonly _factory: BrowserKeyboardMapperFactory; + + constructor( + @IEnvironmentService environmentService: IEnvironmentService, + @IFileService fileService: IFileService, + @INotificationService notificationService: INotificationService, + @IStorageService storageService: IStorageService, + @ICommandService commandService: ICommandService, + @IConfigurationService private configurationService: IConfigurationService, + ) { + super(); + const keyboardConfig = configurationService.getValue<{ layout: string }>('keyboard'); + const layout = keyboardConfig.layout; + this._factory = new BrowserKeyboardMapperFactory(notificationService, storageService, commandService); + + this.registerKeyboardListener(); + + if (layout && layout !== 'autodetect') { + // set keyboard layout + this._factory.setKeyboardLayout(layout); + } + + this._register(configurationService.onDidChangeConfiguration(e => { + if (e.affectedKeys.indexOf('keyboard.layout') >= 0) { + const keyboardConfig = configurationService.getValue<{ layout: string }>('keyboard'); + const layout = keyboardConfig.layout; + + if (layout === 'autodetect') { + this.registerKeyboardListener(); + this._factory.onKeyboardLayoutChanged(); + } else { + this._factory.setKeyboardLayout(layout); + this.layoutChangeListener.clear(); + } + } + })); + + this._userKeyboardLayout = new UserKeyboardLayout(environmentService.keyboardLayoutResource, fileService); + this._userKeyboardLayout.initialize().then(() => { + if (this._userKeyboardLayout.keyboardLayout) { + this._factory.registerKeyboardLayout(this._userKeyboardLayout.keyboardLayout); + + this.setUserKeyboardLayoutIfMatched(); + } + }); + + this._register(this._userKeyboardLayout.onDidChange(() => { + let userKeyboardLayouts = this._factory.keymapInfos.filter(layout => layout.isUserKeyboardLayout); + + if (userKeyboardLayouts.length) { + if (this._userKeyboardLayout.keyboardLayout) { + userKeyboardLayouts[0].update(this._userKeyboardLayout.keyboardLayout); + } else { + this._factory.removeKeyboardLayout(userKeyboardLayouts[0]); + } + } else { + if (this._userKeyboardLayout.keyboardLayout) { + this._factory.registerKeyboardLayout(this._userKeyboardLayout.keyboardLayout); + } + } + + this.setUserKeyboardLayoutIfMatched(); + })); + } + + setUserKeyboardLayoutIfMatched() { + const keyboardConfig = this.configurationService.getValue<{ layout: string }>('keyboard'); + const layout = keyboardConfig.layout; + + if (layout && this._userKeyboardLayout.keyboardLayout) { + if (getKeyboardLayoutId(this._userKeyboardLayout.keyboardLayout.layout) === layout && this._factory.activeKeymap) { + + if (!this._userKeyboardLayout.keyboardLayout.equal(this._factory.activeKeymap)) { + this._factory.setActiveKeymapInfo(this._userKeyboardLayout.keyboardLayout); + } + } + } + } + + registerKeyboardListener() { + this.layoutChangeListener.value = this._factory.onDidChangeKeyboardMapper(() => { + this._onDidChangeKeyboardMapper.fire(); + }); + } + + getKeyboardMapper(dispatchConfig: DispatchConfig): IKeyboardMapper { + return this._factory.getKeyboardMapper(dispatchConfig); + } + + public getCurrentKeyboardLayout(): IKeyboardLayoutInfo | null { + return this._factory.activeKeyboardLayout; + } + + public getAllKeyboardLayouts(): IKeyboardLayoutInfo[] { + return this._factory.keyboardLayouts; + } + + public getRawKeyboardMapping(): IKeyboardMapping | null { + return this._factory.activeKeyMapping; + } + + public validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): void { + this._factory.validateCurrentKeyboardMapping(keyboardEvent); + } +} + +registerSingleton(IKeymapService, BrowserKeymapService, true); + +// Configuration +const configurationRegistry = Registry.as(ConfigExtensions.Configuration); +const keyboardConfiguration: IConfigurationNode = { + 'id': 'keyboard', + 'order': 15, + 'type': 'object', + 'title': nls.localize('keyboardConfigurationTitle', "Keyboard"), + 'overridable': true, + 'properties': { + 'keyboard.layout': { + 'type': 'string', + 'default': 'autodetect', + 'description': nls.localize('keyboard.layout.config', "Control the keyboard layout used in web.") + } + } +}; + +configurationRegistry.registerConfiguration(keyboardConfiguration); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/common/dispatchConfig.ts b/src/vs/workbench/services/keybinding/common/dispatchConfig.ts new file mode 100644 index 00000000000..a92871c7e96 --- /dev/null +++ b/src/vs/workbench/services/keybinding/common/dispatchConfig.ts @@ -0,0 +1,17 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; + +export const enum DispatchConfig { + Code, + KeyCode +} + +export function getDispatchConfig(configurationService: IConfigurationService): DispatchConfig { + const keyboard = configurationService.getValue('keyboard'); + const r = (keyboard ? (keyboard).dispatch : null); + return (r === 'keyCode' ? DispatchConfig.KeyCode : DispatchConfig.Code); +} \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts index 49b53c2d234..b3d4e77869f 100644 --- a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts +++ b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts @@ -186,7 +186,7 @@ export class KeybindingsEditingService extends Disposable implements IKeybinding } private asObject(key: string, command: string | null, when: string | undefined, negate: boolean): any { - const object = { key }; + const object: any = { key }; if (command) { object['command'] = negate ? `-${command}` : command; } @@ -210,7 +210,7 @@ export class KeybindingsEditingService extends Disposable implements IKeybinding private resolveModelReference(): Promise> { return this.fileService.exists(this.resource) .then(exists => { - const EOL = this.configurationService.getValue<{}>('files', { overrideIdentifier: 'json' })['eol']; + const EOL = this.configurationService.getValue<{ eol: string }>('files', { overrideIdentifier: 'json' })['eol']; const result: Promise = exists ? Promise.resolve(null) : this.textFileService.write(this.resource, this.getEmptyContent(EOL), { encoding: 'utf8' }); return result.then(() => this.textModelResolverService.createModelReference(this.resource)); }); diff --git a/src/vs/workbench/services/keybinding/common/keymapInfo.ts b/src/vs/workbench/services/keybinding/common/keymapInfo.ts new file mode 100644 index 00000000000..5282815cd9a --- /dev/null +++ b/src/vs/workbench/services/keybinding/common/keymapInfo.ts @@ -0,0 +1,342 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from 'vs/base/common/event'; +import { isWindows, isLinux } from 'vs/base/common/platform'; +import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { DispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; +import { IKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; +import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; + + +export interface IWindowsKeyMapping { + vkey: string; + value: string; + withShift: string; + withAltGr: string; + withShiftAltGr: string; +} +export interface IWindowsKeyboardMapping { + [code: string]: IWindowsKeyMapping; +} +export interface ILinuxKeyMapping { + value: string; + withShift: string; + withAltGr: string; + withShiftAltGr: string; +} +export interface ILinuxKeyboardMapping { + [code: string]: ILinuxKeyMapping; +} +export interface IMacKeyMapping { + value: string; + withShift: string; + withAltGr: string; + withShiftAltGr: string; + valueIsDeadKey: boolean; + withShiftIsDeadKey: boolean; + withAltGrIsDeadKey: boolean; + withShiftAltGrIsDeadKey: boolean; +} +export interface IMacKeyboardMapping { + [code: string]: IMacKeyMapping; +} + +export type IKeyboardMapping = IWindowsKeyboardMapping | ILinuxKeyboardMapping | IMacKeyboardMapping; + +/* __GDPR__FRAGMENT__ + "IKeyboardLayoutInfo" : { + "name" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "id": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "text": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } +*/ +export interface IWindowsKeyboardLayoutInfo { + name: string; + id: string; + text: string; +} + +/* __GDPR__FRAGMENT__ + "IKeyboardLayoutInfo" : { + "model" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "layout": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "variant": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "options": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "rules": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } +*/ +export interface ILinuxKeyboardLayoutInfo { + model: string; + layout: string; + variant: string; + options: string; + rules: string; +} + +/* __GDPR__FRAGMENT__ + "IKeyboardLayoutInfo" : { + "id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "lang": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "localizedName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } +*/ +export interface IMacKeyboardLayoutInfo { + id: string; + lang: string; + localizedName?: string; +} + +export type IKeyboardLayoutInfo = (IWindowsKeyboardLayoutInfo | ILinuxKeyboardLayoutInfo | IMacKeyboardLayoutInfo) & { isUserKeyboardLayout?: boolean; isUSStandard?: true }; + +export const IKeymapService = createDecorator('keymapService'); + +export interface IKeymapService { + _serviceBrand: ServiceIdentifier; + onDidChangeKeyboardMapper: Event; + getKeyboardMapper(dispatchConfig: DispatchConfig): IKeyboardMapper; + getCurrentKeyboardLayout(): IKeyboardLayoutInfo | null; + getAllKeyboardLayouts(): IKeyboardLayoutInfo[]; + getRawKeyboardMapping(): IKeyboardMapping | null; + validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): void; +} + +export function areKeyboardLayoutsEqual(a: IKeyboardLayoutInfo | null, b: IKeyboardLayoutInfo | null): boolean { + if (!a || !b) { + return false; + } + + if ((a).name && (b).name && (a).name === (b).name) { + return true; + } + + if ((a).id && (b).id && (a).id === (b).id) { + return true; + } + + if ((a).model && + (b).model && + (a).model === (b).model && + (a).layout === (b).layout + ) { + return true; + } + + return false; +} + +export function parseKeyboardLayoutDescription(layout: IKeyboardLayoutInfo | null): { label: string, description: string } { + if (!layout) { + return { label: '', description: '' }; + } + + if ((layout).name) { + // windows + let windowsLayout = layout; + return { + label: windowsLayout.text, + description: '' + }; + } + + if ((layout).id) { + let macLayout = layout; + if (macLayout.localizedName) { + return { + label: macLayout.localizedName, + description: '' + }; + } + + if (/^com\.apple\.keylayout\./.test(macLayout.id)) { + return { + label: macLayout.id.replace(/^com\.apple\.keylayout\./, '').replace(/-/, ' '), + description: '' + }; + } + if (/^.*inputmethod\./.test(macLayout.id)) { + return { + label: macLayout.id.replace(/^.*inputmethod\./, '').replace(/[-\.]/, ' '), + description: `Input Method (${macLayout.lang})` + }; + } + + return { + label: macLayout.lang, + description: '' + }; + } + + let linuxLayout = layout; + + return { + label: linuxLayout.layout, + description: '' + }; +} + +export function getKeyboardLayoutId(layout: IKeyboardLayoutInfo): string { + if ((layout).name) { + return (layout).name; + } + + if ((layout).id) { + return (layout).id; + } + + return (layout).layout; +} + +function deserializeMapping(serializedMapping: ISerializedMapping) { + let mapping = serializedMapping; + + let ret: { [key: string]: any } = {}; + for (let key in mapping) { + let result: (string | number)[] = mapping[key]; + if (result.length) { + let value = result[0]; + let withShift = result[1]; + let withAltGr = result[2]; + let withShiftAltGr = result[3]; + let mask = Number(result[4]); + let vkey = result.length === 6 ? result[5] : undefined; + ret[key] = { + 'value': value, + 'vkey': vkey, + 'withShift': withShift, + 'withAltGr': withAltGr, + 'withShiftAltGr': withShiftAltGr, + 'valueIsDeadKey': (mask & 1) > 0, + 'withShiftIsDeadKey': (mask & 2) > 0, + 'withAltGrIsDeadKey': (mask & 4) > 0, + 'withShiftAltGrIsDeadKey': (mask & 8) > 0 + }; + } else { + ret[key] = { + 'value': '', + 'valueIsDeadKey': false, + 'withShift': '', + 'withShiftIsDeadKey': false, + 'withAltGr': '', + 'withAltGrIsDeadKey': false, + 'withShiftAltGr': '', + 'withShiftAltGrIsDeadKey': false + }; + } + } + + return ret; +} + +export interface IRawMixedKeyboardMapping { + [key: string]: { + value: string, + withShift: string; + withAltGr: string; + withShiftAltGr: string; + valueIsDeadKey?: boolean; + withShiftIsDeadKey?: boolean; + withAltGrIsDeadKey?: boolean; + withShiftAltGrIsDeadKey?: boolean; + + }; +} + +interface ISerializedMapping { + [key: string]: (string | number)[]; +} + +export interface IKeymapInfo { + layout: IKeyboardLayoutInfo; + secondaryLayouts: IKeyboardLayoutInfo[]; + mapping: ISerializedMapping; + isUserKeyboardLayout?: boolean; +} + +export class KeymapInfo { + mapping: IRawMixedKeyboardMapping; + isUserKeyboardLayout: boolean; + + constructor(public layout: IKeyboardLayoutInfo, public secondaryLayouts: IKeyboardLayoutInfo[], keyboardMapping: ISerializedMapping, isUserKeyboardLayout?: boolean) { + this.mapping = deserializeMapping(keyboardMapping); + this.isUserKeyboardLayout = !!isUserKeyboardLayout; + this.layout.isUserKeyboardLayout = !!isUserKeyboardLayout; + } + + static createKeyboardLayoutFromDebugInfo(layout: IKeyboardLayoutInfo, value: IRawMixedKeyboardMapping, isUserKeyboardLayout?: boolean): KeymapInfo { + let keyboardLayoutInfo = new KeymapInfo(layout, [], {}, true); + keyboardLayoutInfo.mapping = value; + return keyboardLayoutInfo; + } + + update(other: KeymapInfo) { + this.layout = other.layout; + this.secondaryLayouts = other.secondaryLayouts; + this.mapping = other.mapping; + this.isUserKeyboardLayout = other.isUserKeyboardLayout; + this.layout.isUserKeyboardLayout = other.isUserKeyboardLayout; + } + + getScore(other: IRawMixedKeyboardMapping): number { + let score = 0; + for (let key in other) { + if (isWindows && (key === 'Backslash' || key === 'KeyQ')) { + // keymap from Chromium is probably wrong. + continue; + } + + if (isLinux && (key === 'Backspace' || key === 'Escape')) { + // native keymap doesn't align with keyboard event + continue; + } + + if (this.mapping[key] === undefined) { + score -= 1; + } + + let currentMapping = this.mapping[key]; + let otherMapping = other[key]; + + if (currentMapping.value !== otherMapping.value) { + score -= 1; + } + } + + return score; + } + + equal(other: KeymapInfo): boolean { + if (this.isUserKeyboardLayout !== other.isUserKeyboardLayout) { + return false; + } + + if (getKeyboardLayoutId(this.layout) !== getKeyboardLayoutId(other.layout)) { + return false; + } + + return this.fuzzyEqual(other.mapping); + } + + fuzzyEqual(other: IRawMixedKeyboardMapping): boolean { + for (let key in other) { + if (isWindows && (key === 'Backslash' || key === 'KeyQ')) { + // keymap from Chromium is probably wrong. + continue; + } + if (this.mapping[key] === undefined) { + return false; + } + + let currentMapping = this.mapping[key]; + let otherMapping = other[key]; + + if (currentMapping.value !== otherMapping.value) { + return false; + } + } + + return true; + } +} diff --git a/src/vs/workbench/electron-browser/actions/media/actions.css b/src/vs/workbench/services/keybinding/common/navigatorKeyboard.ts similarity index 57% rename from src/vs/workbench/electron-browser/actions/media/actions.css rename to src/vs/workbench/services/keybinding/common/navigatorKeyboard.ts index b8a660c3288..51e8de9f790 100644 --- a/src/vs/workbench/electron-browser/actions/media/actions.css +++ b/src/vs/workbench/services/keybinding/common/navigatorKeyboard.ts @@ -3,11 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.vs .action-remove-from-recently-opened { - background: url("remove.svg") center center no-repeat; -} +export interface IKeyboard { + getLayoutMap(): Promise; + lock(keyCodes?: string[]): Promise; + unlock(): void; + addEventListener?(type: string, listener: () => void): void; -.vs-dark .action-remove-from-recently-opened, -.hc-black .action-remove-from-recently-opened { - background: url("remove-dark.svg") center center no-repeat; -} \ No newline at end of file +} +export type INavigatorWithKeyboard = Navigator & { + keyboard: IKeyboard +}; \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybinding.contribution.ts b/src/vs/workbench/services/keybinding/electron-browser/keybinding.contribution.ts new file mode 100644 index 00000000000..eec3ac01744 --- /dev/null +++ b/src/vs/workbench/services/keybinding/electron-browser/keybinding.contribution.ts @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vs/nls'; +import { release } from 'os'; +import { OS, OperatingSystem } from 'vs/base/common/platform'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions as ConfigExtensions, IConfigurationNode, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; + +const configurationRegistry = Registry.as(ConfigExtensions.Configuration); +const keyboardConfiguration: IConfigurationNode = { + 'id': 'keyboard', + 'order': 15, + 'type': 'object', + 'title': nls.localize('keyboardConfigurationTitle', "Keyboard"), + 'overridable': true, + 'properties': { + 'keyboard.touchbar.enabled': { + 'type': 'boolean', + 'default': true, + 'description': nls.localize('touchbar.enabled', "Enables the macOS touchbar buttons on the keyboard if available."), + 'included': OS === OperatingSystem.Macintosh && parseFloat(release()) >= 16 // Minimum: macOS Sierra (10.12.x = darwin 16.x) + } + } +}; + +configurationRegistry.registerConfiguration(keyboardConfiguration); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/electron-browser/nativeKeymapService.ts b/src/vs/workbench/services/keybinding/electron-browser/nativeKeymapService.ts new file mode 100644 index 00000000000..475c881af9f --- /dev/null +++ b/src/vs/workbench/services/keybinding/electron-browser/nativeKeymapService.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nativeKeymap from 'native-keymap'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping } from 'vs/workbench/services/keybinding/common/keymapInfo'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IKeyboardMapper, CachedKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; +import { Emitter, Event } from 'vs/base/common/event'; +import { DispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; +import { MacLinuxFallbackKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxFallbackKeyboardMapper'; +import { OS, OperatingSystem } from 'vs/base/common/platform'; +import { WindowsKeyboardMapper, windowsKeyboardMappingEquals } from 'vs/workbench/services/keybinding/common/windowsKeyboardMapper'; +import { MacLinuxKeyboardMapper, macLinuxKeyboardMappingEquals, IMacLinuxKeyboardMapping } from 'vs/workbench/services/keybinding/common/macLinuxKeyboardMapper'; +import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; + +export class KeyboardMapperFactory { + public static readonly INSTANCE = new KeyboardMapperFactory(); + + private _layoutInfo: nativeKeymap.IKeyboardLayoutInfo | null; + private _rawMapping: nativeKeymap.IKeyboardMapping | null; + private _keyboardMapper: IKeyboardMapper | null; + private _initialized: boolean; + + private readonly _onDidChangeKeyboardMapper = new Emitter(); + public readonly onDidChangeKeyboardMapper: Event = this._onDidChangeKeyboardMapper.event; + + private constructor() { + this._layoutInfo = null; + this._rawMapping = null; + this._keyboardMapper = null; + this._initialized = false; + } + + public _onKeyboardLayoutChanged(): void { + if (this._initialized) { + this._setKeyboardData(nativeKeymap.getCurrentKeyboardLayout(), nativeKeymap.getKeyMap()); + } + } + + public getKeyboardMapper(dispatchConfig: DispatchConfig): IKeyboardMapper { + if (!this._initialized) { + this._setKeyboardData(nativeKeymap.getCurrentKeyboardLayout(), nativeKeymap.getKeyMap()); + } + if (dispatchConfig === DispatchConfig.KeyCode) { + // Forcefully set to use keyCode + return new MacLinuxFallbackKeyboardMapper(OS); + } + return this._keyboardMapper!; + } + + public getCurrentKeyboardLayout(): nativeKeymap.IKeyboardLayoutInfo | null { + if (!this._initialized) { + this._setKeyboardData(nativeKeymap.getCurrentKeyboardLayout(), nativeKeymap.getKeyMap()); + } + return this._layoutInfo; + } + + private static _isUSStandard(_kbInfo: nativeKeymap.IKeyboardLayoutInfo): boolean { + if (OS === OperatingSystem.Linux) { + const kbInfo = _kbInfo; + return (kbInfo && kbInfo.layout === 'us'); + } + + if (OS === OperatingSystem.Macintosh) { + const kbInfo = _kbInfo; + return (kbInfo && kbInfo.id === 'com.apple.keylayout.US'); + } + + if (OS === OperatingSystem.Windows) { + const kbInfo = _kbInfo; + return (kbInfo && kbInfo.name === '00000409'); + } + + return false; + } + + public getRawKeyboardMapping(): nativeKeymap.IKeyboardMapping | null { + if (!this._initialized) { + this._setKeyboardData(nativeKeymap.getCurrentKeyboardLayout(), nativeKeymap.getKeyMap()); + } + return this._rawMapping; + } + + private _setKeyboardData(layoutInfo: nativeKeymap.IKeyboardLayoutInfo, rawMapping: nativeKeymap.IKeyboardMapping): void { + this._layoutInfo = layoutInfo; + + if (this._initialized && KeyboardMapperFactory._equals(this._rawMapping, rawMapping)) { + // nothing to do... + return; + } + + this._initialized = true; + this._rawMapping = rawMapping; + this._keyboardMapper = new CachedKeyboardMapper( + KeyboardMapperFactory._createKeyboardMapper(this._layoutInfo, this._rawMapping) + ); + this._onDidChangeKeyboardMapper.fire(); + } + + private static _createKeyboardMapper(layoutInfo: nativeKeymap.IKeyboardLayoutInfo, rawMapping: nativeKeymap.IKeyboardMapping): IKeyboardMapper { + const isUSStandard = KeyboardMapperFactory._isUSStandard(layoutInfo); + if (OS === OperatingSystem.Windows) { + return new WindowsKeyboardMapper(isUSStandard, rawMapping); + } + + if (Object.keys(rawMapping).length === 0) { + // Looks like reading the mappings failed (most likely Mac + Japanese/Chinese keyboard layouts) + return new MacLinuxFallbackKeyboardMapper(OS); + } + + if (OS === OperatingSystem.Macintosh) { + const kbInfo = layoutInfo; + if (kbInfo.id === 'com.apple.keylayout.DVORAK-QWERTYCMD') { + // Use keyCode based dispatching for DVORAK - QWERTY ⌘ + return new MacLinuxFallbackKeyboardMapper(OS); + } + } + + return new MacLinuxKeyboardMapper(isUSStandard, rawMapping, OS); + } + + private static _equals(a: nativeKeymap.IKeyboardMapping | null, b: nativeKeymap.IKeyboardMapping | null): boolean { + if (OS === OperatingSystem.Windows) { + return windowsKeyboardMappingEquals(a, b); + } + + return macLinuxKeyboardMappingEquals(a, b); + } +} + +class NativeKeymapService extends Disposable implements IKeymapService { + public _serviceBrand: any; + + private readonly _onDidChangeKeyboardMapper = new Emitter(); + public readonly onDidChangeKeyboardMapper: Event = this._onDidChangeKeyboardMapper.event; + + constructor() { + super(); + + this._register(KeyboardMapperFactory.INSTANCE.onDidChangeKeyboardMapper(() => { + this._onDidChangeKeyboardMapper.fire(); + })); + } + + getKeyboardMapper(dispatchConfig: DispatchConfig): IKeyboardMapper { + return KeyboardMapperFactory.INSTANCE.getKeyboardMapper(dispatchConfig); + } + + public getCurrentKeyboardLayout(): IKeyboardLayoutInfo | null { + return KeyboardMapperFactory.INSTANCE.getCurrentKeyboardLayout(); + } + + getAllKeyboardLayouts(): IKeyboardLayoutInfo[] { + return []; + } + + public getRawKeyboardMapping(): IKeyboardMapping | null { + return KeyboardMapperFactory.INSTANCE.getRawKeyboardMapping(); + } + + public validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): void { + return; + } +} + +registerSingleton(IKeymapService, NativeKeymapService, true); diff --git a/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts new file mode 100644 index 00000000000..acf45e1358d --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts @@ -0,0 +1,143 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as assert from 'assert'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin'; // 15% +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { BrowserKeyboardMapperFactoryBase } from '../browser/keymapService'; +import { KeymapInfo, IKeymapInfo } from '../common/keymapInfo'; +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; +import { INotificationService } from 'vs/platform/notification/common/notification'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { IStorageService } from 'vs/platform/storage/common/storage'; + +class TestKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase { + constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) { + super(notificationService, storageService, commandService); + + let keymapInfos: IKeymapInfo[] = KeyboardLayoutContribution.INSTANCE.layoutInfos; + this._keymapInfos.push(...keymapInfos.map(info => (new KeymapInfo(info.layout, info.secondaryLayouts, info.mapping, info.isUserKeyboardLayout)))); + this._mru = this._keymapInfos; + this._initialized = true; + this.onKeyboardLayoutChanged(); + } +} + + +suite('keyboard layout loader', () => { + let instantiationService: TestInstantiationService = new TestInstantiationService(); + let notitifcationService = instantiationService.stub(INotificationService, {}); + let storageService = instantiationService.stub(IStorageService, {}); + let commandService = instantiationService.stub(ICommandService, {}); + let instance = new TestKeyboardMapperFactory(notitifcationService, storageService, commandService); + + test.skip('load default US keyboard layout', () => { + assert.notEqual(instance.activeKeyboardLayout, null); + assert.equal(instance.activeKeyboardLayout!.isUSStandard, true); + }); + + test.skip('isKeyMappingActive', () => { + assert.equal(instance.isKeyMappingActive({ + KeyA: { + value: 'a', + valueIsDeadKey: false, + withShift: 'A', + withShiftIsDeadKey: false, + withAltGr: 'å', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Å', + withShiftAltGrIsDeadKey: false + } + }), true); + + assert.equal(instance.isKeyMappingActive({ + KeyA: { + value: 'a', + valueIsDeadKey: false, + withShift: 'A', + withShiftIsDeadKey: false, + withAltGr: 'å', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Å', + withShiftAltGrIsDeadKey: false + }, + KeyZ: { + value: 'z', + valueIsDeadKey: false, + withShift: 'Z', + withShiftIsDeadKey: false, + withAltGr: 'Ω', + withAltGrIsDeadKey: false, + withShiftAltGr: '¸', + withShiftAltGrIsDeadKey: false + } + }), true); + + assert.equal(instance.isKeyMappingActive({ + KeyZ: { + value: 'y', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: '¥', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ÿ', + withShiftAltGrIsDeadKey: false + }, + }), false); + + }); + + test('Switch keymapping', () => { + instance.setActiveKeyMapping({ + KeyZ: { + value: 'y', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: '¥', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ÿ', + withShiftAltGrIsDeadKey: false + } + }); + assert.equal(!!instance.activeKeyboardLayout!.isUSStandard, false); + assert.equal(instance.isKeyMappingActive({ + KeyZ: { + value: 'y', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: '¥', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ÿ', + withShiftAltGrIsDeadKey: false + }, + }), true); + + instance.setUSKeyboardLayout(); + assert.equal(instance.activeKeyboardLayout!.isUSStandard, true); + }); + + test('Switch keyboard layout info', () => { + instance.setKeyboardLayout('com.apple.keylayout.German'); + assert.equal(!!instance.activeKeyboardLayout!.isUSStandard, false); + assert.equal(instance.isKeyMappingActive({ + KeyZ: { + value: 'y', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: '¥', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ÿ', + withShiftAltGrIsDeadKey: false + }, + }), true); + + instance.setUSKeyboardLayout(); + assert.equal(instance.activeKeyboardLayout!.isUSStandard, true); + }); +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts index fe2da11d9cd..4ae911b01ff 100644 --- a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts +++ b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts @@ -40,11 +40,25 @@ import { KeybindingsEditingService } from 'vs/workbench/services/keybinding/comm import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; -import { TestBackupFileService, TestContextService, TestEditorGroupsService, TestEditorService, TestLifecycleService, TestLogService, TestTextFileService, TestTextResourcePropertiesService } from 'vs/workbench/test/workbenchTestServices'; -import { FileService } from 'vs/workbench/services/files/common/fileService'; +import { TestBackupFileService, TestContextService, TestEditorGroupsService, TestEditorService, TestLifecycleService, TestTextFileService, TestTextResourcePropertiesService } from 'vs/workbench/test/workbenchTestServices'; +import { FileService } from 'vs/platform/files/common/fileService'; import { Schemas } from 'vs/base/common/network'; -import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFileSystemProvider'; +import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; import { URI } from 'vs/base/common/uri'; +import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; +import { parseArgs } from 'vs/platform/environment/node/argv'; +import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/node/environmentService'; +import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; + +class TestEnvironmentService extends WorkbenchEnvironmentService { + + constructor(private _appSettingsHome: URI) { + super(parseArgs(process.argv) as IWindowConfiguration, process.execPath); + } + + get appSettingsHome() { return this._appSettingsHome; } + +} interface Modifiers { metaKey?: boolean; @@ -66,7 +80,8 @@ suite('KeybindingsEditing', () => { instantiationService = new TestInstantiationService(); - instantiationService.stub(IEnvironmentService, { keybindingsResource: URI.file(keybindingsFile), settingsResource: URI.file(path.join(testDir, 'settings.json')) }); + const environmentService = new TestEnvironmentService(URI.file(testDir)); + instantiationService.stub(IEnvironmentService, environmentService); instantiationService.stub(IConfigurationService, ConfigurationService); instantiationService.stub(IConfigurationService, 'getValue', { 'eol': '\n' }); instantiationService.stub(IConfigurationService, 'onDidUpdateConfiguration', () => { }); @@ -79,11 +94,13 @@ suite('KeybindingsEditing', () => { instantiationService.stub(IEditorService, new TestEditorService()); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(IModeService, ModeServiceImpl); - instantiationService.stub(ILogService, new TestLogService()); + instantiationService.stub(ILogService, new NullLogService()); instantiationService.stub(ITextResourcePropertiesService, new TestTextResourcePropertiesService(instantiationService.get(IConfigurationService))); instantiationService.stub(IModelService, instantiationService.createInstance(ModelServiceImpl)); const fileService = new FileService(new NullLogService()); - fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); + const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, diskFileSystemProvider, environmentService)); instantiationService.stub(IFileService, fileService); instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService)); instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService)); @@ -144,16 +161,6 @@ suite('KeybindingsEditing', () => { .then(() => assert.deepEqual(getUserKeybindings(), expected)); }); - test('edit a default keybinding to a non existing keybindings file', () => { - keybindingsFile = path.join(testDir, 'nonExistingFile.json'); - instantiationService.get(IEnvironmentService).keybindingsResource = URI.file(keybindingsFile); - testObject = instantiationService.createInstance(KeybindingsEditingService); - - const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }]; - return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }), 'alt+c', undefined) - .then(() => assert.deepEqual(getUserKeybindings(), expected)); - }); - test('edit a default keybinding to an empty array', () => { writeToKeybindingsFile(); const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }]; diff --git a/src/vs/workbench/services/layout/browser/layoutService.ts b/src/vs/workbench/services/layout/browser/layoutService.ts index c89bbef87c1..d0bf836984f 100644 --- a/src/vs/workbench/services/layout/browser/layoutService.ts +++ b/src/vs/workbench/services/layout/browser/layoutService.ts @@ -138,6 +138,11 @@ export interface IWorkbenchLayoutService extends ILayoutService { */ setPanelPosition(position: Position): void; + /** + * Returns the element that is parent of the workbench element. + */ + getWorkbenchContainer(): HTMLElement; + /** * Returns the element that contains the workbench. */ diff --git a/src/vs/workbench/services/output/node/outputChannelModelService.ts b/src/vs/workbench/services/output/node/outputChannelModelService.ts index 7f540132bce..da44834ef94 100644 --- a/src/vs/workbench/services/output/node/outputChannelModelService.ts +++ b/src/vs/workbench/services/output/node/outputChannelModelService.ts @@ -169,10 +169,7 @@ class DelegatedOutputChannelModel extends Disposable implements IOutputChannelMo } catch (e) { // Do not crash if spdlog rotating logger cannot be loaded (workaround for https://github.com/Microsoft/vscode/issues/47883) this.logService.error(e); - /* __GDPR__ - "output.channel.creation.error" : {} - */ - this.telemetryService.publicLog('output.channel.creation.error'); + this.telemetryService.publicLog2('output.channel.creation.error'); outputChannelModel = this.instantiationService.createInstance(BufferredOutputChannel, modelUri, mimeType); } this._register(outputChannelModel); diff --git a/src/vs/workbench/services/panel/common/panelService.ts b/src/vs/workbench/services/panel/common/panelService.ts index 4609cb5d2bd..9e957d61747 100644 --- a/src/vs/workbench/services/panel/common/panelService.ts +++ b/src/vs/workbench/services/panel/common/panelService.ts @@ -8,6 +8,7 @@ import { IPanel } from 'vs/workbench/common/panel'; import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { IBadge } from 'vs/workbench/services/activity/common/activity'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { IProgressIndicator } from 'vs/platform/progress/common/progress'; export const IPanelService = createDecorator('panelService'); @@ -18,11 +19,11 @@ export interface IPanelIdentifier { } export interface IPanelService { + _serviceBrand: ServiceIdentifier; - onDidPanelOpen: Event<{ panel: IPanel, focus: boolean }>; - - onDidPanelClose: Event; + readonly onDidPanelOpen: Event<{ panel: IPanel, focus: boolean }>; + readonly onDidPanelClose: Event; /** * Opens a panel with the given identifier and pass keyboard focus to it if specified. @@ -35,7 +36,12 @@ export interface IPanelService { getActivePanel(): IPanel | null; /** - * Returns all built-in panels following the default order (Problems - Output - Debug Console - Terminal) + * Returns the panel by id. + */ + getPanel(id: string): IPanelIdentifier | undefined; + + /** + * Returns all built-in panels following the default order */ getPanels(): IPanelIdentifier[]; @@ -44,6 +50,11 @@ export interface IPanelService { */ getPinnedPanels(): IPanelIdentifier[]; + /** + * Returns the progress indicator for the panel bar. + */ + getProgressIndicator(id: string): IProgressIndicator | null; + /** * Show an activity in a panel. */ diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index 9f6330fcd37..75c7be48efc 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -265,12 +265,10 @@ export class PreferencesService extends Disposable implements IPreferencesServic } openGlobalKeybindingSettings(textual: boolean): Promise { - /* __GDPR__ - "openKeybindings" : { - "textual" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - } - */ - this.telemetryService.publicLog('openKeybindings', { textual }); + type OpenKeybindingsClassification = { + textual: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; + }; + this.telemetryService.publicLog2<{ textual: boolean }, OpenKeybindingsClassification>('openKeybindings', { textual }); if (textual) { const emptyContents = '// ' + nls.localize('emptyKeybindingsHeader', "Place your key bindings in this file to override the defaults") + '\n[\n]'; const editableKeybindings = this.environmentService.keybindingsResource; diff --git a/src/vs/workbench/services/preferences/common/keybindingsEditorModel.ts b/src/vs/workbench/services/preferences/common/keybindingsEditorModel.ts index 0f80e25b1d2..01bf60c346a 100644 --- a/src/vs/workbench/services/preferences/common/keybindingsEditorModel.ts +++ b/src/vs/workbench/services/preferences/common/keybindingsEditorModel.ts @@ -160,7 +160,7 @@ export class KeybindingsEditorModel extends EditorModel { return result; } - resolve(editorActionsLabels: { [id: string]: string; }): Promise { + resolve(editorActionsLabels: Map): Promise { const workbenchActionsRegistry = Registry.as(ActionExtensions.WorkbenchActions); this._keybindingItemsSortedByPrecedence = []; @@ -209,9 +209,9 @@ export class KeybindingsEditorModel extends EditorModel { return a.command.localeCompare(b.command); } - private static toKeybindingEntry(command: string, keybindingItem: ResolvedKeybindingItem, workbenchActionsRegistry: IWorkbenchActionRegistry, editorActions: { [id: string]: string; }): IKeybindingItem { - const menuCommand = MenuRegistry.getCommand(command); - const editorActionLabel = editorActions[command]; + private static toKeybindingEntry(command: string, keybindingItem: ResolvedKeybindingItem, workbenchActionsRegistry: IWorkbenchActionRegistry, editorActions: Map): IKeybindingItem { + const menuCommand = MenuRegistry.getCommand(command)!; + const editorActionLabel = editorActions.get(command)!; return { keybinding: keybindingItem.resolvedKeybinding, keybindingItem, diff --git a/src/vs/workbench/services/preferences/test/common/keybindingsEditorModel.test.ts b/src/vs/workbench/services/preferences/test/common/keybindingsEditorModel.test.ts index c70d6d94927..675c17c8b95 100644 --- a/src/vs/workbench/services/preferences/test/common/keybindingsEditorModel.test.ts +++ b/src/vs/workbench/services/preferences/test/common/keybindingsEditorModel.test.ts @@ -56,7 +56,7 @@ suite('KeybindingsEditorModel test', () => { aResolvedKeybindingItem({ command: 'b' + uuid.generateUuid(), firstPart: { keyCode: KeyCode.Escape }, chordPart: { keyCode: KeyCode.Escape } }) ); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actuals = asResolvedKeybindingItems(testObject.fetch('')); assertKeybindingItems(actuals, expected); }); @@ -67,7 +67,7 @@ suite('KeybindingsEditorModel test', () => { aResolvedKeybindingItem({ command: 'b' + uuid.generateUuid(), firstPart: { keyCode: KeyCode.Escape }, chordPart: { keyCode: KeyCode.Escape } }) ); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actuals = asResolvedKeybindingItems(testObject.fetch('').slice(0, 2), true); assertKeybindingItems(actuals, expected); }); @@ -80,7 +80,7 @@ suite('KeybindingsEditorModel test', () => { ); const expected = [keybindings[2], keybindings[0], keybindings[1]]; - await testObject.resolve({}); + await testObject.resolve(new Map()); const actuals = asResolvedKeybindingItems(testObject.fetch('')); assertKeybindingItems(actuals, expected); }); @@ -93,7 +93,7 @@ suite('KeybindingsEditorModel test', () => { ); const expected = [keybindings[1], keybindings[0]]; - await testObject.resolve({}); + await testObject.resolve(new Map()); const actuals = asResolvedKeybindingItems(testObject.fetch('')); assertKeybindingItems(actuals, expected); }); @@ -113,7 +113,7 @@ suite('KeybindingsEditorModel test', () => { instantiationService.stub(IKeybindingService, 'getKeybindings', () => keybindings); instantiationService.stub(IKeybindingService, 'getDefaultKeybindings', () => keybindings); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actuals = asResolvedKeybindingItems(testObject.fetch('')); assertKeybindingItems(actuals, expected); }); @@ -131,7 +131,7 @@ suite('KeybindingsEditorModel test', () => { registerCommandWithTitle(keybindings[3].command!, 'Same Title'); const expected = [keybindings[3], keybindings[1], keybindings[0], keybindings[2]]; - await testObject.resolve({}); + await testObject.resolve(new Map()); const actuals = asResolvedKeybindingItems(testObject.fetch('')); assertKeybindingItems(actuals, expected); }); @@ -143,7 +143,7 @@ suite('KeybindingsEditorModel test', () => { aResolvedKeybindingItem({ command: 'a' + uuid.generateUuid(), firstPart: { keyCode: KeyCode.Backspace } }) ); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actuals = asResolvedKeybindingItems(testObject.fetch('', true)); assertKeybindingItems(actuals, expected); }); @@ -152,7 +152,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command: 'a' + uuid.generateUuid(), firstPart: { keyCode: KeyCode.Escape }, when: 'context1 && context2' }); prepareKeybindingService(expected); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('')[0]; assert.equal(actual.keybindingItem.command, expected.command); assert.equal(actual.keybindingItem.commandLabel, ''); @@ -166,7 +166,7 @@ suite('KeybindingsEditorModel test', () => { prepareKeybindingService(expected); registerCommandWithTitle(expected.command!, 'Some Title'); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('')[0]; assert.equal(actual.keybindingItem.command, expected.command); assert.equal(actual.keybindingItem.commandLabel, 'Some Title'); @@ -179,7 +179,7 @@ suite('KeybindingsEditorModel test', () => { CommandsRegistry.registerCommand('command_without_keybinding', () => { }); prepareKeybindingService(); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('').filter(element => element.keybindingItem.command === 'command_without_keybinding')[0]; assert.equal(actual.keybindingItem.command, 'command_without_keybinding'); assert.equal(actual.keybindingItem.commandLabel, ''); @@ -193,7 +193,7 @@ suite('KeybindingsEditorModel test', () => { registerCommandWithTitle(id, 'some title'); prepareKeybindingService(); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('').filter(element => element.keybindingItem.command === id)[0]; assert.equal(actual.keybindingItem.command, id); assert.equal(actual.keybindingItem.commandLabel, 'some title'); @@ -207,7 +207,7 @@ suite('KeybindingsEditorModel test', () => { registerCommandWithTitle(id, 'some title'); prepareKeybindingService(); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('workbench action view size').filter(element => element.keybindingItem.command === id)[0]; assert.ok(actual); }); @@ -217,7 +217,7 @@ suite('KeybindingsEditorModel test', () => { registerCommandWithTitle(id, 'Increase view size'); prepareKeybindingService(); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('increase size').filter(element => element.keybindingItem.command === id)[0]; assert.ok(actual); }); @@ -227,7 +227,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape }, when: 'context1 && context2' }); prepareKeybindingService(expected); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('default').filter(element => element.keybindingItem.command === command)[0]; assert.ok(actual); }); @@ -237,7 +237,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape }, when: 'context1 && context2', isDefault: false }); prepareKeybindingService(expected); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('user').filter(element => element.keybindingItem.command === command)[0]; assert.ok(actual); }); @@ -247,7 +247,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape }, when: 'context1 && context2', isDefault: true }); prepareKeybindingService(expected); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('@source: default').filter(element => element.keybindingItem.command === command)[0]; assert.ok(actual); }); @@ -257,7 +257,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape }, when: 'context1 && context2', isDefault: false }); prepareKeybindingService(expected); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('@source: user').filter(element => element.keybindingItem.command === command)[0]; assert.ok(actual); }); @@ -267,7 +267,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('when context').filter(element => element.keybindingItem.command === command)[0]; assert.ok(actual); }); @@ -279,7 +279,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('cmd').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true }); @@ -293,7 +293,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('meta').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true }); @@ -307,7 +307,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { altKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('command').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true }); @@ -321,7 +321,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('windows').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true }); @@ -333,7 +333,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { altKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('alt').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { altKey: true }); @@ -345,7 +345,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { altKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('option').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { altKey: true }); @@ -357,7 +357,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('ctrl').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { ctrlKey: true }); @@ -369,7 +369,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('control').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { ctrlKey: true }); @@ -381,7 +381,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('shift').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { shiftKey: true }); @@ -393,7 +393,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.RightArrow, modifiers: { shiftKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('arrow').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { keyCode: true }); @@ -405,7 +405,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.RightArrow, modifiers: { altKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.RightArrow, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('alt right').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { altKey: true, keyCode: true }); @@ -417,7 +417,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.RightArrow, modifiers: { altKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.RightArrow, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('right alt').filter(element => element.keybindingItem.command === command); assert.equal(0, actual.length); }); @@ -428,7 +428,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { altKey: true, metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('alt cmd esc').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { altKey: true, metaKey: true, keyCode: true }); @@ -441,7 +441,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('cmd shift esc').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true, shiftKey: true, keyCode: true }); @@ -454,7 +454,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, chordPart: { keyCode: KeyCode.Delete }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('cmd shift esc').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true, shiftKey: true, keyCode: true }); @@ -467,7 +467,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, chordPart: { keyCode: KeyCode.Delete }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('cmd del').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true }); @@ -480,7 +480,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, chordPart: { keyCode: KeyCode.Delete }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, chordPart: { keyCode: KeyCode.UpArrow }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('cmd shift esc del').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { shiftKey: true, metaKey: true, keyCode: true }); @@ -492,7 +492,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.KEY_C, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, chordPart: { keyCode: KeyCode.KEY_C, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('"ctrl c"').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { ctrlKey: true, keyCode: true }); @@ -504,7 +504,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, chordPart: { keyCode: KeyCode.KEY_C, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.KEY_C, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('"shift meta escape ctrl c"').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { shiftKey: true, metaKey: true, keyCode: true }); @@ -517,7 +517,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, chordPart: { keyCode: KeyCode.Delete, modifiers: { metaKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, chordPart: { keyCode: KeyCode.UpArrow }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('"cmd shift esc del"').filter(element => element.keybindingItem.command === command); assert.equal(0, actual.length); }); @@ -527,7 +527,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.KEY_C, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, chordPart: { keyCode: KeyCode.KEY_C, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('"control+c"').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { ctrlKey: true, keyCode: true }); @@ -539,7 +539,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, chordPart: { keyCode: KeyCode.KEY_C, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.KEY_C, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('"shift+meta+escape ctrl+c"').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { shiftKey: true, metaKey: true, keyCode: true }); @@ -551,7 +551,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Space, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.Backspace, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('"ctrl+space"').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); }); @@ -562,7 +562,7 @@ suite('KeybindingsEditorModel test', () => { const expected = aResolvedKeybindingItem({ command, firstPart: { keyCode: KeyCode.DownArrow } }); prepareKeybindingService(expected, aResolvedKeybindingItem({ command: 'down', firstPart: { keyCode: KeyCode.Escape } })); - await testObject.resolve({}); + await testObject.resolve(new Map()); const actual = testObject.fetch('"down"').filter(element => element.keybindingItem.command === command); assert.equal(1, actual.length); assert.deepEqual(actual[0].keybindingMatches!.firstPart, { keyCode: true }); diff --git a/src/vs/workbench/services/progress/browser/editorProgressService.ts b/src/vs/workbench/services/progress/browser/editorProgressService.ts new file mode 100644 index 00000000000..7ea3daae18e --- /dev/null +++ b/src/vs/workbench/services/progress/browser/editorProgressService.ts @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IEditorProgressService } from 'vs/platform/progress/common/progress'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { ProgressBarIndicator } from 'vs/workbench/services/progress/browser/progressIndicator'; + +export class EditorProgressService extends ProgressBarIndicator { + + _serviceBrand: ServiceIdentifier; +} diff --git a/src/vs/workbench/services/progress/browser/localProgressService.ts b/src/vs/workbench/services/progress/browser/progressIndicator.ts similarity index 74% rename from src/vs/workbench/services/progress/browser/localProgressService.ts rename to src/vs/workbench/services/progress/browser/progressIndicator.ts index 2f2932873d7..1d11c084f7c 100644 --- a/src/vs/workbench/services/progress/browser/localProgressService.ts +++ b/src/vs/workbench/services/progress/browser/progressIndicator.ts @@ -4,263 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable } from 'vs/base/common/lifecycle'; -import * as types from 'vs/base/common/types'; +import { isUndefinedOrNull } from 'vs/base/common/types'; import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; -import { ILocalProgressService, IProgressRunner } from 'vs/platform/progress/common/progress'; -import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { IProgressRunner, IProgressIndicator } from 'vs/platform/progress/common/progress'; -namespace ProgressState { - - export const enum Type { - None, - Done, - Infinite, - While, - Work - } - - export const None = new class { readonly type = Type.None; }; - export const Done = new class { readonly type = Type.Done; }; - export const Infinite = new class { readonly type = Type.Infinite; }; - - export class While { - readonly type = Type.While; - - constructor( - readonly whilePromise: Promise, - readonly whileStart: number, - readonly whileDelay: number, - ) { } - } - - export class Work { - readonly type = Type.Work; - - constructor( - readonly total: number | undefined, - readonly worked: number | undefined - ) { } - } - - export type State = - typeof None - | typeof Done - | typeof Infinite - | While - | Work; -} - -export abstract class ScopedService extends Disposable { - - constructor( - private viewletService: IViewletService, - private panelService: IPanelService, - private scopeId: string - ) { - super(); - - this.registerListeners(); - } - - registerListeners(): void { - this._register(this.viewletService.onDidViewletOpen(viewlet => this.onScopeOpened(viewlet.getId()))); - this._register(this.panelService.onDidPanelOpen(({ panel }) => this.onScopeOpened(panel.getId()))); - - this._register(this.viewletService.onDidViewletClose(viewlet => this.onScopeClosed(viewlet.getId()))); - this._register(this.panelService.onDidPanelClose(panel => this.onScopeClosed(panel.getId()))); - } - - private onScopeClosed(scopeId: string) { - if (scopeId === this.scopeId) { - this.onScopeDeactivated(); - } - } - - private onScopeOpened(scopeId: string) { - if (scopeId === this.scopeId) { - this.onScopeActivated(); - } - } - - abstract onScopeActivated(): void; - - abstract onScopeDeactivated(): void; -} - -export class ScopedProgressService extends ScopedService implements ILocalProgressService { - - _serviceBrand: ServiceIdentifier; - - private isActive: boolean; - private progressbar: ProgressBar; - private progressState: ProgressState.State = ProgressState.None; - - constructor( - progressbar: ProgressBar, - scopeId: string, - isActive: boolean, - @IViewletService viewletService: IViewletService, - @IPanelService panelService: IPanelService - ) { - super(viewletService, panelService, scopeId); - - this.progressbar = progressbar; - this.isActive = isActive || types.isUndefinedOrNull(scopeId); // If service is unscoped, enable by default - } - - onScopeDeactivated(): void { - this.isActive = false; - } - - onScopeActivated(): void { - this.isActive = true; - - // Return early if progress state indicates that progress is done - if (this.progressState.type === ProgressState.Done.type) { - return; - } - - // Replay Infinite Progress from Promise - if (this.progressState.type === ProgressState.Type.While) { - let delay: number | undefined; - if (this.progressState.whileDelay > 0) { - const remainingDelay = this.progressState.whileDelay - (Date.now() - this.progressState.whileStart); - if (remainingDelay > 0) { - delay = remainingDelay; - } - } - - this.doShowWhile(delay); - } - - // Replay Infinite Progress - else if (this.progressState.type === ProgressState.Type.Infinite) { - this.progressbar.infinite().show(); - } - - // Replay Finite Progress (Total & Worked) - else if (this.progressState.type === ProgressState.Type.Work) { - if (this.progressState.total) { - this.progressbar.total(this.progressState.total).show(); - } - - if (this.progressState.worked) { - this.progressbar.worked(this.progressState.worked).show(); - } - } - } - - show(infinite: true, delay?: number): IProgressRunner; - show(total: number, delay?: number): IProgressRunner; - show(infiniteOrTotal: true | number, delay?: number): IProgressRunner { - - // Sort out Arguments - if (typeof infiniteOrTotal === 'boolean') { - this.progressState = ProgressState.Infinite; - } else { - this.progressState = new ProgressState.Work(infiniteOrTotal, undefined); - } - - // Active: Show Progress - if (this.isActive) { - - // Infinite: Start Progressbar and Show after Delay - if (this.progressState.type === ProgressState.Type.Infinite) { - this.progressbar.infinite().show(delay); - } - - // Finite: Start Progressbar and Show after Delay - else if (this.progressState.type === ProgressState.Type.Work && typeof this.progressState.total === 'number') { - this.progressbar.total(this.progressState.total).show(delay); - } - } - - return { - total: (total: number) => { - this.progressState = new ProgressState.Work( - total, - this.progressState.type === ProgressState.Type.Work ? this.progressState.worked : undefined); - - if (this.isActive) { - this.progressbar.total(total); - } - }, - - worked: (worked: number) => { - - // Verify first that we are either not active or the progressbar has a total set - if (!this.isActive || this.progressbar.hasTotal()) { - this.progressState = new ProgressState.Work( - this.progressState.type === ProgressState.Type.Work ? this.progressState.total : undefined, - this.progressState.type === ProgressState.Type.Work && typeof this.progressState.worked === 'number' ? this.progressState.worked + worked : worked); - - if (this.isActive) { - this.progressbar.worked(worked); - } - } - - // Otherwise the progress bar does not support worked(), we fallback to infinite() progress - else { - this.progressState = ProgressState.Infinite; - this.progressbar.infinite().show(); - } - }, - - done: () => { - this.progressState = ProgressState.Done; - - if (this.isActive) { - this.progressbar.stop().hide(); - } - } - }; - } - - async showWhile(promise: Promise, delay?: number): Promise { - - // Join with existing running promise to ensure progress is accurate - if (this.progressState.type === ProgressState.Type.While) { - promise = Promise.all([promise, this.progressState.whilePromise]); - } - - // Keep Promise in State - this.progressState = new ProgressState.While(promise, delay || 0, Date.now()); - - try { - this.doShowWhile(delay); - - await promise; - } catch (error) { - // ignore - } finally { - - // If this is not the last promise in the list of joined promises, skip this - if (this.progressState.type !== ProgressState.Type.While || this.progressState.whilePromise === promise) { - - // The while promise is either null or equal the promise we last hooked on - this.progressState = ProgressState.None; - - if (this.isActive) { - this.progressbar.stop().hide(); - } - } - } - } - - private doShowWhile(delay?: number): void { - - // Show Progress when active - if (this.isActive) { - this.progressbar.infinite().show(delay); - } - } -} - -export class LocalProgressService implements ILocalProgressService { - - _serviceBrand: ServiceIdentifier; +export class ProgressBarIndicator implements IProgressIndicator { constructor(private progressbar: ProgressBar) { } @@ -304,3 +54,247 @@ export class LocalProgressService implements ILocalProgressService { } } } + +namespace ProgressIndicatorState { + + export const enum Type { + None, + Done, + Infinite, + While, + Work + } + + export const None = new class { readonly type = Type.None; }; + export const Done = new class { readonly type = Type.Done; }; + export const Infinite = new class { readonly type = Type.Infinite; }; + + export class While { + readonly type = Type.While; + + constructor( + readonly whilePromise: Promise, + readonly whileStart: number, + readonly whileDelay: number, + ) { } + } + + export class Work { + readonly type = Type.Work; + + constructor( + readonly total: number | undefined, + readonly worked: number | undefined + ) { } + } + + export type State = + typeof None + | typeof Done + | typeof Infinite + | While + | Work; +} + +export abstract class CompositeScope extends Disposable { + + constructor( + private viewletService: IViewletService, + private panelService: IPanelService, + private scopeId: string + ) { + super(); + + this.registerListeners(); + } + + registerListeners(): void { + this._register(this.viewletService.onDidViewletOpen(viewlet => this.onScopeOpened(viewlet.getId()))); + this._register(this.panelService.onDidPanelOpen(({ panel }) => this.onScopeOpened(panel.getId()))); + + this._register(this.viewletService.onDidViewletClose(viewlet => this.onScopeClosed(viewlet.getId()))); + this._register(this.panelService.onDidPanelClose(panel => this.onScopeClosed(panel.getId()))); + } + + private onScopeClosed(scopeId: string) { + if (scopeId === this.scopeId) { + this.onScopeDeactivated(); + } + } + + private onScopeOpened(scopeId: string) { + if (scopeId === this.scopeId) { + this.onScopeActivated(); + } + } + + abstract onScopeActivated(): void; + + abstract onScopeDeactivated(): void; +} + +export class CompositeProgressIndicator extends CompositeScope implements IProgressIndicator { + private isActive: boolean; + private progressbar: ProgressBar; + private progressState: ProgressIndicatorState.State = ProgressIndicatorState.None; + + constructor( + progressbar: ProgressBar, + scopeId: string, + isActive: boolean, + @IViewletService viewletService: IViewletService, + @IPanelService panelService: IPanelService + ) { + super(viewletService, panelService, scopeId); + + this.progressbar = progressbar; + this.isActive = isActive || isUndefinedOrNull(scopeId); // If service is unscoped, enable by default + } + + onScopeDeactivated(): void { + this.isActive = false; + } + + onScopeActivated(): void { + this.isActive = true; + + // Return early if progress state indicates that progress is done + if (this.progressState.type === ProgressIndicatorState.Done.type) { + return; + } + + // Replay Infinite Progress from Promise + if (this.progressState.type === ProgressIndicatorState.Type.While) { + let delay: number | undefined; + if (this.progressState.whileDelay > 0) { + const remainingDelay = this.progressState.whileDelay - (Date.now() - this.progressState.whileStart); + if (remainingDelay > 0) { + delay = remainingDelay; + } + } + + this.doShowWhile(delay); + } + + // Replay Infinite Progress + else if (this.progressState.type === ProgressIndicatorState.Type.Infinite) { + this.progressbar.infinite().show(); + } + + // Replay Finite Progress (Total & Worked) + else if (this.progressState.type === ProgressIndicatorState.Type.Work) { + if (this.progressState.total) { + this.progressbar.total(this.progressState.total).show(); + } + + if (this.progressState.worked) { + this.progressbar.worked(this.progressState.worked).show(); + } + } + } + + show(infinite: true, delay?: number): IProgressRunner; + show(total: number, delay?: number): IProgressRunner; + show(infiniteOrTotal: true | number, delay?: number): IProgressRunner { + + // Sort out Arguments + if (typeof infiniteOrTotal === 'boolean') { + this.progressState = ProgressIndicatorState.Infinite; + } else { + this.progressState = new ProgressIndicatorState.Work(infiniteOrTotal, undefined); + } + + // Active: Show Progress + if (this.isActive) { + + // Infinite: Start Progressbar and Show after Delay + if (this.progressState.type === ProgressIndicatorState.Type.Infinite) { + this.progressbar.infinite().show(delay); + } + + // Finite: Start Progressbar and Show after Delay + else if (this.progressState.type === ProgressIndicatorState.Type.Work && typeof this.progressState.total === 'number') { + this.progressbar.total(this.progressState.total).show(delay); + } + } + + return { + total: (total: number) => { + this.progressState = new ProgressIndicatorState.Work( + total, + this.progressState.type === ProgressIndicatorState.Type.Work ? this.progressState.worked : undefined); + + if (this.isActive) { + this.progressbar.total(total); + } + }, + + worked: (worked: number) => { + + // Verify first that we are either not active or the progressbar has a total set + if (!this.isActive || this.progressbar.hasTotal()) { + this.progressState = new ProgressIndicatorState.Work( + this.progressState.type === ProgressIndicatorState.Type.Work ? this.progressState.total : undefined, + this.progressState.type === ProgressIndicatorState.Type.Work && typeof this.progressState.worked === 'number' ? this.progressState.worked + worked : worked); + + if (this.isActive) { + this.progressbar.worked(worked); + } + } + + // Otherwise the progress bar does not support worked(), we fallback to infinite() progress + else { + this.progressState = ProgressIndicatorState.Infinite; + this.progressbar.infinite().show(); + } + }, + + done: () => { + this.progressState = ProgressIndicatorState.Done; + + if (this.isActive) { + this.progressbar.stop().hide(); + } + } + }; + } + + async showWhile(promise: Promise, delay?: number): Promise { + + // Join with existing running promise to ensure progress is accurate + if (this.progressState.type === ProgressIndicatorState.Type.While) { + promise = Promise.all([promise, this.progressState.whilePromise]); + } + + // Keep Promise in State + this.progressState = new ProgressIndicatorState.While(promise, delay || 0, Date.now()); + + try { + this.doShowWhile(delay); + + await promise; + } catch (error) { + // ignore + } finally { + + // If this is not the last promise in the list of joined promises, skip this + if (this.progressState.type !== ProgressIndicatorState.Type.While || this.progressState.whilePromise === promise) { + + // The while promise is either null or equal the promise we last hooked on + this.progressState = ProgressIndicatorState.None; + + if (this.isActive) { + this.progressbar.stop().hide(); + } + } + } + } + + private doShowWhile(delay?: number): void { + + // Show Progress when active + if (this.isActive) { + this.progressbar.infinite().show(delay); + } + } +} diff --git a/src/vs/workbench/services/progress/browser/progressService.ts b/src/vs/workbench/services/progress/browser/progressService.ts index a5dbd5190e2..d7bb38745a1 100644 --- a/src/vs/workbench/services/progress/browser/progressService.ts +++ b/src/vs/workbench/services/progress/browser/progressService.ts @@ -6,8 +6,8 @@ import 'vs/css!./media/progressService'; import { localize } from 'vs/nls'; -import { IDisposable, dispose, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; -import { IProgressService, IProgressOptions, IProgressStep, ProgressLocation, IProgress, emptyProgress, Progress, IProgressCompositeOptions, IProgressNotificationOptions } from 'vs/platform/progress/common/progress'; +import { IDisposable, dispose, DisposableStore, MutableDisposable, Disposable } from 'vs/base/common/lifecycle'; +import { IProgressService, IProgressOptions, IProgressStep, ProgressLocation, IProgress, Progress, IProgressCompositeOptions, IProgressNotificationOptions, IProgressRunner, IProgressIndicator } from 'vs/platform/progress/common/progress'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { StatusbarAlignment, IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; import { timeout } from 'vs/base/common/async'; @@ -24,34 +24,37 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { EventHelper } from 'vs/base/browser/dom'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; -export class ProgressService implements IProgressService, IDisposable { +export class ProgressService extends Disposable implements IProgressService { _serviceBrand: ServiceIdentifier; - private readonly _stack: [IProgressOptions, Progress][] = []; - private readonly _globalStatusEntry = new MutableDisposable(); + private readonly stack: [IProgressOptions, Progress][] = []; + private readonly globalStatusEntry = this._register(new MutableDisposable()); constructor( - @IActivityService private readonly _activityBar: IActivityService, - @IViewletService private readonly _viewletService: IViewletService, - @INotificationService private readonly _notificationService: INotificationService, - @IStatusbarService private readonly _statusbarService: IStatusbarService, - @ILayoutService private readonly _layoutService: ILayoutService, - @IThemeService private readonly _themeService: IThemeService, - @IKeybindingService private readonly _keybindingService: IKeybindingService - ) { } - - dispose() { - this._globalStatusEntry.dispose(); + @IActivityService private readonly activityService: IActivityService, + @IViewletService private readonly viewletService: IViewletService, + @IPanelService private readonly panelService: IPanelService, + @INotificationService private readonly notificationService: INotificationService, + @IStatusbarService private readonly statusbarService: IStatusbarService, + @ILayoutService private readonly layoutService: ILayoutService, + @IThemeService private readonly themeService: IThemeService, + @IKeybindingService private readonly keybindingService: IKeybindingService + ) { + super(); } withProgress(options: IProgressOptions, task: (progress: IProgress) => Promise, onDidCancel?: () => void): Promise { const { location } = options; if (typeof location === 'string') { - const viewlet = this._viewletService.getViewlet(location); - if (viewlet) { - return this._withViewletProgress(location, task, { ...options, location }); + if (this.viewletService.getProgressIndicator(location)) { + return this.withViewletProgress(location, task, { ...options, location }); + } + + if (this.panelService.getProgressIndicator(location)) { + return this.withPanelProgress(location, task, { ...options, location }); } return Promise.reject(new Error(`Bad progress location: ${location}`)); @@ -59,40 +62,40 @@ export class ProgressService implements IProgressService, IDisposable { switch (location) { case ProgressLocation.Notification: - return this._withNotificationProgress({ ...options, location }, task, onDidCancel); + return this.withNotificationProgress({ ...options, location }, task, onDidCancel); case ProgressLocation.Window: - return this._withWindowProgress(options, task); + return this.withWindowProgress(options, task); case ProgressLocation.Explorer: - return this._withViewletProgress('workbench.view.explorer', task, { ...options, location }); + return this.withViewletProgress('workbench.view.explorer', task, { ...options, location }); case ProgressLocation.Scm: - return this._withViewletProgress('workbench.view.scm', task, { ...options, location }); + return this.withViewletProgress('workbench.view.scm', task, { ...options, location }); case ProgressLocation.Extensions: - return this._withViewletProgress('workbench.view.extensions', task, { ...options, location }); + return this.withViewletProgress('workbench.view.extensions', task, { ...options, location }); case ProgressLocation.Dialog: - return this._withDialogProgress(options, task, onDidCancel); + return this.withDialogProgress(options, task, onDidCancel); default: return Promise.reject(new Error(`Bad progress location: ${location}`)); } } - private _withWindowProgress(options: IProgressOptions, callback: (progress: IProgress<{ message?: string }>) => Promise): Promise { - const task: [IProgressOptions, Progress] = [options, new Progress(() => this._updateWindowProgress())]; + private withWindowProgress(options: IProgressOptions, callback: (progress: IProgress<{ message?: string }>) => Promise): Promise { + const task: [IProgressOptions, Progress] = [options, new Progress(() => this.updateWindowProgress())]; const promise = callback(task[1]); let delayHandle: any = setTimeout(() => { delayHandle = undefined; - this._stack.unshift(task); - this._updateWindowProgress(); + this.stack.unshift(task); + this.updateWindowProgress(); // show progress for at least 150ms Promise.all([ timeout(150), promise ]).finally(() => { - const idx = this._stack.indexOf(task); - this._stack.splice(idx, 1); - this._updateWindowProgress(); + const idx = this.stack.indexOf(task); + this.stack.splice(idx, 1); + this.updateWindowProgress(); }); }, 150); @@ -100,11 +103,11 @@ export class ProgressService implements IProgressService, IDisposable { return promise.finally(() => clearTimeout(delayHandle)); } - private _updateWindowProgress(idx: number = 0) { - this._globalStatusEntry.clear(); + private updateWindowProgress(idx: number = 0) { + this.globalStatusEntry.clear(); - if (idx < this._stack.length) { - const [options, progress] = this._stack[idx]; + if (idx < this.stack.length) { + const [options, progress] = this.stack[idx]; let progressTitle = options.title; let progressMessage = progress.value && progress.value.message; @@ -128,18 +131,18 @@ export class ProgressService implements IProgressService, IDisposable { } else { // no title, no message -> no progress. try with next on stack - this._updateWindowProgress(idx + 1); + this.updateWindowProgress(idx + 1); return; } - this._globalStatusEntry.value = this._statusbarService.addEntry({ + this.globalStatusEntry.value = this.statusbarService.addEntry({ text: `$(sync~spin) ${text}`, tooltip: title }, 'status.progress', localize('status.progress', "Progress Message"), StatusbarAlignment.LEFT); } } - private _withNotificationProgress

, R = unknown>(options: IProgressNotificationOptions, callback: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P { + private withNotificationProgress

, R = unknown>(options: IProgressNotificationOptions, callback: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P { const toDispose = new DisposableStore(); const createNotification = (message: string | undefined, increment?: number): INotificationHandle | undefined => { @@ -169,7 +172,7 @@ export class ProgressService implements IProgressService, IDisposable { } const actions: INotificationActions = { primary: primaryActions, secondary: secondaryActions }; - const handle = this._notificationService.notify({ + const handle = this.notificationService.notify({ severity: Severity.Info, message, source: options.source, @@ -236,21 +239,17 @@ export class ProgressService implements IProgressService, IDisposable { return promise; } - private _withViewletProgress

, R = unknown>(viewletId: string, task: (progress: IProgress<{ message?: string }>) => P, options: IProgressCompositeOptions): P { - const promise = task(emptyProgress); + private withViewletProgress

, R = unknown>(viewletId: string, task: (progress: IProgress) => P, options: IProgressCompositeOptions): P { // show in viewlet - const viewletProgress = this._viewletService.getProgressIndicator(viewletId); - if (viewletProgress) { - viewletProgress.showWhile(promise, options.delay); - } + const promise = this.withCompositeProgress(this.viewletService.getProgressIndicator(viewletId), task, options); // show activity bar let activityProgress: IDisposable; let delayHandle: any = setTimeout(() => { delayHandle = undefined; - const handle = this._activityBar.showActivity( + const handle = this.activityService.showActivity( viewletId, new ProgressBadge(() => ''), 'progress-badge', @@ -281,7 +280,44 @@ export class ProgressService implements IProgressService, IDisposable { return promise; } - private _withDialogProgress

, R = unknown>(options: IProgressOptions, task: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P { + private withPanelProgress

, R = unknown>(panelid: string, task: (progress: IProgress) => P, options: IProgressCompositeOptions): P { + + // show in panel + return this.withCompositeProgress(this.panelService.getProgressIndicator(panelid), task, options); + } + + private withCompositeProgress

, R = unknown>(progressIndicator: IProgressIndicator | null, task: (progress: IProgress) => P, options: IProgressCompositeOptions): P { + let progressRunner: IProgressRunner | undefined = undefined; + + const promise = task({ + report: progress => { + if (!progressRunner) { + return; + } + + if (typeof progress.increment === 'number') { + progressRunner.worked(progress.increment); + } + + if (typeof progress.total === 'number') { + progressRunner.total(progress.total); + } + } + }); + + if (progressIndicator) { + if (typeof options.total === 'number') { + progressRunner = progressIndicator.show(options.total, options.delay); + promise.catch(() => undefined /* ignore */).finally(() => progressRunner ? progressRunner.done() : undefined); + } else { + progressIndicator.showWhile(promise, options.delay); + } + } + + return promise; + } + + private withDialogProgress

, R = unknown>(options: IProgressOptions, task: (progress: IProgress) => P, onDidCancel?: () => void): P { const disposables = new DisposableStore(); const allowableCommands = [ 'workbench.action.quit', @@ -292,13 +328,13 @@ export class ProgressService implements IProgressService, IDisposable { const createDialog = (message: string) => { dialog = new Dialog( - this._layoutService.container, + this.layoutService.container, message, [options.cancellable ? localize('cancel', "Cancel") : localize('dismiss', "Dismiss")], { type: 'pending', keyEventProcessor: (event: StandardKeyboardEvent) => { - const resolved = this._keybindingService.softDispatch(event, this._layoutService.container); + const resolved = this.keybindingService.softDispatch(event, this.layoutService.container); if (resolved && resolved.commandId) { if (allowableCommands.indexOf(resolved.commandId) === -1) { EventHelper.stop(event, true); @@ -309,7 +345,7 @@ export class ProgressService implements IProgressService, IDisposable { ); disposables.add(dialog); - disposables.add(attachDialogStyler(dialog, this._themeService)); + disposables.add(attachDialogStyler(dialog, this.themeService)); dialog.show().then(() => { if (typeof onDidCancel === 'function') { diff --git a/src/vs/workbench/services/progress/test/localProgressService.test.ts b/src/vs/workbench/services/progress/test/progressIndicator.test.ts similarity index 66% rename from src/vs/workbench/services/progress/test/localProgressService.test.ts rename to src/vs/workbench/services/progress/test/progressIndicator.test.ts index dad585ef4f0..a8d2b740d0b 100644 --- a/src/vs/workbench/services/progress/test/localProgressService.test.ts +++ b/src/vs/workbench/services/progress/test/progressIndicator.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { IAction, IActionViewItem } from 'vs/base/common/actions'; import { IEditorControl } from 'vs/workbench/common/editor'; -import { ScopedProgressService, ScopedService } from 'vs/workbench/services/progress/browser/localProgressService'; +import { CompositeScope, CompositeProgressIndicator } from 'vs/workbench/services/progress/browser/progressIndicator'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IViewlet } from 'vs/workbench/common/viewlet'; @@ -16,106 +16,55 @@ class TestViewlet implements IViewlet { constructor(private id: string) { } - getId(): string { - return this.id; - } - - /** - * Returns the name of this composite to show in the title area. - */ - getTitle(): string { - return this.id; - } - - /** - * Returns the primary actions of the composite. - */ - getActions(): IAction[] { - return []; - } - - /** - * Returns the secondary actions of the composite. - */ - getSecondaryActions(): IAction[] { - return []; - } - - /** - * Returns an array of actions to show in the context menu of the composite - */ - public getContextMenuActions(): IAction[] { - return []; - } - - /** - * Returns the action item for a specific action. - */ - getActionViewItem(action: IAction): IActionViewItem { - return null!; - } - - /** - * Returns the underlying control of this composite. - */ - getControl(): IEditorControl { - return null!; - } - - /** - * Asks the underlying control to focus. - */ - focus(): void { - } - - getOptimalWidth(): number { - return 10; - } + getId(): string { return this.id; } + getTitle(): string { return this.id; } + getActions(): IAction[] { return []; } + getSecondaryActions(): IAction[] { return []; } + getContextMenuActions(): IAction[] { return []; } + getActionViewItem(action: IAction): IActionViewItem { return null!; } + getControl(): IEditorControl { return null!; } + focus(): void { } + getOptimalWidth(): number { return 10; } } -class TestScopedService extends ScopedService { - public isActive: boolean; +class TestCompositeScope extends CompositeScope { + isActive: boolean; constructor(viewletService: IViewletService, panelService: IPanelService, scopeId: string) { super(viewletService, panelService, scopeId); } - public onScopeActivated() { - this.isActive = true; - } - public onScopeDeactivated() { - this.isActive = false; - } + onScopeActivated() { this.isActive = true; } + onScopeDeactivated() { this.isActive = false; } } class TestProgressBar { - public fTotal: number; - public fWorked: number; - public fInfinite: boolean; - public fDone: boolean; + fTotal: number; + fWorked: number; + fInfinite: boolean; + fDone: boolean; - constructor() { - } + constructor() { } - public infinite() { + infinite() { this.fDone = null!; this.fInfinite = true; return this; } - public total(total: number) { + total(total: number) { this.fDone = null!; this.fTotal = total; return this; } - public hasTotal() { + hasTotal() { return !!this.fTotal; } - public worked(worked: number) { + worked(worked: number) { this.fDone = null!; if (this.fWorked) { @@ -127,7 +76,7 @@ class TestProgressBar { return this; } - public done() { + done() { this.fDone = true; this.fInfinite = null!; @@ -137,25 +86,21 @@ class TestProgressBar { return this; } - public stop() { + stop() { return this.done(); } - public show(): void { + show(): void { } - } - - public hide(): void { - - } + hide(): void { } } -suite('Progress Service', () => { +suite('Progress Indicator', () => { - test('ScopedService', () => { + test('CompositeScope', () => { let viewletService = new TestViewletService(); let panelService = new TestPanelService(); - let service = new TestScopedService(viewletService, panelService, 'test.scopeId'); + let service = new TestCompositeScope(viewletService, panelService, 'test.scopeId'); const testViewlet = new TestViewlet('test.scopeId'); assert(!service.isActive); @@ -167,11 +112,11 @@ suite('Progress Service', () => { }); - test('WorkbenchProgressService', async () => { + test('CompositeProgressIndicator', async () => { let testProgressBar = new TestProgressBar(); let viewletService = new TestViewletService(); let panelService = new TestPanelService(); - let service = new ScopedProgressService((testProgressBar), 'test.scopeId', true, viewletService, panelService); + let service = new CompositeProgressIndicator((testProgressBar), 'test.scopeId', true, viewletService, panelService); // Active: Show (Infinite) let fn = service.show(true); diff --git a/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts b/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts index 3f2d25705ad..ee8b3c9b9d2 100644 --- a/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts +++ b/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IRemoteAgentConnection } from 'vs/workbench/services/remote/common/remoteAgentService'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { AbstractRemoteAgentService, RemoteAgentConnection } from 'vs/workbench/services/remote/common/abstractRemoteAgentService'; @@ -16,14 +16,14 @@ export class RemoteAgentService extends AbstractRemoteAgentService { private readonly _connection: IRemoteAgentConnection | null = null; constructor( - @IEnvironmentService environmentService: IEnvironmentService, + @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, @IProductService productService: IProductService, @IRemoteAuthorityResolverService remoteAuthorityResolverService: IRemoteAuthorityResolverService, @ISignService signService: ISignService ) { super(environmentService); - const authority = document.location.host; - this._connection = this._register(new RemoteAgentConnection(authority, productService.commit, browserWebSocketFactory, environmentService, remoteAuthorityResolverService, signService)); + + this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.commit, browserWebSocketFactory, environmentService, remoteAuthorityResolverService, signService)); } getConnection(): IRemoteAgentConnection | null { diff --git a/src/vs/workbench/services/search/common/searchService.ts b/src/vs/workbench/services/search/common/searchService.ts index 7051709d15f..53a81175157 100644 --- a/src/vs/workbench/services/search/common/searchService.ts +++ b/src/vs/workbench/services/search/common/searchService.ts @@ -20,6 +20,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { deserializeSearchError, FileMatch, ICachedSearchStats, IFileMatch, IFileQuery, IFileSearchStats, IFolderQuery, IProgressMessage, ISearchComplete, ISearchEngineStats, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, ITextQuery, pathIncludedInQuery, QueryType, SearchError, SearchErrorCode, SearchProviderType, isFileMatch, isProgressMessage } from 'vs/workbench/services/search/common/search'; import { addContextToEditorMatches, editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class SearchService extends Disposable implements ISearchService { _serviceBrand: any; @@ -249,22 +250,33 @@ export class SearchService extends Disposable implements ISearchService { if (fileSearchStats.fromCache) { const cacheStats: ICachedSearchStats = fileSearchStats.detailStats as ICachedSearchStats; - /* __GDPR__ - "cachedSearchComplete" : { - "reason" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "resultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "workspaceFolderCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "endToEndTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "sortingTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cacheWasResolved" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "cacheLookupTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cacheFilterTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cacheEntryCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "scheme" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } - } - */ - this.telemetryService.publicLog('cachedSearchComplete', { + type CachedSearchCompleteClassifcation = { + reason?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + resultCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + workspaceFolderCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + endToEndTime: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + sortingTime?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + cacheWasResolved: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + cacheLookupTime: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + cacheFilterTime: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + cacheEntryCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + scheme: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + }; + type CachedSearchCompleteEvent = { + reason?: string; + resultCount: number; + workspaceFolderCount: number; + type: 'fileSearchProvider' | 'searchProcess'; + endToEndTime: number; + sortingTime?: number; + cacheWasResolved: boolean; + cacheLookupTime: number; + cacheFilterTime: number; + cacheEntryCount: number; + scheme: string; + }; + this.telemetryService.publicLog2('cachedSearchComplete', { reason: query._reason, resultCount: fileSearchStats.resultCount, workspaceFolderCount: query.folderQueries.length, @@ -280,23 +292,37 @@ export class SearchService extends Disposable implements ISearchService { } else { const searchEngineStats: ISearchEngineStats = fileSearchStats.detailStats as ISearchEngineStats; - /* __GDPR__ - "searchComplete" : { - "reason" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "resultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "workspaceFolderCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "endToEndTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "sortingTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "fileWalkTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "directoriesWalked" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "filesWalked" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cmdTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "cmdResultCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "scheme" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } - } - */ - this.telemetryService.publicLog('searchComplete', { + type SearchCompleteClassification = { + reason?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + resultCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + workspaceFolderCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + endToEndTime: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + sortingTime?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + fileWalkTime: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + directoriesWalked: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + filesWalked: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + cmdTime: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + cmdResultCount?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + scheme: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + }; + type SearchCompleteEvent = { + reason?: string; + resultCount: number; + workspaceFolderCount: number; + type: 'fileSearchProvider' | 'searchProcess'; + endToEndTime: number; + sortingTime?: number; + fileWalkTime: number + directoriesWalked: number; + filesWalked: number; + cmdTime: number; + cmdResultCount?: number; + scheme: string; + + }; + + this.telemetryService.publicLog2('searchComplete', { reason: query._reason, resultCount: fileSearchStats.resultCount, workspaceFolderCount: query.folderQueries.length, @@ -322,18 +348,23 @@ export class SearchService extends Disposable implements ISearchService { 'unknown'; } - /* __GDPR__ - "textSearchComplete" : { - "reason" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "workspaceFolderCount" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "endToEndTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, - "scheme" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "error" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "useRipgrep" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "usePCRE2" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } - } - */ - this.telemetryService.publicLog('textSearchComplete', { + type TextSearchCompleteClassification = { + reason?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + workspaceFolderCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + endToEndTime: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; + scheme: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + error?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + usePCRE2: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' }; + }; + type TextSearchCompleteEvent = { + reason?: string; + workspaceFolderCount: number; + endToEndTime: number; + scheme: string; + error?: string; + usePCRE2: boolean; + }; + this.telemetryService.publicLog2('textSearchComplete', { reason: query._reason, workspaceFolderCount: query.folderQueries.length, endToEndTime: endToEndTime, @@ -421,3 +452,4 @@ export class RemoteSearchService extends SearchService { } } +registerSingleton(ISearchService, RemoteSearchService, true); diff --git a/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts b/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts index 12e027284d5..ee39b55b8e8 100644 --- a/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts +++ b/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts @@ -121,9 +121,10 @@ export class RipgrepTextSearchEngine { * "failed" when a fatal error was produced. */ export function rgErrorMsgForDisplay(msg: string): Maybe { - const firstLine = msg.split('\n')[0].trim(); + const lines = msg.split('\n'); + const firstLine = lines[0].trim(); - if (startsWith(firstLine, 'regex parse error')) { + if (lines.some(l => startsWith(l, 'regex parse error'))) { return new SearchError('Regex parse error', SearchErrorCode.regexParseError); } @@ -209,7 +210,7 @@ export class RipgrepParser extends EventEmitter { newlineIdx = dataStr.indexOf('\n', prevIdx); } - this.remainder = dataStr.substring(prevIdx).trim(); + this.remainder = dataStr.substring(prevIdx); } private handleLine(outputLine: string): void { @@ -409,24 +410,25 @@ function getRgArgs(query: TextSearchQuery, options: TextSearchOptions): string[] if ((options).usePCRE2) { args.push('--pcre2'); - - if (query.isRegExp) { - pattern = unicodeEscapesToPCRE2(pattern); - } } + if (query.isRegExp) { + pattern = unicodeEscapesToPCRE2(pattern); + } + + // Allow $ to match /r/n + args.push('--crlf'); + let searchPatternAfterDoubleDashes: Maybe; if (query.isWordMatch) { const regexp = createRegExp(pattern, !!query.isRegExp, { wholeWord: query.isWordMatch }); const regexpStr = regexp.source.replace(/\\\//g, '/'); // RegExp.source arbitrarily returns escaped slashes. Search and destroy. args.push('--regexp', regexpStr); } else if (query.isRegExp) { - let fixedRegexpQuery = fixRegexEndingPattern(query.pattern); - fixedRegexpQuery = fixRegexNewline(fixedRegexpQuery); + let fixedRegexpQuery = fixRegexNewline(query.pattern); fixedRegexpQuery = fixNewline(fixedRegexpQuery); - fixedRegexpQuery = fixRegexCRMatchingNonWordClass(fixedRegexpQuery, !!query.isMultiline); - fixedRegexpQuery = fixRegexCRMatchingWhitespaceClass(fixedRegexpQuery, !!query.isMultiline); args.push('--regexp', fixedRegexpQuery); + args.push('--auto-hybrid-regex'); } else { searchPatternAfterDoubleDashes = pattern; args.push('--fixed-strings'); @@ -508,32 +510,12 @@ export interface IRgSubmatch { export type IRgBytesOrText = { bytes: string } | { text: string }; -export function fixRegexEndingPattern(pattern: string): string { - // Replace an unescaped $ at the end of the pattern with \r?$ - // Match $ preceeded by none or even number of literal \ - return pattern.match(/([^\\]|^)(\\\\)*\$$/) ? - pattern.replace(/\$$/, '\\r?$') : - pattern; -} - export function fixRegexNewline(pattern: string): string { // Replace an unescaped $ at the end of the pattern with \r?$ // Match $ preceeded by none or even number of literal \ return pattern.replace(/([^\\]|^)(\\\\)*\\n/g, '$1$2\\r?\\n'); } -export function fixRegexCRMatchingWhitespaceClass(pattern: string, isMultiline: boolean): string { - return isMultiline ? - pattern.replace(/([^\\]|^)((?:\\\\)*)\\s/g, '$1$2(\\r?\\n|[^\\S\\r])') : - pattern.replace(/([^\\]|^)((?:\\\\)*)\\s/g, '$1$2[ \\t\\f]'); -} - -export function fixRegexCRMatchingNonWordClass(pattern: string, isMultiline: boolean): string { - return isMultiline ? - pattern.replace(/([^\\]|^)((?:\\\\)*)\\W/g, '$1$2(\\r?\\n|[^\\w\\r])') : - pattern.replace(/([^\\]|^)((?:\\\\)*)\\W/g, '$1$2[^\\w\\r]'); -} - export function fixNewline(pattern: string): string { return pattern.replace(/\n/g, '\\r?\\n'); } diff --git a/src/vs/workbench/services/search/test/node/ripgrepTextSearchEngine.test.ts b/src/vs/workbench/services/search/test/node/ripgrepTextSearchEngine.test.ts index 262074bf079..fb307c68bfd 100644 --- a/src/vs/workbench/services/search/test/node/ripgrepTextSearchEngine.test.ts +++ b/src/vs/workbench/services/search/test/node/ripgrepTextSearchEngine.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { joinPath } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; -import { fixRegexCRMatchingNonWordClass, fixRegexCRMatchingWhitespaceClass, fixRegexEndingPattern, fixRegexNewline, IRgMatch, IRgMessage, RipgrepParser, unicodeEscapesToPCRE2, fixNewline } from 'vs/workbench/services/search/node/ripgrepTextSearchEngine'; +import { fixRegexNewline, IRgMatch, IRgMessage, RipgrepParser, unicodeEscapesToPCRE2, fixNewline } from 'vs/workbench/services/search/node/ripgrepTextSearchEngine'; import { Range, TextSearchResult } from 'vs/workbench/services/search/common/searchExtTypes'; suite('RipgrepTextSearchEngine', () => { @@ -24,70 +24,6 @@ suite('RipgrepTextSearchEngine', () => { assert.equal(unicodeEscapesToPCRE2(''), ''); }); - test('fixRegexEndingPattern', () => { - function testFixRegexEndingPattern([input, expectedResult]: string[]): void { - assert.equal(fixRegexEndingPattern(input), expectedResult); - } - - [ - ['foo', 'foo'], - ['', ''], - ['^foo.*bar\\s+', '^foo.*bar\\s+'], - ['foo$', 'foo\\r?$'], - ['$', '\\r?$'], - ['foo\\$', 'foo\\$'], - ['foo\\\\$', 'foo\\\\\\r?$'], - ].forEach(testFixRegexEndingPattern); - }); - - test('fixRegexCRMatchingWhitespaceClass', () => { - function testFixRegexCRMatchingWhitespaceClass([inputReg, isMultiline, testStr, shouldMatch]: [string, boolean, string, boolean]): void { - const fixed = fixRegexCRMatchingWhitespaceClass(inputReg, isMultiline); - const reg = new RegExp(fixed); - assert.equal(reg.test(testStr), shouldMatch, `${inputReg} => ${reg}, ${testStr}, ${shouldMatch}`); - } - - [ - ['foo', false, 'foo', true], - - ['foo\\s', false, 'foo\r\n', false], - ['foo\\sabc', true, 'foo\r\nabc', true], - - ['foo\\s', false, 'foo\n', false], - ['foo\\s', true, 'foo\n', true], - - ['foo\\s\\n', true, 'foo\r\n', false], - ['foo\\r\\s', true, 'foo\r\n', true], - - ['foo\\s+abc', true, 'foo \r\nabc', true], - ['foo\\s+abc', false, 'foo \t abc', true], - ].forEach(testFixRegexCRMatchingWhitespaceClass); - }); - - test('fixRegexCRMatchingNonWordClass', () => { - function testRegexCRMatchingNonWordClass([inputReg, isMultiline, testStr, shouldMatch]: [string, boolean, string, boolean]): void { - const fixed = fixRegexCRMatchingNonWordClass(inputReg, isMultiline); - const reg = new RegExp(fixed); - assert.equal(reg.test(testStr), shouldMatch, `${inputReg} => ${reg}, ${testStr}, ${shouldMatch}`); - } - - [ - ['foo', false, 'foo', true], - - ['foo\\W', false, 'foo\r\n', false], - ['foo\\Wabc', true, 'foo\r\nabc', true], - - ['foo\\W', false, 'foo\n', true], - ['foo\\W', true, 'foo\n', true], - - ['foo\\W\\n', true, 'foo\r\n', false], - ['foo\\r\\W', true, 'foo\r\n', true], - - ['foo\\W+abc', true, 'foo \r\nabc', true], - ['foo\\W+abc', false, 'foo .-\t abc', true], - ].forEach(testRegexCRMatchingNonWordClass); - }); - test('fixRegexNewline', () => { function testFixRegexNewline([inputReg, testStr, shouldMatch]: [string, string, boolean]): void { const fixed = fixRegexNewline(inputReg); @@ -223,15 +159,16 @@ suite('RipgrepTextSearchEngine', () => { test('chopped-up input chunks', () => { const dataStrs = [ - makeRgMatch('file1.js', 'foobar', 4, [{ start: 3, end: 6 }]), + makeRgMatch('file1.js', 'foo bar', 4, [{ start: 3, end: 7 }]), makeRgMatch('app/file2.js', 'foobar', 4, [{ start: 3, end: 6 }]), makeRgMatch('app2/file3.js', 'foobar', 4, [{ start: 3, end: 6 }]), ]; + const dataStr0Space = dataStrs[0].indexOf(' '); testParser( [ - dataStrs[0].substring(0, 5), - dataStrs[0].substring(5), + dataStrs[0].substring(0, dataStr0Space + 1), + dataStrs[0].substring(dataStr0Space + 1), '\n', dataStrs[1].trim(), '\n' + dataStrs[2].substring(0, 25), @@ -240,11 +177,11 @@ suite('RipgrepTextSearchEngine', () => { [ { preview: { - text: 'foobar', - matches: [new Range(0, 3, 0, 6)] + text: 'foo bar', + matches: [new Range(0, 3, 0, 7)] }, uri: joinPath(TEST_FOLDER, 'file1.js'), - ranges: [new Range(3, 3, 3, 6)] + ranges: [new Range(3, 3, 3, 7)] }, { preview: { diff --git a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts index b751b3b0c15..6f39df77250 100644 --- a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts +++ b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts @@ -378,7 +378,7 @@ suite('Search-integration', function () { folderQueries: ROOT_FOLDER_QUERY, contentPattern: { pattern: 'foo' }, includePattern: { - '***': true + '{{}': true } }; @@ -386,26 +386,10 @@ suite('Search-integration', function () { throw new Error('expected fail'); }, err => { const searchError = deserializeSearchError(err.message); - assert.equal(searchError.message, 'Error parsing glob \'***\': invalid use of **; must be one path component'); + assert.equal(searchError.message, 'Error parsing glob \'/{{}\': nested alternate groups are not allowed'); assert.equal(searchError.code, SearchErrorCode.globParseError); }); }); - - test('invalid literal', () => { - const config: ITextQuery = { - type: QueryType.Text, - folderQueries: ROOT_FOLDER_QUERY, - contentPattern: { pattern: 'foo\nbar', isRegExp: true } - }; - - return doSearchTest(config, 0).then(() => { - throw new Error('expected fail'); - }, err => { - const searchError = deserializeSearchError(err.message); - assert.equal(searchError.message, 'The literal \'"\\n"\' is not allowed in a regex'); - assert.equal(searchError.code, SearchErrorCode.invalidLiteral); - }); - }); }); }); diff --git a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts index c445313f091..5583a243cb2 100644 --- a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts @@ -16,6 +16,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/node/workbenchCommonProperties'; import { TelemetryService as BaseTelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; export class TelemetryService extends Disposable implements ITelemetryService { @@ -59,6 +60,10 @@ export class TelemetryService extends Disposable implements ITelemetryService { return this.impl.publicLog(eventName, data, anonymizeFilePaths); } + publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean) { + return this.publicLog(eventName, data as ITelemetryData, anonymizeFilePaths); + } + getTelemetryInfo(): Promise { return this.impl.getTelemetryInfo(); } diff --git a/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts b/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts index 316a6f97a50..1259cec8914 100644 --- a/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts +++ b/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts @@ -12,7 +12,7 @@ import * as resources from 'vs/base/common/resources'; import * as types from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { TokenizationResult, TokenizationResult2 } from 'vs/editor/common/core/token'; -import { IState, ITokenizationSupport, LanguageId, TokenMetadata, TokenizationRegistry } from 'vs/editor/common/modes'; +import { IState, ITokenizationSupport, LanguageId, TokenMetadata, TokenizationRegistry, StandardTokenType, LanguageIdentifier } from 'vs/editor/common/modes'; import { nullTokenize2 } from 'vs/editor/common/modes/nullMode'; import { generateTokensCSSForColorMap } from 'vs/editor/common/modes/supports/tokenization'; import { IModeService } from 'vs/editor/common/services/modeService'; @@ -20,122 +20,14 @@ import { IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ExtensionMessageCollector } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { IEmbeddedLanguagesMap, ITMSyntaxExtensionPoint, TokenTypesContribution, grammarsExtPoint } from 'vs/workbench/services/textMate/common/TMGrammars'; +import { ITMSyntaxExtensionPoint, grammarsExtPoint } from 'vs/workbench/services/textMate/common/TMGrammars'; import { ITextMateService } from 'vs/workbench/services/textMate/common/textMateService'; -import { ITokenColorizationRule, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; -import { IEmbeddedLanguagesMap as IEmbeddedLanguagesMap2, IGrammar, ITokenTypeMap, Registry, StackElement, StandardTokenType, RegistryOptions, IRawGrammar } from 'vscode-textmate'; +import { ITokenColorizationRule, IWorkbenchThemeService, IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { IGrammar, StackElement, IOnigLib, IRawTheme } from 'vscode-textmate'; import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; - -export class TMScopeRegistry extends Disposable { - - private _scopeNameToLanguageRegistration: { [scopeName: string]: TMLanguageRegistration; }; - private _encounteredLanguages: boolean[]; - - private readonly _onDidEncounterLanguage = this._register(new Emitter()); - public readonly onDidEncounterLanguage: Event = this._onDidEncounterLanguage.event; - - constructor() { - super(); - this.reset(); - } - - public reset(): void { - this._scopeNameToLanguageRegistration = Object.create(null); - this._encounteredLanguages = []; - } - - public register(scopeName: string, grammarLocation: URI, embeddedLanguages?: IEmbeddedLanguagesMap, tokenTypes?: TokenTypesContribution): void { - if (this._scopeNameToLanguageRegistration[scopeName]) { - const existingRegistration = this._scopeNameToLanguageRegistration[scopeName]; - if (!resources.isEqual(existingRegistration.grammarLocation, grammarLocation)) { - console.warn( - `Overwriting grammar scope name to file mapping for scope ${scopeName}.\n` + - `Old grammar file: ${existingRegistration.grammarLocation.toString()}.\n` + - `New grammar file: ${grammarLocation.toString()}` - ); - } - } - this._scopeNameToLanguageRegistration[scopeName] = new TMLanguageRegistration(scopeName, grammarLocation, embeddedLanguages, tokenTypes); - } - - public getLanguageRegistration(scopeName: string): TMLanguageRegistration { - return this._scopeNameToLanguageRegistration[scopeName] || null; - } - - public getGrammarLocation(scopeName: string): URI | null { - let data = this.getLanguageRegistration(scopeName); - return data ? data.grammarLocation : null; - } - - /** - * To be called when tokenization found/hit an embedded language. - */ - public onEncounteredLanguage(languageId: LanguageId): void { - if (!this._encounteredLanguages[languageId]) { - this._encounteredLanguages[languageId] = true; - this._onDidEncounterLanguage.fire(languageId); - } - } -} - -export class TMLanguageRegistration { - _topLevelScopeNameDataBrand: void; - - readonly scopeName: string; - readonly grammarLocation: URI; - readonly embeddedLanguages: IEmbeddedLanguagesMap; - readonly tokenTypes: ITokenTypeMap; - - constructor(scopeName: string, grammarLocation: URI, embeddedLanguages: IEmbeddedLanguagesMap | undefined, tokenTypes: TokenTypesContribution | undefined) { - this.scopeName = scopeName; - this.grammarLocation = grammarLocation; - - // embeddedLanguages handling - this.embeddedLanguages = Object.create(null); - - if (embeddedLanguages) { - // If embeddedLanguages are configured, fill in `this._embeddedLanguages` - let scopes = Object.keys(embeddedLanguages); - for (let i = 0, len = scopes.length; i < len; i++) { - let scope = scopes[i]; - let language = embeddedLanguages[scope]; - if (typeof language !== 'string') { - // never hurts to be too careful - continue; - } - this.embeddedLanguages[scope] = language; - } - } - - this.tokenTypes = Object.create(null); - if (tokenTypes) { - // If tokenTypes is configured, fill in `this._tokenTypes` - const scopes = Object.keys(tokenTypes); - for (const scope of scopes) { - const tokenType = tokenTypes[scope]; - switch (tokenType) { - case 'string': - this.tokenTypes[scope] = StandardTokenType.String; - break; - case 'other': - this.tokenTypes[scope] = StandardTokenType.Other; - break; - case 'comment': - this.tokenTypes[scope] = StandardTokenType.Comment; - break; - } - } - } - } -} - -interface ICreateGrammarResult { - languageId: LanguageId; - grammar: IGrammar; - initialState: StackElement; - containsEmbeddedLanguages: boolean; -} +import { IValidGrammarDefinition, IValidEmbeddedLanguagesMap, IValidTokenTypeMap } from 'vs/workbench/services/textMate/common/TMScopeRegistry'; +import { TMGrammarFactory } from 'vs/workbench/services/textMate/common/TMGrammarFactory'; export abstract class AbstractTextMateService extends Disposable implements ITextMateService { public _serviceBrand: any; @@ -145,20 +37,17 @@ export abstract class AbstractTextMateService extends Disposable implements ITex private readonly _styleElement: HTMLStyleElement; private readonly _createdModes: string[]; + private readonly _encounteredLanguages: boolean[]; - protected _scopeRegistry: TMScopeRegistry; - private _injections: { [scopeName: string]: string[]; }; - private _injectedEmbeddedLanguages: { [scopeName: string]: IEmbeddedLanguagesMap[]; }; - protected _languageToScope: Map; - private _grammarRegistry: Promise<[Registry, StackElement]> | null; + private _grammarDefinitions: IValidGrammarDefinition[] | null; + private _grammarFactory: TMGrammarFactory | null; private _tokenizersRegistrations: IDisposable[]; private _currentTokenColors: ITokenColorizationRule[] | null; - private _themeListener: IDisposable | null; constructor( @IModeService private readonly _modeService: IModeService, @IWorkbenchThemeService private readonly _themeService: IWorkbenchThemeService, - @IFileService private readonly _fileService: IFileService, + @IFileService protected readonly _fileService: IFileService, @INotificationService private readonly _notificationService: INotificationService, @ILogService private readonly _logService: ILogService, @IConfigurationService private readonly _configurationService: IConfigurationService @@ -167,33 +56,79 @@ export abstract class AbstractTextMateService extends Disposable implements ITex this._styleElement = dom.createStyleSheet(); this._styleElement.className = 'vscode-tokens-styles'; this._createdModes = []; - this._scopeRegistry = new TMScopeRegistry(); - this._scopeRegistry.onDidEncounterLanguage((language) => this._onDidEncounterLanguage.fire(language)); - this._injections = {}; - this._injectedEmbeddedLanguages = {}; - this._languageToScope = new Map(); - this._grammarRegistry = null; + this._encounteredLanguages = []; + + this._grammarDefinitions = null; + this._grammarFactory = null; this._tokenizersRegistrations = []; - this._currentTokenColors = null; - this._themeListener = null; grammarsExtPoint.setHandler((extensions) => { - this._scopeRegistry.reset(); - this._injections = {}; - this._injectedEmbeddedLanguages = {}; - this._languageToScope = new Map(); - this._grammarRegistry = null; - this._tokenizersRegistrations = dispose(this._tokenizersRegistrations); - this._currentTokenColors = null; - if (this._themeListener) { - this._themeListener.dispose(); - this._themeListener = null; + this._grammarDefinitions = null; + if (this._grammarFactory) { + this._grammarFactory.dispose(); + this._grammarFactory = null; + this._onDidDisposeGrammarFactory(); } + this._tokenizersRegistrations = dispose(this._tokenizersRegistrations); + this._grammarDefinitions = []; for (const extension of extensions) { - let grammars = extension.value; + const grammars = extension.value; for (const grammar of grammars) { - this._handleGrammarExtensionPointUser(extension.description.extensionLocation, grammar, extension.collector); + if (!this._validateGrammarExtensionPoint(extension.description.extensionLocation, grammar, extension.collector)) { + continue; + } + const grammarLocation = resources.joinPath(extension.description.extensionLocation, grammar.path); + + const embeddedLanguages: IValidEmbeddedLanguagesMap = Object.create(null); + if (grammar.embeddedLanguages) { + let scopes = Object.keys(grammar.embeddedLanguages); + for (let i = 0, len = scopes.length; i < len; i++) { + let scope = scopes[i]; + let language = grammar.embeddedLanguages[scope]; + if (typeof language !== 'string') { + // never hurts to be too careful + continue; + } + let languageIdentifier = this._modeService.getLanguageIdentifier(language); + if (languageIdentifier) { + embeddedLanguages[scope] = languageIdentifier.id; + } + } + } + + const tokenTypes: IValidTokenTypeMap = Object.create(null); + if (grammar.tokenTypes) { + const scopes = Object.keys(grammar.tokenTypes); + for (const scope of scopes) { + const tokenType = grammar.tokenTypes[scope]; + switch (tokenType) { + case 'string': + tokenTypes[scope] = StandardTokenType.String; + break; + case 'other': + tokenTypes[scope] = StandardTokenType.Other; + break; + case 'comment': + tokenTypes[scope] = StandardTokenType.Comment; + break; + } + } + } + + let languageIdentifier: LanguageIdentifier | null = null; + if (grammar.language) { + languageIdentifier = this._modeService.getLanguageIdentifier(grammar.language); + } + + this._grammarDefinitions.push({ + location: grammarLocation, + language: languageIdentifier ? languageIdentifier.id : undefined, + scopeName: grammar.scopeName, + embeddedLanguages: embeddedLanguages, + tokenTypes: tokenTypes, + injectTo: grammar.injectTo, + }); } } @@ -202,6 +137,12 @@ export abstract class AbstractTextMateService extends Disposable implements ITex } }); + this._register(this._themeService.onDidColorThemeChange(() => { + if (this._grammarFactory) { + this._updateTheme(this._grammarFactory, this._themeService.getColorTheme(), false); + } + })); + // Generate some color map until the grammar registry is loaded let colorTheme = this._themeService.getColorTheme(); let defaultForeground: Color = Color.transparent; @@ -226,59 +167,68 @@ export abstract class AbstractTextMateService extends Disposable implements ITex }); } - private _registerDefinitionIfAvailable(modeId: string): void { - if (this._languageToScope.has(modeId)) { - const promise = this._createGrammar(modeId).then((r) => { - return new TMTokenization(this._scopeRegistry, r.languageId, r.grammar, r.initialState, r.containsEmbeddedLanguages, this._notificationService, this._configurationService); - }, e => { - onUnexpectedError(e); - return null; - }); - this._tokenizersRegistrations.push(TokenizationRegistry.registerPromise(modeId, promise)); - } + private _canCreateGrammarFactory(): boolean { + // Check if extension point is ready + return (this._grammarDefinitions ? true : false); } - protected _getRegistryOptions(parseRawGrammar: (content: string, filePath: string) => IRawGrammar): RegistryOptions { - return { - loadGrammar: async (scopeName: string) => { - const location = this._scopeRegistry.getGrammarLocation(scopeName); - if (!location) { - this._logService.trace(`No grammar found for scope ${scopeName}`); - return null; - } - try { - const content = await this._fileService.readFile(location); - return parseRawGrammar(content.value.toString(), location.path); - } catch (e) { - this._logService.error(`Unable to load and parse grammar for scope ${scopeName} from ${location}`, e); - return null; - } - }, - getInjections: (scopeName: string) => { - const scopeParts = scopeName.split('.'); - let injections: string[] = []; - for (let i = 1; i <= scopeParts.length; i++) { - const subScopeName = scopeParts.slice(0, i).join('.'); - injections = [...injections, ...(this._injections[subScopeName] || [])]; - } - return injections; + private async _getOrCreateGrammarFactory(): Promise { + if (this._grammarFactory) { + return this._grammarFactory; + } + + const vscodeTextmate = await this._loadVSCodeTextmate(); + + // Avoid duplicate instantiations + if (this._grammarFactory) { + return this._grammarFactory; + } + + this._grammarFactory = new TMGrammarFactory({ + logTrace: (msg: string) => this._logService.trace(msg), + logError: (msg: string, err: any) => this._logService.error(msg, err), + readFile: async (resource: URI) => { + const content = await this._fileService.readFile(resource); + return content.value.toString(); } - }; + }, this._grammarDefinitions || [], vscodeTextmate, this._loadOnigLib()); + this._onDidCreateGrammarFactory(this._grammarDefinitions || []); + + this._updateTheme(this._grammarFactory, this._themeService.getColorTheme(), true); + + return this._grammarFactory; } - private async _createGrammarRegistry(): Promise<[Registry, StackElement]> { - const { Registry, INITIAL, parseRawGrammar } = await this._loadVSCodeTextmate(); - const grammarRegistry = new Registry(this._getRegistryOptions(parseRawGrammar)); - this._updateTheme(grammarRegistry); - this._themeListener = this._themeService.onDidColorThemeChange((e) => this._updateTheme(grammarRegistry)); - return <[Registry, StackElement]>[grammarRegistry, INITIAL]; - } - - private _getOrCreateGrammarRegistry(): Promise<[Registry, StackElement]> { - if (!this._grammarRegistry) { - this._grammarRegistry = this._createGrammarRegistry(); + private async _registerDefinitionIfAvailable(modeId: string): Promise { + const languageIdentifier = this._modeService.getLanguageIdentifier(modeId); + if (!languageIdentifier) { + return; + } + const languageId = languageIdentifier.id; + try { + if (!this._canCreateGrammarFactory()) { + return; + } + const grammarFactory = await this._getOrCreateGrammarFactory(); + if (grammarFactory.has(languageId)) { + const promise = grammarFactory.createGrammar(languageId).then((r) => { + const tokenization = new TMTokenization(r.grammar, r.initialState, r.containsEmbeddedLanguages); + tokenization.onDidEncounterLanguage((languageId) => { + if (!this._encounteredLanguages[languageId]) { + this._encounteredLanguages[languageId] = true; + this._onDidEncounterLanguage.fire(languageId); + } + }); + return new TMTokenizationSupport(r.languageId, tokenization, this._notificationService, this._configurationService); + }, e => { + onUnexpectedError(e); + return null; + }); + this._tokenizersRegistrations.push(TokenizationRegistry.registerPromise(modeId, promise)); + } + } catch (err) { + onUnexpectedError(err); } - return this._grammarRegistry; } private static _toColorMap(colorMap: string[]): Color[] { @@ -289,190 +239,127 @@ export abstract class AbstractTextMateService extends Disposable implements ITex return result; } - private _updateTheme(grammarRegistry: Registry): void { - let colorTheme = this._themeService.getColorTheme(); - if (!this.compareTokenRules(colorTheme.tokenColors)) { + private _updateTheme(grammarFactory: TMGrammarFactory, colorTheme: IColorTheme, forceUpdate: boolean): void { + if (!forceUpdate && AbstractTextMateService.equalsTokenRules(this._currentTokenColors, colorTheme.tokenColors)) { return; } - grammarRegistry.setTheme({ name: colorTheme.label, settings: colorTheme.tokenColors }); - let colorMap = AbstractTextMateService._toColorMap(grammarRegistry.getColorMap()); + this._currentTokenColors = colorTheme.tokenColors; + this._doUpdateTheme(grammarFactory, { name: colorTheme.label, settings: colorTheme.tokenColors }); + } + + protected _doUpdateTheme(grammarFactory: TMGrammarFactory, theme: IRawTheme): void { + grammarFactory.setTheme(theme); + let colorMap = AbstractTextMateService._toColorMap(grammarFactory.getColorMap()); let cssRules = generateTokensCSSForColorMap(colorMap); this._styleElement.innerHTML = cssRules; TokenizationRegistry.setColorMap(colorMap); } - private compareTokenRules(newRules: ITokenColorizationRule[]): boolean { - let currRules = this._currentTokenColors; - this._currentTokenColors = newRules; - if (!newRules || !currRules || newRules.length !== currRules.length) { - return true; + private static equalsTokenRules(a: ITokenColorizationRule[] | null, b: ITokenColorizationRule[] | null): boolean { + if (!b || !a || b.length !== a.length) { + return false; } - for (let i = newRules.length - 1; i >= 0; i--) { - let r1 = newRules[i]; - let r2 = currRules[i]; + for (let i = b.length - 1; i >= 0; i--) { + let r1 = b[i]; + let r2 = a[i]; if (r1.scope !== r2.scope) { - return true; + return false; } let s1 = r1.settings; let s2 = r2.settings; if (s1 && s2) { if (s1.fontStyle !== s2.fontStyle || s1.foreground !== s2.foreground || s1.background !== s2.background) { - return true; + return false; } } else if (!s1 || !s2) { - return true; + return false; } } - return false; + return true; } - private _handleGrammarExtensionPointUser(extensionLocation: URI, syntax: ITMSyntaxExtensionPoint, collector: ExtensionMessageCollector): void { + private _validateGrammarExtensionPoint(extensionLocation: URI, syntax: ITMSyntaxExtensionPoint, collector: ExtensionMessageCollector): boolean { if (syntax.language && ((typeof syntax.language !== 'string') || !this._modeService.isRegisteredMode(syntax.language))) { collector.error(nls.localize('invalid.language', "Unknown language in `contributes.{0}.language`. Provided value: {1}", grammarsExtPoint.name, String(syntax.language))); - return; + return false; } if (!syntax.scopeName || (typeof syntax.scopeName !== 'string')) { collector.error(nls.localize('invalid.scopeName', "Expected string in `contributes.{0}.scopeName`. Provided value: {1}", grammarsExtPoint.name, String(syntax.scopeName))); - return; + return false; } if (!syntax.path || (typeof syntax.path !== 'string')) { collector.error(nls.localize('invalid.path.0', "Expected string in `contributes.{0}.path`. Provided value: {1}", grammarsExtPoint.name, String(syntax.path))); - return; + return false; } if (syntax.injectTo && (!Array.isArray(syntax.injectTo) || syntax.injectTo.some(scope => typeof scope !== 'string'))) { collector.error(nls.localize('invalid.injectTo', "Invalid value in `contributes.{0}.injectTo`. Must be an array of language scope names. Provided value: {1}", grammarsExtPoint.name, JSON.stringify(syntax.injectTo))); - return; + return false; } if (syntax.embeddedLanguages && !types.isObject(syntax.embeddedLanguages)) { collector.error(nls.localize('invalid.embeddedLanguages', "Invalid value in `contributes.{0}.embeddedLanguages`. Must be an object map from scope name to language. Provided value: {1}", grammarsExtPoint.name, JSON.stringify(syntax.embeddedLanguages))); - return; + return false; } if (syntax.tokenTypes && !types.isObject(syntax.tokenTypes)) { collector.error(nls.localize('invalid.tokenTypes', "Invalid value in `contributes.{0}.tokenTypes`. Must be an object map from scope name to token type. Provided value: {1}", grammarsExtPoint.name, JSON.stringify(syntax.tokenTypes))); - return; + return false; } const grammarLocation = resources.joinPath(extensionLocation, syntax.path); if (!resources.isEqualOrParent(grammarLocation, extensionLocation)) { collector.warn(nls.localize('invalid.path.1', "Expected `contributes.{0}.path` ({1}) to be included inside extension's folder ({2}). This might make the extension non-portable.", grammarsExtPoint.name, grammarLocation.path, extensionLocation.path)); } - - this._scopeRegistry.register(syntax.scopeName, grammarLocation, syntax.embeddedLanguages, syntax.tokenTypes); - - if (syntax.injectTo) { - for (let injectScope of syntax.injectTo) { - let injections = this._injections[injectScope]; - if (!injections) { - this._injections[injectScope] = injections = []; - } - injections.push(syntax.scopeName); - } - - if (syntax.embeddedLanguages) { - for (let injectScope of syntax.injectTo) { - let injectedEmbeddedLanguages = this._injectedEmbeddedLanguages[injectScope]; - if (!injectedEmbeddedLanguages) { - this._injectedEmbeddedLanguages[injectScope] = injectedEmbeddedLanguages = []; - } - injectedEmbeddedLanguages.push(syntax.embeddedLanguages); - } - } - } - - let modeId = syntax.language; - if (modeId) { - this._languageToScope.set(modeId, syntax.scopeName); - } - } - - private _resolveEmbeddedLanguages(embeddedLanguages: IEmbeddedLanguagesMap): IEmbeddedLanguagesMap2 { - let scopes = Object.keys(embeddedLanguages); - let result: IEmbeddedLanguagesMap2 = Object.create(null); - for (let i = 0, len = scopes.length; i < len; i++) { - let scope = scopes[i]; - let language = embeddedLanguages[scope]; - let languageIdentifier = this._modeService.getLanguageIdentifier(language); - if (languageIdentifier) { - result[scope] = languageIdentifier.id; - } - } - return result; + return true; } public async createGrammar(modeId: string): Promise { - const { grammar } = await this._createGrammar(modeId); + const grammarFactory = await this._getOrCreateGrammarFactory(); + const { grammar } = await grammarFactory.createGrammar(this._modeService.getLanguageIdentifier(modeId)!.id); return grammar; } - private async _createGrammar(modeId: string): Promise { - const scopeName = this._languageToScope.get(modeId); - if (typeof scopeName !== 'string') { - // No TM grammar defined - return Promise.reject(new Error(nls.localize('no-tm-grammar', "No TM Grammar registered for this language."))); - } - const languageRegistration = this._scopeRegistry.getLanguageRegistration(scopeName); - if (!languageRegistration) { - // No TM grammar defined - return Promise.reject(new Error(nls.localize('no-tm-grammar', "No TM Grammar registered for this language."))); - } - let embeddedLanguages = this._resolveEmbeddedLanguages(languageRegistration.embeddedLanguages); - let rawInjectedEmbeddedLanguages = this._injectedEmbeddedLanguages[scopeName]; - if (rawInjectedEmbeddedLanguages) { - let injectedEmbeddedLanguages: IEmbeddedLanguagesMap2[] = rawInjectedEmbeddedLanguages.map(this._resolveEmbeddedLanguages.bind(this)); - for (const injected of injectedEmbeddedLanguages) { - for (const scope of Object.keys(injected)) { - embeddedLanguages[scope] = injected[scope]; - } - } - } + protected _onDidCreateGrammarFactory(grammarDefinitions: IValidGrammarDefinition[]): void { + } - let languageId = this._modeService.getLanguageIdentifier(modeId)!.id; - let containsEmbeddedLanguages = (Object.keys(embeddedLanguages).length > 0); - - const [grammarRegistry, initialState] = await this._getOrCreateGrammarRegistry(); - const grammar = await grammarRegistry.loadGrammarWithConfiguration(scopeName, languageId, { embeddedLanguages, tokenTypes: languageRegistration.tokenTypes }); - return { - languageId: languageId, - grammar: grammar, - initialState: initialState, - containsEmbeddedLanguages: containsEmbeddedLanguages - }; + protected _onDidDisposeGrammarFactory(): void { } protected abstract _loadVSCodeTextmate(): Promise; + protected abstract _loadOnigLib(): Promise | undefined; } -class TMTokenization implements ITokenizationSupport { - - private readonly _scopeRegistry: TMScopeRegistry; +class TMTokenizationSupport implements ITokenizationSupport { private readonly _languageId: LanguageId; - private readonly _grammar: IGrammar; - private readonly _containsEmbeddedLanguages: boolean; - private readonly _seenLanguages: boolean[]; - private readonly _initialState: StackElement; - private _maxTokenizationLineLength: number; + private readonly _actual: TMTokenization; private _tokenizationWarningAlreadyShown: boolean; + private _maxTokenizationLineLength: number; - constructor(scopeRegistry: TMScopeRegistry, languageId: LanguageId, grammar: IGrammar, initialState: StackElement, containsEmbeddedLanguages: boolean, @INotificationService private readonly notificationService: INotificationService, @IConfigurationService readonly configurationService: IConfigurationService) { - this._scopeRegistry = scopeRegistry; + constructor( + languageId: LanguageId, + actual: TMTokenization, + @INotificationService private readonly _notificationService: INotificationService, + @IConfigurationService private readonly _configurationService: IConfigurationService + ) { this._languageId = languageId; - this._grammar = grammar; - this._initialState = initialState; - this._containsEmbeddedLanguages = containsEmbeddedLanguages; - this._seenLanguages = []; - this._maxTokenizationLineLength = configurationService.getValue('editor.maxTokenizationLineLength'); + this._actual = actual; + this._tokenizationWarningAlreadyShown = false; + this._maxTokenizationLineLength = this._configurationService.getValue('editor.maxTokenizationLineLength'); + this._configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('editor.maxTokenizationLineLength')) { + this._maxTokenizationLineLength = this._configurationService.getValue('editor.maxTokenizationLineLength'); + } + }); } - public getInitialState(): IState { - return this._initialState; + getInitialState(): IState { + return this._actual.getInitialState(); } - public tokenize(line: string, state: IState, offsetDelta: number): TokenizationResult { + tokenize(line: string, state: IState, offsetDelta: number): TokenizationResult { throw new Error('Not supported!'); } - public tokenize2(line: string, state: StackElement, offsetDelta: number): TokenizationResult2 { + tokenize2(line: string, state: StackElement, offsetDelta: number): TokenizationResult2 { if (offsetDelta !== 0) { throw new Error('Unexpected: offsetDelta should be 0.'); } @@ -481,12 +368,39 @@ class TMTokenization implements ITokenizationSupport { if (line.length >= this._maxTokenizationLineLength) { if (!this._tokenizationWarningAlreadyShown) { this._tokenizationWarningAlreadyShown = true; - this.notificationService.warn(nls.localize('too many characters', "Tokenization is skipped for long lines for performance reasons. The length of a long line can be configured via `editor.maxTokenizationLineLength`.")); + this._notificationService.warn(nls.localize('too many characters', "Tokenization is skipped for long lines for performance reasons. The length of a long line can be configured via `editor.maxTokenizationLineLength`.")); } console.log(`Line (${line.substr(0, 15)}...): longer than ${this._maxTokenizationLineLength} characters, tokenization skipped.`); return nullTokenize2(this._languageId, line, state, offsetDelta); } + return this._actual.tokenize2(line, state); + } +} + +class TMTokenization extends Disposable { + + private readonly _grammar: IGrammar; + private readonly _containsEmbeddedLanguages: boolean; + private readonly _seenLanguages: boolean[]; + private readonly _initialState: StackElement; + + private readonly _onDidEncounterLanguage: Emitter = this._register(new Emitter()); + public readonly onDidEncounterLanguage: Event = this._onDidEncounterLanguage.event; + + constructor(grammar: IGrammar, initialState: StackElement, containsEmbeddedLanguages: boolean) { + super(); + this._grammar = grammar; + this._initialState = initialState; + this._containsEmbeddedLanguages = containsEmbeddedLanguages; + this._seenLanguages = []; + } + + public getInitialState(): IState { + return this._initialState; + } + + public tokenize2(line: string, state: StackElement): TokenizationResult2 { let textMateResult = this._grammar.tokenizeLine2(line, state); if (this._containsEmbeddedLanguages) { @@ -500,7 +414,7 @@ class TMTokenization implements ITokenizationSupport { if (!seenLanguages[languageId]) { seenLanguages[languageId] = true; - this._scopeRegistry.onEncounteredLanguage(languageId); + this._onDidEncounterLanguage.fire(languageId); } } } diff --git a/src/vs/workbench/services/textMate/browser/textMateService.ts b/src/vs/workbench/services/textMate/browser/textMateService.ts index c126bf74d25..0e95d04a847 100644 --- a/src/vs/workbench/services/textMate/browser/textMateService.ts +++ b/src/vs/workbench/services/textMate/browser/textMateService.ts @@ -32,10 +32,8 @@ export class TextMateService extends AbstractTextMateService { return import('vscode-textmate'); } - protected _getRegistryOptions(parseRawGrammar: (content: string, filePath: string) => vscodeTextmate.IRawGrammar): vscodeTextmate.RegistryOptions { - const result = super._getRegistryOptions(parseRawGrammar); - result.getOnigLib = () => loadOnigasm(); - return result; + protected _loadOnigLib(): Promise | undefined { + return loadOnigasm(); } } diff --git a/src/vs/workbench/services/textMate/common/TMGrammarFactory.ts b/src/vs/workbench/services/textMate/common/TMGrammarFactory.ts new file mode 100644 index 00000000000..1ea68789895 --- /dev/null +++ b/src/vs/workbench/services/textMate/common/TMGrammarFactory.ts @@ -0,0 +1,147 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vs/nls'; +import { URI } from 'vs/base/common/uri'; +import { LanguageId } from 'vs/editor/common/modes'; +import { IGrammar, Registry, StackElement, IRawTheme, IOnigLib } from 'vscode-textmate'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { TMScopeRegistry, IValidGrammarDefinition, IValidEmbeddedLanguagesMap } from 'vs/workbench/services/textMate/common/TMScopeRegistry'; + +interface ITMGrammarFactoryHost { + logTrace(msg: string): void; + logError(msg: string, err: any): void; + readFile(resource: URI): Promise; +} + +export interface ICreateGrammarResult { + languageId: LanguageId; + grammar: IGrammar; + initialState: StackElement; + containsEmbeddedLanguages: boolean; +} + +export class TMGrammarFactory extends Disposable { + + private readonly _host: ITMGrammarFactoryHost; + private readonly _initialState: StackElement; + private readonly _scopeRegistry: TMScopeRegistry; + private readonly _injections: { [scopeName: string]: string[]; }; + private readonly _injectedEmbeddedLanguages: { [scopeName: string]: IValidEmbeddedLanguagesMap[]; }; + private readonly _languageToScope2: string[]; + private readonly _grammarRegistry: Registry; + + constructor(host: ITMGrammarFactoryHost, grammarDefinitions: IValidGrammarDefinition[], vscodeTextmate: typeof import('vscode-textmate'), onigLib: Promise | undefined) { + super(); + this._host = host; + this._initialState = vscodeTextmate.INITIAL; + this._scopeRegistry = this._register(new TMScopeRegistry()); + this._injections = {}; + this._injectedEmbeddedLanguages = {}; + this._languageToScope2 = []; + this._grammarRegistry = new vscodeTextmate.Registry({ + getOnigLib: (typeof onigLib === 'undefined' ? undefined : () => onigLib), + loadGrammar: async (scopeName: string) => { + const grammarDefinition = this._scopeRegistry.getGrammarDefinition(scopeName); + if (!grammarDefinition) { + this._host.logTrace(`No grammar found for scope ${scopeName}`); + return null; + } + const location = grammarDefinition.location; + try { + const content = await this._host.readFile(location); + return vscodeTextmate.parseRawGrammar(content, location.path); + } catch (e) { + this._host.logError(`Unable to load and parse grammar for scope ${scopeName} from ${location}`, e); + return null; + } + }, + getInjections: (scopeName: string) => { + const scopeParts = scopeName.split('.'); + let injections: string[] = []; + for (let i = 1; i <= scopeParts.length; i++) { + const subScopeName = scopeParts.slice(0, i).join('.'); + injections = [...injections, ...(this._injections[subScopeName] || [])]; + } + return injections; + } + }); + + for (const validGrammar of grammarDefinitions) { + this._scopeRegistry.register(validGrammar); + + if (validGrammar.injectTo) { + for (let injectScope of validGrammar.injectTo) { + let injections = this._injections[injectScope]; + if (!injections) { + this._injections[injectScope] = injections = []; + } + injections.push(validGrammar.scopeName); + } + + if (validGrammar.embeddedLanguages) { + for (let injectScope of validGrammar.injectTo) { + let injectedEmbeddedLanguages = this._injectedEmbeddedLanguages[injectScope]; + if (!injectedEmbeddedLanguages) { + this._injectedEmbeddedLanguages[injectScope] = injectedEmbeddedLanguages = []; + } + injectedEmbeddedLanguages.push(validGrammar.embeddedLanguages); + } + } + } + + if (validGrammar.language) { + this._languageToScope2[validGrammar.language] = validGrammar.scopeName; + } + } + } + + public has(languageId: LanguageId): boolean { + return this._languageToScope2[languageId] ? true : false; + } + + public setTheme(theme: IRawTheme): void { + this._grammarRegistry.setTheme(theme); + } + + public getColorMap(): string[] { + return this._grammarRegistry.getColorMap(); + } + + public async createGrammar(languageId: LanguageId): Promise { + const scopeName = this._languageToScope2[languageId]; + if (typeof scopeName !== 'string') { + // No TM grammar defined + return Promise.reject(new Error(nls.localize('no-tm-grammar', "No TM Grammar registered for this language."))); + } + + const grammarDefinition = this._scopeRegistry.getGrammarDefinition(scopeName); + if (!grammarDefinition) { + // No TM grammar defined + return Promise.reject(new Error(nls.localize('no-tm-grammar', "No TM Grammar registered for this language."))); + } + + let embeddedLanguages = grammarDefinition.embeddedLanguages; + if (this._injectedEmbeddedLanguages[scopeName]) { + const injectedEmbeddedLanguages = this._injectedEmbeddedLanguages[scopeName]; + for (const injected of injectedEmbeddedLanguages) { + for (const scope of Object.keys(injected)) { + embeddedLanguages[scope] = injected[scope]; + } + } + } + + const containsEmbeddedLanguages = (Object.keys(embeddedLanguages).length > 0); + + const grammar = await this._grammarRegistry.loadGrammarWithConfiguration(scopeName, languageId, { embeddedLanguages, tokenTypes: grammarDefinition.tokenTypes }); + + return { + languageId: languageId, + grammar: grammar, + initialState: this._initialState, + containsEmbeddedLanguages: containsEmbeddedLanguages + }; + } +} diff --git a/src/vs/workbench/services/textMate/common/TMScopeRegistry.ts b/src/vs/workbench/services/textMate/common/TMScopeRegistry.ts new file mode 100644 index 00000000000..4c352da67a4 --- /dev/null +++ b/src/vs/workbench/services/textMate/common/TMScopeRegistry.ts @@ -0,0 +1,58 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as resources from 'vs/base/common/resources'; +import { URI } from 'vs/base/common/uri'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { StandardTokenType, LanguageId } from 'vs/editor/common/modes'; + +export interface IValidGrammarDefinition { + location: URI; + language?: LanguageId; + scopeName: string; + embeddedLanguages: IValidEmbeddedLanguagesMap; + tokenTypes: IValidTokenTypeMap; + injectTo?: string[]; +} + +export interface IValidTokenTypeMap { + [selector: string]: StandardTokenType; +} + +export interface IValidEmbeddedLanguagesMap { + [scopeName: string]: LanguageId; +} + +export class TMScopeRegistry extends Disposable { + + private _scopeNameToLanguageRegistration: { [scopeName: string]: IValidGrammarDefinition; }; + + constructor() { + super(); + this.reset(); + } + + public reset(): void { + this._scopeNameToLanguageRegistration = Object.create(null); + } + + public register(def: IValidGrammarDefinition): void { + if (this._scopeNameToLanguageRegistration[def.scopeName]) { + const existingRegistration = this._scopeNameToLanguageRegistration[def.scopeName]; + if (!resources.isEqual(existingRegistration.location, def.location)) { + console.warn( + `Overwriting grammar scope name to file mapping for scope ${def.scopeName}.\n` + + `Old grammar file: ${existingRegistration.location.toString()}.\n` + + `New grammar file: ${def.location.toString()}` + ); + } + } + this._scopeNameToLanguageRegistration[def.scopeName] = def; + } + + public getGrammarDefinition(scopeName: string): IValidGrammarDefinition | null { + return this._scopeNameToLanguageRegistration[scopeName] || null; + } +} diff --git a/src/vs/workbench/services/textMate/electron-browser/textMateService.ts b/src/vs/workbench/services/textMate/electron-browser/textMateService.ts index 4b5ec093cd9..9e301b37d85 100644 --- a/src/vs/workbench/services/textMate/electron-browser/textMateService.ts +++ b/src/vs/workbench/services/textMate/electron-browser/textMateService.ts @@ -6,12 +6,191 @@ import { ITextMateService } from 'vs/workbench/services/textMate/common/textMateService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { AbstractTextMateService } from 'vs/workbench/services/textMate/browser/abstractTextMateService'; +import { IModeService } from 'vs/editor/common/services/modeService'; +import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { IFileService } from 'vs/platform/files/common/files'; +import { INotificationService } from 'vs/platform/notification/common/notification'; +import { ILogService } from 'vs/platform/log/common/log'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { createWebWorker, MonacoWebWorker } from 'vs/editor/common/services/webWorker'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { IOnigLib } from 'vscode-textmate'; +import { IValidGrammarDefinition } from 'vs/workbench/services/textMate/common/TMScopeRegistry'; +import { TextMateWorker } from 'vs/workbench/services/textMate/electron-browser/textMateWorker'; +import { ITextModel } from 'vs/editor/common/model'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { UriComponents, URI } from 'vs/base/common/uri'; + +const RUN_TEXTMATE_IN_WORKER = false; + +class ModelWorkerTextMateTokenizer extends Disposable { + + private readonly _worker: TextMateWorker; + private readonly _model: ITextModel; + private _isSynced: boolean; + + constructor(worker: TextMateWorker, model: ITextModel) { + super(); + this._worker = worker; + this._model = model; + this._isSynced = false; + + this._register(this._model.onDidChangeAttached(() => this._onDidChangeAttached())); + this._onDidChangeAttached(); + + this._register(this._model.onDidChangeContent((e) => { + if (this._isSynced) { + this._worker.acceptModelChanged(this._model.uri.toString(), e); + } + })); + + this._register(this._model.onDidChangeLanguage((e) => { + if (this._isSynced) { + this._worker.acceptModelLanguageChanged(this._model.uri.toString(), this._model.getLanguageIdentifier().id); + } + })); + } + + private _onDidChangeAttached(): void { + if (this._model.isAttachedToEditor()) { + if (!this._isSynced) { + this._beginSync(); + } + } else { + if (this._isSynced) { + this._endSync(); + } + } + } + + private _beginSync(): void { + this._isSynced = true; + this._worker.acceptNewModel({ + uri: this._model.uri, + versionId: this._model.getVersionId(), + lines: this._model.getLinesContent(), + EOL: this._model.getEOL(), + languageId: this._model.getLanguageIdentifier().id, + }); + } + + private _endSync(): void { + this._isSynced = false; + this._worker.acceptRemovedModel(this._model.uri.toString()); + } + + public dispose() { + super.dispose(); + this._endSync(); + } +} + +export class TextMateWorkerHost { + + constructor(@IFileService private readonly _fileService: IFileService) { + } + + async readFile(_resource: UriComponents): Promise { + const resource = URI.revive(_resource); + const content = await this._fileService.readFile(resource); + return content.value.toString(); + } +} export class TextMateService extends AbstractTextMateService { + private _worker: MonacoWebWorker | null; + private _workerProxy: TextMateWorker | null; + private _tokenizers: { [uri: string]: ModelWorkerTextMateTokenizer; }; + + constructor( + @IModeService modeService: IModeService, + @IWorkbenchThemeService themeService: IWorkbenchThemeService, + @IFileService fileService: IFileService, + @INotificationService notificationService: INotificationService, + @ILogService logService: ILogService, + @IConfigurationService configurationService: IConfigurationService, + @IModelService private readonly _modelService: IModelService, + ) { + super(modeService, themeService, fileService, notificationService, logService, configurationService); + this._worker = null; + this._workerProxy = null; + this._tokenizers = Object.create(null); + this._register(this._modelService.onModelAdded(model => this._onModelAdded(model))); + this._register(this._modelService.onModelRemoved(model => this._onModelRemoved(model))); + this._modelService.getModels().forEach((model) => this._onModelAdded(model)); + } + + private _onModelAdded(model: ITextModel): void { + if (!this._workerProxy) { + return; + } + if (model.isTooLargeForSyncing()) { + return; + } + const key = model.uri.toString(); + const tokenizer = new ModelWorkerTextMateTokenizer(this._workerProxy, model); + this._tokenizers[key] = tokenizer; + } + + private _onModelRemoved(model: ITextModel): void { + const key = model.uri.toString(); + if (this._tokenizers[key]) { + this._tokenizers[key].dispose(); + delete this._tokenizers[key]; + } + } + protected _loadVSCodeTextmate(): Promise { return import('vscode-textmate'); } + + protected _loadOnigLib(): Promise | undefined { + return undefined; + } + + protected _onDidCreateGrammarFactory(grammarDefinitions: IValidGrammarDefinition[]): void { + this._killWorker(); + + if (RUN_TEXTMATE_IN_WORKER) { + const workerHost = new TextMateWorkerHost(this._fileService); + const worker = createWebWorker(this._modelService, { + createData: { + grammarDefinitions + }, + label: 'textMateWorker', + moduleId: 'vs/workbench/services/textMate/electron-browser/textMateWorker', + host: workerHost + }); + + this._worker = worker; + worker.getProxy().then((proxy) => { + if (this._worker !== worker) { + // disposed in the meantime + return; + } + this._workerProxy = proxy; + this._modelService.getModels().forEach((model) => this._onModelAdded(model)); + }); + } + } + + protected _onDidDisposeGrammarFactory(): void { + this._killWorker(); + } + + private _killWorker(): void { + for (let key of Object.keys(this._tokenizers)) { + this._tokenizers[key].dispose(); + } + this._tokenizers = Object.create(null); + + if (this._worker) { + this._worker.dispose(); + this._worker = null; + } + this._workerProxy = null; + } } registerSingleton(ITextMateService, TextMateService); \ No newline at end of file diff --git a/src/vs/workbench/services/textMate/electron-browser/textMateWorker.ts b/src/vs/workbench/services/textMate/electron-browser/textMateWorker.ts new file mode 100644 index 00000000000..27361f4835e --- /dev/null +++ b/src/vs/workbench/services/textMate/electron-browser/textMateWorker.ts @@ -0,0 +1,128 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IWorkerContext } from 'vs/editor/common/services/editorSimpleWorker'; +import { UriComponents, URI } from 'vs/base/common/uri'; +import { LanguageId } from 'vs/editor/common/modes'; +import { IValidEmbeddedLanguagesMap, IValidTokenTypeMap, IValidGrammarDefinition } from 'vs/workbench/services/textMate/common/TMScopeRegistry'; +import { TMGrammarFactory, ICreateGrammarResult } from 'vs/workbench/services/textMate/common/TMGrammarFactory'; +import { IModelChangedEvent, MirrorTextModel } from 'vs/editor/common/model/mirrorTextModel'; +import { TextMateWorkerHost } from 'vs/workbench/services/textMate/electron-browser/textMateService'; + +export interface IValidGrammarDefinitionDTO { + location: UriComponents; + language?: LanguageId; + scopeName: string; + embeddedLanguages: IValidEmbeddedLanguagesMap; + tokenTypes: IValidTokenTypeMap; + injectTo?: string[]; +} + +export interface ICreateData { + grammarDefinitions: IValidGrammarDefinitionDTO[]; +} + +export interface IRawModelData { + uri: UriComponents; + versionId: number; + lines: string[]; + EOL: string; + languageId: LanguageId; +} + +class TextMateWorkerModel extends MirrorTextModel { + + private readonly _worker: TextMateWorker; + private _languageId: LanguageId; + + constructor(uri: URI, lines: string[], eol: string, versionId: number, worker: TextMateWorker, languageId: LanguageId) { + super(uri, lines, eol, versionId); + this._worker = worker; + this._languageId = languageId; + this._resetTokenization(); + } + + onLanguageId(languageId: LanguageId): void { + this._languageId = languageId; + this._resetTokenization(); + } + + private _resetTokenization(): void { + this._worker.getOrCreateGrammar(this._languageId).then((r) => { + console.log(r); + }); + } +} + +export class TextMateWorker { + + private readonly _host: TextMateWorkerHost; + private readonly _models: { [uri: string]: TextMateWorkerModel; }; + private readonly _grammarCache: Promise[]; + private readonly _grammarFactory: TMGrammarFactory; + + constructor(ctx: IWorkerContext, createData: ICreateData) { + this._host = ctx.host; + this._models = Object.create(null); + this._grammarCache = []; + const grammarDefinitions = createData.grammarDefinitions.map((def) => { + return { + location: URI.revive(def.location), + language: def.language, + scopeName: def.scopeName, + embeddedLanguages: def.embeddedLanguages, + tokenTypes: def.tokenTypes, + injectTo: def.injectTo, + }; + }); + + let vscodeTextmate: typeof import('vscode-textmate'); + const globalDefine = (self).define; + try { + (self).define.amd = undefined; + vscodeTextmate = require.__$__nodeRequire('vscode-textmate'); + } catch (err) { + console.error(err); + return; + } finally { + (self).define = globalDefine; + } + + this._grammarFactory = new TMGrammarFactory({ + logTrace: (msg: string) => console.log(msg), + logError: (msg: string, err: any) => console.error(msg, err), + readFile: (resource: URI) => this._host.readFile(resource) + }, grammarDefinitions, vscodeTextmate, undefined); + } + + public acceptNewModel(data: IRawModelData): void { + const uri = URI.revive(data.uri); + const key = uri.toString(); + this._models[key] = new TextMateWorkerModel(uri, data.lines, data.EOL, data.versionId, this, data.languageId); + } + + public acceptModelChanged(strURL: string, e: IModelChangedEvent): void { + this._models[strURL].onEvents(e); + } + + public acceptModelLanguageChanged(strURL: string, newLanguageId: LanguageId): void { + this._models[strURL].onLanguageId(newLanguageId); + } + + public acceptRemovedModel(strURL: string): void { + delete this._models[strURL]; + } + + public getOrCreateGrammar(languageId: LanguageId): Promise { + if (!this._grammarCache[languageId]) { + this._grammarCache[languageId] = this._grammarFactory.createGrammar(languageId); + } + return this._grammarCache[languageId]; + } +} + +export function create(ctx: IWorkerContext, createData: ICreateData): TextMateWorker { + return new TextMateWorker(ctx, createData); +} diff --git a/src/vs/workbench/services/textfile/browser/textFileService.ts b/src/vs/workbench/services/textfile/browser/textFileService.ts index d15549e21cc..9f0660e400c 100644 --- a/src/vs/workbench/services/textfile/browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/browser/textFileService.ts @@ -6,6 +6,8 @@ import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService'; import { ITextFileService, IResourceEncodings, IResourceEncoding } from 'vs/workbench/services/textfile/common/textfiles'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle'; +import { Schemas } from 'vs/base/common/network'; export class BrowserTextFileService extends TextFileService { @@ -14,6 +16,42 @@ export class BrowserTextFileService extends TextFileService { return { encoding: 'utf8', hasBOM: false }; } }; + + protected beforeShutdown(reason: ShutdownReason): boolean { + // Web: we cannot perform long running in the shutdown phase + // As such we need to check sync if there are any dirty files + // that have not been backed up yet and then prevent the shutdown + // if that is the case. + return this.doBeforeShutdownSync(reason); + } + + private doBeforeShutdownSync(reason: ShutdownReason): boolean { + const dirtyResources = this.getDirty(); + if (!dirtyResources.length) { + return false; // no dirty: no veto + } + + if (!this.isHotExitEnabled) { + return true; // dirty without backup: veto + } + + for (const dirtyResource of dirtyResources) { + let hasBackup = false; + + if (this.fileService.canHandleResource(dirtyResource)) { + const model = this.models.get(dirtyResource); + hasBackup = !!(model && model.hasBackup()); + } else if (dirtyResource.scheme === Schemas.untitled) { + hasBackup = this.untitledEditorService.hasBackup(dirtyResource); + } + + if (!hasBackup) { + return true; // dirty without backup: veto + } + } + + return false; // dirty with backups: no veto + } } registerSingleton(ITextFileService, BrowserTextFileService); \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index dc6f69145e7..e860bcd6048 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -24,8 +24,7 @@ import { RunOnceScheduler, timeout } from 'vs/base/common/async'; import { ITextBufferFactory } from 'vs/editor/common/model'; import { hash } from 'vs/base/common/hash'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { isLinux } from 'vs/base/common/platform'; -import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { toDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { ILogService } from 'vs/platform/log/common/log'; import { isEqual, isEqualOrParent, extname, basename, joinPath } from 'vs/base/common/resources'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -38,6 +37,22 @@ export interface IBackupMetaData { orphaned: boolean; } +type FileTelemetryDataFragment = { + mimeType: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + ext: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + path: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + reason?: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; + whitelistedjson?: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; +}; + +type TelemetryData = { + mimeType: string; + ext: string; + path: number; + reason?: number; + whitelistedjson?: string; +}; + /** * The text file editor model listens to changes to its underlying code editor model and saves these changes through the file service back to the disk. */ @@ -75,7 +90,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil private autoSaveAfterMillies?: number; private autoSaveAfterMilliesEnabled: boolean; - private autoSaveDisposable?: IDisposable; + private readonly autoSaveDisposable = this._register(new MutableDisposable()); private saveSequentializer: SaveSequentializer; private lastSaveAttemptTime: number; @@ -237,13 +252,17 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } } + hasBackup(): boolean { + return this.backupFileService.hasBackupSync(this.resource, this.versionId); + } + async revert(soft?: boolean): Promise { if (!this.isResolved()) { return; } // Cancel any running auto-save - this.cancelPendingAutoSave(); + this.autoSaveDisposable.clear(); // Unset flags const undo = this.setDirty(false); @@ -427,21 +446,15 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Telemetry: We log the fileGet telemetry event after the model has been loaded to ensure a good mimetype const settingsType = this.getTypeIfSettings(); if (settingsType) { - /* __GDPR__ - "settingsRead" : { - "settingsType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('settingsRead', { settingsType }); // Do not log read to user settings.json and .vscode folder as a fileGet event as it ruins our JSON usage data + type SettingsReadClassification = { + settingsType: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + }; + + this.telemetryService.publicLog2<{ settingsType: string }, SettingsReadClassification>('settingsRead', { settingsType }); // Do not log read to user settings.json and .vscode folder as a fileGet event as it ruins our JSON usage data } else { - /* __GDPR__ - "fileGet" : { - "${include}": [ - "${FileTelemetryData}" - ] - } - */ - this.telemetryService.publicLog('fileGet', this.getTelemetryData(options && options.reason ? options.reason : LoadReason.OTHER)); + type FileGetClassification = {} & FileTelemetryDataFragment; + + this.telemetryService.publicLog2('fileGet', this.getTelemetryData(options && options.reason ? options.reason : LoadReason.OTHER)); } return this; @@ -567,7 +580,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil this.logService.trace(`doAutoSave() - enter for versionId ${versionId}`, this.resource); // Cancel any currently running auto saves to make this the one that succeeds - this.cancelPendingAutoSave(); + this.autoSaveDisposable.clear(); // Create new save timer and store it for disposal as needed const handle = setTimeout(() => { @@ -578,25 +591,18 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } }, this.autoSaveAfterMillies); - this.autoSaveDisposable = toDisposable(() => clearTimeout(handle)); + this.autoSaveDisposable.value = toDisposable(() => clearTimeout(handle)); } - private cancelPendingAutoSave(): void { - if (this.autoSaveDisposable) { - this.autoSaveDisposable.dispose(); - this.autoSaveDisposable = undefined; - } - } - - save(options: ISaveOptions = Object.create(null)): Promise { + async save(options: ISaveOptions = Object.create(null)): Promise { if (!this.isResolved()) { - return Promise.resolve(); + return; } this.logService.trace('save() - enter', this.resource); // Cancel any currently running auto saves to make this the one that succeeds - this.cancelPendingAutoSave(); + this.autoSaveDisposable.clear(); return this.doSave(this.versionId, options); } @@ -740,21 +746,13 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Telemetry const settingsType = this.getTypeIfSettings(); if (settingsType) { - /* __GDPR__ - "settingsWritten" : { - "settingsType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('settingsWritten', { settingsType }); // Do not log write to user settings.json and .vscode folder as a filePUT event as it ruins our JSON usage data + type SettingsWrittenClassification = { + settingsType: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + }; + this.telemetryService.publicLog2<{ settingsType: string }, SettingsWrittenClassification>('settingsWritten', { settingsType }); // Do not log write to user settings.json and .vscode folder as a filePUT event as it ruins our JSON usage data } else { - /* __GDPR__ - "filePUT" : { - "${include}": [ - "${FileTelemetryData}" - ] - } - */ - this.telemetryService.publicLog('filePUT', this.getTelemetryData(options.reason)); + type FilePutClassfication = {} & FileTelemetryDataFragment; + this.telemetryService.publicLog2('filePUT', this.getTelemetryData(options.reason)); } }, error => { this.logService.error(`doSave(${versionId}) - exit - resulted in a save error: ${error.toString()}`, this.resource); @@ -782,22 +780,22 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } // Check for global settings file - if (isEqual(this.resource, this.environmentService.settingsResource, !isLinux)) { + if (isEqual(this.resource, this.environmentService.settingsResource)) { return 'global-settings'; } // Check for keybindings file - if (isEqual(this.resource, this.environmentService.keybindingsResource, !isLinux)) { + if (isEqual(this.resource, this.environmentService.keybindingsResource)) { return 'keybindings'; } // Check for locale file - if (isEqual(this.resource, joinPath(this.environmentService.appSettingsHome, 'locale.json'), !isLinux)) { + if (isEqual(this.resource, joinPath(this.environmentService.userRoamingDataHome, 'locale.json'))) { return 'locale'; } // Check for snippets - if (isEqualOrParent(this.resource, joinPath(this.environmentService.appSettingsHome, 'snippets'))) { + if (isEqualOrParent(this.resource, joinPath(this.environmentService.userRoamingDataHome, 'snippets'))) { return 'snippets'; } @@ -815,7 +813,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil return ''; } - private getTelemetryData(reason: number | undefined): object { + private getTelemetryData(reason: number | undefined): TelemetryData { const ext = extname(this.resource); const fileName = basename(this.resource); const path = this.resource.scheme === Schemas.file ? this.resource.fsPath : this.resource.path; @@ -823,22 +821,14 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil mimeType: guessMimeTypes(this.resource).join(', '), ext, path: hash(path), - reason + reason, + whitelistedjson: undefined as string | undefined }; if (ext === '.json' && TextFileEditorModel.WHITELIST_JSON.indexOf(fileName) > -1) { telemetryData['whitelistedjson'] = fileName; } - /* __GDPR__FRAGMENT__ - "FileTelemetryData" : { - "mimeType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "ext": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "path": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "whitelistedjson": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ return telemetryData; } @@ -1038,8 +1028,6 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil this.inOrphanMode = false; this.inErrorMode = false; - this.cancelPendingAutoSave(); - super.dispose(); } } diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index 9b1c25db695..34ac606235f 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -31,7 +31,6 @@ import { createTextBufferFactoryFromSnapshot, createTextBufferFactoryFromStream import { IModelService } from 'vs/editor/common/services/modelService'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { isEqualOrParent, isEqual, joinPath, dirname, extname, basename, toLocalResource } from 'vs/base/common/resources'; -import { posix } from 'vs/base/common/path'; import { getConfirmMessage, IDialogService, IFileDialogService, ISaveDialogOptions, IConfirmation } from 'vs/platform/dialogs/common/dialogs'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -73,7 +72,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer constructor( @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IFileService protected readonly fileService: IFileService, - @IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService, + @IUntitledEditorService protected readonly untitledEditorService: IUntitledEditorService, @ILifecycleService private readonly lifecycleService: ILifecycleService, @IInstantiationService protected instantiationService: IInstantiationService, @IConfigurationService private readonly configurationService: IConfigurationService, @@ -119,7 +118,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer })); } - private beforeShutdown(reason: ShutdownReason): boolean | Promise { + protected beforeShutdown(reason: ShutdownReason): boolean | Promise { // Dirty files need treatment on shutdown const dirty = this.getDirty(); @@ -152,7 +151,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer // If hot exit is enabled, backup dirty files and allow to exit without confirmation if (this.isHotExitEnabled) { - return this.backupBeforeShutdown(dirty, this.models, reason).then(didBackup => { + return this.backupBeforeShutdown(dirty, reason).then(didBackup => { if (didBackup) { return this.noVeto({ cleanUpBackups: false }); // no veto and no backup cleanup (since backup was successful) } @@ -171,7 +170,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer return this.confirmBeforeShutdown(); } - private async backupBeforeShutdown(dirtyToBackup: URI[], textFileEditorModelManager: ITextFileEditorModelManager, reason: ShutdownReason): Promise { + private async backupBeforeShutdown(dirtyToBackup: URI[], reason: ShutdownReason): Promise { const windowCount = await this.windowsService.getWindowCount(); // When quit is requested skip the confirm callback and attempt to backup all workspaces. @@ -212,24 +211,24 @@ export abstract class TextFileService extends Disposable implements ITextFileSer return false; } - await this.backupAll(dirtyToBackup, textFileEditorModelManager); + await this.backupAll(dirtyToBackup); return true; } - private backupAll(dirtyToBackup: URI[], textFileEditorModelManager: ITextFileEditorModelManager): Promise { + private backupAll(dirtyToBackup: URI[]): Promise { // split up between files and untitled const filesToBackup: ITextFileEditorModel[] = []; const untitledToBackup: URI[] = []; - dirtyToBackup.forEach(s => { - if (this.fileService.canHandleResource(s)) { - const model = textFileEditorModelManager.get(s); + dirtyToBackup.forEach(dirty => { + if (this.fileService.canHandleResource(dirty)) { + const model = this.models.get(dirty); if (model) { filesToBackup.push(model); } - } else if (s.scheme === Schemas.untitled) { - untitledToBackup.push(s); + } else if (dirty.scheme === Schemas.untitled) { + untitledToBackup.push(dirty); } }); @@ -436,7 +435,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer } async delete(resource: URI, options?: { useTrash?: boolean, recursive?: boolean }): Promise { - const dirtyFiles = this.getDirty().filter(dirty => isEqualOrParent(dirty, resource, !platform.isLinux /* ignorecase */)); + const dirtyFiles = this.getDirty().filter(dirty => isEqualOrParent(dirty, resource)); await this.revertAll(dirtyFiles, { soft: true }); @@ -467,7 +466,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer } // Handle dirty source models if existing (if source URI is a folder, this can be multiple) - const dirtySourceModels = this.getDirtyFileModels().filter(model => isEqualOrParent(model.getResource(), source, !platform.isLinux /* ignorecase */)); + const dirtySourceModels = this.getDirtyFileModels().filter(model => isEqualOrParent(model.getResource(), source)); const dirtyTargetModelUris: URI[] = []; if (dirtySourceModels.length) { await Promise.all(dirtySourceModels.map(async sourceModel => { @@ -475,7 +474,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer let targetModelResource: URI; // If the source is the actual model, just use target as new resource - if (isEqual(sourceModelResource, source, !platform.isLinux /* ignorecase */)) { + if (isEqual(sourceModelResource, source)) { targetModelResource = target; } @@ -538,7 +537,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer async confirmSave(resources?: URI[]): Promise { if (this.environmentService.isExtensionDevelopment) { - return ConfirmResult.DONT_SAVE; // no veto when we are in extension dev mode because we cannot assum we run interactive (e.g. tests) + return ConfirmResult.DONT_SAVE; // no veto when we are in extension dev mode because we cannot assume we run interactive (e.g. tests) } const resourcesToConfirm = this.getDirty(resources); @@ -593,11 +592,11 @@ export abstract class TextFileService extends Disposable implements ITextFileSer // split up between files and untitled const filesToSave: URI[] = []; const untitledToSave: URI[] = []; - toSave.forEach(s => { - if ((Array.isArray(arg1) || arg1 === true /* includeUntitled */) && s.scheme === Schemas.untitled) { - untitledToSave.push(s); + toSave.forEach(resourceToSave => { + if ((Array.isArray(arg1) || arg1 === true /* includeUntitled */) && resourceToSave.scheme === Schemas.untitled) { + untitledToSave.push(resourceToSave); } else { - filesToSave.push(s); + filesToSave.push(resourceToSave); } }); @@ -648,18 +647,19 @@ export abstract class TextFileService extends Disposable implements ITextFileSer return result; } - protected async promptForPath(resource: URI, defaultUri: URI): Promise { + protected async promptForPath(resource: URI, defaultUri: URI, availableFileSystems?: string[]): Promise { // Help user to find a name for the file by opening it first await this.editorService.openEditor({ resource, options: { revealIfOpened: true, preserveFocus: true, } }); - return this.fileDialogService.showSaveDialog(this.getSaveDialogOptions(defaultUri)); + return this.fileDialogService.pickFileToSave(this.getSaveDialogOptions(defaultUri, availableFileSystems)); } - private getSaveDialogOptions(defaultUri: URI): ISaveDialogOptions { + private getSaveDialogOptions(defaultUri: URI, availableFileSystems?: string[]): ISaveDialogOptions { const options: ISaveDialogOptions = { defaultUri, - title: nls.localize('saveAsTitle', "Save As") + title: nls.localize('saveAsTitle', "Save As"), + availableFileSystems, }; // Filters are only enabled on Windows where they work properly @@ -765,7 +765,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer dialogPath = this.suggestFileName(resource); } - targetResource = await this.promptForPath(resource, dialogPath); + targetResource = await this.promptForPath(resource, dialogPath, options ? options.availableFileSystems : undefined); } if (!targetResource) { @@ -855,14 +855,15 @@ export abstract class TextFileService extends Disposable implements ITextFileSer return false; } - // take over encoding, mode and model value from source model + // take over encoding, mode (only if more specific) and model value from source model targetModel.updatePreferredEncoding(sourceModel.getEncoding()); if (sourceModel.isResolved() && targetModel.isResolved()) { this.modelService.updateModel(targetModel.textEditorModel, createTextBufferFactoryFromSnapshot(sourceModel.createSnapshot())); - const mode = sourceModel.textEditorModel.getLanguageIdentifier(); - if (mode.language !== PLAINTEXT_MODE_ID) { - targetModel.textEditorModel.setMode(mode); // only use if more specific than plain/text + const sourceMode = sourceModel.textEditorModel.getLanguageIdentifier(); + const targetMode = targetModel.textEditorModel.getLanguageIdentifier(); + if (sourceMode.language !== PLAINTEXT_MODE_ID && targetMode.language === PLAINTEXT_MODE_ID) { + targetModel.textEditorModel.setMode(sourceMode); // only use if more specific than plain/text } } @@ -902,7 +903,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer return joinPath(lastActiveFolder, untitledFileName); } - return schemeFilter === Schemas.file ? URI.file(untitledFileName) : URI.from({ scheme: schemeFilter, authority: remoteAuthority, path: posix.sep + untitledFileName }); + return untitledResource.with({ path: untitledFileName }); } async revert(resource: URI, options?: IRevertOptions): Promise { diff --git a/src/vs/workbench/services/textfile/node/textResourcePropertiesService.ts b/src/vs/workbench/services/textfile/common/textResourcePropertiesService.ts similarity index 100% rename from src/vs/workbench/services/textfile/node/textResourcePropertiesService.ts rename to src/vs/workbench/services/textfile/common/textResourcePropertiesService.ts diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index fd36a109bf8..1cbf25a56ef 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -136,12 +136,12 @@ export interface ITextFileService extends IDisposable { confirmSave(resources?: URI[]): Promise; /** - * Convinient fast access to the current auto save mode. + * Convenient fast access to the current auto save mode. */ getAutoSaveMode(): AutoSaveMode; /** - * Convinient fast access to the raw configured auto save settings. + * Convenient fast access to the raw configured auto save settings. */ getAutoSaveConfiguration(): IAutoSaveConfiguration; } @@ -428,6 +428,7 @@ export interface ISaveOptions { overwriteEncoding?: boolean; skipSaveParticipants?: boolean; writeElevated?: boolean; + availableFileSystems?: string[]; } export interface ILoadOptions { @@ -467,6 +468,8 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport backup(target?: URI): Promise; + hasBackup(): boolean; + isDirty(): boolean; isResolved(): this is IResolvedTextFileEditorModel; diff --git a/src/vs/workbench/services/textfile/node/textFileService.ts b/src/vs/workbench/services/textfile/node/textFileService.ts index 242aadab987..3db51b4e10f 100644 --- a/src/vs/workbench/services/textfile/node/textFileService.ts +++ b/src/vs/workbench/services/textfile/node/textFileService.ts @@ -13,7 +13,7 @@ import { IFileStatWithMetadata, ICreateFileOptions, FileOperationError, FileOper import { Schemas } from 'vs/base/common/network'; import { exists, stat, chmod, rimraf, MAX_FILE_SIZE, MAX_HEAP_SIZE } from 'vs/base/node/pfs'; import { join, dirname } from 'vs/base/common/path'; -import { isMacintosh, isLinux } from 'vs/base/common/platform'; +import { isMacintosh } from 'vs/base/common/platform'; import product from 'vs/platform/product/node/product'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -390,7 +390,7 @@ export class EncodingOracle extends Disposable implements IResourceEncodings { const defaultEncodingOverrides: IEncodingOverride[] = []; // Global settings - defaultEncodingOverrides.push({ parent: this.environmentService.appSettingsHome, encoding: UTF8 }); + defaultEncodingOverrides.push({ parent: this.environmentService.userRoamingDataHome, encoding: UTF8 }); // Workspace files defaultEncodingOverrides.push({ extension: WORKSPACE_EXTENSION, encoding: UTF8 }); @@ -490,7 +490,7 @@ export class EncodingOracle extends Disposable implements IResourceEncodings { for (const override of this.encodingOverrides) { // check if the resource is child of encoding override path - if (override.parent && isEqualOrParent(resource, override.parent, !isLinux /* ignorecase */)) { + if (override.parent && isEqualOrParent(resource, override.parent)) { return override.encoding; } diff --git a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts index 3337c56b2a2..586639b4e8e 100644 --- a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts @@ -18,11 +18,11 @@ import { Schemas } from 'vs/base/common/network'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { rimraf, RimRafMode, copy, readFile, exists } from 'vs/base/node/pfs'; import { DisposableStore } from 'vs/base/common/lifecycle'; -import { FileService } from 'vs/workbench/services/files/common/fileService'; +import { FileService } from 'vs/platform/files/common/fileService'; import { NullLogService } from 'vs/platform/log/common/log'; import { getRandomTestPath } from 'vs/base/test/node/testUtils'; import { tmpdir } from 'os'; -import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFileSystemProvider'; +import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; import { generateUuid } from 'vs/base/common/uuid'; import { join, basename } from 'vs/base/common/path'; import { getPathFromAmdModule } from 'vs/base/common/amd'; @@ -247,7 +247,10 @@ suite('Files - TextFileService i/o', () => { } test('write - use encoding (cp1252)', async () => { - await testEncodingKeepsData(URI.file(join(testDir, 'some_cp1252.txt')), 'cp1252', ['ObjectCount = LoadObjects("Öffentlicher Ordner");', '', 'Private = "Persönliche Information"', ''].join(isWindows ? '\r\n' : '\n')); + const filePath = join(testDir, 'some_cp1252.txt'); + const contents = await readFile(filePath, 'utf8'); + const eol = /\r\n/.test(contents) ? '\r\n' : '\n'; + await testEncodingKeepsData(URI.file(filePath), 'cp1252', ['ObjectCount = LoadObjects("Öffentlicher Ordner");', '', 'Private = "Persönliche Information"', ''].join(eol)); }); test('write - use encoding (shiftjis)', async () => { diff --git a/src/vs/workbench/services/themes/common/fileIconThemeData.ts b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts similarity index 97% rename from src/vs/workbench/services/themes/common/fileIconThemeData.ts rename to src/vs/workbench/services/themes/browser/fileIconThemeData.ts index 306d58f9155..3059579a649 100644 --- a/src/vs/workbench/services/themes/common/fileIconThemeData.ts +++ b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts @@ -11,6 +11,7 @@ import * as Json from 'vs/base/common/json'; import { ExtensionData, IThemeExtensionPoint, IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IFileService } from 'vs/platform/files/common/files'; import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages'; +import { asDomUri } from 'vs/base/browser/dom'; export class FileIconThemeData implements IFileIconTheme { id: string; @@ -331,7 +332,7 @@ function _processIconThemeDocument(id: string, iconThemeDocumentLocation: URI, i let fonts = iconThemeDocument.fonts; if (Array.isArray(fonts)) { fonts.forEach(font => { - let src = font.src.map(l => `url('${resolvePath(l.path)}') format('${l.format}')`).join(', '); + let src = font.src.map(l => `url('${asDomUri(resolvePath(l.path))}') format('${l.format}')`).join(', '); cssRules.push(`@font-face { src: ${src}; font-family: '${font.id}'; font-weight: ${font.weight}; font-style: ${font.style}; }`); }); cssRules.push(`.show-file-icons .file-icon::before, .show-file-icons .folder-icon::before, .show-file-icons .rootfolder-icon::before { font-family: '${fonts[0].id}'; font-size: ${fonts[0].size || '150%'}}`); @@ -342,7 +343,7 @@ function _processIconThemeDocument(id: string, iconThemeDocumentLocation: URI, i let definition = iconThemeDocument.iconDefinitions[defId]; if (definition) { if (definition.iconPath) { - cssRules.push(`${selectors.join(', ')} { content: ' '; background-image: url("${resolvePath(definition.iconPath)}"); }`); + cssRules.push(`${selectors.join(', ')} { content: ' '; background-image: url("${asDomUri(resolvePath(definition.iconPath))}"); }`); } if (definition.fontCharacter || definition.fontColor) { let body = ''; @@ -366,5 +367,5 @@ function _processIconThemeDocument(id: string, iconThemeDocumentLocation: URI, i return result; } function escapeCSS(str: string) { - return window['CSS'].escape(str); + return (window)['CSS'].escape(str); } diff --git a/src/vs/workbench/services/themes/common/fileIconThemeStore.ts b/src/vs/workbench/services/themes/browser/fileIconThemeStore.ts similarity index 99% rename from src/vs/workbench/services/themes/common/fileIconThemeStore.ts rename to src/vs/workbench/services/themes/browser/fileIconThemeStore.ts index dfc2b180f4e..e4eb557f54c 100644 --- a/src/vs/workbench/services/themes/common/fileIconThemeStore.ts +++ b/src/vs/workbench/services/themes/browser/fileIconThemeStore.ts @@ -11,7 +11,7 @@ import { ExtensionsRegistry, ExtensionMessageCollector } from 'vs/workbench/serv import { ExtensionData, IThemeExtensionPoint } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { Event, Emitter } from 'vs/base/common/event'; -import { FileIconThemeData } from 'vs/workbench/services/themes/common/fileIconThemeData'; +import { FileIconThemeData } from 'vs/workbench/services/themes/browser/fileIconThemeData'; import { URI } from 'vs/base/common/uri'; import { Disposable } from 'vs/base/common/lifecycle'; diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index 3ff44d30384..cf5e181779a 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -19,8 +19,8 @@ import { Event, Emitter } from 'vs/base/common/event'; import { registerFileIconThemeSchemas } from 'vs/workbench/services/themes/common/fileIconThemeSchema'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { ColorThemeStore } from 'vs/workbench/services/themes/common/colorThemeStore'; -import { FileIconThemeStore } from 'vs/workbench/services/themes/common/fileIconThemeStore'; -import { FileIconThemeData } from 'vs/workbench/services/themes/common/fileIconThemeData'; +import { FileIconThemeStore } from 'vs/workbench/services/themes/browser/fileIconThemeStore'; +import { FileIconThemeData } from 'vs/workbench/services/themes/browser/fileIconThemeData'; import { removeClasses, addClasses } from 'vs/base/browser/dom'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IFileService, FileChangeType } from 'vs/platform/files/common/files'; @@ -31,6 +31,7 @@ import { textmateColorsSchemaId, registerColorThemeSchemas, textmateColorSetting import { workbenchColorsSchemaId } from 'vs/platform/theme/common/colorRegistry'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; +import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; // implementation @@ -96,10 +97,11 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { @IConfigurationService private readonly configurationService: IConfigurationService, @ITelemetryService private readonly telemetryService: ITelemetryService, @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, - @IFileService private readonly fileService: IFileService + @IFileService private readonly fileService: IFileService, + @IWorkbenchLayoutService readonly layoutService: IWorkbenchLayoutService ) { - this.container = document.body; + this.container = layoutService.getWorkbenchContainer(); this.colorThemeStore = new ColorThemeStore(extensionService, ColorThemeData.createLoadedEmptyTheme(DEFAULT_THEME_ID, DEFAULT_THEME_SETTING_VALUE)); this.onFileIconThemeChange = new Emitter(); this.iconThemeStore = new FileIconThemeStore(extensionService); @@ -372,29 +374,26 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { } private updateDynamicCSSRules(themeData: ITheme) { - let cssRules: string[] = []; - let hasRule: { [rule: string]: boolean } = {}; - let ruleCollector = { + const cssRules = new Set(); + const ruleCollector = { addRule: (rule: string) => { - if (!hasRule[rule]) { - cssRules.push(rule); - hasRule[rule] = true; + if (!cssRules.has(rule)) { + cssRules.add(rule); } } }; themingRegistry.getThemingParticipants().forEach(p => p(themeData, ruleCollector, this.environmentService)); - _applyRules(cssRules.join('\n'), colorThemeRulesClassName); + _applyRules([...cssRules].join('\n'), colorThemeRulesClassName); } private applyTheme(newTheme: ColorThemeData, settingsTarget: ConfigurationTarget | undefined | 'auto', silent = false): Promise { - if (this.container) { - if (this.currentColorTheme) { - removeClasses(this.container, this.currentColorTheme.id); - } else { - removeClasses(this.container, VS_DARK_THEME, VS_LIGHT_THEME, VS_HC_THEME); - } - addClasses(this.container, newTheme.id); + if (this.currentColorTheme) { + removeClasses(this.container, this.currentColorTheme.id); + } else { + removeClasses(this.container, VS_DARK_THEME, VS_LIGHT_THEME, VS_HC_THEME); } + addClasses(this.container, newTheme.id); + this.currentColorTheme = newTheme; if (!this.themingParticipantChangeListener) { this.themingParticipantChangeListener = themingRegistry.onThemingParticipantAdded(_ => this.updateDynamicCSSRules(this.currentColorTheme)); @@ -438,16 +437,21 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (themeData) { let key = themeType + themeData.extensionId; if (!this.themeExtensionsActivated.get(key)) { - /* __GDPR__ - "activatePlugin" : { - "id" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, - "name": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, - "isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "publisherDisplayName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "themeId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('activatePlugin', { + type ActivatePluginClassification = { + id: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; + name: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; + isBuiltin: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; + publisherDisplayName: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + themeId: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; + }; + type ActivatePluginEvent = { + id: string; + name: string; + isBuiltin: boolean; + publisherDisplayName: string; + themeId: string; + }; + this.telemetryService.publicLog2('activatePlugin', { id: themeData.extensionId, name: themeData.extensionName, isBuiltin: themeData.extensionIsBuiltin, @@ -509,12 +513,10 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { private doSetFileIconTheme(iconThemeData: FileIconThemeData): void { this.currentIconTheme = iconThemeData; - if (this.container) { - if (iconThemeData.id) { - addClasses(this.container, fileIconsEnabledClass); - } else { - removeClasses(this.container, fileIconsEnabledClass); - } + if (iconThemeData.id) { + addClasses(this.container, fileIconsEnabledClass); + } else { + removeClasses(this.container, fileIconsEnabledClass); } if (this.fileService && !resources.isEqual(iconThemeData.location, this.watchedIconThemeLocation)) { @@ -571,12 +573,10 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { } private getBaseThemeFromContainer() { - if (this.container) { - for (let i = this.container.classList.length - 1; i >= 0; i--) { - const item = document.body.classList.item(i); - if (item === VS_LIGHT_THEME || item === VS_DARK_THEME || item === VS_HC_THEME) { - return item; - } + for (let i = this.container.classList.length - 1; i >= 0; i--) { + const item = this.container.classList.item(i); + if (item === VS_LIGHT_THEME || item === VS_DARK_THEME || item === VS_HC_THEME) { + return item; } } return VS_DARK_THEME; @@ -693,4 +693,4 @@ const tokenColorCustomizationConfiguration: IConfigurationNode = { }; configurationRegistry.registerConfiguration(tokenColorCustomizationConfiguration); -registerSingleton(IWorkbenchThemeService, WorkbenchThemeService); \ No newline at end of file +registerSingleton(IWorkbenchThemeService, WorkbenchThemeService); diff --git a/src/vs/workbench/services/themes/common/colorThemeData.ts b/src/vs/workbench/services/themes/common/colorThemeData.ts index 08253f09445..6d39ebd157e 100644 --- a/src/vs/workbench/services/themes/common/colorThemeData.ts +++ b/src/vs/workbench/services/themes/common/colorThemeData.ts @@ -23,7 +23,7 @@ import { startsWith } from 'vs/base/common/strings'; let colorRegistry = Registry.as(Extensions.ColorContribution); -const tokenGroupToScopesMap: { [setting: string]: string[] } = { +const tokenGroupToScopesMap = { comments: ['comment'], strings: ['string'], keywords: ['keyword - keyword.operator', 'keyword.control', 'storage', 'storage.type'], @@ -146,10 +146,11 @@ export class ColorThemeData implements IColorTheme { // Put the general customizations such as comments, strings, etc. first so that // they can be overridden by specific customizations like "string.interpolated" for (let tokenGroup in tokenGroupToScopesMap) { - let value = customTokenColors[tokenGroup]; + const group = tokenGroup; // TS doesn't type 'tokenGroup' properly + let value = customTokenColors[group]; if (value) { let settings = typeof value === 'string' ? { foreground: value } : value; - let scopes = tokenGroupToScopesMap[tokenGroup]; + let scopes = tokenGroupToScopesMap[group]; for (let scope of scopes) { this.customTokenColors.push({ scope, settings }); } @@ -186,7 +187,7 @@ export class ColorThemeData implements IColorTheme { } toStorageData() { - let colorMapData = {}; + let colorMapData: { [key: string]: string } = {}; for (let key in this.colorMap) { colorMapData[key] = Color.Format.CSS.formatHexA(this.colorMap[key], true); } diff --git a/src/vs/workbench/services/themes/common/plistParser.ts b/src/vs/workbench/services/themes/common/plistParser.ts index e4478a5ecf6..6825c65147b 100644 --- a/src/vs/workbench/services/themes/common/plistParser.ts +++ b/src/vs/workbench/services/themes/common/plistParser.ts @@ -143,7 +143,7 @@ function _parse(content: string, filename: string | null, locationKeyName: strin if (curKey === null) { return fail('missing '); } - let newDict = {}; + let newDict: { [key: string]: any } = {}; if (locationKeyName !== null) { newDict[locationKeyName] = { filename: filename, @@ -168,7 +168,7 @@ function _parse(content: string, filename: string | null, locationKeyName: strin const arrState = { enterDict: function () { - let newDict = {}; + let newDict: { [key: string]: any } = {}; if (locationKeyName !== null) { newDict[locationKeyName] = { filename: filename, diff --git a/src/vs/workbench/services/themes/common/themeCompatibility.ts b/src/vs/workbench/services/themes/common/themeCompatibility.ts index 577b32e4206..6518ff4a4ac 100644 --- a/src/vs/workbench/services/themes/common/themeCompatibility.ts +++ b/src/vs/workbench/services/themes/common/themeCompatibility.ts @@ -26,7 +26,8 @@ export function convertSettings(oldSettings: ITokenColorizationRule[], resultRul if (!settings) { rule.settings = {}; } else { - for (let key in settings) { + for (const settingKey in settings) { + const key = settingKey; let mappings = settingToColorIdMapping[key]; if (mappings) { let colorHex = settings[key]; diff --git a/src/vs/workbench/services/themes/common/workbenchThemeService.ts b/src/vs/workbench/services/themes/common/workbenchThemeService.ts index 831b8ad3391..deb116b60f8 100644 --- a/src/vs/workbench/services/themes/common/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/common/workbenchThemeService.ts @@ -69,6 +69,7 @@ export interface IColorCustomizations { } export interface ITokenColorCustomizations { + [groupIdOrThemeSettingsId: string]: string | ITokenColorizationSetting | ITokenColorCustomizations | undefined | ITokenColorizationRule[]; comments?: string | ITokenColorizationSetting; strings?: string | ITokenColorizationSetting; numbers?: string | ITokenColorizationSetting; @@ -103,5 +104,6 @@ export interface IThemeExtensionPoint { label?: string; description?: string; path: string; + uiTheme?: typeof VS_LIGHT_THEME | typeof VS_DARK_THEME | typeof VS_HC_THEME; _watch: boolean; // unsupported options to watch location } \ No newline at end of file diff --git a/src/vs/workbench/services/untitled/common/untitledEditorService.ts b/src/vs/workbench/services/untitled/common/untitledEditorService.ts index 35b571ec52b..5996ee18648 100644 --- a/src/vs/workbench/services/untitled/common/untitledEditorService.ts +++ b/src/vs/workbench/services/untitled/common/untitledEditorService.ts @@ -66,6 +66,11 @@ export interface IUntitledEditorService { */ isDirty(resource: URI): boolean; + /** + * Find out if a backup with the provided resource exists and has a backup on disk. + */ + hasBackup(resource: URI): boolean; + /** * Reverts the untitled resources if found. */ @@ -170,6 +175,12 @@ export class UntitledEditorService extends Disposable implements IUntitledEditor return input ? input.isDirty() : false; } + hasBackup(resource: URI): boolean { + const input = this.get(resource); + + return input ? input.hasBackup() : false; + } + getDirty(resources?: URI[]): URI[] { let inputs: UntitledEditorInput[]; if (resources) { @@ -234,21 +245,10 @@ export class UntitledEditorService extends Disposable implements IUntitledEditor const input = this.instantiationService.createInstance(UntitledEditorInput, untitledResource, hasAssociatedFilePath, mode, initialValue, encoding); - const contentListener = input.onDidModelChangeContent(() => { - this._onDidChangeContent.fire(untitledResource); - }); - - const dirtyListener = input.onDidChangeDirty(() => { - this._onDidChangeDirty.fire(untitledResource); - }); - - const encodingListener = input.onDidModelChangeEncoding(() => { - this._onDidChangeEncoding.fire(untitledResource); - }); - - const disposeListener = input.onDispose(() => { - this._onDidDisposeModel.fire(untitledResource); - }); + const contentListener = input.onDidModelChangeContent(() => this._onDidChangeContent.fire(untitledResource)); + const dirtyListener = input.onDidChangeDirty(() => this._onDidChangeDirty.fire(untitledResource)); + const encodingListener = input.onDidModelChangeEncoding(() => this._onDidChangeEncoding.fire(untitledResource)); + const disposeListener = input.onDispose(() => this._onDidDisposeModel.fire(untitledResource)); // Remove from cache on dispose const onceDispose = Event.once(input.onDispose); diff --git a/src/vs/workbench/services/userData/common/fileUserDataProvider.ts b/src/vs/workbench/services/userData/common/fileUserDataProvider.ts new file mode 100644 index 00000000000..4bf98510ac4 --- /dev/null +++ b/src/vs/workbench/services/userData/common/fileUserDataProvider.ts @@ -0,0 +1,142 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event, Emitter } from 'vs/base/common/event'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { IFileSystemProviderWithFileReadWriteCapability, IFileChange, IWatchOptions, IStat, FileOverwriteOptions, FileType, FileWriteOptions, FileDeleteOptions, FileSystemProviderCapabilities, IFileSystemProviderWithOpenReadWriteCloseCapability, FileOpenOptions, hasReadWriteCapability, hasOpenReadWriteCloseCapability } from 'vs/platform/files/common/files'; +import { URI } from 'vs/base/common/uri'; +import * as resources from 'vs/base/common/resources'; +import { startsWith } from 'vs/base/common/strings'; +import { BACKUPS } from 'vs/platform/environment/common/environment'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; + +export class FileUserDataProvider extends Disposable implements IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithOpenReadWriteCloseCapability { + + readonly capabilities: FileSystemProviderCapabilities = this.fileSystemProvider.capabilities; + readonly onDidChangeCapabilities: Event = Event.None; + + private readonly _onDidChangeFile: Emitter = this._register(new Emitter()); + readonly onDidChangeFile: Event = this._onDidChangeFile.event; + + private readonly userDataHome: URI; + + constructor( + private readonly fileSystemUserDataHome: URI, + private readonly fileSystemBackupsHome: URI, + private readonly fileSystemProvider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability, + environmentService: IWorkbenchEnvironmentService + ) { + super(); + + this.userDataHome = environmentService.userRoamingDataHome; + + // Assumption: This path always exists + this._register(this.fileSystemProvider.watch(this.fileSystemUserDataHome, { recursive: false, excludes: [] })); + this._register(this.fileSystemProvider.onDidChangeFile(e => this.handleFileChanges(e))); + } + + watch(resource: URI, opts: IWatchOptions): IDisposable { + return this.fileSystemProvider.watch(this.toFileSystemResource(resource), opts); + } + + stat(resource: URI): Promise { + return this.fileSystemProvider.stat(this.toFileSystemResource(resource)); + } + + mkdir(resource: URI): Promise { + return this.fileSystemProvider.mkdir(this.toFileSystemResource(resource)); + } + + rename(from: URI, to: URI, opts: FileOverwriteOptions): Promise { + return this.fileSystemProvider.rename(this.toFileSystemResource(from), this.toFileSystemResource(to), opts); + } + + readFile(resource: URI): Promise { + if (hasReadWriteCapability(this.fileSystemProvider)) { + return this.fileSystemProvider.readFile(this.toFileSystemResource(resource)); + } + throw new Error('not supported'); + } + + readdir(resource: URI): Promise<[string, FileType][]> { + return this.fileSystemProvider.readdir(this.toFileSystemResource(resource)); + } + + writeFile(resource: URI, content: Uint8Array, opts: FileWriteOptions): Promise { + if (hasReadWriteCapability(this.fileSystemProvider)) { + return this.fileSystemProvider.writeFile(this.toFileSystemResource(resource), content, opts); + } + throw new Error('not supported'); + } + + open(resource: URI, opts: FileOpenOptions): Promise { + if (hasOpenReadWriteCloseCapability(this.fileSystemProvider)) { + return this.fileSystemProvider.open(this.toFileSystemResource(resource), opts); + } + throw new Error('not supported'); + } + + close(fd: number): Promise { + if (hasOpenReadWriteCloseCapability(this.fileSystemProvider)) { + return this.fileSystemProvider.close(fd); + } + throw new Error('not supported'); + } + + read(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise { + if (hasOpenReadWriteCloseCapability(this.fileSystemProvider)) { + return this.fileSystemProvider.read(fd, pos, data, offset, length); + } + throw new Error('not supported'); + } + + write(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise { + if (hasOpenReadWriteCloseCapability(this.fileSystemProvider)) { + return this.fileSystemProvider.write(fd, pos, data, offset, length); + } + throw new Error('not supported'); + } + + delete(resource: URI, opts: FileDeleteOptions): Promise { + return this.fileSystemProvider.delete(this.toFileSystemResource(resource), opts); + } + + private handleFileChanges(changes: IFileChange[]): void { + const userDataChanges: IFileChange[] = []; + for (const change of changes) { + const userDataResource = this.toUserDataResource(change.resource); + if (userDataResource) { + userDataChanges.push({ + resource: userDataResource, + type: change.type + }); + } + } + if (userDataChanges.length) { + this._onDidChangeFile.fire(userDataChanges); + } + } + + private toFileSystemResource(userDataResource: URI): URI { + const relativePath = resources.relativePath(this.userDataHome, userDataResource)!; + if (startsWith(relativePath, BACKUPS)) { + return resources.joinPath(resources.dirname(this.fileSystemBackupsHome), relativePath); + } + return resources.joinPath(this.fileSystemUserDataHome, relativePath); + } + + private toUserDataResource(fileSystemResource: URI): URI | null { + if (resources.isEqualOrParent(fileSystemResource, this.fileSystemUserDataHome)) { + const relativePath = resources.relativePath(this.fileSystemUserDataHome, fileSystemResource); + return relativePath ? resources.joinPath(this.userDataHome, relativePath) : this.userDataHome; + } + if (resources.isEqualOrParent(fileSystemResource, this.fileSystemBackupsHome)) { + const relativePath = resources.relativePath(this.fileSystemBackupsHome, fileSystemResource); + return relativePath ? resources.joinPath(this.userDataHome, BACKUPS, relativePath) : resources.joinPath(this.userDataHome, BACKUPS); + } + return null; + } + +} \ No newline at end of file diff --git a/src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts b/src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts new file mode 100644 index 00000000000..9693eaa5e00 --- /dev/null +++ b/src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event, Emitter } from 'vs/base/common/event'; +import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IUserDataProvider, FileChangeEvent } from 'vs/workbench/services/userData/common/userData'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { FileChangeType } from 'vs/platform/files/common/files'; + +export class InMemoryUserDataProvider extends Disposable implements IUserDataProvider { + _serviceBrand: any; + + private _onDidChangeFile: Emitter = this._register(new Emitter()); + readonly onDidChangeFile: Event = this._onDidChangeFile.event; + + private readonly store: Map = new Map(); + + constructor() { + super(); + this._register(toDisposable(() => this.store.clear())); + } + + async listFiles(path: string): Promise { + return []; + } + + async readFile(path: string): Promise { + if (this.store.has(path)) { + return VSBuffer.fromString(this.store.get(path)!).buffer; + } + throw new Error(`Not Found: ${path}`); + } + + async writeFile(path: string, value: Uint8Array): Promise { + const exists = this.store.has(path); + const content = VSBuffer.wrap(value).toString(); + if (!exists || content !== this.store.get(path)) { + this.store.set(path, content); + this._onDidChangeFile.fire([{ path, type: exists ? FileChangeType.UPDATED : FileChangeType.ADDED }]); + } + } + + async deleteFile(path: string): Promise { + if (this.store.has(path)) { + this.store.delete(path); + this._onDidChangeFile.fire([{ path, type: FileChangeType.DELETED }]); + } + } +} \ No newline at end of file diff --git a/src/vs/workbench/services/userData/common/userData.ts b/src/vs/workbench/services/userData/common/userData.ts new file mode 100644 index 00000000000..6ce93879fc3 --- /dev/null +++ b/src/vs/workbench/services/userData/common/userData.ts @@ -0,0 +1,80 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from 'vs/base/common/event'; +import { FileChangeType } from 'vs/platform/files/common/files'; + +/** + * The event user data providers must use to signal a file change. + */ +export interface FileChangeEvent { + + /** + * The type of change. + */ + readonly type: FileChangeType; + + /** + * The path of the file that has changed. + */ + readonly path: string; +} + +/** + * The userDataProvider is used to handle user specific application + * state like settings, keybindings, UI state (e.g. opened editors) and snippets. + * + * The API reflects a simple file system provider that comes with the notion of paths + * (UNIX slash separated) as well as files. Folders are not a top level concept (e.g. we + * do not require to create or delete them), however, files can be grouped beneath one path + * and also listed from that path. + * + * Example: + * ```ts + * await writeFile('snippets/global/markdown.json', ); + * await writeFile('snippets/global/html.json', ); + * await writeFile('snippets/global/javascript.json', ); + * + * const files = await listFiles('snippets/global'); + * console.log(files); // -> ['snippets/global/markdown.json', 'snippets/global/html.json', 'snippets/global/javascript.json'] + * ``` + */ +export interface IUserDataProvider { + + /** + * An event to signal that a file has been created, changed, or deleted. + */ + readonly onDidChangeFile: Event; + + /** + * Read the file contents of the given path. + * + * Throw an error if the path does not exist. + */ + readFile(path: string): Promise; + + /** + * Writes the provided content to the file path overwriting any existing content on that path. + * + * If the path does not exist, it will be created. + * + * Throw an error if the path is a parent to existing files. + */ + writeFile(path: string, content: Uint8Array): Promise; + + /** + * Delete the file at the given path. + * + * Does NOT throw an error when the path does not exist. + */ + deleteFile(path: string): Promise; + + /** + * Returns an array of files at the given path. + * + * Throw an error if the path does not exist or points to a file. + */ + listFiles(path: string): Promise; +} diff --git a/src/vs/workbench/services/userData/test/electron-browser/fileUserDataProvider.test.ts b/src/vs/workbench/services/userData/test/electron-browser/fileUserDataProvider.test.ts new file mode 100644 index 00000000000..b8ba819bba8 --- /dev/null +++ b/src/vs/workbench/services/userData/test/electron-browser/fileUserDataProvider.test.ts @@ -0,0 +1,478 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import * as os from 'os'; +import * as path from 'vs/base/common/path'; +import * as uuid from 'vs/base/common/uuid'; +import * as pfs from 'vs/base/node/pfs'; +import { IFileService, FileChangeType, IFileChange, IFileSystemProviderWithFileReadWriteCapability, IStat, FileType, FileSystemProviderCapabilities } from 'vs/platform/files/common/files'; +import { FileService } from 'vs/platform/files/common/fileService'; +import { NullLogService } from 'vs/platform/log/common/log'; +import { Schemas } from 'vs/base/common/network'; +import { URI } from 'vs/base/common/uri'; +import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; +import { joinPath, dirname } from 'vs/base/common/resources'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider'; +import { BACKUPS } from 'vs/platform/environment/common/environment'; +import { DisposableStore, IDisposable, Disposable } from 'vs/base/common/lifecycle'; +import { BrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; +import { Emitter, Event } from 'vs/base/common/event'; +import { timeout } from 'vs/base/common/async'; + +suite('FileUserDataProvider', () => { + + let testObject: IFileService; + let rootPath: string; + let userDataPath: string; + let backupsPath: string; + let userDataResource: URI; + const disposables = new DisposableStore(); + + setup(async () => { + const logService = new NullLogService(); + testObject = new FileService(logService); + disposables.add(testObject); + + const diskFileSystemProvider = new DiskFileSystemProvider(logService); + disposables.add(diskFileSystemProvider); + disposables.add(testObject.registerProvider(Schemas.file, diskFileSystemProvider)); + + rootPath = path.join(os.tmpdir(), 'vsctests', uuid.generateUuid()); + userDataPath = path.join(rootPath, 'user'); + backupsPath = path.join(rootPath, BACKUPS); + userDataResource = URI.file(userDataPath).with({ scheme: Schemas.userData }); + await Promise.all([pfs.mkdirp(userDataPath), pfs.mkdirp(backupsPath)]); + + const environmentService = new BrowserWorkbenchEnvironmentService({ workspaceId: 'workspaceId' }); + environmentService.userRoamingDataHome = userDataResource; + + const userDataFileSystemProvider = new FileUserDataProvider(URI.file(userDataPath), URI.file(backupsPath), diskFileSystemProvider, environmentService); + disposables.add(userDataFileSystemProvider); + disposables.add(testObject.registerProvider(Schemas.userData, userDataFileSystemProvider)); + }); + + teardown(async () => { + disposables.clear(); + await pfs.rimraf(rootPath, pfs.RimRafMode.MOVE); + }); + + test('exists return false when file does not exist', async () => { + const exists = await testObject.exists(joinPath(userDataResource, 'settings.json')); + assert.equal(exists, false); + }); + + test('read file throws error if not exist', async () => { + try { + await testObject.readFile(joinPath(userDataResource, 'settings.json')); + assert.fail('Should fail since file does not exist'); + } catch (e) { } + }); + + test('read existing file', async () => { + await pfs.writeFile(path.join(userDataPath, 'settings.json'), '{}'); + const result = await testObject.readFile(joinPath(userDataResource, 'settings.json')); + assert.equal(result.value, '{}'); + }); + + test('create file', async () => { + const resource = joinPath(userDataResource, 'settings.json'); + const actual1 = await testObject.createFile(resource, VSBuffer.fromString('{}')); + assert.equal(actual1.resource.toString(), resource.toString()); + const actual2 = await pfs.readFile(path.join(userDataPath, 'settings.json')); + assert.equal(actual2, '{}'); + }); + + test('write file creates the file if not exist', async () => { + const resource = joinPath(userDataResource, 'settings.json'); + const actual1 = await testObject.writeFile(resource, VSBuffer.fromString('{}')); + assert.equal(actual1.resource.toString(), resource.toString()); + const actual2 = await pfs.readFile(path.join(userDataPath, 'settings.json')); + assert.equal(actual2, '{}'); + }); + + test('write to existing file', async () => { + const resource = joinPath(userDataResource, 'settings.json'); + await pfs.writeFile(path.join(userDataPath, 'settings.json'), '{}'); + const actual1 = await testObject.writeFile(resource, VSBuffer.fromString('{a:1}')); + assert.equal(actual1.resource.toString(), resource.toString()); + const actual2 = await pfs.readFile(path.join(userDataPath, 'settings.json')); + assert.equal(actual2, '{a:1}'); + }); + + test('delete file', async () => { + await pfs.writeFile(path.join(userDataPath, 'settings.json'), ''); + await testObject.del(joinPath(userDataResource, 'settings.json')); + const result = await pfs.exists(path.join(userDataPath, 'settings.json')); + assert.equal(false, result); + }); + + test('resolve file', async () => { + await pfs.writeFile(path.join(userDataPath, 'settings.json'), ''); + const result = await testObject.resolve(joinPath(userDataResource, 'settings.json')); + assert.ok(!result.isDirectory); + assert.ok(result.children === undefined); + }); + + test('exists return false for folder that does not exist', async () => { + const exists = await testObject.exists(joinPath(userDataResource, 'snippets')); + assert.equal(exists, false); + }); + + test('exists return true for folder that exists', async () => { + await pfs.mkdirp(path.join(userDataPath, 'snippets')); + const exists = await testObject.exists(joinPath(userDataResource, 'snippets')); + assert.equal(exists, true); + }); + + test('read file throws error for folder', async () => { + await pfs.mkdirp(path.join(userDataPath, 'snippets')); + try { + await testObject.readFile(joinPath(userDataResource, 'snippets')); + assert.fail('Should fail since read file is not supported for folders'); + } catch (e) { } + }); + + test('read file under folder', async () => { + await pfs.mkdirp(path.join(userDataPath, 'snippets')); + await pfs.writeFile(path.join(userDataPath, 'snippets', 'settings.json'), '{}'); + const resource = joinPath(userDataResource, 'snippets/settings.json'); + const actual = await testObject.readFile(resource); + assert.equal(actual.resource.toString(), resource.toString()); + assert.equal(actual.value, '{}'); + }); + + test('read file under sub folder', async () => { + await pfs.mkdirp(path.join(userDataPath, 'snippets', 'java')); + await pfs.writeFile(path.join(userDataPath, 'snippets', 'java', 'settings.json'), '{}'); + const resource = joinPath(userDataResource, 'snippets/java/settings.json'); + const actual = await testObject.readFile(resource); + assert.equal(actual.resource.toString(), resource.toString()); + assert.equal(actual.value, '{}'); + }); + + test('create file under folder that exists', async () => { + await pfs.mkdirp(path.join(userDataPath, 'snippets')); + const resource = joinPath(userDataResource, 'snippets/settings.json'); + const actual1 = await testObject.createFile(resource, VSBuffer.fromString('{}')); + assert.equal(actual1.resource.toString(), resource.toString()); + const actual2 = await pfs.readFile(path.join(userDataPath, 'snippets', 'settings.json')); + assert.equal(actual2, '{}'); + }); + + test('create file under folder that does not exist', async () => { + const resource = joinPath(userDataResource, 'snippets/settings.json'); + const actual1 = await testObject.createFile(resource, VSBuffer.fromString('{}')); + assert.equal(actual1.resource.toString(), resource.toString()); + const actual2 = await pfs.readFile(path.join(userDataPath, 'snippets', 'settings.json')); + assert.equal(actual2, '{}'); + }); + + test('write to not existing file under container that exists', async () => { + await pfs.mkdirp(path.join(userDataPath, 'snippets')); + const resource = joinPath(userDataResource, 'snippets/settings.json'); + const actual1 = await testObject.writeFile(resource, VSBuffer.fromString('{}')); + assert.equal(actual1.resource.toString(), resource.toString()); + const actual = await pfs.readFile(path.join(userDataPath, 'snippets', 'settings.json')); + assert.equal(actual, '{}'); + }); + + test('write to not existing file under container that does not exists', async () => { + const resource = joinPath(userDataResource, 'snippets/settings.json'); + const actual1 = await testObject.writeFile(resource, VSBuffer.fromString('{}')); + assert.equal(actual1.resource.toString(), resource.toString()); + const actual = await pfs.readFile(path.join(userDataPath, 'snippets', 'settings.json')); + assert.equal(actual, '{}'); + }); + + test('write to existing file under container', async () => { + await pfs.mkdirp(path.join(userDataPath, 'snippets')); + await pfs.writeFile(path.join(userDataPath, 'snippets', 'settings.json'), '{}'); + const resource = joinPath(userDataResource, 'snippets/settings.json'); + const actual1 = await testObject.writeFile(resource, VSBuffer.fromString('{a:1}')); + assert.equal(actual1.resource.toString(), resource.toString()); + const actual = await pfs.readFile(path.join(userDataPath, 'snippets', 'settings.json')); + assert.equal(actual.toString(), '{a:1}'); + }); + + test('write file under sub container', async () => { + const resource = joinPath(userDataResource, 'snippets/java/settings.json'); + const actual1 = await testObject.writeFile(resource, VSBuffer.fromString('{}')); + assert.equal(actual1.resource.toString(), resource.toString()); + const actual = await pfs.readFile(path.join(userDataPath, 'snippets', 'java', 'settings.json')); + assert.equal(actual, '{}'); + }); + + test('delete throws error for folder that does not exist', async () => { + try { + await testObject.del(joinPath(userDataResource, 'snippets')); + assert.fail('Should fail the folder does not exist'); + } catch (e) { } + }); + + test('delete not existing file under container that exists', async () => { + await pfs.mkdirp(path.join(userDataPath, 'snippets')); + try { + await testObject.del(joinPath(userDataResource, 'snippets/settings.json')); + assert.fail('Should fail since file does not exist'); + } catch (e) { } + }); + + test('delete not existing file under container that does not exists', async () => { + try { + await testObject.del(joinPath(userDataResource, 'snippets/settings.json')); + assert.fail('Should fail since file does not exist'); + } catch (e) { } + }); + + test('delete existing file under folder', async () => { + await pfs.mkdirp(path.join(userDataPath, 'snippets')); + await pfs.writeFile(path.join(userDataPath, 'snippets', 'settings.json'), '{}'); + await testObject.del(joinPath(userDataResource, 'snippets/settings.json')); + const exists = await pfs.exists(path.join(userDataPath, 'snippets', 'settings.json')); + assert.equal(exists, false); + }); + + test('resolve folder', async () => { + await pfs.mkdirp(path.join(userDataPath, 'snippets')); + await pfs.writeFile(path.join(userDataPath, 'snippets', 'settings.json'), '{}'); + const result = await testObject.resolve(joinPath(userDataResource, 'snippets')); + assert.ok(result.isDirectory); + assert.ok(result.children !== undefined); + assert.equal(result.children!.length, 1); + assert.equal(result.children![0].resource.toString(), joinPath(userDataResource, 'snippets/settings.json').toString()); + }); + + test('read backup file', async () => { + await pfs.writeFile(path.join(backupsPath, 'backup.json'), '{}'); + const result = await testObject.readFile(joinPath(userDataResource, `${BACKUPS}/backup.json`)); + assert.equal(result.value, '{}'); + }); + + test('create backup file', async () => { + await testObject.createFile(joinPath(userDataResource, `${BACKUPS}/backup.json`), VSBuffer.fromString('{}')); + const result = await pfs.readFile(path.join(backupsPath, 'backup.json')); + assert.equal(result, '{}'); + }); + + test('write backup file', async () => { + await pfs.writeFile(path.join(backupsPath, 'backup.json'), '{}'); + await testObject.writeFile(joinPath(userDataResource, `${BACKUPS}/backup.json`), VSBuffer.fromString('{a:1}')); + const result = await pfs.readFile(path.join(backupsPath, 'backup.json')); + assert.equal(result, '{a:1}'); + }); + + test('resolve backups folder', async () => { + await pfs.writeFile(path.join(backupsPath, 'backup.json'), '{}'); + const result = await testObject.resolve(joinPath(userDataResource, BACKUPS)); + assert.ok(result.isDirectory); + assert.ok(result.children !== undefined); + assert.equal(result.children!.length, 1); + assert.equal(result.children![0].resource.toString(), joinPath(userDataResource, `${BACKUPS}/backup.json`).toString()); + }); +}); + +class TestFileSystemProvider implements IFileSystemProviderWithFileReadWriteCapability { + + constructor(readonly onDidChangeFile: Event) { } + + readonly capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.FileReadWrite; + + readonly onDidChangeCapabilities: Event = Event.None; + + watch(): IDisposable { return Disposable.None; } + + stat(): Promise { throw new Error('Not Supported'); } + + mkdir(resource: URI): Promise { throw new Error('Not Supported'); } + + rename(): Promise { throw new Error('Not Supported'); } + + readFile(resource: URI): Promise { throw new Error('Not Supported'); } + + readdir(resource: URI): Promise<[string, FileType][]> { throw new Error('Not Supported'); } + + writeFile(): Promise { throw new Error('Not Supported'); } + + delete(): Promise { throw new Error('Not Supported'); } + +} + +suite('FileUserDataProvider - Watching', () => { + + let testObject: IFileService; + let localBackupsResource: URI; + let localUserDataResource: URI; + let userDataResource: URI; + const disposables = new DisposableStore(); + + const fileEventEmitter: Emitter = new Emitter(); + disposables.add(fileEventEmitter); + + setup(() => { + + const rootPath = path.join(os.tmpdir(), 'vsctests', uuid.generateUuid()); + const userDataPath = path.join(rootPath, 'user'); + const backupsPath = path.join(rootPath, BACKUPS); + localBackupsResource = URI.file(backupsPath); + localUserDataResource = URI.file(userDataPath); + userDataResource = localUserDataResource.with({ scheme: Schemas.userData }); + + const environmentService = new BrowserWorkbenchEnvironmentService({ workspaceId: 'workspaceId' }); + environmentService.userRoamingDataHome = userDataResource; + + const userDataFileSystemProvider = new FileUserDataProvider(localUserDataResource, localBackupsResource, new TestFileSystemProvider(fileEventEmitter.event), environmentService); + disposables.add(userDataFileSystemProvider); + + testObject = new FileService(new NullLogService()); + disposables.add(testObject); + disposables.add(testObject.registerProvider(Schemas.userData, userDataFileSystemProvider)); + }); + + teardown(() => { + disposables.clear(); + }); + + test('file added change event', done => { + const expected = joinPath(userDataResource, 'settings.json'); + const target = joinPath(localUserDataResource, 'settings.json'); + testObject.onFileChanges(e => { + if (e.contains(expected, FileChangeType.ADDED)) { + done(); + } + }); + fileEventEmitter.fire([{ + resource: target, + type: FileChangeType.ADDED + }]); + }); + + test('file updated change event', done => { + const expected = joinPath(userDataResource, 'settings.json'); + const target = joinPath(localUserDataResource, 'settings.json'); + testObject.onFileChanges(e => { + if (e.contains(expected, FileChangeType.UPDATED)) { + done(); + } + }); + fileEventEmitter.fire([{ + resource: target, + type: FileChangeType.UPDATED + }]); + }); + + test('file deleted change event', done => { + const expected = joinPath(userDataResource, 'settings.json'); + const target = joinPath(localUserDataResource, 'settings.json'); + testObject.onFileChanges(e => { + if (e.contains(expected, FileChangeType.DELETED)) { + done(); + } + }); + fileEventEmitter.fire([{ + resource: target, + type: FileChangeType.DELETED + }]); + }); + + test('file under folder created change event', done => { + const expected = joinPath(userDataResource, 'snippets', 'settings.json'); + const target = joinPath(localUserDataResource, 'snippets', 'settings.json'); + testObject.onFileChanges(e => { + if (e.contains(expected, FileChangeType.ADDED)) { + done(); + } + }); + fileEventEmitter.fire([{ + resource: target, + type: FileChangeType.ADDED + }]); + }); + + test('file under folder updated change event', done => { + const expected = joinPath(userDataResource, 'snippets', 'settings.json'); + const target = joinPath(localUserDataResource, 'snippets', 'settings.json'); + testObject.onFileChanges(e => { + if (e.contains(expected, FileChangeType.UPDATED)) { + done(); + } + }); + fileEventEmitter.fire([{ + resource: target, + type: FileChangeType.UPDATED + }]); + }); + + test('file under folder deleted change event', done => { + const expected = joinPath(userDataResource, 'snippets', 'settings.json'); + const target = joinPath(localUserDataResource, 'snippets', 'settings.json'); + testObject.onFileChanges(e => { + if (e.contains(expected, FileChangeType.DELETED)) { + done(); + } + }); + fileEventEmitter.fire([{ + resource: target, + type: FileChangeType.DELETED + }]); + }); + + test('event is not triggered if file is not under user data', async () => { + const target = joinPath(dirname(localUserDataResource), 'settings.json'); + let triggered = false; + testObject.onFileChanges(() => triggered = true); + fileEventEmitter.fire([{ + resource: target, + type: FileChangeType.DELETED + }]); + await timeout(0); + if (triggered) { + assert.fail('event should not be triggered'); + } + }); + + test('backup file created change event', done => { + const expected = joinPath(userDataResource, BACKUPS, 'settings.json'); + const target = joinPath(localBackupsResource, 'settings.json'); + testObject.onFileChanges(e => { + if (e.contains(expected, FileChangeType.ADDED)) { + done(); + } + }); + fileEventEmitter.fire([{ + resource: target, + type: FileChangeType.ADDED + }]); + }); + + test('backup file update change event', done => { + const expected = joinPath(userDataResource, BACKUPS, 'settings.json'); + const target = joinPath(localBackupsResource, 'settings.json'); + testObject.onFileChanges(e => { + if (e.contains(expected, FileChangeType.UPDATED)) { + done(); + } + }); + fileEventEmitter.fire([{ + resource: target, + type: FileChangeType.UPDATED + }]); + }); + + test('backup file delete change event', done => { + const expected = joinPath(userDataResource, BACKUPS, 'settings.json'); + const target = joinPath(localBackupsResource, 'settings.json'); + testObject.onFileChanges(e => { + if (e.contains(expected, FileChangeType.DELETED)) { + done(); + } + }); + fileEventEmitter.fire([{ + resource: target, + type: FileChangeType.DELETED + }]); + }); +}); \ No newline at end of file diff --git a/src/vs/workbench/services/viewlet/browser/viewlet.ts b/src/vs/workbench/services/viewlet/browser/viewlet.ts index 2567f4cacea..92349b87a4b 100644 --- a/src/vs/workbench/services/viewlet/browser/viewlet.ts +++ b/src/vs/workbench/services/viewlet/browser/viewlet.ts @@ -7,17 +7,18 @@ import { IViewlet } from 'vs/workbench/common/viewlet'; import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { Event } from 'vs/base/common/event'; import { ViewletDescriptor } from 'vs/workbench/browser/viewlet'; -import { ILocalProgressService } from 'vs/platform/progress/common/progress'; +import { IProgressIndicator } from 'vs/platform/progress/common/progress'; export const IViewletService = createDecorator('viewletService'); export interface IViewletService { + _serviceBrand: ServiceIdentifier; - onDidViewletRegister: Event; - onDidViewletDeregister: Event; - onDidViewletOpen: Event; - onDidViewletClose: Event; + readonly onDidViewletRegister: Event; + readonly onDidViewletDeregister: Event; + readonly onDidViewletOpen: Event; + readonly onDidViewletClose: Event; /** * Opens a viewlet with the given identifier and pass keyboard focus to it if specified. @@ -47,7 +48,7 @@ export interface IViewletService { /** * Returns the progress indicator for the side bar. */ - getProgressIndicator(id: string): ILocalProgressService | null; + getProgressIndicator(id: string): IProgressIndicator | null; /** * Hide the active viewlet. diff --git a/src/vs/workbench/services/window/electron-browser/windowService.ts b/src/vs/workbench/services/window/electron-browser/windowService.ts index d3975f0acdd..031e015589c 100644 --- a/src/vs/workbench/services/window/electron-browser/windowService.ts +++ b/src/vs/workbench/services/window/electron-browser/windowService.ts @@ -5,7 +5,7 @@ import { Event } from 'vs/base/common/event'; import { IWindowService, IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult, IMessageBoxResult, IDevToolsOptions, IOpenSettings, IURIToOpen, isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/windows/common/windows'; -import { IRecentlyOpened } from 'vs/platform/history/common/history'; +import { IRecentlyOpened, IRecent } from 'vs/platform/history/common/history'; import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { URI } from 'vs/base/common/uri'; @@ -109,7 +109,7 @@ export class WindowService extends Disposable implements IWindowService { return this.windowsService.closeWindow(this.windowId); } - toggleFullScreen(): Promise { + toggleFullScreen(target?: HTMLElement): Promise { return this.windowsService.toggleFullScreen(this.windowId); } @@ -121,6 +121,14 @@ export class WindowService extends Disposable implements IWindowService { return this.windowsService.getRecentlyOpened(this.windowId); } + addRecentlyOpened(recents: IRecent[]): Promise { + return this.windowsService.addRecentlyOpened(recents); + } + + removeFromRecentlyOpened(paths: URI[]): Promise { + return this.windowsService.removeFromRecentlyOpened(paths); + } + focusWindow(): Promise { return this.windowsService.focusWindow(this.windowId); } diff --git a/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts b/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts index f7324b042a1..500f4761c45 100644 --- a/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts @@ -16,8 +16,8 @@ import { StorageService } from 'vs/platform/storage/node/storageService'; import { ConfigurationScope, IConfigurationRegistry, Extensions as ConfigurationExtensions, IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry'; import { Registry } from 'vs/platform/registry/common/platform'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; -import { BackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; +import { IBackupFileService, toBackupWorkspaceResource } from 'vs/workbench/services/backup/common/backup'; +import { BackupFileService } from 'vs/workbench/services/backup/common/backupFileService'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { distinct } from 'vs/base/common/arrays'; import { isLinux, isWindows, isMacintosh } from 'vs/base/common/platform'; @@ -32,10 +32,11 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ILabelService } from 'vs/platform/label/common/label'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; export class WorkspaceEditingService implements IWorkspaceEditingService { - _serviceBrand: any; + _serviceBrand: ServiceIdentifier; constructor( @IJSONEditingService private readonly jsonEditingService: IJSONEditingService, @@ -57,14 +58,16 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { @ILifecycleService readonly lifecycleService: ILifecycleService, @ILabelService readonly labelService: ILabelService ) { + this.registerListeners(); + } - lifecycleService.onBeforeShutdown(async e => { + private registerListeners(): void { + this.lifecycleService.onBeforeShutdown(async e => { const saveOperation = this.saveUntitedBeforeShutdown(e.reason); if (saveOperation) { e.veto(saveOperation); } }); - } private async saveUntitedBeforeShutdown(reason: ShutdownReason): Promise { @@ -132,7 +135,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { const newWorkspaceIdentifier = await this.workspaceService.getWorkspaceIdentifier(newWorkspacePath); const label = this.labelService.getWorkspaceLabel(newWorkspaceIdentifier, { verbose: true }); - this.windowsService.addRecentlyOpened([{ label, workspace: newWorkspaceIdentifier }]); + this.windowService.addRecentlyOpened([{ label, workspace: newWorkspaceIdentifier }]); this.workspaceService.deleteUntitledWorkspace(workspaceIdentifier); } catch (error) { @@ -216,6 +219,13 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { private async doAddFolders(foldersToAdd: IWorkspaceFolderCreationData[], index?: number, donotNotifyError: boolean = false): Promise { const state = this.contextService.getWorkbenchState(); + if (this.environmentService.configuration.remoteAuthority) { + // Do not allow workspace folders with scheme different than the current remote scheme + const schemas = this.contextService.getWorkspace().folders.map(f => f.uri.scheme); + if (schemas.length && foldersToAdd.some(f => schemas.indexOf(f.uri.scheme) === -1)) { + return Promise.reject(new Error(nls.localize('differentSchemeRoots', "Workspace folders from different providers are not allowed in the same workspace."))); + } + } // If we are in no-workspace or single-folder workspace, adding folders has to // enter a workspace. @@ -388,7 +398,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { await this.migrateStorage(result.workspace); // Reinitialize backup service if (this.backupFileService instanceof BackupFileService) { - this.backupFileService.initialize(result.backupPath!); + this.backupFileService.initialize(toBackupWorkspaceResource(result.backupPath!, this.environmentService)); } } @@ -415,7 +425,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { private doCopyWorkspaceSettings(toWorkspace: IWorkspaceIdentifier, filter?: (config: IConfigurationPropertySchema) => boolean): Promise { const configurationProperties = Registry.as(ConfigurationExtensions.Configuration).getConfigurationProperties(); - const targetWorkspaceConfiguration = {}; + const targetWorkspaceConfiguration: any = {}; for (const key of this.configurationService.keys().workspace) { if (configurationProperties[key]) { if (filter && !filter(configurationProperties[key])) { diff --git a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts index 2f39779eb3a..779c40e9656 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -16,10 +16,8 @@ import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/c import { IModelService } from 'vs/editor/common/services/modelService'; import { ExtHostLanguageFeatures } from 'vs/workbench/api/common/extHostLanguageFeatures'; import { MainThreadLanguageFeatures } from 'vs/workbench/api/browser/mainThreadLanguageFeatures'; -import { IHeapService, NullHeapService } from 'vs/workbench/services/heap/common/heap'; import { ExtHostApiCommands } from 'vs/workbench/api/common/extHostApiCommands'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; -import { ExtHostHeapService } from 'vs/workbench/api/common/extHostHeapService'; import { MainThreadCommands } from 'vs/workbench/api/browser/mainThreadCommands'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; @@ -67,14 +65,14 @@ suite('ExtHostLanguageFeatureCommands', function () { { let instantiationService = new TestInstantiationService(); rpcProtocol = new TestRPCProtocol(); - instantiationService.stub(IHeapService, NullHeapService); instantiationService.stub(ICommandService, { _serviceBrand: undefined, executeCommand(id: string, args: any): any { - if (!CommandsRegistry.getCommands()[id]) { + const command = CommandsRegistry.getCommands().get(id); + if (!command) { return Promise.reject(new Error(id + ' NOT known')); } - let { handler } = CommandsRegistry.getCommands()[id]; + const { handler } = command; return Promise.resolve(instantiationService.invokeFunction(handler, args)); } }); @@ -109,9 +107,7 @@ suite('ExtHostLanguageFeatureCommands', function () { const extHostDocuments = new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors); rpcProtocol.set(ExtHostContext.ExtHostDocuments, extHostDocuments); - const heapService = new ExtHostHeapService(); - - commands = new ExtHostCommands(rpcProtocol, heapService, new NullLogService()); + commands = new ExtHostCommands(rpcProtocol, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostCommands, commands); rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); ExtHostApiCommands.register(commands); @@ -119,7 +115,7 @@ suite('ExtHostLanguageFeatureCommands', function () { const diagnostics = new ExtHostDiagnostics(rpcProtocol); rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, diagnostics); - extHost = new ExtHostLanguageFeatures(rpcProtocol, null, extHostDocuments, commands, heapService, diagnostics, new NullLogService()); + extHost = new ExtHostLanguageFeatures(rpcProtocol, null, extHostDocuments, commands, diagnostics, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, extHost); mainThread = rpcProtocol.set(MainContext.MainThreadLanguageFeatures, inst.createInstance(MainThreadLanguageFeatures, rpcProtocol)); @@ -801,9 +797,9 @@ suite('ExtHostLanguageFeatureCommands', function () { })); await rpcProtocol.sync(); - let value = await commands.executeCommand('vscode.executeSelectionRangeProvider', model.uri, [new types.Position(0, 10)]); + let value = await commands.executeCommand('vscode.executeSelectionRangeProvider', model.uri, [new types.Position(0, 10)]); assert.equal(value.length, 1); - assert.ok(value[0].length >= 2); + assert.ok(value[0].parent); }); }); diff --git a/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts index 07bb3ac3cea..d0cf59f320e 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts @@ -26,7 +26,7 @@ suite('ExtHostCommands', function () { } }; - const commands = new ExtHostCommands(SingleProxyRPCProtocol(shape), undefined!, new NullLogService()); + const commands = new ExtHostCommands(SingleProxyRPCProtocol(shape), new NullLogService()); commands.registerCommand(true, 'foo', (): any => { }).dispose(); assert.equal(lastUnregister!, 'foo'); assert.equal(CommandsRegistry.getCommand('foo'), undefined); @@ -46,7 +46,7 @@ suite('ExtHostCommands', function () { } }; - const commands = new ExtHostCommands(SingleProxyRPCProtocol(shape), undefined!, new NullLogService()); + const commands = new ExtHostCommands(SingleProxyRPCProtocol(shape), new NullLogService()); const reg = commands.registerCommand(true, 'foo', (): any => { }); reg.dispose(); reg.dispose(); diff --git a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts index 16a5eef9fc9..db499917207 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts @@ -40,7 +40,7 @@ suite('ExtHostConfiguration', function () { user: new ConfigurationModel(contents), workspace: new ConfigurationModel(), folders: Object.create(null), - configurationScopes: {} + configurationScopes: [] }; } @@ -138,7 +138,7 @@ suite('ExtHostConfiguration', function () { testObject = all.getConfiguration('workbench'); actual = testObject.get('colorCustomizations')!; - delete actual['statusBar.foreground']; + actual['statusBar.foreground'] = undefined; assert.equal(actual['statusBar.foreground'], undefined); testObject = all.getConfiguration('workbench'); actual = testObject.get('colorCustomizations')!; @@ -278,7 +278,7 @@ suite('ExtHostConfiguration', function () { }, ['editor.wordWrap']), workspace: new ConfigurationModel({}, []), folders: Object.create(null), - configurationScopes: {} + configurationScopes: [] } ); @@ -326,7 +326,7 @@ suite('ExtHostConfiguration', function () { }, ['editor.wordWrap']), workspace, folders, - configurationScopes: {} + configurationScopes: [] } ); @@ -402,7 +402,7 @@ suite('ExtHostConfiguration', function () { }, ['editor.wordWrap']), workspace, folders, - configurationScopes: {} + configurationScopes: [] } ); diff --git a/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts index 38c627a64c5..4eca9307e09 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts @@ -91,18 +91,18 @@ suite('ExtHostDiagnostics', () => { new Diagnostic(new Range(0, 0, 1, 1), 'message-2') ]); - let array = collection.get(URI.parse('foo:bar')); + let array = collection.get(URI.parse('foo:bar')) as Diagnostic[]; assert.throws(() => array.length = 0); assert.throws(() => array.pop()); assert.throws(() => array[0] = new Diagnostic(new Range(0, 0, 0, 0), 'evil')); - collection.forEach((uri, array) => { + collection.forEach((uri, array: Diagnostic[]) => { assert.throws(() => array.length = 0); assert.throws(() => array.pop()); assert.throws(() => array[0] = new Diagnostic(new Range(0, 0, 0, 0), 'evil')); }); - array = collection.get(URI.parse('foo:bar')); + array = collection.get(URI.parse('foo:bar')) as Diagnostic[]; assert.equal(array.length, 2); collection.dispose(); diff --git a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts index 0096e76b934..99724c53a21 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts @@ -85,7 +85,7 @@ suite('ExtHostDocumentSaveParticipant', () => { sub.dispose(); assert.ok(event); - assert.throws(() => { event.document = null!; }); + assert.throws(() => { (event.document as any) = null!; }); }); }); diff --git a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts index ff72eb8df42..18ecedc673b 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts @@ -18,7 +18,6 @@ import { ExtHostLanguageFeatures } from 'vs/workbench/api/common/extHostLanguage import { MainThreadLanguageFeatures } from 'vs/workbench/api/browser/mainThreadLanguageFeatures'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { MainThreadCommands } from 'vs/workbench/api/browser/mainThreadCommands'; -import { IHeapService, NullHeapService } from 'vs/workbench/services/heap/common/heap'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { getDocumentSymbols } from 'vs/editor/contrib/quickOpen/quickOpen'; @@ -37,7 +36,6 @@ import { getDocumentFormattingEditsUntilResult, getDocumentRangeFormattingEditsU import { getLinks } from 'vs/editor/contrib/links/getLinks'; import { MainContext, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; -import { ExtHostHeapService } from 'vs/workbench/api/common/extHostHeapService'; import * as vscode from 'vscode'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { NullLogService } from 'vs/platform/log/common/log'; @@ -81,7 +79,6 @@ suite('ExtHostLanguageFeatures', function () { { let instantiationService = new TestInstantiationService(); instantiationService.stub(IMarkerService, MarkerService); - instantiationService.stub(IHeapService, NullHeapService); inst = instantiationService; } @@ -102,16 +99,14 @@ suite('ExtHostLanguageFeatures', function () { const extHostDocuments = new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors); rpcProtocol.set(ExtHostContext.ExtHostDocuments, extHostDocuments); - const heapService = new ExtHostHeapService(); - - const commands = new ExtHostCommands(rpcProtocol, heapService, new NullLogService()); + const commands = new ExtHostCommands(rpcProtocol, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostCommands, commands); rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); const diagnostics = new ExtHostDiagnostics(rpcProtocol); rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, diagnostics); - extHost = new ExtHostLanguageFeatures(rpcProtocol, null, extHostDocuments, commands, heapService, diagnostics, new NullLogService()); + extHost = new ExtHostLanguageFeatures(rpcProtocol, null, extHostDocuments, commands, diagnostics, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, extHost); mainThread = rpcProtocol.set(MainContext.MainThreadLanguageFeatures, inst.createInstance(MainThreadLanguageFeatures, rpcProtocol)); diff --git a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts index f7d746d4761..0d15201d893 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts @@ -16,8 +16,8 @@ import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch'; import { Range } from 'vs/workbench/api/common/extHostTypes'; import { IFileMatch, IFileQuery, IPatternInfo, IRawFileMatch2, ISearchCompleteStats, ISearchQuery, ITextQuery, QueryType, resultIsMatch } from 'vs/workbench/services/search/common/search'; import { TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol'; -import { TestLogService } from 'vs/workbench/test/workbenchTestServices'; import * as vscode from 'vscode'; +import { NullLogService } from 'vs/platform/log/common/log'; let rpcProtocol: TestRPCProtocol; let extHostSearch: ExtHostSearch; @@ -130,7 +130,7 @@ suite('ExtHostSearch', () => { rpcProtocol = new TestRPCProtocol(); mockMainThreadSearch = new MockMainThreadSearch(); - const logService = new TestLogService(); + const logService = new NullLogService(); rpcProtocol.set(MainContext.MainThreadSearch, mockMainThreadSearch); diff --git a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts index 7619369f02c..5f05a9bc453 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts @@ -11,7 +11,6 @@ import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { MainThreadTreeViewsShape, MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { TreeDataProvider, TreeItem } from 'vscode'; import { TestRPCProtocol } from './testRPCProtocol'; -import { ExtHostHeapService } from 'vs/workbench/api/common/extHostHeapService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { MainThreadCommands } from 'vs/workbench/api/browser/mainThreadCommands'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -72,7 +71,7 @@ suite('ExtHostTreeView', function () { rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); target = new RecordingShape(); - testObject = new ExtHostTreeViews(target, new ExtHostCommands(rpcProtocol, new ExtHostHeapService(), new NullLogService()), new NullLogService()); + testObject = new ExtHostTreeViews(target, new ExtHostCommands(rpcProtocol, new NullLogService()), new NullLogService()); onDidChangeTreeNode = new Emitter<{ key: string }>(); onDidChangeTreeNodeWithId = new Emitter<{ key: string }>(); testObject.createTreeView('testNodeTreeProvider', { treeDataProvider: aNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription); diff --git a/src/vs/workbench/test/electron-browser/api/extHostWebview.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWebview.test.ts index 2650c602cdf..8a121279041 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWebview.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWebview.test.ts @@ -10,14 +10,15 @@ import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import * as vscode from 'vscode'; import { SingleProxyRPCProtocol } from './testRPCProtocol'; import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor'; +import { URI } from 'vs/base/common/uri'; -suite('ExtHostWebview', function () { +suite('ExtHostWebview', () => { test('Cannot register multiple serializers for the same view type', async () => { const viewType = 'view.type'; const shape = createNoopMainThreadWebviews(); - const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape)); + const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape), { webviewCspSource: '', webviewResourceRoot: '' }); let lastInvokedDeserializer: vscode.WebviewPanelSerializer | undefined = undefined; @@ -46,11 +47,95 @@ suite('ExtHostWebview', function () { await extHostWebviews.$deserializeWebviewPanel('x', viewType, 'title', {}, 0 as EditorViewColumn, {}); assert.strictEqual(lastInvokedDeserializer, serializerB); }); + + test('toWebviewResource for desktop vscode-resource scheme', () => { + const shape = createNoopMainThreadWebviews(); + const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape), { + webviewCspSource: '', + webviewResourceRoot: 'vscode-resource:{{resource}}' + }); + const webview = extHostWebviews.createWebviewPanel({} as any, 'type', 'title', 1, {}); + + assert.strictEqual( + webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html')).toString(), + 'vscode-resource:/Users/codey/file.html', + 'Unix basic' + ); + + assert.strictEqual( + webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html#frag')).toString(), + 'vscode-resource:/Users/codey/file.html#frag', + 'Unix should preserve fragment' + ); + + assert.strictEqual( + webview.webview.toWebviewResource(URI.parse('file:///Users/codey/f%20ile.html')).toString(), + 'vscode-resource:/Users/codey/f%20ile.html', + 'Unix with encoding' + ); + + assert.strictEqual( + webview.webview.toWebviewResource(URI.parse('file://localhost/Users/codey/file.html')).toString(), + 'vscode-resource://localhost/Users/codey/file.html', + 'Unix should preserve authority' + ); + + assert.strictEqual( + webview.webview.toWebviewResource(URI.parse('file:///c:/codey/file.txt')).toString(), + 'vscode-resource:/c%3A/codey/file.txt', + 'Windows C drive' + ); + }); + + test('toWebviewResource for web endpoint', () => { + const shape = createNoopMainThreadWebviews(); + + const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape), { + webviewCspSource: '', + webviewResourceRoot: `https://{{uuid}}.webview.contoso.com/commit{{resource}}` + }); + const webview = extHostWebviews.createWebviewPanel({} as any, 'type', 'title', 1, {}); + + function stripEndpointUuid(input: string) { + return input.replace(/^https:\/\/[^\.]+?\./, ''); + } + + assert.strictEqual( + stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html')).toString()), + 'webview.contoso.com/commit///Users/codey/file.html', + 'Unix basic' + ); + + assert.strictEqual( + stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html#frag')).toString()), + 'webview.contoso.com/commit///Users/codey/file.html#frag', + 'Unix should preserve fragment' + ); + + assert.strictEqual( + stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/f%20ile.html')).toString()), + 'webview.contoso.com/commit///Users/codey/f%20ile.html', + 'Unix with encoding' + ); + + assert.strictEqual( + stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file://localhost/Users/codey/file.html')).toString()), + 'webview.contoso.com/commit//localhost/Users/codey/file.html', + 'Unix should preserve authority' + ); + + assert.strictEqual( + stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///c:/codey/file.txt')).toString()), + 'webview.contoso.com/commit///c%3A/codey/file.txt', + 'Windows C drive' + ); + }); }); function createNoopMainThreadWebviews() { return new class extends mock() { + $createWebviewPanel() { /* noop */ } $registerSerializer() { /* noop */ } $unregisterSerializer() { /* noop */ } }; diff --git a/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts b/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts index 40eb17f7d9a..c61f19b0d58 100644 --- a/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts +++ b/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts @@ -12,12 +12,15 @@ import { debugExceptionWidgetBackground } from 'vs/workbench/contrib/debug/brows import { debugToolBarBackground } from 'vs/workbench/contrib/debug/browser/debugToolBar'; import { buttonBackground } from 'vs/workbench/contrib/welcome/page/browser/welcomePage'; import { embeddedEditorBackground } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart'; -import { request, asText } from 'vs/base/node/request'; +import { asText } from 'vs/platform/request/common/request'; import * as pfs from 'vs/base/node/pfs'; import * as path from 'vs/base/common/path'; import * as assert from 'assert'; import { getPathFromAmdModule } from 'vs/base/common/amd'; import { CancellationToken } from 'vs/base/common/cancellation'; +import { RequestService } from 'vs/platform/request/node/requestService'; +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { NullLogService } from 'vs/platform/log/common/log'; interface ColorInfo { @@ -40,7 +43,7 @@ export const experimental: string[] = []; // 'settings.modifiedItemForeground', suite('Color Registry', function () { test('all colors documented', async function () { - const reqContext = await request({ url: 'https://raw.githubusercontent.com/Microsoft/vscode-docs/vnext/docs/getstarted/theme-color-reference.md' }, CancellationToken.None); + const reqContext = await new RequestService(new TestConfigurationService(), new NullLogService()).request({ url: 'https://raw.githubusercontent.com/Microsoft/vscode-docs/vnext/docs/getstarted/theme-color-reference.md' }, CancellationToken.None); const content = (await asText(reqContext))!; const expression = /\-\s*\`([\w\.]+)\`: (.*)/g; diff --git a/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts b/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts index a0c7e9a27fe..4b246719249 100644 --- a/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts +++ b/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts @@ -29,6 +29,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editor import { LocalSearchService } from 'vs/workbench/services/search/node/searchService'; import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { TestContextService, TestEditorGroupsService, TestEditorService, TestEnvironmentService, TestTextResourcePropertiesService } from 'vs/workbench/test/workbenchTestServices'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; namespace Timer { export interface ITimerEvent { @@ -172,6 +173,10 @@ class TestTelemetryService implements ITelemetryService { return Promise.resolve(undefined); } + public publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + return this.publicLog(eventName, data as any); + } + public getTelemetryInfo(): Promise { return Promise.resolve({ instanceId: 'someValue.instanceId', diff --git a/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts b/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts index be16e39397a..e08748c6364 100644 --- a/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts +++ b/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts @@ -33,6 +33,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { testWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; import { NullLogService, ILogService } from 'vs/platform/log/common/log'; import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; declare var __dirname: string; @@ -165,6 +166,10 @@ class TestTelemetryService implements ITelemetryService { return Promise.resolve(); } + public publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + return this.publicLog(eventName, data as any); + } + public getTelemetryInfo(): Promise { return Promise.resolve({ instanceId: 'someValue.instanceId', diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 09b4ed6f217..9e9e0d739e8 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -38,7 +38,7 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/ import { IWindowsService, IWindowService, INativeOpenDialogOptions, IEnterWorkspaceResult, IMessageBoxResult, MenuBarVisibility, IURIToOpen, IOpenSettings, IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; @@ -64,14 +64,14 @@ import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon'; import { EditorGroup } from 'vs/workbench/common/editor/editorGroup'; import { Dimension } from 'vs/base/browser/dom'; -import { ILogService, LogLevel } from 'vs/platform/log/common/log'; +import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { ILabelService } from 'vs/platform/label/common/label'; import { timeout } from 'vs/base/common/async'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { ViewletDescriptor, Viewlet } from 'vs/workbench/browser/viewlet'; import { IViewlet } from 'vs/workbench/common/viewlet'; import { IStorageService, InMemoryStorageService } from 'vs/platform/storage/common/storage'; -import { isLinux, isMacintosh } from 'vs/base/common/platform'; +import { isLinux, isMacintosh, IProcessEnvironment } from 'vs/base/common/platform'; import { LabelService } from 'vs/workbench/services/label/common/labelService'; import { IDimension } from 'vs/platform/layout/browser/layoutService'; import { Part } from 'vs/workbench/browser/part'; @@ -82,7 +82,7 @@ import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedPr import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/node/environmentService'; import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer'; -import { BrowserTextFileService } from 'vs/workbench/services/textfile/browser/textFileService'; +import { NodeTextFileService } from 'vs/workbench/services/textfile/node/textFileService'; import { Schemas } from 'vs/base/common/network'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { @@ -177,7 +177,7 @@ export class TestContextService implements IWorkspaceContextService { } } -export class TestTextFileService extends BrowserTextFileService { +export class TestTextFileService extends NodeTextFileService { public cleanupBackupsBeforeShutdownCalled: boolean; private promptPath: URI; @@ -311,7 +311,7 @@ export function workbenchInstantiationService(): IInstantiationService { instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService)); instantiationService.stub(ITextModelService, instantiationService.createInstance(TextModelResolverService)); instantiationService.stub(IThemeService, new TestThemeService()); - instantiationService.stub(ILogService, new TestLogService()); + instantiationService.stub(ILogService, new NullLogService()); instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService([new TestEditorGroup(0)])); instantiationService.stub(ILabelService, instantiationService.createInstance(LabelService)); const editorService = new TestEditorService(); @@ -322,19 +322,6 @@ export function workbenchInstantiationService(): IInstantiationService { return instantiationService; } -export class TestLogService implements ILogService { - _serviceBrand: any; onDidChangeLogLevel: Event; - getLevel(): LogLevel { return LogLevel.Info; } - setLevel(_level: LogLevel): void { } - trace(_message: string, ..._args: any[]): void { } - debug(_message: string, ..._args: any[]): void { } - info(_message: string, ..._args: any[]): void { } - warn(_message: string, ..._args: any[]): void { } - error(_message: string | Error, ..._args: any[]): void { } - critical(_message: string | Error, ..._args: any[]): void { } - dispose(): void { } -} - export class TestDecorationsService implements IDecorationsService { _serviceBrand: any; onDidChangeDecorations: Event = Event.None; @@ -439,6 +426,9 @@ export class TestFileDialogService implements IFileDialogService { public pickWorkspaceAndOpen(_options: IPickAndOpenOptions): Promise { return Promise.resolve(0); } + public pickFileToSave(_options: ISaveDialogOptions): Promise { + return Promise.resolve(undefined); + } public showSaveDialog(_options: ISaveDialogOptions): Promise { return Promise.resolve(undefined); } @@ -544,6 +534,8 @@ export class TestLayoutService implements IWorkbenchLayoutService { public addClass(_clazz: string): void { } public removeClass(_clazz: string): void { } + + public getWorkbenchContainer(): HTMLElement { throw new Error('not implemented'); } public getWorkbenchElement(): HTMLElement { throw new Error('not implemented'); } public toggleZenMode(): void { } @@ -620,6 +612,10 @@ export class TestPanelService implements IPanelService { return null!; } + public getPanel(id: string): any { + return activeViewlet; + } + public getPanels(): any[] { return []; } @@ -641,6 +637,10 @@ export class TestPanelService implements IPanelService { throw new Error('Method not implemented.'); } + public getProgressIndicator(id: string) { + return null!; + } + public hideActivePanel(): void { } public getLastActivePanelId(): string { @@ -703,11 +703,11 @@ export class TestEditorGroupsService implements IEditorGroupsService { throw new Error('not implemented'); } - getSize(_group: number | IEditorGroup): number { - return 100; + getSize(_group: number | IEditorGroup): { width: number, height: number } { + return { width: 100, height: 100 }; } - setSize(_group: number | IEditorGroup, _size: number): void { } + setSize(_group: number | IEditorGroup, _size: { width: number, height: number }): void { } arrangeGroups(_arrangement: GroupsArrangement): void { } @@ -1075,6 +1075,10 @@ export class TestBackupFileService implements IBackupFileService { return Promise.resolve(false); } + public hasBackupSync(resource: URI, versionId?: number): boolean { + return false; + } + public loadBackupResource(resource: URI): Promise { return this.hasBackup(resource).then(hasBackup => { if (hasBackup) { @@ -1220,6 +1224,14 @@ export class TestWindowService implements IWindowService { }); } + addRecentlyOpened(_recents: IRecent[]): Promise { + return Promise.resolve(); + } + + removeFromRecentlyOpened(_paths: URI[]): Promise { + return Promise.resolve(); + } + focusWindow(): Promise { return Promise.resolve(); } @@ -1449,6 +1461,10 @@ export class TestWindowsService implements IWindowsService { return Promise.resolve(); } + openExtensionDevelopmentHostWindow(args: ParsedArgs, env: IProcessEnvironment): Promise { + return Promise.resolve(); + } + getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]> { throw new Error('not implemented'); } @@ -1579,30 +1595,6 @@ export class TestSharedProcessService implements ISharedProcessService { registerChannel(channelName: string, channel: any): void { } } -export class NullFileSystemProvider implements IFileSystemProvider { - - capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.Readonly; - - onDidChangeCapabilities: Event = Event.None; - onDidChangeFile: Event = Event.None; - - constructor(private disposableFactory: () => IDisposable = () => Disposable.None) { } - - watch(resource: URI, opts: IWatchOptions): IDisposable { return this.disposableFactory(); } - stat(resource: URI): Promise { return Promise.resolve(undefined!); } - mkdir(resource: URI): Promise { return Promise.resolve(undefined!); } - readdir(resource: URI): Promise<[string, FileType][]> { return Promise.resolve(undefined!); } - delete(resource: URI, opts: FileDeleteOptions): Promise { return Promise.resolve(undefined!); } - rename(from: URI, to: URI, opts: FileOverwriteOptions): Promise { return Promise.resolve(undefined!); } - copy?(from: URI, to: URI, opts: FileOverwriteOptions): Promise { return Promise.resolve(undefined!); } - readFile?(resource: URI): Promise { return Promise.resolve(undefined!); } - writeFile?(resource: URI, content: Uint8Array, opts: FileWriteOptions): Promise { return Promise.resolve(undefined!); } - open?(resource: URI, opts: FileOpenOptions): Promise { return Promise.resolve(undefined!); } - close?(fd: number): Promise { return Promise.resolve(undefined!); } - read?(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise { return Promise.resolve(undefined!); } - write?(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise { return Promise.resolve(undefined!); } -} - export class RemoteFileSystemProvider implements IFileSystemProvider { constructor(private readonly diskFileSystemProvider: IFileSystemProvider, private readonly remoteAuthority: string) { } diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 58189180c39..1d4bb760313 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -20,6 +20,8 @@ import 'vs/workbench/electron-browser/main'; //#region --- workbench actions import 'vs/workbench/browser/actions/layoutActions'; +import 'vs/workbench/browser/actions/windowActions'; +import 'vs/workbench/browser/actions/developerActions'; import 'vs/workbench/browser/actions/listCommands'; import 'vs/workbench/browser/actions/navigationActions'; import 'vs/workbench/browser/parts/quickopen/quickOpenActions'; @@ -66,8 +68,8 @@ import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; -import { IRequestService } from 'vs/platform/request/node/request'; -import { RequestService } from 'vs/platform/request/electron-browser/requestService'; +import { IRequestService } from 'vs/platform/request/common/request'; +import { RequestService } from 'vs/platform/request/browser/requestService'; import { LifecycleService } from 'vs/platform/lifecycle/electron-browser/lifecycleService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; @@ -89,8 +91,6 @@ import { IURLService } from 'vs/platform/url/common/url'; import { RelayURLService } from 'vs/platform/url/electron-browser/urlService'; import { ITunnelService } from 'vs/platform/remote/common/tunnel'; import { TunnelService } from 'vs/workbench/services/remote/node/tunnelService'; -import { ConfigurationResolverService } from 'vs/workbench/services/configurationResolver/electron-browser/configurationResolverService'; -import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService'; @@ -112,14 +112,15 @@ import 'vs/workbench/services/textmodelResolver/common/textModelResolverService' import 'vs/workbench/services/textfile/node/textFileService'; import 'vs/workbench/services/dialogs/browser/fileDialogService'; import 'vs/workbench/services/dialogs/electron-browser/dialogService'; -import 'vs/workbench/services/backup/node/backupFileService'; import 'vs/workbench/services/editor/browser/editorService'; import 'vs/workbench/services/history/browser/history'; import 'vs/workbench/services/activity/browser/activityService'; import 'vs/workbench/browser/parts/views/views'; -import 'vs/workbench/services/keybinding/electron-browser/keybindingService'; +import 'vs/workbench/services/keybinding/electron-browser/nativeKeymapService'; +import 'vs/workbench/services/keybinding/electron-browser/keybinding.contribution'; +import 'vs/workbench/services/keybinding/browser/keybindingService'; import 'vs/workbench/services/untitled/common/untitledEditorService'; -import 'vs/workbench/services/textfile/node/textResourcePropertiesService'; +import 'vs/workbench/services/textfile/common/textResourcePropertiesService'; import 'vs/workbench/services/mode/common/workbenchModeService'; import 'vs/workbench/services/commands/common/commandService'; import 'vs/workbench/services/themes/browser/workbenchThemeService'; @@ -131,10 +132,14 @@ import 'vs/workbench/services/label/common/labelService'; import 'vs/workbench/services/extensions/electron-browser/extensionManagementServerService'; import 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; import 'vs/workbench/services/notification/common/notificationService'; -import 'vs/workbench/services/heap/node/heap'; import 'vs/workbench/services/window/electron-browser/windowService'; import 'vs/workbench/services/telemetry/electron-browser/telemetryService'; +import 'vs/workbench/services/configurationResolver/electron-browser/configurationResolverService'; +import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; +import { BackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; + +registerSingleton(IBackupFileService, BackupFileService); registerSingleton(IMenuService, MenuService, true); registerSingleton(IListService, ListService, true); registerSingleton(IOpenerService, OpenerService, true); @@ -161,7 +166,6 @@ registerSingleton(IWorkspacesService, WorkspacesService); registerSingleton(IMenubarService, MenubarService); registerSingleton(IURLService, RelayURLService); registerSingleton(ITunnelService, TunnelService, true); -registerSingleton(IConfigurationResolverService, ConfigurationResolverService, true); registerSingleton(ICredentialsService, KeytarCredentialsService, true); //#endregion @@ -196,11 +200,12 @@ import 'vs/workbench/contrib/localizations/browser/localizations.contribution'; import 'vs/workbench/contrib/preferences/browser/preferences.contribution'; import 'vs/workbench/contrib/preferences/browser/keybindingsEditorContribution'; import { IPreferencesSearchService } from 'vs/workbench/contrib/preferences/common/preferences'; -import { PreferencesSearchService } from 'vs/workbench/contrib/preferences/electron-browser/preferencesSearch'; +import { PreferencesSearchService } from 'vs/workbench/contrib/preferences/browser/preferencesSearch'; registerSingleton(IPreferencesSearchService, PreferencesSearchService, true); // Logs import 'vs/workbench/contrib/logs/common/logs.contribution'; +import 'vs/workbench/contrib/logs/electron-browser/logs.contribution'; // Quick Open Handlers import 'vs/workbench/contrib/quickopen/browser/quickopen.contribution'; @@ -214,7 +219,7 @@ import 'vs/workbench/contrib/files/browser/files.contribution'; import 'vs/workbench/contrib/backup/common/backup.contribution'; // Stats -import 'vs/workbench/contrib/stats/node/stats.contribution'; +import 'vs/workbench/contrib/stats/electron-browser/stats.contribution'; // Rapid Render Splash import 'vs/workbench/contrib/splash/electron-browser/partsSplash.contribution'; @@ -229,11 +234,12 @@ import 'vs/workbench/contrib/scm/browser/scm.contribution'; import 'vs/workbench/contrib/scm/browser/scmViewlet'; // Debug -import 'vs/workbench/contrib/debug/electron-browser/debug.contribution'; +import 'vs/workbench/contrib/debug/browser/debug.contribution'; import 'vs/workbench/contrib/debug/browser/debugQuickOpen'; import 'vs/workbench/contrib/debug/browser/debugEditorContribution'; import 'vs/workbench/contrib/debug/browser/repl'; import 'vs/workbench/contrib/debug/browser/debugViewlet'; +import 'vs/workbench/contrib/debug/node/debugHelperService'; // Markers import 'vs/workbench/contrib/markers/browser/markers.contribution'; @@ -267,9 +273,13 @@ import 'vs/workbench/contrib/terminal/browser/terminalPanel'; import 'vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution'; // Tasks -import 'vs/workbench/contrib/tasks/electron-browser/task.contribution'; +import 'vs/workbench/contrib/tasks/browser/task.contribution'; +import { TaskService } from 'vs/workbench/contrib/tasks/electron-browser/taskService'; +import { ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; +registerSingleton(ITaskService, TaskService, true); // Remote +import 'vs/workbench/contrib/remote/common/remote.contribution'; import 'vs/workbench/contrib/remote/electron-browser/remote.contribution'; // Emmet @@ -280,7 +290,8 @@ import 'vs/workbench/contrib/codeEditor/browser/codeEditor.contribution'; import 'vs/workbench/contrib/codeEditor/electron-browser/codeEditor.contribution'; // Execution -import 'vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution'; +import 'vs/workbench/contrib/externalTerminal/node/externalTerminalService'; +import 'vs/workbench/contrib/externalTerminal/browser/externalTerminal.contribution'; // Snippets import 'vs/workbench/contrib/snippets/browser/snippets.contribution'; diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts new file mode 100644 index 00000000000..ae193ae3e26 --- /dev/null +++ b/src/vs/workbench/workbench.web.api.ts @@ -0,0 +1,54 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/workbench/workbench.web.main'; +import { main } from 'vs/workbench/browser/web.main'; +import { UriComponents } from 'vs/base/common/uri'; +import { IFileSystemProvider } from 'vs/platform/files/common/files'; + +export interface IWorkbenchConstructionOptions { + + /** + * Experimental: the remote authority is the IP:PORT from where the workbench is served + * from. It is for example being used for the websocket connections as address. + */ + remoteAuthority: string; + + /** + * Experimental: An endpoint to serve iframe content ("webview") from. This is required + * to provide full security isolation from the workbench host. + */ + webviewEndpoint?: string; + + /** + * Experimental: An optional folder that is set as workspace context for the workbench. + */ + folderUri?: UriComponents; + + /** + * Experimental: An optional workspace that is set as workspace context for the workbench. + */ + workspaceUri?: UriComponents; + + /** + * Experimental: The userDataProvider is used to handle user specific application + * state like settings, keybindings, UI state (e.g. opened editors) and snippets. + */ + userDataProvider?: IFileSystemProvider; +} + +/** + * Experimental: Creates the workbench with the provided options in the provided container. + * + * @param domElement the container to create the workbench in + * @param options for setting up the workbench + */ +function create(domElement: HTMLElement, options: IWorkbenchConstructionOptions): Promise { + return main(domElement, options); +} + +export { + create +}; \ No newline at end of file diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index a2216b4db2f..60173e2f739 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -9,7 +9,6 @@ import 'vs/editor/editor.all'; import 'vs/workbench/api/browser/extensionHost.contribution'; -// import 'vs/workbench/electron-browser/main.contribution'; import 'vs/workbench/browser/workbench.contribution'; import 'vs/workbench/browser/web.main'; @@ -20,6 +19,8 @@ import 'vs/workbench/browser/web.main'; //#region --- workbench actions import 'vs/workbench/browser/actions/layoutActions'; +import 'vs/workbench/browser/actions/windowActions'; +import 'vs/workbench/browser/actions/developerActions'; import 'vs/workbench/browser/actions/listCommands'; import 'vs/workbench/browser/actions/navigationActions'; import 'vs/workbench/browser/parts/quickopen/quickOpenActions'; @@ -52,8 +53,8 @@ import { IMarkerService } from 'vs/platform/markers/common/markers'; import { MarkerService } from 'vs/platform/markers/common/markerService'; // import { IDownloadService } from 'vs/platform/download/common/download'; // import { DownloadService } from 'vs/platform/download/node/downloadService'; -// import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; -// import { ClipboardService } from 'vs/platform/clipboard/electron-browser/clipboardService'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { BrowserClipboardService } from 'vs/platform/clipboard/browser/clipboardService'; import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IModelService } from 'vs/editor/common/services/modelService'; @@ -62,14 +63,15 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/res import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { BrowserAccessibilityService } from 'vs/platform/accessibility/common/accessibilityService'; -import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; +// import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; // import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; -// import { IRequestService } from 'vs/platform/request/node/request'; -// import { RequestService } from 'vs/platform/request/electron-browser/requestService'; -// import { LifecycleService } from 'vs/platform/lifecycle/electron-browser/lifecycleService'; -// import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { IRequestService } from 'vs/platform/request/common/request'; +import { RequestService } from 'vs/platform/request/browser/requestService'; +import { BrowserLifecycleService } from 'vs/platform/lifecycle/browser/lifecycleService'; +import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { DialogService } from 'vs/platform/dialogs/browser/dialogService'; // import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; // import { LocalizationsService } from 'vs/platform/localizations/electron-browser/localizationsService'; // import { ISharedProcessService, SharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; @@ -89,12 +91,8 @@ import { ContextViewService } from 'vs/platform/contextview/browser/contextViewS // import { RelayURLService } from 'vs/platform/url/electron-browser/urlService'; // import { ITunnelService } from 'vs/platform/remote/common/tunnel'; // import { TunnelService } from 'vs/workbench/services/remote/node/tunnelService'; -import { IHeapService, NullHeapService } from 'vs/workbench/services/heap/common/heap'; -import { ConfigurationResolverService } from 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; -import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; -import { ISearchService } from 'vs/workbench/services/search/common/search'; -import { RemoteSearchService } from 'vs/workbench/services/search/common/searchService'; -import 'vs/platform/dialogs/browser/dialogService'; +// import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; +// import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService'; import 'vs/workbench/services/bulkEdit/browser/bulkEditService'; // import 'vs/workbench/services/integrity/node/integrityService'; import 'vs/workbench/services/keybinding/common/keybindingEditing'; @@ -102,7 +100,7 @@ import 'vs/workbench/services/textMate/browser/textMateService'; // import 'vs/workbench/services/workspace/electron-browser/workspaceEditingService'; // import 'vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler'; import 'vs/workbench/services/decorations/browser/decorationsService'; -// import 'vs/workbench/services/search/node/searchService'; +import 'vs/workbench/services/search/common/searchService'; import 'vs/workbench/services/progress/browser/progressService'; import 'vs/workbench/services/editor/browser/codeEditorService'; // import 'vs/workbench/services/extensions/electron-browser/extensionHostDebugService'; @@ -113,14 +111,14 @@ import 'vs/workbench/services/textmodelResolver/common/textModelResolverService' import 'vs/workbench/services/textfile/browser/textFileService'; import 'vs/workbench/services/dialogs/browser/fileDialogService'; // import 'vs/workbench/services/dialogs/electron-browser/dialogService'; -// import 'vs/workbench/services/backup/node/backupFileService'; import 'vs/workbench/services/editor/browser/editorService'; import 'vs/workbench/services/history/browser/history'; import 'vs/workbench/services/activity/browser/activityService'; import 'vs/workbench/browser/parts/views/views'; -// import 'vs/workbench/services/keybinding/electron-browser/keybindingService'; +import 'vs/workbench/services/keybinding/browser/keymapService'; +import 'vs/workbench/services/keybinding/browser/keybindingService'; import 'vs/workbench/services/untitled/common/untitledEditorService'; -// import 'vs/workbench/services/textfile/node/textResourcePropertiesService'; +import 'vs/workbench/services/textfile/common/textResourcePropertiesService'; import 'vs/workbench/services/mode/common/workbenchModeService'; import 'vs/workbench/services/commands/common/commandService'; import 'vs/workbench/services/themes/browser/workbenchThemeService'; @@ -132,12 +130,18 @@ import 'vs/workbench/services/label/common/labelService'; // import 'vs/workbench/services/extensions/electron-browser/extensionManagementServerService'; // import 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; import 'vs/workbench/services/notification/common/notificationService'; -// import 'vs/workbench/services/heap/node/heap'; // import 'vs/workbench/services/window/electron-browser/windowService'; // import 'vs/workbench/services/telemetry/electron-browser/telemetryService'; +import 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; +import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; +import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; +import { BackupFileService } from 'vs/workbench/services/backup/common/backupFileService'; import 'vs/workbench/browser/web.simpleservices'; +registerSingleton(IBackupFileService, BackupFileService); +registerSingleton(IDialogService, DialogService, true); registerSingleton(IMenuService, MenuService, true); registerSingleton(IListService, ListService, true); registerSingleton(IOpenerService, OpenerService, true); @@ -145,28 +149,26 @@ registerSingleton(IEditorWorkerService, EditorWorkerServiceImpl); registerSingleton(IMarkerDecorationsService, MarkerDecorationsService); registerSingleton(IMarkerService, MarkerService, true); // registerSingleton(IDownloadService, DownloadService, true); -// registerSingleton(IClipboardService, ClipboardService, true); +registerSingleton(IClipboardService, BrowserClipboardService, true); registerSingleton(IContextKeyService, ContextKeyService); registerSingleton(IModelService, ModelServiceImpl, true); registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationService); registerSingleton(IAccessibilityService, BrowserAccessibilityService, true); registerSingleton(IContextViewService, ContextViewService, true); // registerSingleton(IExtensionGalleryService, ExtensionGalleryService, true); -// registerSingleton(IRequestService, RequestService, true); -// registerSingleton(ILifecycleService, LifecycleService); +registerSingleton(IRequestService, RequestService, true); +registerSingleton(ILifecycleService, BrowserLifecycleService); // registerSingleton(ILocalizationsService, LocalizationsService); // registerSingleton(ISharedProcessService, SharedProcessService, true); -// registerSingleton(IProductService, ProductService, true); // registerSingleton(IWindowsService, WindowsService); // registerSingleton(IUpdateService, UpdateService); // registerSingleton(IIssueService, IssueService); // registerSingleton(IWorkspacesService, WorkspacesService); // registerSingleton(IMenubarService, MenubarService); // registerSingleton(IURLService, RelayURLService); -registerSingleton(ISearchService, RemoteSearchService, true); -registerSingleton(IHeapService, NullHeapService); +// registerSingleton(ITunnelService, TunnelService, true); +// registerSingleton(ICredentialsService, KeytarCredentialsService, true); registerSingleton(IContextMenuService, ContextMenuService); -registerSingleton(IConfigurationResolverService, ConfigurationResolverService, true); //#endregion @@ -187,6 +189,9 @@ import 'vs/workbench/browser/parts/statusbar/statusbarPart'; //#region --- workbench contributions +// Resource Service Worker +import 'vs/workbench/contrib/resources/browser/resourceServiceWorkerClient'; + // Workspace File Watching import 'vs/workbench/services/files/common/workspaceWatcher'; @@ -199,6 +204,7 @@ import 'vs/workbench/contrib/telemetry/browser/telemetry.contribution'; // Preferences import 'vs/workbench/contrib/preferences/browser/preferences.contribution'; import 'vs/workbench/contrib/preferences/browser/keybindingsEditorContribution'; +import 'vs/workbench/contrib/preferences/browser/keyboardLayoutPicker'; import { IPreferencesSearchService } from 'vs/workbench/contrib/preferences/common/preferences'; import { PreferencesSearchService } from 'vs/workbench/contrib/preferences/browser/preferencesSearch'; registerSingleton(IPreferencesSearchService, PreferencesSearchService, true); @@ -218,7 +224,7 @@ import 'vs/workbench/contrib/files/browser/files.contribution'; import 'vs/workbench/contrib/backup/common/backup.contribution'; // Stats -// import 'vs/workbench/contrib/stats/node/stats.contribution'; +// import 'vs/workbench/contrib/stats/electron-browser/stats.contribution'; // Rapid Render Splash // import 'vs/workbench/contrib/splash/electron-browser/partsSplash.contribution'; @@ -233,29 +239,29 @@ import 'vs/workbench/contrib/scm/browser/scm.contribution'; import 'vs/workbench/contrib/scm/browser/scmViewlet'; // Debug -// import 'vs/workbench/contrib/debug/electron-browser/debug.contribution'; -// import 'vs/workbench/contrib/debug/browser/debugQuickOpen'; -// import 'vs/workbench/contrib/debug/browser/debugEditorContribution'; -// import 'vs/workbench/contrib/debug/browser/repl'; -// import 'vs/workbench/contrib/debug/browser/debugViewlet'; +import 'vs/workbench/contrib/debug/browser/debug.contribution'; +import 'vs/workbench/contrib/debug/browser/debugQuickOpen'; +import 'vs/workbench/contrib/debug/browser/debugEditorContribution'; +import 'vs/workbench/contrib/debug/browser/repl'; +import 'vs/workbench/contrib/debug/browser/debugViewlet'; +import 'vs/workbench/contrib/debug/browser/debugHelperService'; // Markers import 'vs/workbench/contrib/markers/browser/markers.contribution'; // Comments -// import 'vs/workbench/contrib/comments/browser/comments.contribution'; +import 'vs/workbench/contrib/comments/browser/comments.contribution'; // URL Support import 'vs/workbench/contrib/url/common/url.contribution'; // Webview -// import 'vs/workbench/contrib/webview/browser/webview.contribution'; -// import 'vs/workbench/contrib/webview/electron-browser/webview.contribution'; +import 'vs/workbench/contrib/webview/browser/webview.contribution'; import { IWebviewService } from 'vs/workbench/contrib/webview/common/webview'; -import { NullWebviewService } from 'vs/workbench/contrib/webview/browser/webviewService'; +import { WebviewService } from 'vs/workbench/contrib/webview/browser/webviewService'; import { IWebviewEditorService, WebviewEditorService } from 'vs/workbench/contrib/webview/browser/webviewEditorService'; -registerSingleton(IWebviewService, NullWebviewService, true); +registerSingleton(IWebviewService, WebviewService, true); registerSingleton(IWebviewEditorService, WebviewEditorService, true); // Extensions Management @@ -284,9 +290,13 @@ registerSingleton(ITerminalInstanceService, TerminalInstanceService, true); // import 'vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution'; // Tasks -// import 'vs/workbench/contrib/tasks/electron-browser/task.contribution'; +import 'vs/workbench/contrib/tasks/browser/task.contribution'; +import { TaskService } from 'vs/workbench/contrib/tasks/browser/taskService'; +import { ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; +registerSingleton(ITaskService, TaskService, true); // Remote +import 'vs/workbench/contrib/remote/common/remote.contribution'; // import 'vs/workbench/contrib/remote/electron-browser/remote.contribution'; // Emmet @@ -296,8 +306,8 @@ import 'vs/workbench/contrib/emmet/browser/emmet.contribution'; import 'vs/workbench/contrib/codeEditor/browser/codeEditor.contribution'; // import 'vs/workbench/contrib/codeEditor/electron-browser/codeEditor.contribution'; -// Execution -// import 'vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution'; +// External terminal +import 'vs/workbench/contrib/externalTerminal/browser/externalTerminal.contribution'; // Snippets import 'vs/workbench/contrib/snippets/browser/snippets.contribution'; diff --git a/test/electron/index.js b/test/electron/index.js index ebd97e3b98b..f21b3615c0e 100644 --- a/test/electron/index.js +++ b/test/electron/index.js @@ -100,20 +100,29 @@ function parseReporterOption(value) { app.on('ready', () => { + ipcMain.on('error', (_, err) => { + if (!argv.debug) { + console.error(err); + app.exit(1); + } + }); + const win = new BrowserWindow({ height: 600, width: 800, show: false, webPreferences: { backgroundThrottling: false, - webSecurity: false + nodeIntegration: true, + webSecurity: false, + webviewTag: true } }); win.webContents.on('did-finish-load', () => { if (argv.debug) { win.show(); - win.webContents.openDevTools({ mode: 'right' }); + win.webContents.openDevTools(); } win.webContents.send('run', argv); }); diff --git a/test/electron/renderer.js b/test/electron/renderer.js index addb1f0b93c..4d5a7f0f1ee 100644 --- a/test/electron/renderer.js +++ b/test/electron/renderer.js @@ -273,5 +273,12 @@ function runTests(opts) { ipcRenderer.on('run', (e, opts) => { initLoader(opts); - runTests(opts).catch(err => console.error(typeof err === 'string' ? err : JSON.stringify(err))); + runTests(opts).catch(err => { + if (typeof err !== 'string') { + err = JSON.stringify(err); + } + + console.error(err); + ipcRenderer.send('error', err); + }); }); diff --git a/test/smoke/package.json b/test/smoke/package.json index cf0ce7cde1f..979eb8ee0a0 100644 --- a/test/smoke/package.json +++ b/test/smoke/package.json @@ -22,7 +22,7 @@ "@types/webdriverio": "4.6.1", "concurrently": "^3.5.1", "cpx": "^1.5.0", - "electron": "4.2.3", + "electron": "4.2.5", "htmlparser2": "^3.9.2", "mkdirp": "^0.5.1", "mocha": "^5.2.0", diff --git a/test/smoke/src/application.ts b/test/smoke/src/application.ts index 4f5b7aa2e85..40fc3097639 100644 --- a/test/smoke/src/application.ts +++ b/test/smoke/src/application.ts @@ -140,7 +140,7 @@ export class Application { // await this.code.waitForElement('.monaco-workbench'); // if (this.remote) { - // await this.code.waitForElement('.monaco-workbench .statusbar-item.statusbar-entry a[title="Editing on TestResolver"]'); + // await this.code.waitForElement('.monaco-workbench .statusbar-item[title="Editing on TestResolver"]'); // } // wait a bit, since focus might be stolen off widgets diff --git a/test/smoke/src/areas/git/git.test.ts b/test/smoke/src/areas/git/git.test.ts index d04677eafbc..11546f7d7fe 100644 --- a/test/smoke/src/areas/git/git.test.ts +++ b/test/smoke/src/areas/git/git.test.ts @@ -7,7 +7,7 @@ import * as cp from 'child_process'; import { Application } from '../../application'; const DIFF_EDITOR_LINE_INSERT = '.monaco-diff-editor .editor.modified .line-insert'; -const SYNC_STATUSBAR = 'div[id="workbench.parts.statusbar"] .statusbar-entry a[title$="Synchronize Changes"]'; +const SYNC_STATUSBAR = 'div[id="workbench.parts.statusbar"] .statusbar-item[title$="Synchronize Changes"]'; export function setup() { describe('Git', () => { diff --git a/test/smoke/src/areas/problems/problems.ts b/test/smoke/src/areas/problems/problems.ts index c71b7d33791..e0499151dcb 100644 --- a/test/smoke/src/areas/problems/problems.ts +++ b/test/smoke/src/areas/problems/problems.ts @@ -39,7 +39,7 @@ export class Problems { } public static getSelectorInProblemsView(problemType: ProblemSeverity): string { - let selector = problemType === ProblemSeverity.WARNING ? 'warning' : 'error'; + let selector = problemType === ProblemSeverity.WARNING ? 'severity-warning' : 'severity-error'; return `div[id="workbench.panel.markers"] .monaco-tl-contents .marker-icon.${selector}`; } diff --git a/test/smoke/src/areas/statusbar/statusbar.ts b/test/smoke/src/areas/statusbar/statusbar.ts index c9bfa19bc5c..66e1186fd4c 100644 --- a/test/smoke/src/areas/statusbar/statusbar.ts +++ b/test/smoke/src/areas/statusbar/statusbar.ts @@ -38,7 +38,7 @@ export class StatusBar { } async waitForStatusbarText(title: string, text: string): Promise { - await this.code.waitForTextContent(`${this.mainSelector} span[title="${title}"]`, text); + await this.code.waitForTextContent(`${this.mainSelector} .statusbar-item[title="${title}"]`, text); } private getSelector(element: StatusBarElement): string { @@ -50,15 +50,15 @@ export class StatusBar { case StatusBarElement.PROBLEMS_STATUS: return `${this.mainSelector} ${this.leftSelector} .octicon.octicon-error`; case StatusBarElement.SELECTION_STATUS: - return `${this.mainSelector} ${this.rightSelector} a[title="Go to Line"]`; + return `${this.mainSelector} ${this.rightSelector}[title="Go to Line"]`; case StatusBarElement.INDENTATION_STATUS: - return `${this.mainSelector} ${this.rightSelector} a[title="Select Indentation"]`; + return `${this.mainSelector} ${this.rightSelector}[title="Select Indentation"]`; case StatusBarElement.ENCODING_STATUS: - return `${this.mainSelector} ${this.rightSelector} a[title="Select Encoding"]`; + return `${this.mainSelector} ${this.rightSelector}[title="Select Encoding"]`; case StatusBarElement.EOL_STATUS: - return `${this.mainSelector} ${this.rightSelector} a[title="Select End of Line Sequence"]`; + return `${this.mainSelector} ${this.rightSelector}[title="Select End of Line Sequence"]`; case StatusBarElement.LANGUAGE_STATUS: - return `${this.mainSelector} ${this.rightSelector} a[title="Select Language Mode"]`; + return `${this.mainSelector} ${this.rightSelector}[title="Select Language Mode"]`; case StatusBarElement.FEEDBACK_ICON: return `${this.mainSelector} ${this.rightSelector} .monaco-dropdown.send-feedback`; default: diff --git a/test/smoke/src/areas/workbench/localization.test.ts b/test/smoke/src/areas/workbench/localization.test.ts index c0844c2c6bf..e9e0b44a4f0 100644 --- a/test/smoke/src/areas/workbench/localization.test.ts +++ b/test/smoke/src/areas/workbench/localization.test.ts @@ -37,7 +37,7 @@ export function setup() { await app.workbench.scm.waitForTitle(title => /quellcodeverwaltung/i.test(title)); await app.workbench.debug.openDebugViewlet(); - await app.workbench.debug.waitForTitle(title => /debuggen/i.test(title)); + await app.workbench.debug.waitForTitle(title => /debug/i.test(title)); await app.workbench.extensions.openExtensionsViewlet(); await app.workbench.extensions.waitForTitle(title => /erweiterungen/i.test(title)); diff --git a/test/smoke/yarn.lock b/test/smoke/yarn.lock index cdcb6f7dada..ca28dd6bf19 100644 --- a/test/smoke/yarn.lock +++ b/test/smoke/yarn.lock @@ -74,14 +74,6 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -ajv@^4.9.1: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY= - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" - ajv@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda" @@ -126,9 +118,9 @@ aproba@^1.0.3: integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" - integrity sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0= + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== dependencies: delegates "^1.0.0" readable-stream "^2.0.6" @@ -140,11 +132,21 @@ arr-diff@^2.0.0: dependencies: arr-flatten "^1.0.1" -arr-flatten@^1.0.1: +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" @@ -170,6 +172,11 @@ array-unique@^0.2.1: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -180,36 +187,31 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - integrity sha1-104bh+ev/A24qttwIfP+SBAasjQ= +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - integrity sha1-GdOGodntxufByF04iu28xW0zYC0= + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" - integrity sha1-FDQt0428yU0OW4fXY81jYSwOeU8= +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= -aws4@^1.2.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" - integrity sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w== - aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" @@ -228,6 +230,19 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + bcrypt-pbkdf@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" @@ -236,29 +251,15 @@ bcrypt-pbkdf@^1.0.0: tweetnacl "^0.14.3" binary-extensions@^1.0.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" - integrity sha1-RqoXUftqL5PuXmibsQh9SxTGwgU= - -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= - dependencies: - inherits "~2.0.0" + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== bluebird@^2.9.34: version "2.11.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE= -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - integrity sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8= - dependencies: - hoek "2.x.x" - boom@4.x.x: version "4.3.1" resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" @@ -290,6 +291,22 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + browser-stdout@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" @@ -300,6 +317,21 @@ builtin-modules@^1.0.0: resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + camelcase-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" @@ -350,6 +382,21 @@ chokidar@^1.6.0: optionalDependencies: fsevents "^1.0.0" +chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -360,6 +407,14 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + combined-stream@^1.0.5, combined-stream@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" @@ -382,6 +437,11 @@ commander@^2.8.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -415,10 +475,15 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + core-js@^2.4.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" - integrity sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs= + version "2.6.9" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" + integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -447,13 +512,6 @@ crypt@~0.0.1: resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - integrity sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g= - dependencies: - boom "2.x.x" - cryptiles@3.x.x: version "3.1.2" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" @@ -480,7 +538,7 @@ date-fns@^1.23.0: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" integrity sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw== -debug@2.6.9, debug@^2.1.3, debug@^2.2.0: +debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -494,7 +552,7 @@ debug@3.1.0, debug@^3.1.0: dependencies: ms "2.0.0" -debug@^3.0.0: +debug@^3.0.0, debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== @@ -506,15 +564,37 @@ decamelize@^1.1.2: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-extend@~0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" - integrity sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8= +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" delayed-stream@~1.0.0: version "1.0.0" @@ -596,10 +676,10 @@ electron-download@^4.1.0: semver "^5.4.1" sumchecker "^2.0.2" -electron@4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/electron/-/electron-4.2.3.tgz#5d45da9dd5ae97269dbee2623840da808c72d29d" - integrity sha512-nx+jHxj2eNhaYHXFGdzr7zgSphpVHEU9WAu6qqEUsQ936X3c6bQ5Bdg08KbHZj+cyRRQ06JMu6/ILh5pWrDZaA== +electron@4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/electron/-/electron-4.2.5.tgz#1d1432c38e2b2190318f7ca30897cdfdcf942e5a" + integrity sha512-P132MXzTtyn2ZaekhKi5JeHzmTAMuR/uQt4hrg3vfJV7fpncx9SL6UFwHAK1DU13iiyZJqqIziNUu+o8nODHsA== dependencies: "@types/node" "^10.12.18" electron-download "^4.1.0" @@ -641,6 +721,19 @@ expand-brackets@^0.1.4: dependencies: is-posix-bracket "^0.1.0" +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + expand-range@^1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" @@ -648,7 +741,22 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -extend@~3.0.0, extend@~3.0.1: +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ= @@ -660,6 +768,20 @@ extglob@^0.3.1: dependencies: is-extglob "^1.0.0" +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + extract-zip@^1.0.3: version "1.6.6" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c" @@ -698,16 +820,26 @@ filename-regex@^2.0.0: integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - integrity sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM= + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== dependencies: is-number "^2.1.0" isobject "^2.0.0" - randomatic "^1.1.3" + randomatic "^3.0.0" repeat-element "^1.1.2" repeat-string "^1.5.2" +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + find-index@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" @@ -721,7 +853,7 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -for-in@^1.0.1: +for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= @@ -738,15 +870,6 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@~2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" - integrity sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE= - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - form-data@~2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" @@ -756,6 +879,13 @@ form-data@~2.3.1: combined-stream "^1.0.5" mime-types "^2.1.12" +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + fs-extra@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" @@ -765,37 +895,25 @@ fs-extra@^4.0.1: jsonfile "^4.0.0" universalify "^0.1.0" +fs-minipass@^1.2.5: + version "1.2.6" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" + integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ== + dependencies: + minipass "^2.2.1" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" - integrity sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q== + version "1.2.9" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" + integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== dependencies: - nan "^2.3.0" - node-pre-gyp "^0.6.39" - -fstream-ignore@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" - integrity sha1-nDHa40dnAY/h0kmyTa2mfQktoQU= - dependencies: - fstream "^1.0.0" - inherits "2" - minimatch "^3.0.0" - -fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" - integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" + nan "^2.12.1" + node-pre-gyp "^0.12.0" gauge@~2.7.3: version "2.7.4" @@ -816,6 +934,11 @@ get-stdin@^4.0.1: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" @@ -857,6 +980,11 @@ glob@7.1.2, glob@^7.0.5: once "^1.3.0" path-is-absolute "^1.0.0" +graceful-fs@^4.1.11: + version "4.2.0" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" + integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== + graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -867,24 +995,11 @@ growl@1.10.5: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== -har-schema@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" - integrity sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4= - har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" - integrity sha1-M0gdDxu/9gDdID11gSpqX7oALio= - dependencies: - ajv "^4.9.1" - har-schema "^1.0.5" - har-validator@~5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" @@ -915,15 +1030,36 @@ has-unicode@^2.0.0: resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= -hawk@3.1.3, hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - integrity sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ= +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" hawk@~6.0.2: version "6.0.2" @@ -940,11 +1076,6 @@ he@1.1.1: resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= - hoek@4.x.x: version "4.2.0" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" @@ -967,15 +1098,6 @@ htmlparser2@^3.9.2: inherits "^2.0.1" readable-stream "^2.0.2" -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" - integrity sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8= - dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -985,6 +1107,20 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" + indent-string@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" @@ -1000,7 +1136,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= @@ -1010,6 +1146,20 @@ ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" integrity sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4= +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -1034,6 +1184,38 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -1046,11 +1228,18 @@ is-equal-shallow@^0.1.3: dependencies: is-primitive "^2.0.0" -is-extendable@^0.1.1: +is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + is-extglob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" @@ -1070,6 +1259,11 @@ is-fullwidth-code-point@^1.0.0: dependencies: number-is-nan "^1.0.0" +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -1091,6 +1285,18 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" @@ -1111,6 +1317,11 @@ is-utf8@^0.2.0: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" @@ -1128,6 +1339,11 @@ isobject@^2.0.0: dependencies: isarray "1.0.0" +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -1148,13 +1364,6 @@ json-schema@0.2.3: resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -1182,7 +1391,7 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -kind-of@^3.0.2: +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= @@ -1196,6 +1405,16 @@ kind-of@^4.0.0: dependencies: is-buffer "^1.1.5" +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -1225,11 +1444,28 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +math-random@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + md5@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" @@ -1279,16 +1515,30 @@ micromatch@^2.1.5: parse-glob "^3.0.4" regex-cache "^0.4.2" +micromatch@^3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + mime-db@~1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" integrity sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE= -mime-db@~1.33.0: - version "1.33.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" - integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== - mime-types@^2.1.12, mime-types@~2.1.17: version "2.1.17" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" @@ -1296,14 +1546,7 @@ mime-types@^2.1.12, mime-types@~2.1.17: dependencies: mime-db "~1.30.0" -mime-types@~2.1.7: - version "2.1.18" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" - integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== - dependencies: - mime-db "~1.33.0" - -minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -1320,6 +1563,29 @@ minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= +minipass@^2.2.1, minipass@^2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + mkdirp@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" @@ -1327,7 +1593,7 @@ mkdirp@0.5.0: dependencies: minimist "0.0.8" -mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -1380,32 +1646,57 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -nan@^2.3.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" - integrity sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA== +nan@^2.12.1: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" ncp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= -node-pre-gyp@^0.6.39: - version "0.6.39" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" - integrity sha512-OsJV74qxnvz/AMGgcfZoDaeDXKD3oY3QVIbBmwszTFkRisTSXbMQyn4UWzUMOtA5SVhrBZOTp0wcoSBgfMfMmQ== +needle@^2.2.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" + integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +node-pre-gyp@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== dependencies: detect-libc "^1.0.2" - hawk "3.1.3" mkdirp "^0.5.1" + needle "^2.2.1" nopt "^4.0.1" + npm-packlist "^1.1.6" npmlog "^4.0.2" - rc "^1.1.7" - request "2.81.0" + rc "^1.2.7" rimraf "^2.6.1" semver "^5.3.0" - tar "^2.2.1" - tar-pack "^3.4.0" + tar "^4" nopt@^4.0.1: version "4.0.1" @@ -1432,6 +1723,19 @@ normalize-path@^2.0.0, normalize-path@^2.0.1: dependencies: remove-trailing-separator "^1.0.1" +npm-bundled@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" + integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== + +npm-packlist@^1.1.6: + version "1.4.4" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.4.tgz#866224233850ac534b63d1a6e76050092b5d2f44" + integrity sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -1460,7 +1764,7 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -oauth-sign@~0.8.1, oauth-sign@~0.8.2: +oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= @@ -1470,11 +1774,27 @@ object-assign@^4.0.1, object-assign@^4.1.0: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + object-keys@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -1483,7 +1803,14 @@ object.omit@^2.0.0: for-own "^0.1.4" is-extendable "^0.1.1" -once@^1.3.0, once@^1.3.3: +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -1525,6 +1852,11 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -1542,10 +1874,10 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" - integrity sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME= +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== path-type@^1.0.0: version "1.1.0" @@ -1561,11 +1893,6 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= -performance-now@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" - integrity sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU= - performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -1597,6 +1924,11 @@ portastic@^1.0.1: commander "^2.8.1" debug "^2.2.0" +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" @@ -1616,9 +1948,9 @@ process-nextick-args@~1.0.6: integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== progress-stream@^1.1.0: version "1.2.0" @@ -1633,35 +1965,21 @@ punycode@^1.4.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= -qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" - integrity sha1-E+JtKK1rD/qpExLNO/cI7TUecjM= - qs@~6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" integrity sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A== -randomatic@^1.1.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" - integrity sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how== +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" -rc@^1.1.7: - version "1.2.6" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.6.tgz#eb18989c6d4f4f162c399f79ddd29f3835568092" - integrity sha1-6xiYnG1PTxYsOZ953dKfODVWgJI= - dependencies: - deep-extend "~0.4.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -rc@^1.2.1: +rc@^1.2.1, rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -1701,7 +2019,7 @@ readable-stream@^2.0.2, readable-stream@^2.2.2: string_decoder "~1.0.3" util-deprecate "~1.0.1" -readable-stream@^2.0.6, readable-stream@^2.1.4: +readable-stream@^2.0.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -1725,14 +2043,13 @@ readable-stream@~1.1.9: string_decoder "~0.10.x" readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - integrity sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg= + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" + graceful-fs "^4.1.11" + micromatch "^3.1.10" readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" redent@^1.0.0: version "1.0.0" @@ -1743,9 +2060,9 @@ redent@^1.0.0: strip-indent "^1.0.1" regenerator-runtime@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" - integrity sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A== + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== regex-cache@^0.4.2: version "0.4.4" @@ -1754,17 +2071,25 @@ regex-cache@^0.4.2: dependencies: is-equal-shallow "^0.1.3" +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - integrity sha1-7wiaF40Ug7quTZPrmLT55OEdmQo= + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.5.2: +repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -1776,34 +2101,6 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@2.81.0: - version "2.81.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" - integrity sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA= - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~4.2.1" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - performance-now "^0.2.0" - qs "~6.4.0" - safe-buffer "^5.0.1" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "^0.6.0" - uuid "^3.0.0" - request@^2.45.0: version "2.83.0" resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" @@ -1832,14 +2129,24 @@ request@^2.45.0: tunnel-agent "^0.6.0" uuid "^3.1.0" -resolve@^1.1.7: - version "1.7.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.0.tgz#2bdf5374811207285df0df652b78f118ab8f3c5e" - integrity sha512-QdgZ5bjR1WAlpLaO5yHepFvC+o3rCr6wpfE2tpJNMkXdulf2jKomQBdNRQITF3ZKHNlT71syG98yQP03gasgnA== - dependencies: - path-parse "^1.0.5" +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1: +resolve@^1.1.7: + version "1.11.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" + integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== + dependencies: + path-parse "^1.0.6" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== @@ -1856,11 +2163,38 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== -"semver@2 || 3 || 4 || 5", semver@^5.3.0: +safe-buffer@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +"semver@2 || 3 || 4 || 5": version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== +semver@^5.3.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + semver@^5.4.1: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" @@ -1871,10 +2205,15 @@ set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" shell-quote@^1.6.1: version "1.6.1" @@ -1898,12 +2237,35 @@ single-line-log@^1.1.2: dependencies: string-width "^1.0.1" -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: - hoek "2.x.x" + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" sntp@2.x.x: version "2.1.0" @@ -1912,6 +2274,27 @@ sntp@2.x.x: dependencies: hoek "4.x.x" +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + spawn-command@^0.0.2-1: version "0.0.2-1" resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" @@ -1939,6 +2322,13 @@ speedometer@~0.1.2: resolved "https://registry.yarnpkg.com/speedometer/-/speedometer-0.1.4.tgz#9876dbd2a169d3115402d48e6ea6329c8816a50d" integrity sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0= +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + sshpk@^1.7.0: version "1.13.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" @@ -1954,7 +2344,15 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" -string-width@^1.0.1, string-width@^1.0.2: +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= @@ -1963,6 +2361,14 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" @@ -1982,7 +2388,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringstream@~0.0.4, stringstream@~0.0.5: +stringstream@~0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" integrity sha1-TkhM1N5aC7vuGORjB3EKioFiGHg= @@ -2060,28 +2466,18 @@ supports-color@^3.2.3: dependencies: has-flag "^1.0.0" -tar-pack@^3.4.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" - integrity sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg== +tar@^4: + version "4.4.10" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" + integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== dependencies: - debug "^2.2.0" - fstream "^1.0.10" - fstream-ignore "^1.0.5" - once "^1.3.3" - readable-stream "^2.1.4" - rimraf "^2.5.1" - tar "^2.2.1" - uid-number "^0.0.6" - -tar@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= - dependencies: - block-stream "*" - fstream "^1.0.2" - inherits "2" + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.5" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" throttleit@0.0.2: version "0.0.2" @@ -2103,12 +2499,30 @@ tmp@0.0.33: dependencies: os-tmpdir "~1.0.2" -tough-cookie@~2.3.0: - version "2.3.4" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" - integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: - punycode "^1.4.1" + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" tough-cookie@~2.3.3: version "2.3.3" @@ -2149,26 +2563,44 @@ typescript@2.9.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c" integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w== -uid-number@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -uuid@^3.0.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" - integrity sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA== - uuid@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" @@ -2200,11 +2632,11 @@ watch@^1.0.2: minimist "^1.2.0" wide-align@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" - integrity sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w== + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: - string-width "^1.0.2" + string-width "^1.0.2 || 2" wrappy@1: version "1.0.2" @@ -2223,6 +2655,11 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" +yallist@^3.0.0, yallist@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + yauzl@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" diff --git a/tslint.json b/tslint.json index 2b9cbdbbb02..3ff7147730b 100644 --- a/tslint.json +++ b/tslint.json @@ -364,6 +364,7 @@ "**/vs/platform/*/{common,browser}/**", "**/vs/editor/{common,browser}/**", "**/vs/editor/contrib/**", // editor/contrib is equivalent to /browser/ by convention + "**/vs/workbench/workbench.web.api", "**/vs/workbench/{common,browser}/**", "**/vs/workbench/services/*/{common,browser}/**", "assert" @@ -429,7 +430,8 @@ "**/vs/editor/common/**", "**/vs/workbench/common/**", "**/vs/workbench/services/**/common/**", - "**/vs/workbench/api/**/common/**" + "**/vs/workbench/api/**/common/**", + "vscode-textmate" ] }, { @@ -440,6 +442,7 @@ "**/vs/base/**/{common,browser}/**", "**/vs/platform/**/{common,browser}/**", "**/vs/editor/{common,browser}/**", + "**/vs/workbench/workbench.web.api", "**/vs/workbench/{common,browser}/**", "**/vs/workbench/services/**/{common,browser}/**", "vscode-textmate", diff --git a/yarn.lock b/yarn.lock index 0e22653e4dc..d47dd07a343 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35,10 +35,10 @@ resolved "https://registry.yarnpkg.com/@types/fancy-log/-/fancy-log-1.3.0.tgz#a61ab476e5e628cd07a846330df53b85e05c8ce0" integrity sha512-mQjDxyOM1Cpocd+vm1kZBP7smwKZ4TNokFeds9LV7OZibmPJFEzY3+xZMrKfUdNT71lv8GoCPD6upKwHxubClw== -"@types/keytar@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/keytar/-/keytar-4.0.1.tgz#e2cf6405dc33861424e59b67516c66d2cf7bc21b" - integrity sha512-loKBID6UL4QjhD2scuvv6oAPlQ/WAY7aYTDyKlKo7fIgriLS8EZExqT567cHL5CY6si51MRoX1+r3mitD3eYrA== +"@types/keytar@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@types/keytar/-/keytar-4.4.0.tgz#ca24e6ee6d0df10c003aafe26e93113b8faf0d8e" + integrity sha512-cq/NkUUy6rpWD8n7PweNQQBpw2o0cf5v6fbkUVEpOB9VzzIvyPvSEId1/goIj+MciW2v1Lw5mRimKO01XgE9EA== "@types/minimist@^1.2.0": version "1.2.0" @@ -303,10 +303,10 @@ acorn@^5.0.0, acorn@^5.6.2: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" integrity sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ== -acorn@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" - integrity sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w== +acorn@^5.5.0: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== acorn@^6.0.2: version "6.0.7" @@ -327,24 +327,16 @@ agent-base@~4.2.0: dependencies: es6-promisify "^5.0.0" -ajv-keywords@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" - integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw= +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + integrity sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I= ajv-keywords@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= -ajv@^4.7.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY= - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" - ajv@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda" @@ -355,7 +347,7 @@ ajv@^5.1.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" -ajv@^5.3.0: +ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= @@ -423,11 +415,6 @@ ansi-cyan@^0.1.1: dependencies: ansi-wrap "0.1.0" -ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= - ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" @@ -467,6 +454,11 @@ ansi-regex@^4.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -828,7 +820,7 @@ azure-storage@^2.10.2: xml2js "0.2.8" xmlbuilder "^9.0.7" -babel-code-frame@^6.16.0: +babel-code-frame@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= @@ -1260,6 +1252,11 @@ camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + caniuse-api@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" @@ -1309,7 +1306,7 @@ chalk@2.3.1: escape-string-regexp "^1.0.5" supports-color "^5.2.0" -chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -1347,6 +1344,11 @@ chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= + chardet@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.5.0.tgz#fe3ac73c00c3d865ffcc02a0682e2c20b6a06029" @@ -1473,13 +1475,6 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -cli-cursor@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" - integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc= - dependencies: - restore-cursor "^1.0.1" - cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -1519,6 +1514,15 @@ cliui@^4.0.0: strip-ansi "^4.0.0" wrap-ansi "^2.0.0" +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + clone-buffer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" @@ -1720,7 +1724,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@1.6.0, concat-stream@^1.5.2: +concat-stream@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" integrity sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc= @@ -1894,7 +1898,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" -cross-spawn@^5.0.1: +cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= @@ -1903,7 +1907,7 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.5: +cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -2083,7 +2087,7 @@ debug@2.2.0: dependencies: ms "0.7.1" -debug@2.6.9, debug@^2.1.1, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3: +debug@2.6.9, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -2111,7 +2115,7 @@ debug@^4.0.1, debug@^4.1.0: dependencies: ms "^2.1.1" -decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -2319,14 +2323,6 @@ dir-glob@^2.0.0: arrify "^1.0.1" path-type "^3.0.0" -doctrine@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" - integrity sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -2525,6 +2521,11 @@ elliptic@^6.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -2592,18 +2593,6 @@ es6-iterator@^2.0.1, es6-iterator@~2.0.1: es5-ext "^0.10.35" es6-symbol "^3.1.1" -es6-map@^0.1.3: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" - integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-set "~0.1.5" - es6-symbol "~3.1.1" - event-emitter "~0.3.5" - es6-promise@^4.0.3: version "4.2.4" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" @@ -2616,18 +2605,7 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -es6-set@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" - integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-symbol "3.1.1" - event-emitter "~0.3.5" - -es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: +es6-symbol@^3.1.1, es6-symbol@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= @@ -2684,13 +2662,11 @@ escodegen@1.8.x: optionalDependencies: source-map "~0.2.0" -escope@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" - integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM= +eslint-scope@^3.7.1: + version "3.7.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" + integrity sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA== dependencies: - es6-map "^0.1.3" - es6-weak-map "^2.0.1" esrecurse "^4.1.0" estraverse "^4.1.1" @@ -2712,46 +2688,49 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@^3.4.0: - version "3.19.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" - integrity sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw= +eslint@^4.18.2: + version "4.19.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" + integrity sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ== dependencies: - babel-code-frame "^6.16.0" - chalk "^1.1.3" - concat-stream "^1.5.2" - debug "^2.1.1" - doctrine "^2.0.0" - escope "^3.6.0" - espree "^3.4.0" + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.1.0" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.4" esquery "^1.0.0" - estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" - glob "^7.0.3" - globals "^9.14.0" - ignore "^3.2.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.0.1" + ignore "^3.3.3" imurmurhash "^0.1.4" - inquirer "^0.12.0" - is-my-json-valid "^2.10.0" + inquirer "^3.0.6" is-resolvable "^1.0.0" - js-yaml "^3.5.1" - json-stable-stringify "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.0.0" - mkdirp "^0.5.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" - path-is-inside "^1.0.1" - pluralize "^1.2.1" - progress "^1.1.8" - require-uncached "^1.0.2" - shelljs "^0.7.5" - strip-bom "^3.0.0" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^1.0.1" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" strip-json-comments "~2.0.1" - table "^3.7.8" + table "4.0.2" text-table "~0.2.0" - user-home "^2.0.0" eslint@^5.0.1: version "5.13.0" @@ -2795,12 +2774,12 @@ eslint@^5.0.1: table "^5.0.2" text-table "^0.2.0" -espree@^3.4.0: - version "3.5.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca" - integrity sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ== +espree@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== dependencies: - acorn "^5.2.1" + acorn "^5.5.0" acorn-jsx "^3.0.0" espree@^5.0.0: @@ -2859,7 +2838,7 @@ estraverse@^1.9.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= @@ -2874,14 +2853,6 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= -event-emitter@~0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= - dependencies: - d "1" - es5-ext "~0.10.14" - event-stream@3.3.4, event-stream@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" @@ -2939,10 +2910,18 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -exit-hook@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" - integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g= +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" expand-brackets@^0.1.4: version "0.1.5" @@ -2971,10 +2950,10 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -expand-template@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.1.tgz#981f188c0c3a87d2e28f559bc541426ff94f21dd" - integrity sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg== +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" @@ -3051,6 +3030,15 @@ extend@^3.0.2, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +external-editor@^2.0.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + external-editor@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.0.tgz#dc35c48c6f98a30ca27a20e9687d7f3c77704bb6" @@ -3187,14 +3175,6 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -figures@^1.3.5: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" - integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= - dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" - figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -3477,9 +3457,9 @@ fs-extra@^2.0.0: jsonfile "^2.1.0" fs-extra@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.0.tgz#8cc3f47ce07ef7b3593a11b9fb245f7e34c041d6" - integrity sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ== + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== dependencies: graceful-fs "^4.1.2" jsonfile "^4.0.0" @@ -3565,11 +3545,6 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -gc-signals@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/gc-signals/-/gc-signals-0.0.2.tgz#1cfa8a00adecaeeb93ea0dda72dad9e9f333e62f" - integrity sha512-Ghj4Co6x5bd3dvbAFuiDc6gN+BVK8ic8CBn70dXjzrtbC5hq4a+s4S6acEvftMP7LcQuHKN5v+30PGXhkCLoCQ== - generate-function@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" @@ -3587,6 +3562,11 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" integrity sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U= +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" @@ -3597,6 +3577,13 @@ get-stream@^3.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -3727,7 +3714,7 @@ glob@^6.0.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2: +glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== @@ -3776,16 +3763,16 @@ global-prefix@^1.0.1: is-windows "^1.0.1" which "^1.2.14" +globals@^11.0.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + globals@^11.7.0: version "11.10.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.10.0.tgz#1e09776dffda5e01816b3bb4077c8b59c24eaa50" integrity sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ== -globals@^9.14.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== - globby@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" @@ -4401,20 +4388,27 @@ iconv-lite@0.4.19, iconv-lite@^0.4.19: resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ== -iconv-lite@0.4.23, iconv-lite@^0.4.22, iconv-lite@^0.4.4: - version "0.4.23" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" - integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== +iconv-lite@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.5.0.tgz#59cdde0a2a297cc2aeb0c6445a195ee89f127550" + integrity sha512-NnEhI9hIEKHOzJ4f697DMz9IQEXr/MMJ5w64vN2/4Ai+wRnvV7SBrL0KLoRlwaKVghOc7LQ5YkPLuX146b6Ydw== dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.4.24: +iconv-lite@^0.4.17, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@^0.4.22, iconv-lite@^0.4.4: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + ieee754@^1.1.11, ieee754@^1.1.4: version "1.1.12" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" @@ -4432,12 +4426,7 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" -ignore@^3.2.0: - version "3.3.7" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" - integrity sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA== - -ignore@^3.3.5: +ignore@^3.3.3, ignore@^3.3.5: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== @@ -4508,28 +4497,29 @@ ini@^1.3.4, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" integrity sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4= -innosetup-compiler@^5.5.60: - version "5.5.62" - resolved "https://registry.yarnpkg.com/innosetup-compiler/-/innosetup-compiler-5.5.62.tgz#fc12cd8d17cf75a2e3833b2754a5c2bc4f26cc4e" - integrity sha1-/BLNjRfPdaLjgzsnVKXCvE8mzE4= +innosetup@5.6.1: + version "5.6.1" + resolved "https://registry.yarnpkg.com/innosetup/-/innosetup-5.6.1.tgz#6e7031ba35b23e716e4f29686bc994052e0c278c" + integrity sha512-Eit24N3JR8O0Wpuq/dMWCl2r550eiNP2124SbdbwOob43x89WPGL/SGpZG5EPHu20kV2N+4TwvHwFIM8pFUJ0g== -inquirer@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" - integrity sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34= +inquirer@^3.0.6: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== dependencies: - ansi-escapes "^1.1.0" - ansi-regex "^2.0.0" - chalk "^1.0.0" - cli-cursor "^1.0.1" + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" cli-width "^2.0.0" - figures "^1.3.5" + external-editor "^2.0.4" + figures "^2.0.0" lodash "^4.3.0" - readline2 "^1.0.1" - run-async "^0.1.0" - rx-lite "^3.1.2" - string-width "^1.0.1" - strip-ansi "^3.0.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" through "^2.3.6" inquirer@^6.0.0: @@ -4575,11 +4565,6 @@ int64-buffer@^0.1.9: resolved "https://registry.yarnpkg.com/int64-buffer/-/int64-buffer-0.1.9.tgz#9e039da043b24f78b196b283e04653ef5e990f61" integrity sha1-ngOdoEOyT3ixlrKD4EZT716ZD2E= -interpret@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0" - integrity sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA= - interpret@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" @@ -4590,6 +4575,11 @@ invert-kv@^1.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -4777,7 +4767,7 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" -is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: +is-my-json-valid@^2.12.4: version "2.16.1" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" integrity sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ== @@ -5071,7 +5061,7 @@ js-yaml@3.6.1: argparse "^1.0.7" esprima "^2.6.0" -js-yaml@3.x, js-yaml@^3.5.1: +js-yaml@3.x: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" integrity sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA== @@ -5087,7 +5077,7 @@ js-yaml@^3.12.0: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^3.13.0: +js-yaml@^3.13.0, js-yaml@^3.9.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -5160,7 +5150,7 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: +json-stable-stringify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= @@ -5221,13 +5211,13 @@ just-debounce@^1.0.0: resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.0.0.tgz#87fccfaeffc0b68cd19d55f6722943f929ea35ea" integrity sha1-h/zPrv/AtozRnVX2cilD+SnqNeo= -keytar@4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/keytar/-/keytar-4.2.1.tgz#8a06a6577fdf6373e0aa6b112277e63dec77fd12" - integrity sha1-igamV3/fY3PgqmsRInfmPex3/RI= +keytar@^4.11.0: + version "4.11.0" + resolved "https://registry.yarnpkg.com/keytar/-/keytar-4.11.0.tgz#891569045b287a0dabe69320e2381e059b02363f" + integrity sha512-cGn2xd4NY0yCBrU5zQ/lwIagP1UBOhUEemi6iSJU2gshN1RHkxHekSdLUji9IWNo5B1Va/iwXXWzGD2p8ziqfQ== dependencies: - nan "2.8.0" - prebuild-install "^2.4.1" + nan "2.14.0" + prebuild-install "5.3.0" kind-of@^1.1.0: version "1.1.0" @@ -5304,6 +5294,13 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + lcov-parse@0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" @@ -5454,7 +5451,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.3.0: +lodash@^4.13.1, lodash@^4.15.0, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" integrity sha1-eCA6TRwyiuHYbcpkYONptX9AVa4= @@ -5567,6 +5564,13 @@ mamacro@^0.0.3: resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + map-cache@^0.2.0, map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -5654,6 +5658,15 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -5702,7 +5715,7 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromatch@^2.1.5, micromatch@^2.3.7: +micromatch@^2.3.7: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= @@ -5792,6 +5805,11 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" integrity sha1-5md4PZLonb00KBi1IwudYqZyrRg= +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + mimic-response@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" @@ -5985,20 +6003,15 @@ mute-stdout@^1.0.0: resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== -mute-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" - integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA= - mute-stream@0.0.7, mute-stream@~0.0.4: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -nan@2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" - integrity sha1-7XFfP+neArV6XmJS2QqWZ14fCFo= +nan@2.14.0, nan@^2.0.0, nan@^2.13.2, nan@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nan@^2.10.0: version "2.11.0" @@ -6010,12 +6023,7 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== -nan@^2.13.2, nan@^2.14.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== - -nan@^2.9.2, nan@~2.10.0: +nan@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" integrity sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA== @@ -6037,15 +6045,20 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +napi-build-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.1.tgz#1381a0f92c39d66bf19852e7873432fc2123e508" + integrity sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA== + native-is-elevated@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/native-is-elevated/-/native-is-elevated-0.2.1.tgz#70a2123a8575b9f624a3ef465d98cb74ae017385" integrity sha1-cKISOoV1ufYko+9GXZjLdK4Bc4U= -native-keymap@1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/native-keymap/-/native-keymap-1.2.5.tgz#1035a9417b9a9340cf8097763a43c76d588165a5" - integrity sha1-EDWpQXuak0DPgJd2OkPHbViBZaU= +native-keymap@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/native-keymap/-/native-keymap-2.0.0.tgz#7491ba8f9cc75bd6ada7e754dadb7716c793a3e3" + integrity sha512-KIlDZp0yKaHaGIkEVdlYN3QIaZICXwG1qh/oeBeQdM8TwAi90IAZlAD57qsNDkEvIJIzerCzb5jYYQAdHGBgYg== native-watchdog@1.0.0: version "1.0.0" @@ -6081,10 +6094,10 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" integrity sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA== -node-abi@^2.2.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.4.1.tgz#7628c4d4ec4e9cd3764ceb3652f36b2e7f8d4923" - integrity sha512-pUlswqpHQ7zGPI9lGjZ4XDNIEUDbHxsltfIRb7dTnYdhgHWHOcB0MLZKLoCz6UMcGzSPG5wGl1HODZVQAUsH6w== +node-abi@^2.7.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.9.0.tgz#ae4075b298dab2d92dd1e22c48ccc7ffd7f06200" + integrity sha512-jmEOvv0eanWjhX8dX1pmjb7oJl1U1oR4FOh0b2GnvALwSYoOdU7sj+kLDSAyjo4pfC9aj/IxkloxdLJQhSSQBA== dependencies: semver "^5.4.1" @@ -6138,10 +6151,10 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -node-pty@0.9.0-beta17: - version "0.9.0-beta17" - resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.9.0-beta17.tgz#9b490df86a8124dea595e9fbedeaaf4b2eedbbcb" - integrity sha512-E94XwIs3JxLKAboquHY9Kytbbj/T/tJtRpQoAUdfPE7UXRta/NV+xdmRNhZkeU9jCji+plm656GbYFievgNPkQ== +node-pty@0.9.0-beta19: + version "0.9.0-beta19" + resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.9.0-beta19.tgz#0fd381b2006f4665c4c2ee0509219e591842371a" + integrity sha512-MkKEvBnauGnzgXNr/oaoWQLVXm1gheIKZs4YQp8883ZiETmbEnpSvD0FU3bELcPXG5VFPRqIGsQJ4KUMBLzkPA== dependencies: nan "^2.13.2" @@ -6194,18 +6207,18 @@ normalize-path@^1.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" integrity sha1-MtDkcvkf80VwHBWoMRAY07CpA3k= -normalize-path@^2.0.0, normalize-path@^2.1.1: +normalize-path@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" + integrity sha1-R4hqwWYnYNQmG32XnSQXCdPOP3o= + +normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" - integrity sha1-R4hqwWYnYNQmG32XnSQXCdPOP3o= - normalize-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -6263,6 +6276,16 @@ npmlog@^4.0.1, npmlog@^4.0.2: gauge "~2.7.3" set-blocking "~2.0.0" +nsfw@1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/nsfw/-/nsfw-1.2.5.tgz#febe581af616f7b042f89df133abe62416c4c803" + integrity sha512-m3mwZUKXiCR69PDMLfAmKmiNzy0Oe9LhFE0DYZC5cc1htNj5Hyb1sAgglXhuaDkibFy22AVvPC5cCFB3A6mYIw== + dependencies: + fs-extra "^7.0.0" + lodash.isinteger "^4.0.4" + lodash.isundefined "^3.0.1" + nan "^2.0.0" + nth-check@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4" @@ -6404,11 +6427,6 @@ once@1.x, once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: dependencies: wrappy "1" -onetime@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" - integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= - onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" @@ -6421,12 +6439,12 @@ onigasm-umd@^2.2.2: resolved "https://registry.yarnpkg.com/onigasm-umd/-/onigasm-umd-2.2.2.tgz#b989d762df61f899a3052ac794a50bd93fe20257" integrity sha512-v2eMOJu7iE444L2iJN+U6s6s5S0y7oj/N0DAkrd6wokRtTVoq/v/yaDI1lIqFrTeJbNtqNzYvguDF5yNzW3Rvw== -oniguruma@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/oniguruma/-/oniguruma-7.0.2.tgz#a5c922cf7066da1dbcc60f6385a90437a83f8d0b" - integrity sha512-zCsdNxTrrB4yVPMxhcIODGv1p4NVBu9WvsWnIGhMpu5djO4MQWXrC7YKjtza+OyoRqqgy27CqYWa1h5e2DDbig== +oniguruma@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/oniguruma/-/oniguruma-7.2.0.tgz#c9a59c1ea7b9fe67e237a02e02139b638856f3af" + integrity sha512-bh+ZLdykY1sdIx8jBp2zpLbVFDBc3XmKH4Ceo2lijNaN1WhEqtnpqFlmtCbRuDB17nJ58RAUStVwfW8e8uEbnA== dependencies: - nan "^2.10.0" + nan "^2.14.0" opener@~1.4.0: version "1.4.3" @@ -6520,6 +6538,15 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" +os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + os-tmpdir@^1.0.0, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -6548,11 +6575,21 @@ p-all@^1.0.0: dependencies: p-map "^1.0.0" +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + p-limit@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -6808,6 +6845,11 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picomatch@^2.0.4: + version "2.0.7" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" + integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== + pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -6867,10 +6909,10 @@ plugin-error@1.0.1, plugin-error@^1.0.1: arr-union "^3.1.0" extend-shallow "^3.0.2" -pluralize@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" - integrity sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU= +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== portfinder@^1.0.13: version "1.0.20" @@ -7126,22 +7168,23 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0 source-map "^0.5.6" supports-color "^3.2.3" -prebuild-install@^2.4.1: - version "2.5.3" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-2.5.3.tgz#9f65f242782d370296353710e9bc843490c19f69" - integrity sha512-/rI36cN2g7vDQnKWN8Uzupi++KjyqS9iS+/fpwG4Ea8d0Pip0PQ5bshUNzVwt+/D2MRfhVAplYMMvWLqWrCF/g== +prebuild-install@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.0.tgz#58b4d8344e03590990931ee088dd5401b03004c8" + integrity sha512-aaLVANlj4HgZweKttFNUVNRxDukytuIuxeK2boIMHjagNJCiVKWFsKF4tCE3ql3GbrD2tExPQ7/pwtEJcHNZeg== dependencies: detect-libc "^1.0.3" - expand-template "^1.0.2" + expand-template "^2.0.3" github-from-package "0.0.0" minimist "^1.2.0" mkdirp "^0.5.1" - node-abi "^2.2.0" + napi-build-utils "^1.0.1" + node-abi "^2.7.0" noop-logger "^0.1.1" npmlog "^4.0.1" os-homedir "^1.0.1" pump "^2.0.1" - rc "^1.1.6" + rc "^1.2.7" simple-get "^2.7.0" tar-fs "^1.13.0" tunnel-agent "^0.6.0" @@ -7294,6 +7337,14 @@ pump@^2.0.0, pump@^2.0.1: end-of-stream "^1.1.0" once "^1.3.1" +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + pumpify@^1.3.3, pumpify@^1.3.5: version "1.5.1" resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" @@ -7444,7 +7495,7 @@ rc@^1.1.2: minimist "^1.2.0" strip-json-comments "~2.0.1" -rc@^1.1.6, rc@^1.2.7: +rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -7574,15 +7625,6 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -readline2@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" - integrity sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - mute-stream "0.0.5" - rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -7630,6 +7672,11 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpp@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + integrity sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw== + regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" @@ -7808,7 +7855,12 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= -require-uncached@^1.0.2: +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= @@ -7882,14 +7934,6 @@ resolve@^1.4.0: dependencies: path-parse "^1.0.6" -restore-cursor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" - integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE= - dependencies: - exit-hook "^1.0.0" - onetime "^1.0.0" - restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -7944,13 +7988,6 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -run-async@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" - integrity sha1-yK1KXhEGYeQCp9IbUw4AnyX444k= - dependencies: - once "^1.3.0" - run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -7965,10 +8002,17 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rx-lite@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" - integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI= +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= rxjs@^6.1.0: version "6.2.2" @@ -8165,15 +8209,6 @@ shebang-regex@^1.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= -shelljs@^0.7.5: - version "0.7.8" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" - integrity sha1-3svPh0sNHl+3LhSxZKloMEjprLM= - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - sigmund@^1.0.1, sigmund@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" @@ -8220,10 +8255,12 @@ slash@^1.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= -slice-ansi@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" - integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== + dependencies: + is-fullwidth-code-point "^2.0.0" slice-ansi@^2.0.0: version "2.1.0" @@ -8544,6 +8581,15 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + string_decoder@^1.0.0, string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -8596,6 +8642,13 @@ strip-ansi@^5.0.0: dependencies: ansi-regex "^4.0.0" +strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + strip-bom-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" @@ -8611,11 +8664,6 @@ strip-bom@^2.0.0: dependencies: is-utf8 "^0.2.0" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -8633,10 +8681,10 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -sudo-prompt@8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-8.2.0.tgz#bcd4aaacdb367b77b4bffcce1c658c2b1dd327f3" - integrity sha512-n5Nv2lIZaWfVBg10EWC8yaJCB6xV7sEsuaISAVFIS9F4fTRjy/O35A82lkweKuSqQItDlKOGQpTHK9/udQhRRw== +sudo-prompt@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.0.0.tgz#eebedeee9fcd6f661324e6bb46335e3288e8dc8a" + integrity sha512-kUn5fiOk0nhY2oKD9onIkcNCE4Zt85WTsvOfSmqCplmlEvXCcPOmp1npH5YWuf8Bmyy9wLWkIxx+D+8cThBORQ== sumchecker@^2.0.1: version "2.0.2" @@ -8704,17 +8752,17 @@ svgo@^0.7.0: sax "~1.2.1" whet.extend "~0.9.9" -table@^3.7.8: - version "3.8.3" - resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" - integrity sha1-K7xULw/amGGnVdOUf+/Ys/UThV8= +table@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" + integrity sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA== dependencies: - ajv "^4.7.0" - ajv-keywords "^1.0.0" - chalk "^1.1.1" - lodash "^4.0.0" - slice-ansi "0.0.4" - string-width "^2.0.0" + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" table@^5.0.2: version "5.2.2" @@ -9101,10 +9149,10 @@ typescript-formatter@7.1.0: commandpost "^1.0.0" editorconfig "^0.15.0" -typescript@3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.1.tgz#ba72a6a600b2158139c5dd8850f700e231464202" - integrity sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw== +typescript@3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.2.tgz#a09e1dc69bc9551cadf17dba10ee42cf55e5d56c" + integrity sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA== typescript@^2.6.2: version "2.6.2" @@ -9283,6 +9331,11 @@ upath@^1.0.5, upath@^1.1.0: resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== +upath@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" + integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + uri-js@^4.2.1, uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -9318,13 +9371,6 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -user-home@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" - integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8= - dependencies: - os-homedir "^1.0.0" - util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -9562,46 +9608,49 @@ vsce@1.48.0: yauzl "^2.3.1" yazl "^2.2.2" -vscode-anymatch@1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/vscode-anymatch/-/vscode-anymatch-1.3.3.tgz#0613d31a949c8025473bbdad848d219f47a44f86" - integrity sha512-LQ4vF4BWb9gwAvbMtN+3HC4HKDxLd+ZyWmAjACOdD05O/ZMcgvvnjO24GseEIQ6cWn8gW+Ft08gHFihnQy1eSw== +vscode-anymatch@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/vscode-anymatch/-/vscode-anymatch-3.0.3.tgz#5a79101e6df7e659a1f070367bc42f190eb4ae76" + integrity sha512-qQgfbzJJ5nNShh4jjC3BBekY4d8emcxHFgnqcXwsB/PUKvJPCg7AZYXM7hqS7EDnKrX9tsIFwFMihZ7yut92Qg== dependencies: - micromatch "^2.1.5" - normalize-path "^2.0.0" + normalize-path "^3.0.0" + picomatch "^2.0.4" -vscode-chokidar@1.6.5: - version "1.6.5" - resolved "https://registry.yarnpkg.com/vscode-chokidar/-/vscode-chokidar-1.6.5.tgz#f38a1f909fa364a5429a4d4d70ecb40a15b54d0b" - integrity sha512-bc5dNF8tW2R+oesYT/Au//qumyd/0HTwSRqVXcg8ADQW1MsWKFwv+IxfSIuCHckaEy4I81GpSDaRWVGQqtsELw== +vscode-chokidar@2.1.7: + version "2.1.7" + resolved "https://registry.yarnpkg.com/vscode-chokidar/-/vscode-chokidar-2.1.7.tgz#c5b31eb87402f4779bb4170915245bdcb6f7854b" + integrity sha512-uSNEQetPjAlgIAHmcF9E6M+KCw0f842rsEnJ64aamUAV6TO7gkXNCvLSzb4MuLsPU7ZQyCa++DrLQFjvciK5dg== dependencies: - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" is-binary-path "^1.0.0" - is-glob "^2.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" path-is-absolute "^1.0.0" - readdirp "^2.0.0" - vscode-anymatch "1.3.3" + readdirp "^2.2.1" + upath "^1.1.1" + vscode-anymatch "3.0.3" optionalDependencies: - vscode-fsevents "0.3.10" + vscode-fsevents "1.2.12" vscode-debugprotocol@1.35.0: version "1.35.0" resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.35.0.tgz#565140cd42945e30c6c85cafb38c631457d4a46c" integrity sha512-+OMm11R1bGYbpIJ5eQIkwoDGFF4GvBz3Ztl6/VM+/RNNb2Gjk2c0Ku+oMmfhlTmTlPCpgHBsH4JqVCbUYhu5bA== -vscode-fsevents@0.3.10: - version "0.3.10" - resolved "https://registry.yarnpkg.com/vscode-fsevents/-/vscode-fsevents-0.3.10.tgz#65a586c3c6df3080bea20482146963a0f3a2c58d" - integrity sha512-iNlCKNgEB9A2JZkLf4h4sJlOS1u0lbe4QjM0Dr0PHaTmsttkJEfOaQeci2Ja1wUA7hUUAF6sNbei/Qp2DacFLw== +vscode-fsevents@1.2.12: + version "1.2.12" + resolved "https://registry.yarnpkg.com/vscode-fsevents/-/vscode-fsevents-1.2.12.tgz#01a71a01f90ee95ca822c34427aba437a17c03a7" + integrity sha512-bH/jRdDpSesGpqiVLjp6gHLSKUOh7oNvppzZ17JIrdbRYCcDmV7dIWR5gQc27DFy0RD9JDT+t+ixMid94MkM1A== dependencies: - nan "^2.10.0" + nan "^2.14.0" -vscode-nls-dev@3.2.5: - version "3.2.5" - resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.2.5.tgz#bea2b6e0cae709c48144180585e1a511edc9fb8d" - integrity sha512-eiNkwDHgTjP1h23BCOmAlXbFVembGokALYIvID5LMBzYppOiJzN/rGatHBlThQl6lnHWv599UEre6/AbjioYYw== +vscode-nls-dev@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.3.1.tgz#15fc03e0c9ca5a150abb838690d9554ac06f77e4" + integrity sha512-fug18D7CXb8pv8JoQ0D0JmZaIYDQoKLiyZxkAy5P8Cln/FwlNsdzwQILDph62EdGY5pvsJ2Jd1T5qgHAExe/tg== dependencies: ansi-colors "^3.2.3" clone "^2.1.1" @@ -9614,17 +9663,7 @@ vscode-nls-dev@3.2.5: typescript "^2.6.2" vinyl "^2.1.0" xml2js "^0.4.19" - yargs "^10.1.1" - -vscode-nsfw@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vscode-nsfw/-/vscode-nsfw-1.1.2.tgz#9cb9073b5854386801afe41f7152f721b4ea9e80" - integrity sha512-J0So+JNK/5kQboTO1hKNk4ie/wwUegrJilYSY5sVxU9JJlo3aQdP0zi2NtU8CEK3kkN6qRp0MbXCzbT0LKGorg== - dependencies: - fs-extra "^7.0.0" - lodash.isinteger "^4.0.4" - lodash.isundefined "^3.0.1" - nan "^2.10.0" + yargs "^13.2.4" vscode-proxy-agent@0.4.0: version "0.4.0" @@ -9636,24 +9675,24 @@ vscode-proxy-agent@0.4.0: https-proxy-agent "2.2.1" socks-proxy-agent "4.0.1" -vscode-ripgrep@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.2.5.tgz#2093c8f36d52bd2dab9eb45b003dd02533c5499c" - integrity sha512-n5XBm9od5hahpljw9T8wbkuMnAY7LlAG1OyEEtcCZEX9aCHFuBKSP0IcvciGRTbtWRovNuT83A2iRjt6PL3bLg== +vscode-ripgrep@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.3.1.tgz#51fb93debcd0c18a8b90dbc37f84f94333d0c486" + integrity sha512-4WLB/n4ZeWNi5AEzPTkfYrqbKtXlv0SlgmxbRVdulwZzGx/lfWeWPu9Shy32orM27IofQAQDuirbRBOYNJVzBA== -vscode-sqlite3@4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/vscode-sqlite3/-/vscode-sqlite3-4.0.7.tgz#7adbf0fe411c87716ca3c4e467f04de3a7353125" - integrity sha512-1BqWdf6Nzs+q7JC+JFXDLX2Z8ZID7lZH69AoLh9FXos7XgLbF4dsmUZO5a6d9X3Jccu/m0PfKK1K4E6dk/xiRg== +vscode-sqlite3@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/vscode-sqlite3/-/vscode-sqlite3-4.0.8.tgz#1eba415b996d2661628d80d4a191a20767713829" + integrity sha512-FsFtYSHmy0mYjtt9ibFKsJqbRzqaltDKZ5SLdpykjvORugFMr0HfGunkh+qGaz9CvAiqjM2KVO91NE9KdyTWKQ== dependencies: - nan "~2.10.0" + nan "^2.14.0" -vscode-textmate@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.1.1.tgz#857e836fbc13a376ec624242437e1747d79610a9" - integrity sha512-xBjq9LH6fMhWDhIVkbKlB1JeCu6lT3FI/QKN24Xi4RKPBUm16IhHTqs6Q6SUGewkNsFZGkb1tJdZsuMnlmVpgw== +vscode-textmate@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.2.2.tgz#0b4dabc69a6fba79a065cb6b615f66eac07c8f4c" + integrity sha512-1U4ih0E/KP1zNK/EbpUqyYtI7PY+Ccd2nDGTtiMR/UalLFnmaYkwoWhN1oI7B91ptBN8NdVwWuvyUnvJAulCUw== dependencies: - oniguruma "^7.0.0" + oniguruma "^7.2.0" vscode-windows-ca-certs@0.1.0: version "0.1.0" @@ -9818,12 +9857,12 @@ windows-mutex@0.2.1: bindings "^1.2.1" nan "^2.10.0" -windows-process-tree@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/windows-process-tree/-/windows-process-tree-0.2.3.tgz#6b781f0a320e8a0d6434c9399add4389c709cf6e" - integrity sha512-SzPJSubVVsToz1g5lr2P+4mQT70gvJ9u/nlnpfkOeQcAhOuhKz5DiO1TARgR0OnVsv21LPzxbA2m/4JQkGh1wA== +windows-process-tree@0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/windows-process-tree/-/windows-process-tree-0.2.4.tgz#747af587b54cc6c996f2be0836cc8a8fd0dc038f" + integrity sha512-9gag9AHm3Iin/4YC1EwoIfZlqW/rG2eV7rJZ4Fy5NnAMGdewmnwsie5Rz+CJo2vSolqzzfw7hPeu3oOdniNejg== dependencies: - nan "^2.10.0" + nan "^2.13.2" wordwrap@0.0.2: version "0.0.2" @@ -9855,6 +9894,15 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -9945,20 +9993,20 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" -xterm-addon-search@0.1.0-beta6: - version "0.1.0-beta6" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.1.0-beta6.tgz#e2a2b441f8f7b0245c63731d0b2af32c7d4e6747" - integrity sha512-XKxdfO48HkCJW2m1wXW0PK/BOk00WEaN+W2LgDQqCBwwUjyBzWc9HaV8gzLXhSCDAYesWvtQa3RfqHfSp9qsbQ== +xterm-addon-search@0.2.0-beta2: + version "0.2.0-beta2" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta2.tgz#c3173f0a6f207ee9f1848849174ee5d6b6ce8262" + integrity sha512-XEcwi2TeFGk2MuIFjiI/OpVXSNO5dGQBvHH3o+9KzqG3ooVqhhDqzwxs092QGNcNCGh8hGn/PWZiczaBBnKm/g== xterm-addon-web-links@0.1.0-beta10: version "0.1.0-beta10" resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta34: - version "3.15.0-beta34" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta34.tgz#32ca9523f842cfc213bf64cbb199bb9adaddcd2d" - integrity sha512-eqq/K002xVCfYXZggbI7v7dRgRKTvJhVFTHqcs6MdMHuiOYl4lwZFkv4aFf896kkbnKQOZZGGzhnBFfa1w1rTA== +xterm@3.15.0-beta71: + version "3.15.0-beta71" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta71.tgz#2728c9800ca3b08423e835e9504bd1f4b5de6253" + integrity sha512-8M/cLaxZ+iDopRxLPdPfKuDGaNNyYTdCeytdxjMSH0N7dZzbx6fbaEygQdCrV5pO9cGnT92MefSjVPGRXRiBLA== y18n@^3.2.1: version "3.2.1" @@ -9987,6 +10035,14 @@ yargs-parser@^10.1.0: dependencies: camelcase "^4.1.0" +yargs-parser@^13.1.0: + version "13.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" + integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs-parser@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" @@ -9994,31 +10050,6 @@ yargs-parser@^5.0.0: dependencies: camelcase "^3.0.0" -yargs-parser@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" - integrity sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ== - dependencies: - camelcase "^4.1.0" - -yargs@^10.1.1: - version "10.1.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5" - integrity sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig== - dependencies: - cliui "^4.0.0" - decamelize "^1.1.1" - find-up "^2.1.0" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^8.1.0" - yargs@^12.0.1: version "12.0.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.1.tgz#6432e56123bb4e7c3562115401e98374060261c2" @@ -10037,6 +10068,23 @@ yargs@^12.0.1: y18n "^3.2.1 || ^4.0.0" yargs-parser "^10.1.0" +yargs@^13.2.4: + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.0" + yargs@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8"