diff --git a/build/package.json b/build/package.json index bf3ec5ce3f9..84556e6e17d 100644 --- a/build/package.json +++ b/build/package.json @@ -40,7 +40,7 @@ "mime": "^1.3.4", "minimist": "^1.2.0", "request": "^2.85.0", - "terser": "4.3.1", + "terser": "4.3.8", "tslint": "^5.9.1", "typescript": "3.6.2", "vsce": "1.48.0", diff --git a/build/yarn.lock b/build/yarn.lock index 937eb1daa43..2451df9b537 100644 --- a/build/yarn.lock +++ b/build/yarn.lock @@ -2178,10 +2178,10 @@ terser@*: source-map "~0.6.1" source-map-support "~0.5.12" -terser@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.1.tgz#09820bcb3398299c4b48d9a86aefc65127d0ed65" - integrity sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg== +terser@4.3.8: + version "4.3.8" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.8.tgz#707f05f3f4c1c70c840e626addfdb1c158a17136" + integrity sha512-otmIRlRVmLChAWsnSFNO0Bfk6YySuBp6G9qrHiJwlLDd4mxe2ta4sjI7TzIR+W1nBMjilzrMcPOz9pSusgx3hQ== dependencies: commander "^2.20.0" source-map "~0.6.1" diff --git a/extensions/csharp/language-configuration.json b/extensions/csharp/language-configuration.json index 88107685266..d8698b46c09 100644 --- a/extensions/csharp/language-configuration.json +++ b/extensions/csharp/language-configuration.json @@ -13,8 +13,7 @@ ["[", "]"], ["(", ")"], { "open": "'", "close": "'", "notIn": ["string", "comment"] }, - { "open": "\"", "close": "\"", "notIn": ["string", "comment"] }, - { "open": "/*", "close": " */", "notIn": ["string"] } + { "open": "\"", "close": "\"", "notIn": ["string", "comment"] } ], "surroundingPairs": [ ["{", "}"], @@ -30,4 +29,4 @@ "end": "^\\s*#endregion\\b" } } -} \ No newline at end of file +} diff --git a/extensions/css-language-features/server/src/cssServerMain.ts b/extensions/css-language-features/server/src/cssServerMain.ts index 0856a649326..7cf07998b1e 100644 --- a/extensions/css-language-features/server/src/cssServerMain.ts +++ b/extensions/css-language-features/server/src/cssServerMain.ts @@ -75,9 +75,9 @@ const fileSystemProvider: FileSystemProvider = { let type = FileType.Unknown; if (stats.isFile()) { type = FileType.File; - } else if (stats.isDirectory) { + } else if (stats.isDirectory()) { type = FileType.Directory; - } else if (stats.isSymbolicLink) { + } else if (stats.isSymbolicLink()) { type = FileType.SymbolicLink; } diff --git a/extensions/git/package.json b/extensions/git/package.json index b64dfb4707e..eafc4916439 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -362,6 +362,11 @@ "title": "%command.ignore%", "category": "Git" }, + { + "command": "git.revealInExplorer", + "title": "%command.revealInExplorer%", + "category": "Git" + }, { "command": "git.stashIncludeUntracked", "title": "%command.stashIncludeUntracked%", @@ -507,6 +512,10 @@ "command": "git.restoreCommitTemplate", "when": "false" }, + { + "command": "git.revealInExplorer", + "when": "false" + }, { "command": "git.undoCommit", "when": "config.git.enabled && gitOpenRepositoryCount != 0" @@ -913,6 +922,11 @@ "when": "scmProvider == git && scmResourceGroup == merge", "group": "inline" }, + { + "command": "git.revealInExplorer", + "when": "scmProvider == git && scmResourceGroup == merge", + "group": "2_view" + }, { "command": "git.openFile2", "when": "scmProvider == git && scmResourceGroup == merge && config.git.showInlineOpenFileAction && config.git.openDiffOnClick", @@ -948,6 +962,11 @@ "when": "scmProvider == git && scmResourceGroup == index", "group": "inline" }, + { + "command": "git.revealInExplorer", + "when": "scmProvider == git && scmResourceGroup == index", + "group": "2_view" + }, { "command": "git.openFile2", "when": "scmProvider == git && scmResourceGroup == index && config.git.showInlineOpenFileAction && config.git.openDiffOnClick", @@ -1007,6 +1026,11 @@ "command": "git.ignore", "when": "scmProvider == git && scmResourceGroup == workingTree", "group": "1_modification@3" + }, + { + "command": "git.revealInExplorer", + "when": "scmProvider == git && scmResourceGroup == workingTree", + "group": "2_view" } ], "editor/title": [ diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 6587b65421d..c6a474439f5 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -56,6 +56,7 @@ "command.publish": "Publish Branch", "command.showOutput": "Show Git Output", "command.ignore": "Add to .gitignore", + "command.revealInExplorer": "Reveal in Explorer", "command.stashIncludeUntracked": "Stash (Include Untracked)", "command.stash": "Stash", "command.stashPop": "Pop Stash...", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index d17c27e7c28..fdef8f17989 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -2069,6 +2069,19 @@ export class CommandCenter { await this.runByRepository(resources, async (repository, resources) => repository.ignore(resources)); } + @command('git.revealInExplorer') + async revealInExplorer(resourceState: SourceControlResourceState): Promise { + if (!resourceState) { + return; + } + + if (!(resourceState.resourceUri instanceof Uri)) { + return; + } + + await commands.executeCommand('revealInExplorer', resourceState.resourceUri); + } + private async _stash(repository: Repository, includeUntracked = false): Promise { const noUnstagedChanges = repository.workingTreeGroup.resourceStates.length === 0; const noStagedChanges = repository.indexGroup.resourceStates.length === 0; diff --git a/extensions/git/src/util.ts b/extensions/git/src/util.ts index d2e201ca01d..0722cb16fbd 100644 --- a/extensions/git/src/util.ts +++ b/extensions/git/src/util.ts @@ -160,7 +160,7 @@ export async function mkdirp(path: string, mode?: number): Promise { if (err.code === 'EEXIST') { const stat = await nfcall(fs.stat, path); - if (stat.isDirectory) { + if (stat.isDirectory()) { return; } diff --git a/extensions/image-preview/media/main.css b/extensions/image-preview/media/main.css index 913d2b46726..0f50cef683c 100644 --- a/extensions/image-preview/media/main.css +++ b/extensions/image-preview/media/main.css @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ html, body { + width: 100%; height: 100%; - max-height: 100%; text-align: center; } diff --git a/extensions/json/language-configuration.json b/extensions/json/language-configuration.json index 9a73ac64aae..7faa70cef7a 100644 --- a/extensions/json/language-configuration.json +++ b/extensions/json/language-configuration.json @@ -12,8 +12,7 @@ { "open": "[", "close": "]", "notIn": ["string"] }, { "open": "(", "close": ")", "notIn": ["string"] }, { "open": "'", "close": "'", "notIn": ["string"] }, - { "open": "/*", "close": "*/", "notIn": ["string"] }, { "open": "\"", "close": "\"", "notIn": ["string", "comment"] }, { "open": "`", "close": "`", "notIn": ["string", "comment"] } ] -} \ No newline at end of file +} diff --git a/extensions/npm/README.md b/extensions/npm/README.md index a24a7d69d6e..941da175102 100644 --- a/extensions/npm/README.md +++ b/extensions/npm/README.md @@ -24,7 +24,7 @@ the hover shown on a script or using the command `Run Selected Npm Script`. ### Others -The extension fetches data from https://registry.npmjs/org and https://registry.bower.io to provide auto-completion and information on hover features on npm dependencies. +The extension fetches data from https://registry.npmjs.org and https://registry.bower.io to provide auto-completion and information on hover features on npm dependencies. ## Settings diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index 40121b8fa8d..b5e00dd614b 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -7,7 +7,7 @@ "config.npm.exclude": "Configure glob patterns for folders that should be excluded from automatic script detection.", "config.npm.enableScriptExplorer": "Enable an explorer view for npm scripts when there is no top-level 'package.json' file.", "config.npm.scriptExplorerAction": "The default click action used in the scripts explorer: `open` or `run`, the default is `open`.", - "config.npm.fetchOnlinePackageInfo": "Fetch data from https://registry.npmjs/org and https://registry.bower.io to provide auto-completion and information on hover features on npm dependencies.", + "config.npm.fetchOnlinePackageInfo": "Fetch data from https://registry.npmjs.org and https://registry.bower.io to provide auto-completion and information on hover features on npm dependencies.", "npm.parseError": "Npm task detection: failed to parse the file {0}", "taskdef.script": "The npm script to customize.", "taskdef.path": "The path to the folder of the package.json file that provides the script. Can be omitted.", diff --git a/extensions/shellscript/package.json b/extensions/shellscript/package.json index a55af2b08ff..211401a070c 100644 --- a/extensions/shellscript/package.json +++ b/extensions/shellscript/package.json @@ -23,6 +23,12 @@ "language": "shellscript", "scopeName": "source.shell", "path": "./syntaxes/shell-unix-bash.tmLanguage.json" - }] + }], + "configurationDefaults": { + "[shellscript]": { + "files.eol": "\n" + } + } + } } diff --git a/package.json b/package.json index fbeb6d1e659..a66d71711fe 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.40.0", - "distro": "fd32ba99f225d591cb667f0bdf23dbb481743eab", + "distro": "7d62db65536347b7a7c21ae355071b55920c4d84", "author": { "name": "Microsoft Corporation" }, @@ -28,10 +28,9 @@ "update-distro": "node build/npm/update-distro.js" }, "dependencies": { - "@microsoft/applicationinsights-web": "^2.1.1", "applicationinsights": "1.0.8", "chokidar": "3.1.0", - "graceful-fs": "4.1.11", + "graceful-fs": "4.2.2", "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.1", "iconv-lite": "0.5.0", @@ -52,8 +51,8 @@ "vscode-ripgrep": "^1.5.7", "vscode-sqlite3": "4.0.8", "vscode-textmate": "^4.2.2", - "xterm": "4.1.0-beta8", - "xterm-addon-search": "0.2.0", + "xterm": "4.2.0-beta4", + "xterm-addon-search": "0.3.0-beta5", "xterm-addon-web-links": "0.2.0", "yauzl": "^2.9.2", "yazl": "^2.4.3" @@ -101,6 +100,7 @@ "gulp-tslint": "^8.1.3", "gulp-untar": "^0.0.7", "gulp-vinyl-zip": "^2.1.2", + "husky": "^0.13.1", "innosetup": "5.6.1", "is": "^3.1.0", "istanbul-lib-coverage": "^2.0.5", @@ -153,4 +153,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} diff --git a/remote/package.json b/remote/package.json index 10c377499f1..15aaa8f30b1 100644 --- a/remote/package.json +++ b/remote/package.json @@ -2,11 +2,10 @@ "name": "vscode-reh", "version": "0.0.0", "dependencies": { - "@microsoft/applicationinsights-web": "^2.1.1", "applicationinsights": "1.0.8", "chokidar": "3.1.0", "cookie": "^0.4.0", - "graceful-fs": "4.1.11", + "graceful-fs": "4.2.2", "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.1", "iconv-lite": "0.5.0", @@ -21,8 +20,8 @@ "vscode-proxy-agent": "0.4.0", "vscode-ripgrep": "^1.5.7", "vscode-textmate": "^4.2.2", - "xterm": "4.1.0-beta8", - "xterm-addon-search": "0.2.0", + "xterm": "4.2.0-beta4", + "xterm-addon-search": "0.3.0-beta5", "xterm-addon-web-links": "0.2.0", "yauzl": "^2.9.2", "yazl": "^2.4.3" diff --git a/remote/web/package.json b/remote/web/package.json index ab86c010ead..db6e5d18e12 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -2,12 +2,11 @@ "name": "vscode-web", "version": "0.0.0", "dependencies": { - "@microsoft/applicationinsights-web": "^2.1.1", "onigasm-umd": "^2.2.2", "semver-umd": "^5.5.3", "vscode-textmate": "^4.2.2", - "xterm": "4.1.0-beta8", - "xterm-addon-search": "0.2.0", + "xterm": "4.2.0-beta4", + "xterm-addon-search": "0.3.0-beta5", "xterm-addon-web-links": "0.2.0" } } diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index ccc09170f6f..759deded50b 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -2,69 +2,6 @@ # yarn lockfile v1 -"@microsoft/applicationinsights-analytics-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" - integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-channel-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" - integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-common@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" - integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== - dependencies: - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-core-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" - integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== - dependencies: - tslib "^1.9.3" - -"@microsoft/applicationinsights-dependencies-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" - integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-properties-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" - integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-web@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" - integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== - dependencies: - "@microsoft/applicationinsights-analytics-js" "2.1.1" - "@microsoft/applicationinsights-channel-js" "2.1.1" - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - "@microsoft/applicationinsights-dependencies-js" "2.1.1" - "@microsoft/applicationinsights-properties-js" "2.1.1" - nan@^2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" @@ -87,11 +24,6 @@ semver-umd@^5.5.3: resolved "https://registry.yarnpkg.com/semver-umd/-/semver-umd-5.5.3.tgz#b64d7a2d4f5a717b369d56e31940a38e47e34d1e" integrity sha512-HOnQrn2iKnVe/xlqCTzMXQdvSz3rPbD0DmQXYuQ+oK1dpptGFfPghonQrx5JHl2O7EJwDqtQnjhE7ME23q6ngw== -tslib@^1.9.3: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - vscode-textmate@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.2.2.tgz#0b4dabc69a6fba79a065cb6b615f66eac07c8f4c" @@ -99,17 +31,17 @@ vscode-textmate@^4.2.2: dependencies: oniguruma "^7.2.0" -xterm-addon-search@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0.tgz#46659c7c33f9fc268ad3e7e6c5824bb2fdb65852" - integrity sha512-C/v2VvFn3hb1qUgjJPo7LxzxNCLBgNJv8n6v/bH2NqPz32/PNUF+IHu0SFf1TaIH+pydUpKXCtob5a/UyZg/+Q== +xterm-addon-search@0.3.0-beta5: + version "0.3.0-beta5" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.3.0-beta5.tgz#fd53d33a77a0235018479c712be8c12f7c0d083a" + integrity sha512-3GkGc4hST35/4hzgnQPLLvQ29WH7MkZ0mUrBE/Vm1IQum7TnMvWPTkGemwM+wAl4tdBmynNccHJlFeQzaQtVUg== xterm-addon-web-links@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.2.0.tgz#b408a0be46211d8d4a0bb5e701d8f3c2bd07d473" integrity sha512-dq81c4Pzli2PgKVBgY2REte9sCVibR3df8AP3SEvCTM9uYFnUFxtxzMTplPnc7+rXabVhFdbU6x+rstIk8HNQg== -xterm@4.1.0-beta8: - version "4.1.0-beta8" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.1.0-beta8.tgz#c1ef323ba336d92f5b52302b66f672dfff75b3ef" - integrity sha512-6lf+XVv0qT285w49P92tSYoUB406jdbgdhnPKNzxCIGtGX8kcwK+pHZ8HncDwcEhmTmI4LZ/WXPGtOQJg+onwg== +xterm@4.2.0-beta4: + version "4.2.0-beta4" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.2.0-beta4.tgz#596577f94a1da372119d192363ea2b19d1f8b50c" + integrity sha512-BmkpxCpqdOJoNdIcddkRT8S65sGjgBbWI0uIJNSnzZvj81OKcraMSTmF/ODw0TF/MDLc33Fx9cpDx/D6lQgl8Q== diff --git a/remote/yarn.lock b/remote/yarn.lock index 052c1fa7847..b018aafbaab 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -2,69 +2,6 @@ # yarn lockfile v1 -"@microsoft/applicationinsights-analytics-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" - integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-channel-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" - integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-common@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" - integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== - dependencies: - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-core-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" - integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== - dependencies: - tslib "^1.9.3" - -"@microsoft/applicationinsights-dependencies-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" - integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-properties-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" - integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-web@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" - integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== - dependencies: - "@microsoft/applicationinsights-analytics-js" "2.1.1" - "@microsoft/applicationinsights-channel-js" "2.1.1" - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - "@microsoft/applicationinsights-dependencies-js" "2.1.1" - "@microsoft/applicationinsights-properties-js" "2.1.1" - agent-base@4, agent-base@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.0.tgz#9838b5c3392b962bad031e6a4c5e1024abec45ce" @@ -211,7 +148,12 @@ glob-parent@^5.0.0: dependencies: is-glob "^4.0.1" -graceful-fs@4.1.11, graceful-fs@^4.1.2: +graceful-fs@4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" + integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== + +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= @@ -430,11 +372,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -tslib@^1.9.3: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -479,20 +416,20 @@ vscode-windows-registry@1.0.2: resolved "https://registry.yarnpkg.com/vscode-windows-registry/-/vscode-windows-registry-1.0.2.tgz#b863e704a6a69c50b3098a55fbddbe595b0c124a" integrity sha512-/CLLvuOSM2Vme2z6aNyB+4Omd7hDxpf4Thrt8ImxnXeQtxzel2bClJpFQvQqK/s4oaXlkBKS7LqVLeZM+uSVIA== -xterm-addon-search@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0.tgz#46659c7c33f9fc268ad3e7e6c5824bb2fdb65852" - integrity sha512-C/v2VvFn3hb1qUgjJPo7LxzxNCLBgNJv8n6v/bH2NqPz32/PNUF+IHu0SFf1TaIH+pydUpKXCtob5a/UyZg/+Q== +xterm-addon-search@0.3.0-beta5: + version "0.3.0-beta5" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.3.0-beta5.tgz#fd53d33a77a0235018479c712be8c12f7c0d083a" + integrity sha512-3GkGc4hST35/4hzgnQPLLvQ29WH7MkZ0mUrBE/Vm1IQum7TnMvWPTkGemwM+wAl4tdBmynNccHJlFeQzaQtVUg== xterm-addon-web-links@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.2.0.tgz#b408a0be46211d8d4a0bb5e701d8f3c2bd07d473" integrity sha512-dq81c4Pzli2PgKVBgY2REte9sCVibR3df8AP3SEvCTM9uYFnUFxtxzMTplPnc7+rXabVhFdbU6x+rstIk8HNQg== -xterm@4.1.0-beta8: - version "4.1.0-beta8" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.1.0-beta8.tgz#c1ef323ba336d92f5b52302b66f672dfff75b3ef" - integrity sha512-6lf+XVv0qT285w49P92tSYoUB406jdbgdhnPKNzxCIGtGX8kcwK+pHZ8HncDwcEhmTmI4LZ/WXPGtOQJg+onwg== +xterm@4.2.0-beta4: + version "4.2.0-beta4" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.2.0-beta4.tgz#596577f94a1da372119d192363ea2b19d1f8b50c" + integrity sha512-BmkpxCpqdOJoNdIcddkRT8S65sGjgBbWI0uIJNSnzZvj81OKcraMSTmF/ODw0TF/MDLc33Fx9cpDx/D6lQgl8Q== yauzl@^2.9.2: version "2.10.0" diff --git a/resources/linux/bin/code.sh b/resources/linux/bin/code.sh index 564f13ef95c..516c05e4ee0 100755 --- a/resources/linux/bin/code.sh +++ b/resources/linux/bin/code.sh @@ -30,7 +30,7 @@ if [ ! -L $0 ]; then # if path is not a symlink, find relatively VSCODE_PATH="$(dirname $0)/.." else - if which readlink >/dev/null; then + if command -v readlink >/dev/null; then # if readlink exists, follow the symlink and find relatively VSCODE_PATH="$(dirname $(readlink -f $0))/.." else diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat index 8de32c95a0f..0d7b9ee4b37 100644 --- a/scripts/test-integration.bat +++ b/scripts/test-integration.bat @@ -29,10 +29,12 @@ call .\scripts\test.bat --runGlob **\*.integrationTest.js %* if %errorlevel% neq 0 exit /b %errorlevel% :: Tests in the extension host -call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-api-tests\testWorkspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% + +call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-api-tests\testWorkspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% if %errorlevel% neq 0 exit /b %errorlevel% -call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-api-tests\testworkspace.code-workspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\workspace-tests --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% +call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-api-tests\testworkspace.code-workspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\workspace-tests --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% + if %errorlevel% neq 0 exit /b %errorlevel% call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-colorize-tests\test --extensionDevelopmentPath=%~dp0\..\extensions\vscode-colorize-tests --extensionTestsPath=%~dp0\..\extensions\vscode-colorize-tests\out --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh index 04ffdf64e3c..a3891cf96fc 100755 --- a/scripts/test-integration.sh +++ b/scripts/test-integration.sh @@ -37,10 +37,11 @@ fi ./scripts/test.sh --runGlob **/*.integrationTest.js "$@" # Tests in the extension host -"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-api-tests/testWorkspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --skip-getting-started --user-data-dir=$VSCODEUSERDATADIR -"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --skip-getting-started --user-data-dir=$VSCODEUSERDATADIR -"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --skip-getting-started --user-data-dir=$VSCODEUSERDATADIR -"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/markdown-language-features/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --skip-getting-started --user-data-dir=$VSCODEUSERDATADIR +"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-api-tests/testWorkspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --skip-getting-started --user-data-dir=$VSCODEUSERDATADIR +"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --skip-getting-started --user-data-dir=$VSCODEUSERDATADIR +"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --skip-getting-started --user-data-dir=$VSCODEUSERDATADIR +"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/markdown-language-features/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --skip-getting-started --user-data-dir=$VSCODEUSERDATADIR + mkdir -p $ROOT/extensions/emmet/test-fixtures "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_NO_SANDBOX $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-telemetry --disable-crash-reporter --disable-updates --disable-extensions --skip-getting-started --user-data-dir=$VSCODEUSERDATADIR diff --git a/src/vs/base/browser/touch.ts b/src/vs/base/browser/touch.ts index 4519d7e0e16..bef90a94d4d 100644 --- a/src/vs/base/browser/touch.ts +++ b/src/vs/base/browser/touch.ts @@ -67,7 +67,7 @@ export class Gesture extends Disposable { private static readonly SCROLL_FRICTION = -0.005; private static INSTANCE: Gesture; - private static HOLD_DELAY = 700; + private static readonly HOLD_DELAY = 700; private dispatched = false; private targets: HTMLElement[]; diff --git a/src/vs/base/browser/ui/countBadge/countBadge.ts b/src/vs/base/browser/ui/countBadge/countBadge.ts index e4b1f68568f..cb04c5099f3 100644 --- a/src/vs/base/browser/ui/countBadge/countBadge.ts +++ b/src/vs/base/browser/ui/countBadge/countBadge.ts @@ -85,15 +85,15 @@ export class CountBadge { private applyStyles(): void { if (this.element) { - const background = this.badgeBackground ? this.badgeBackground.toString() : null; - const foreground = this.badgeForeground ? this.badgeForeground.toString() : null; - const border = this.badgeBorder ? this.badgeBorder.toString() : null; + const background = this.badgeBackground ? this.badgeBackground.toString() : ''; + const foreground = this.badgeForeground ? this.badgeForeground.toString() : ''; + const border = this.badgeBorder ? this.badgeBorder.toString() : ''; this.element.style.backgroundColor = background; this.element.style.color = foreground; - this.element.style.borderWidth = border ? '1px' : null; - this.element.style.borderStyle = border ? 'solid' : null; + this.element.style.borderWidth = border ? '1px' : ''; + this.element.style.borderStyle = border ? 'solid' : ''; this.element.style.borderColor = border; } } diff --git a/src/vs/base/browser/ui/dialog/dialog.ts b/src/vs/base/browser/ui/dialog/dialog.ts index 9be85097748..723bf64b975 100644 --- a/src/vs/base/browser/ui/dialog/dialog.ts +++ b/src/vs/base/browser/ui/dialog/dialog.ts @@ -241,10 +241,10 @@ export class Dialog extends Disposable { if (this.styles) { const style = this.styles; - const fgColor = style.dialogForeground ? `${style.dialogForeground}` : null; - const bgColor = style.dialogBackground ? `${style.dialogBackground}` : null; - const shadowColor = style.dialogShadow ? `0 0px 8px ${style.dialogShadow}` : null; - const border = style.dialogBorder ? `1px solid ${style.dialogBorder}` : null; + const fgColor = style.dialogForeground ? `${style.dialogForeground}` : ''; + const bgColor = style.dialogBackground ? `${style.dialogBackground}` : ''; + const shadowColor = style.dialogShadow ? `0 0px 8px ${style.dialogShadow}` : ''; + const border = style.dialogBorder ? `1px solid ${style.dialogBorder}` : ''; if (this.element) { this.element.style.color = fgColor; diff --git a/src/vs/base/browser/ui/grid/grid.ts b/src/vs/base/browser/ui/grid/grid.ts index 28b184f76d9..c2448a2fbff 100644 --- a/src/vs/base/browser/ui/grid/grid.ts +++ b/src/vs/base/browser/ui/grid/grid.ts @@ -9,7 +9,6 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { tail2 as tail, equals } from 'vs/base/common/arrays'; import { orthogonal, IView as IGridViewView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles, IViewSize, IGridViewOptions } from './gridview'; import { Event } from 'vs/base/common/event'; -import { InvisibleSizing } from 'vs/base/browser/ui/splitview/splitview'; export { Orientation, Sizing as GridViewSizing, IViewSize, orthogonal, LayoutPriority } from './gridview'; diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index d743e3bf9f2..a3cf52ca023 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -373,7 +373,7 @@ export class InputBox extends Widget { dom.addClass(this.element, this.classForType(message.type)); const styles = this.stylesForType(this.message.type); - this.element.style.border = styles.border ? `1px solid ${styles.border}` : null; + this.element.style.border = styles.border ? `1px solid ${styles.border}` : ''; // ARIA Support let alertText: string; @@ -473,9 +473,9 @@ export class InputBox extends Widget { dom.addClass(spanElement, this.classForType(this.message.type)); const styles = this.stylesForType(this.message.type); - spanElement.style.backgroundColor = styles.background ? styles.background.toString() : null; + spanElement.style.backgroundColor = styles.background ? styles.background.toString() : ''; spanElement.style.color = styles.foreground ? styles.foreground.toString() : null; - spanElement.style.border = styles.border ? `1px solid ${styles.border}` : null; + spanElement.style.border = styles.border ? `1px solid ${styles.border}` : ''; dom.append(div, spanElement); @@ -552,17 +552,17 @@ export class InputBox extends Widget { } protected applyStyles(): void { - const background = this.inputBackground ? this.inputBackground.toString() : null; - const foreground = this.inputForeground ? this.inputForeground.toString() : null; - const border = this.inputBorder ? this.inputBorder.toString() : null; + const background = this.inputBackground ? this.inputBackground.toString() : ''; + const foreground = this.inputForeground ? this.inputForeground.toString() : ''; + const border = this.inputBorder ? this.inputBorder.toString() : ''; this.element.style.backgroundColor = background; this.element.style.color = foreground; this.input.style.backgroundColor = background; this.input.style.color = foreground; - this.element.style.borderWidth = border ? '1px' : null; - this.element.style.borderStyle = border ? 'solid' : null; + this.element.style.borderWidth = border ? '1px' : ''; + this.element.style.borderStyle = border ? 'solid' : ''; this.element.style.borderColor = border; } diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index b81aee160eb..4e94f810672 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -204,7 +204,7 @@ export class Menu extends ActionBar { })); const scrollElement = this.scrollableElement.getDomNode(); - scrollElement.style.position = null; + scrollElement.style.position = ''; menuElement.style.maxHeight = `${Math.max(10, window.innerHeight - container.getBoundingClientRect().top - 30)}px`; @@ -231,10 +231,10 @@ export class Menu extends ActionBar { style(style: IMenuStyles): void { const container = this.getContainer(); - const fgColor = style.foregroundColor ? `${style.foregroundColor}` : null; - const bgColor = style.backgroundColor ? `${style.backgroundColor}` : null; - const border = style.borderColor ? `2px solid ${style.borderColor}` : null; - const shadow = style.shadowColor ? `0 2px 4px ${style.shadowColor}` : null; + const fgColor = style.foregroundColor ? `${style.foregroundColor}` : ''; + const bgColor = style.backgroundColor ? `${style.backgroundColor}` : ''; + const border = style.borderColor ? `2px solid ${style.borderColor}` : ''; + const shadow = style.shadowColor ? `0 2px 4px ${style.shadowColor}` : ''; container.style.border = border; this.domNode.style.color = fgColor; @@ -575,11 +575,11 @@ class BaseMenuActionViewItem extends BaseActionViewItem { const isSelected = this.element && hasClass(this.element, 'focused'); const fgColor = isSelected && this.menuStyle.selectionForegroundColor ? this.menuStyle.selectionForegroundColor : this.menuStyle.foregroundColor; const bgColor = isSelected && this.menuStyle.selectionBackgroundColor ? this.menuStyle.selectionBackgroundColor : this.menuStyle.backgroundColor; - const border = isSelected && this.menuStyle.selectionBorderColor ? `thin solid ${this.menuStyle.selectionBorderColor}` : null; + const border = isSelected && this.menuStyle.selectionBorderColor ? `thin solid ${this.menuStyle.selectionBorderColor}` : ''; this.item.style.color = fgColor ? `${fgColor}` : null; - this.check.style.backgroundColor = fgColor ? `${fgColor}` : null; - this.item.style.backgroundColor = bgColor ? `${bgColor}` : null; + this.check.style.backgroundColor = fgColor ? `${fgColor}` : ''; + this.item.style.backgroundColor = bgColor ? `${bgColor}` : ''; this.container.style.border = border; } @@ -793,7 +793,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem { const isSelected = this.element && hasClass(this.element, 'focused'); const fgColor = isSelected && this.menuStyle.selectionForegroundColor ? this.menuStyle.selectionForegroundColor : this.menuStyle.foregroundColor; - this.submenuIndicator.style.backgroundColor = fgColor ? `${fgColor}` : null; + this.submenuIndicator.style.backgroundColor = fgColor ? `${fgColor}` : ''; if (this.parentData.submenu) { this.parentData.submenu.style(this.menuStyle); @@ -819,7 +819,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem { class MenuSeparatorActionViewItem extends ActionViewItem { style(style: IMenuStyles): void { if (this.label) { - this.label.style.borderBottomColor = style.separatorColor ? `${style.separatorColor}` : null; + this.label.style.borderBottomColor = style.separatorColor ? `${style.separatorColor}` : ''; } } } diff --git a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts index b5f2fe57c72..7e6ee0f7f6a 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts @@ -374,9 +374,9 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi // Style parent select if (this.selectElement) { - const background = this.styles.selectBackground ? this.styles.selectBackground.toString() : null; - const foreground = this.styles.selectForeground ? this.styles.selectForeground.toString() : null; - const border = this.styles.selectBorder ? this.styles.selectBorder.toString() : null; + const background = this.styles.selectBackground ? this.styles.selectBackground.toString() : ''; + const foreground = this.styles.selectForeground ? this.styles.selectForeground.toString() : ''; + const border = this.styles.selectBorder ? this.styles.selectBorder.toString() : ''; this.selectElement.style.backgroundColor = background; this.selectElement.style.color = foreground; @@ -392,10 +392,10 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi private styleList() { if (this.selectList) { - let background = this.styles.selectBackground ? this.styles.selectBackground.toString() : null; + const background = this.styles.selectBackground ? this.styles.selectBackground.toString() : ''; this.selectList.style({}); - let listBackground = this.styles.selectListBackground ? this.styles.selectListBackground.toString() : background; + const listBackground = this.styles.selectListBackground ? this.styles.selectListBackground.toString() : background; this.selectDropDownListContainer.style.backgroundColor = listBackground; this.selectionDetailsPane.style.backgroundColor = listBackground; const optionsBorder = this.styles.focusBorder ? this.styles.focusBorder.toString() : ''; diff --git a/src/vs/base/browser/ui/selectBox/selectBoxNative.ts b/src/vs/base/browser/ui/selectBox/selectBoxNative.ts index afaed056d4c..8c50b057fb5 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxNative.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxNative.ts @@ -147,9 +147,9 @@ export class SelectBoxNative extends Disposable implements ISelectBoxDelegate { // Style native select if (this.selectElement) { - const background = this.styles.selectBackground ? this.styles.selectBackground.toString() : null; - const foreground = this.styles.selectForeground ? this.styles.selectForeground.toString() : null; - const border = this.styles.selectBorder ? this.styles.selectBorder.toString() : null; + const background = this.styles.selectBackground ? this.styles.selectBackground.toString() : ''; + const foreground = this.styles.selectForeground ? this.styles.selectForeground.toString() : ''; + const border = this.styles.selectBorder ? this.styles.selectBorder.toString() : ''; this.selectElement.style.backgroundColor = background; this.selectElement.style.color = foreground; diff --git a/src/vs/base/browser/ui/splitview/panelview.ts b/src/vs/base/browser/ui/splitview/panelview.ts index 875537e8817..f7c63a466c6 100644 --- a/src/vs/base/browser/ui/splitview/panelview.ts +++ b/src/vs/base/browser/ui/splitview/panelview.ts @@ -229,8 +229,8 @@ export abstract class Panel extends Disposable implements IView { this.header.setAttribute('aria-expanded', String(expanded)); this.header.style.color = this.styles.headerForeground ? this.styles.headerForeground.toString() : null; - this.header.style.backgroundColor = this.styles.headerBackground ? this.styles.headerBackground.toString() : null; - this.header.style.borderTop = this.styles.headerBorder ? `1px solid ${this.styles.headerBorder}` : null; + this.header.style.backgroundColor = this.styles.headerBackground ? this.styles.headerBackground.toString() : ''; + this.header.style.borderTop = this.styles.headerBorder ? `1px solid ${this.styles.headerBorder}` : ''; this._dropBackground = this.styles.dropBackground; } @@ -340,7 +340,7 @@ class PanelDraggable extends Disposable { backgroundColor = (this.panel.dropBackground || PanelDraggable.DefaultDragOverBackgroundColor).toString(); } - this.panel.dropTargetElement.style.backgroundColor = backgroundColor; + this.panel.dropTargetElement.style.backgroundColor = backgroundColor || ''; } } diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 68754b3e448..925a9128552 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -238,7 +238,7 @@ class EventCollection implements Collection { class TreeRenderer implements IListRenderer, ITreeListTemplateData> { - private static DefaultIndent = 8; + private static readonly DefaultIndent = 8; readonly templateId: string; private renderedElements = new Map>(); diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index 4cf442d26df..e7514bfabe6 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -7,7 +7,7 @@ import { ComposedTreeDelegate, IAbstractTreeOptions, IAbstractTreeOptionsUpdate import { ObjectTree, IObjectTreeOptions, CompressibleObjectTree, ICompressibleTreeRenderer, ICompressibleKeyboardNavigationLabelProvider, ICompressibleObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree'; import { IListVirtualDelegate, IIdentityProvider, IListDragAndDrop, IListDragOverReaction } from 'vs/base/browser/ui/list/list'; import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter, ICollapseStateChangeEvent, IAsyncDataSource, ITreeDragAndDrop, TreeError, WeakMapper } from 'vs/base/browser/ui/tree/tree'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; import { Emitter, Event } from 'vs/base/common/event'; import { timeout, CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; import { IListStyles } from 'vs/base/browser/ui/list/listWidget'; @@ -88,7 +88,6 @@ class AsyncDataTreeRenderer implements IT readonly templateId: string; private renderedNodes = new Map, IDataTreeListTemplateData>(); - private disposables: IDisposable[] = []; constructor( protected renderer: ITreeRenderer, @@ -124,7 +123,6 @@ class AsyncDataTreeRenderer implements IT dispose(): void { this.renderedNodes.clear(); - this.disposables = dispose(this.disposables); } } @@ -292,7 +290,7 @@ export class AsyncDataTree implements IDisposable protected readonly nodeMapper: AsyncDataTreeNodeMapper = new WeakMapper(node => new AsyncDataTreeNodeWrapper(node)); - protected readonly disposables: IDisposable[] = []; + protected readonly disposables = new DisposableStore(); get onDidScroll(): Event { return this.tree.onDidScroll; } @@ -930,7 +928,7 @@ export class AsyncDataTree implements IDisposable } dispose(): void { - dispose(this.disposables); + this.disposables.dispose(); } } diff --git a/src/vs/base/common/diff/diff.ts b/src/vs/base/common/diff/diff.ts index 6eb26b885af..0183b199249 100644 --- a/src/vs/base/common/diff/diff.ts +++ b/src/vs/base/common/diff/diff.ts @@ -4,22 +4,28 @@ *--------------------------------------------------------------------------------------------*/ import { DiffChange } from 'vs/base/common/diff/diffChange'; +import { stringHash } from 'vs/base/common/hash'; -function createStringSequence(a: string): ISequence { - return { - getLength() { return a.length; }, - getElementAtIndex(pos: number) { return a.charCodeAt(pos); } - }; +export class StringDiffSequence implements ISequence { + + constructor(private source: string) { } + + getElements(): Int32Array | number[] | string[] { + const source = this.source; + const characters = new Int32Array(source.length); + for (let i = 0, len = source.length; i < len; i++) { + characters[i] = source.charCodeAt(i); + } + return characters; + } } export function stringDiff(original: string, modified: string, pretty: boolean): IDiffChange[] { - return new LcsDiff(createStringSequence(original), createStringSequence(modified)).ComputeDiff(pretty); + return new LcsDiff(new StringDiffSequence(original), new StringDiffSequence(modified)).ComputeDiff(pretty); } - export interface ISequence { - getLength(): number; - getElementAtIndex(index: number): number | string; + getElements(): Int32Array | number[] | string[]; } export interface IDiffChange { @@ -49,7 +55,7 @@ export interface IDiffChange { } export interface IContinueProcessingPredicate { - (furthestOriginalIndex: number, originalSequence: ISequence, matchLengthOfLongest: number): boolean; + (furthestOriginalIndex: number, matchLengthOfLongest: number): boolean; } // @@ -86,6 +92,11 @@ export class MyArray { destinationArray[destinationIndex + i] = sourceArray[sourceIndex + i]; } } + public static Copy2(sourceArray: Int32Array, sourceIndex: number, destinationArray: Int32Array, destinationIndex: number, length: number) { + for (let i = 0; i < length; i++) { + destinationArray[destinationIndex + i] = sourceArray[sourceIndex + i]; + } + } } //***************************************************************************** @@ -214,39 +225,81 @@ class DiffChangeHelper { */ export class LcsDiff { - private OriginalSequence: ISequence; - private ModifiedSequence: ISequence; - private ContinueProcessingPredicate: IContinueProcessingPredicate | null; + private readonly ContinueProcessingPredicate: IContinueProcessingPredicate | null; - private m_forwardHistory: number[][]; - private m_reverseHistory: number[][]; + private readonly _hasStrings: boolean; + private readonly _originalStringElements: string[]; + private readonly _originalElementsOrHash: Int32Array; + private readonly _modifiedStringElements: string[]; + private readonly _modifiedElementsOrHash: Int32Array; + + private m_forwardHistory: Int32Array[]; + private m_reverseHistory: Int32Array[]; /** * Constructs the DiffFinder */ - constructor(originalSequence: ISequence, newSequence: ISequence, continueProcessingPredicate: IContinueProcessingPredicate | null = null) { - this.OriginalSequence = originalSequence; - this.ModifiedSequence = newSequence; + constructor(originalSequence: ISequence, modifiedSequence: ISequence, continueProcessingPredicate: IContinueProcessingPredicate | null = null) { this.ContinueProcessingPredicate = continueProcessingPredicate; + const [originalStringElements, originalElementsOrHash, originalHasStrings] = LcsDiff._getElements(originalSequence); + const [modifiedStringElements, modifiedElementsOrHash, modifiedHasStrings] = LcsDiff._getElements(modifiedSequence); + + this._hasStrings = (originalHasStrings && modifiedHasStrings); + this._originalStringElements = originalStringElements; + this._originalElementsOrHash = originalElementsOrHash; + this._modifiedStringElements = modifiedStringElements; + this._modifiedElementsOrHash = modifiedElementsOrHash; + this.m_forwardHistory = []; this.m_reverseHistory = []; } + private static _isStringArray(arr: Int32Array | number[] | string[]): arr is string[] { + return (arr.length > 0 && typeof arr[0] === 'string'); + } + + private static _getElements(sequence: ISequence): [string[], Int32Array, boolean] { + const elements = sequence.getElements(); + + if (LcsDiff._isStringArray(elements)) { + const hashes = new Int32Array(elements.length); + for (let i = 0, len = elements.length; i < len; i++) { + hashes[i] = stringHash(elements[i], 0); + } + return [elements, hashes, true]; + } + + if (elements instanceof Int32Array) { + return [[], elements, false]; + } + + return [[], new Int32Array(elements), false]; + } + private ElementsAreEqual(originalIndex: number, newIndex: number): boolean { - return (this.OriginalSequence.getElementAtIndex(originalIndex) === this.ModifiedSequence.getElementAtIndex(newIndex)); + if (this._originalElementsOrHash[originalIndex] !== this._modifiedElementsOrHash[newIndex]) { + return false; + } + return (this._hasStrings ? this._originalStringElements[originalIndex] === this._modifiedStringElements[newIndex] : true); } private OriginalElementsAreEqual(index1: number, index2: number): boolean { - return (this.OriginalSequence.getElementAtIndex(index1) === this.OriginalSequence.getElementAtIndex(index2)); + if (this._originalElementsOrHash[index1] !== this._originalElementsOrHash[index2]) { + return false; + } + return (this._hasStrings ? this._originalStringElements[index1] === this._originalStringElements[index2] : true); } private ModifiedElementsAreEqual(index1: number, index2: number): boolean { - return (this.ModifiedSequence.getElementAtIndex(index1) === this.ModifiedSequence.getElementAtIndex(index2)); + if (this._modifiedElementsOrHash[index1] !== this._modifiedElementsOrHash[index2]) { + return false; + } + return (this._hasStrings ? this._modifiedStringElements[index1] === this._modifiedStringElements[index2] : true); } public ComputeDiff(pretty: boolean): IDiffChange[] { - return this._ComputeDiff(0, this.OriginalSequence.getLength() - 1, 0, this.ModifiedSequence.getLength() - 1, pretty); + return this._ComputeDiff(0, this._originalElementsOrHash.length - 1, 0, this._modifiedElementsOrHash.length - 1, pretty); } /** @@ -358,7 +411,7 @@ export class LcsDiff { private WALKTRACE(diagonalForwardBase: number, diagonalForwardStart: number, diagonalForwardEnd: number, diagonalForwardOffset: number, diagonalReverseBase: number, diagonalReverseStart: number, diagonalReverseEnd: number, diagonalReverseOffset: number, - forwardPoints: number[], reversePoints: number[], + forwardPoints: Int32Array, reversePoints: Int32Array, originalIndex: number, originalEnd: number, midOriginalArr: number[], modifiedIndex: number, modifiedEnd: number, midModifiedArr: number[], deltaIsEven: boolean, quitEarlyArr: boolean[]): DiffChange[] { @@ -523,8 +576,8 @@ export class LcsDiff { // The modifiedIndex can be computed mathematically from the originalIndex and the diagonal number. let maxDifferences = (originalEnd - originalStart) + (modifiedEnd - modifiedStart); let numDiagonals = maxDifferences + 1; - let forwardPoints: number[] = new Array(numDiagonals); - let reversePoints: number[] = new Array(numDiagonals); + let forwardPoints = new Int32Array(numDiagonals); + let reversePoints = new Int32Array(numDiagonals); // diagonalForwardBase: Index into forwardPoints of the diagonal which passes through (originalStart, modifiedStart) // diagonalReverseBase: Index into reversePoints of the diagonal which passes through (originalEnd, modifiedEnd) let diagonalForwardBase = (modifiedEnd - modifiedStart); @@ -624,7 +677,7 @@ export class LcsDiff { // Check to see if we should be quitting early, before moving on to the next iteration. let matchLengthOfLongest = ((furthestOriginalIndex - originalStart) + (furthestModifiedIndex - modifiedStart) - numDifferences) / 2; - if (this.ContinueProcessingPredicate !== null && !this.ContinueProcessingPredicate(furthestOriginalIndex, this.OriginalSequence, matchLengthOfLongest)) { + if (this.ContinueProcessingPredicate !== null && !this.ContinueProcessingPredicate(furthestOriginalIndex, matchLengthOfLongest)) { // We can't finish, so skip ahead to generating a result from what we have. quitEarlyArr[0] = true; @@ -711,14 +764,14 @@ export class LcsDiff { if (numDifferences <= MaxDifferencesHistory) { // We are allocating space for one extra int, which we fill with // the index of the diagonal base index - let temp: number[] = new Array(diagonalForwardEnd - diagonalForwardStart + 2); + let temp = new Int32Array(diagonalForwardEnd - diagonalForwardStart + 2); temp[0] = diagonalForwardBase - diagonalForwardStart + 1; - MyArray.Copy(forwardPoints, diagonalForwardStart, temp, 1, diagonalForwardEnd - diagonalForwardStart + 1); + MyArray.Copy2(forwardPoints, diagonalForwardStart, temp, 1, diagonalForwardEnd - diagonalForwardStart + 1); this.m_forwardHistory.push(temp); - temp = new Array(diagonalReverseEnd - diagonalReverseStart + 2); + temp = new Int32Array(diagonalReverseEnd - diagonalReverseStart + 2); temp[0] = diagonalReverseBase - diagonalReverseStart + 1; - MyArray.Copy(reversePoints, diagonalReverseStart, temp, 1, diagonalReverseEnd - diagonalReverseStart + 1); + MyArray.Copy2(reversePoints, diagonalReverseStart, temp, 1, diagonalReverseEnd - diagonalReverseStart + 1); this.m_reverseHistory.push(temp); } @@ -750,8 +803,8 @@ export class LcsDiff { // Shift all the changes down first for (let i = 0; i < changes.length; i++) { const change = changes[i]; - const originalStop = (i < changes.length - 1) ? changes[i + 1].originalStart : this.OriginalSequence.getLength(); - const modifiedStop = (i < changes.length - 1) ? changes[i + 1].modifiedStart : this.ModifiedSequence.getLength(); + const originalStop = (i < changes.length - 1) ? changes[i + 1].originalStart : this._originalElementsOrHash.length; + const modifiedStop = (i < changes.length - 1) ? changes[i + 1].modifiedStart : this._modifiedElementsOrHash.length; const checkOriginal = change.originalLength > 0; const checkModified = change.modifiedLength > 0; @@ -826,11 +879,10 @@ export class LcsDiff { } private _OriginalIsBoundary(index: number): boolean { - if (index <= 0 || index >= this.OriginalSequence.getLength() - 1) { + if (index <= 0 || index >= this._originalElementsOrHash.length - 1) { return true; } - const element = this.OriginalSequence.getElementAtIndex(index); - return (typeof element === 'string' && /^\s*$/.test(element)); + return (this._hasStrings && /^\s*$/.test(this._originalStringElements[index])); } private _OriginalRegionIsBoundary(originalStart: number, originalLength: number): boolean { @@ -847,11 +899,10 @@ export class LcsDiff { } private _ModifiedIsBoundary(index: number): boolean { - if (index <= 0 || index >= this.ModifiedSequence.getLength() - 1) { + if (index <= 0 || index >= this._modifiedElementsOrHash.length - 1) { return true; } - const element = this.ModifiedSequence.getElementAtIndex(index); - return (typeof element === 'string' && /^\s*$/.test(element)); + return (this._hasStrings && /^\s*$/.test(this._modifiedStringElements[index])); } private _ModifiedRegionIsBoundary(modifiedStart: number, modifiedLength: number): boolean { diff --git a/src/vs/base/common/hash.ts b/src/vs/base/common/hash.ts index 0a5106d3bd6..1902e82c312 100644 --- a/src/vs/base/common/hash.ts +++ b/src/vs/base/common/hash.ts @@ -36,7 +36,7 @@ function booleanHash(b: boolean, initialHashVal: number): number { return numberHash(b ? 433 : 863, initialHashVal); } -function stringHash(s: string, hashVal: number) { +export function stringHash(s: string, hashVal: number) { hashVal = numberHash(149417, hashVal); for (let i = 0, length = s.length; i < length; i++) { hashVal = numberHash(s.charCodeAt(i), hashVal); diff --git a/src/vs/base/common/keyCodes.ts b/src/vs/base/common/keyCodes.ts index ec08bea7e91..98ac19e0843 100644 --- a/src/vs/base/common/keyCodes.ts +++ b/src/vs/base/common/keyCodes.ts @@ -5,6 +5,7 @@ import { OperatingSystem } from 'vs/base/common/platform'; import { illegalArgument } from 'vs/base/common/errors'; +import { equals } from 'vs/base/common/arrays'; /** * Virtual Key Codes, the value does not hold any inherent meaning. @@ -525,15 +526,7 @@ export class ChordKeybinding { if (other === null) { return false; } - if (this.parts.length !== other.parts.length) { - return false; - } - for (let i = 0; i < this.parts.length; i++) { - if (!this.parts[i].equals(other.parts[i])) { - return false; - } - } - return true; + return equals(this.parts, other.parts, (a, b) => a.equals(b)); } } diff --git a/src/vs/base/common/lifecycle.ts b/src/vs/base/common/lifecycle.ts index 44cfdada8ab..8d1cbd5b996 100644 --- a/src/vs/base/common/lifecycle.ts +++ b/src/vs/base/common/lifecycle.ts @@ -138,7 +138,7 @@ export class DisposableStore implements IDisposable { export abstract class Disposable implements IDisposable { - static None = Object.freeze({ dispose() { } }); + static readonly None = Object.freeze({ dispose() { } }); private readonly _store = new DisposableStore(); diff --git a/src/vs/base/node/macAddress.ts b/src/vs/base/node/macAddress.ts index dd36be22344..524b136c06b 100644 --- a/src/vs/base/node/macAddress.ts +++ b/src/vs/base/node/macAddress.ts @@ -11,21 +11,15 @@ const cmdline = { unix: '/sbin/ifconfig -a || /sbin/ip link' }; -const invalidMacAddresses = [ +const invalidMacAddresses = new Set([ '00:00:00:00:00:00', 'ff:ff:ff:ff:ff:ff', 'ac:de:48:00:11:22' -]; +]); function validateMacAddress(candidate: string): boolean { - let tempCandidate = candidate.replace(/\-/g, ':').toLowerCase(); - for (let invalidMacAddress of invalidMacAddresses) { - if (invalidMacAddress === tempCandidate) { - return false; - } - } - - return true; + const tempCandidate = candidate.replace(/\-/g, ':').toLowerCase(); + return !invalidMacAddresses.has(tempCandidate); } export function getMac(): Promise { @@ -66,4 +60,4 @@ function doGetMac(): Promise { reject(err); } }); -} \ No newline at end of file +} diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 7b60ba4a101..48f75577206 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -8,7 +8,6 @@ import { IDisposable, toDisposable, combinedDisposable } from 'vs/base/common/li import { CancelablePromise, createCancelablePromise, timeout } from 'vs/base/common/async'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import * as errors from 'vs/base/common/errors'; -import { IServerChannel, IChannel } from 'vs/base/parts/ipc/common/ipc'; import { VSBuffer } from 'vs/base/common/buffer'; /** diff --git a/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts b/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts index b310a886f67..bac2223ede6 100644 --- a/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts +++ b/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts @@ -23,7 +23,7 @@ function createScopedOnMessageEvent(senderId: number, eventName: string): Event< export class Server extends IPCServer { - private static Clients = new Map(); + private static readonly Clients = new Map(); private static getOnDidClientConnect(): Event { const onHello = Event.fromNodeEventEmitter(ipcMain, 'ipc:hello', ({ sender }) => sender); diff --git a/src/vs/base/parts/quickopen/browser/quickOpenModel.ts b/src/vs/base/parts/quickopen/browser/quickOpenModel.ts index fdd8bcbf06b..5e1b2154cc1 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenModel.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenModel.ts @@ -53,7 +53,7 @@ export const QuickOpenItemAccessor = new QuickOpenItemAccessorClass(); export class QuickOpenEntry { private id: string; - private labelHighlights: IHighlight[]; + private labelHighlights?: IHighlight[]; private descriptionHighlights?: IHighlight[]; private detailHighlights?: IHighlight[]; private hidden: boolean | undefined; @@ -160,7 +160,7 @@ export class QuickOpenEntry { /** * Allows to set highlight ranges that should show up for the entry label and optionally description if set. */ - setHighlights(labelHighlights: IHighlight[], descriptionHighlights?: IHighlight[], detailHighlights?: IHighlight[]): void { + setHighlights(labelHighlights?: IHighlight[], descriptionHighlights?: IHighlight[], detailHighlights?: IHighlight[]): void { this.labelHighlights = labelHighlights; this.descriptionHighlights = descriptionHighlights; this.detailHighlights = detailHighlights; @@ -169,7 +169,7 @@ export class QuickOpenEntry { /** * Allows to return highlight ranges that should show up for the entry label and description. */ - getHighlights(): [IHighlight[] /* Label */, IHighlight[] | undefined /* Description */, IHighlight[] | undefined /* Detail */] { + getHighlights(): [IHighlight[] | undefined /* Label */, IHighlight[] | undefined /* Description */, IHighlight[] | undefined /* Detail */] { return [this.labelHighlights, this.descriptionHighlights, this.detailHighlights]; } @@ -260,7 +260,7 @@ export class QuickOpenEntryGroup extends QuickOpenEntry { return this.entry; } - getHighlights(): [IHighlight[], IHighlight[] | undefined, IHighlight[] | undefined] { + getHighlights(): [IHighlight[] | undefined, IHighlight[] | undefined, IHighlight[] | undefined] { return this.entry ? this.entry.getHighlights() : super.getHighlights(); } @@ -268,7 +268,7 @@ export class QuickOpenEntryGroup extends QuickOpenEntry { return this.entry ? this.entry.isHidden() : super.isHidden(); } - setHighlights(labelHighlights: IHighlight[], descriptionHighlights?: IHighlight[], detailHighlights?: IHighlight[]): void { + setHighlights(labelHighlights?: IHighlight[], descriptionHighlights?: IHighlight[], detailHighlights?: IHighlight[]): void { this.entry ? this.entry.setHighlights(labelHighlights, descriptionHighlights, detailHighlights) : super.setHighlights(labelHighlights, descriptionHighlights, detailHighlights); } diff --git a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts index f5276b7baa3..7a3a473d970 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts @@ -396,16 +396,16 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { protected applyStyles(): void { if (this.element) { const foreground = this.styles.foreground ? this.styles.foreground.toString() : null; - const background = this.styles.background ? this.styles.background.toString() : null; - const borderColor = this.styles.borderColor ? this.styles.borderColor.toString() : null; - const widgetShadow = this.styles.widgetShadow ? this.styles.widgetShadow.toString() : null; + const background = this.styles.background ? this.styles.background.toString() : ''; + const borderColor = this.styles.borderColor ? this.styles.borderColor.toString() : ''; + const widgetShadow = this.styles.widgetShadow ? this.styles.widgetShadow.toString() : ''; this.element.style.color = foreground; this.element.style.backgroundColor = background; this.element.style.borderColor = borderColor; - this.element.style.borderWidth = borderColor ? '1px' : null; - this.element.style.borderStyle = borderColor ? 'solid' : null; - this.element.style.boxShadow = widgetShadow ? `0 5px 8px ${widgetShadow}` : null; + this.element.style.borderWidth = borderColor ? '1px' : ''; + this.element.style.borderStyle = borderColor ? 'solid' : ''; + this.element.style.boxShadow = widgetShadow ? `0 5px 8px ${widgetShadow}` : ''; } if (this.progressBar) { diff --git a/src/vs/base/parts/storage/node/storage.ts b/src/vs/base/parts/storage/node/storage.ts index 5042879c655..e73aafe6ad4 100644 --- a/src/vs/base/parts/storage/node/storage.ts +++ b/src/vs/base/parts/storage/node/storage.ts @@ -32,12 +32,12 @@ export interface ISQLiteStorageDatabaseLoggingOptions { export class SQLiteStorageDatabase implements IStorageDatabase { - static IN_MEMORY_PATH = ':memory:'; + static readonly IN_MEMORY_PATH = ':memory:'; get onDidChangeItemsExternal(): Event { return Event.None; } // since we are the only client, there can be no external changes - private static BUSY_OPEN_TIMEOUT = 2000; // timeout in ms to retry when opening DB fails with SQLITE_BUSY - private static MAX_HOST_PARAMETERS = 256; // maximum number of parameters within a statement + private static readonly BUSY_OPEN_TIMEOUT = 2000; // timeout in ms to retry when opening DB fails with SQLITE_BUSY + private static readonly MAX_HOST_PARAMETERS = 256; // maximum number of parameters within a statement private path: string; private name: string; diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index bdd8f7da8e8..ee6a900f23a 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -398,8 +398,8 @@ function reactionEquals(one: _.IDragOverReaction, other: _.IDragOverReaction | n export class TreeView extends HeightMap { - static BINDING = 'monaco-tree-row'; - static LOADING_DECORATION_DELAY = 800; + static readonly BINDING = 'monaco-tree-row'; + static readonly LOADING_DECORATION_DELAY = 800; private static counter: number = 0; private instance: number; @@ -925,12 +925,11 @@ export class TreeView extends HeightMap { if (!skipDiff) { const lcs = new Diff.LcsDiff( { - getLength: () => previousChildrenIds.length, - getElementAtIndex: (i: number) => previousChildrenIds[i] - }, { - getLength: () => afterModelItems.length, - getElementAtIndex: (i: number) => afterModelItems[i].id - }, + getElements: () => previousChildrenIds + }, + { + getElements: () => afterModelItems.map(item => item.id) + }, null ); diff --git a/src/vs/base/test/common/diff/diff.test.ts b/src/vs/base/test/common/diff/diff.test.ts index f80a6169f28..be34bca0556 100644 --- a/src/vs/base/test/common/diff/diff.test.ts +++ b/src/vs/base/test/common/diff/diff.test.ts @@ -4,21 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { LcsDiff, IDiffChange, ISequence } from 'vs/base/common/diff/diff'; - -class StringDiffSequence implements ISequence { - - constructor(private source: string) { - } - - getLength() { - return this.source.length; - } - - getElementAtIndex(i: number) { - return this.source.charCodeAt(i); - } -} +import { LcsDiff, IDiffChange, StringDiffSequence } from 'vs/base/common/diff/diff'; function createArray(length: number, value: T): T[] { const r: T[] = []; @@ -123,12 +109,11 @@ suite('Diff - Ported from VS', () => { // doesn't get there first. let predicateCallCount = 0; - let diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) { + let diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, longestMatchSoFar) { assert.equal(predicateCallCount, 0); predicateCallCount++; - assert.equal(leftSequence.getLength(), left.length); assert.equal(leftIndex, 1); // cancel processing @@ -144,7 +129,7 @@ suite('Diff - Ported from VS', () => { // Cancel after the first match ('c') - diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) { + diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, longestMatchSoFar) { assert(longestMatchSoFar <= 1); // We never see a match of length > 1 // Continue processing as long as there hasn't been a match made. @@ -157,7 +142,7 @@ suite('Diff - Ported from VS', () => { // Cancel after the second match ('d') - diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) { + diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, longestMatchSoFar) { assert(longestMatchSoFar <= 2); // We never see a match of length > 2 // Continue processing as long as there hasn't been a match made. @@ -171,7 +156,7 @@ suite('Diff - Ported from VS', () => { // Cancel *one iteration* after the second match ('d') let hitSecondMatch = false; - diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) { + diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, longestMatchSoFar) { assert(longestMatchSoFar <= 2); // We never see a match of length > 2 let hitYet = hitSecondMatch; @@ -186,7 +171,7 @@ suite('Diff - Ported from VS', () => { // Cancel after the third and final match ('e') - diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) { + diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, longestMatchSoFar) { assert(longestMatchSoFar <= 3); // We never see a match of length > 3 // Continue processing as long as there hasn't been a match made. diff --git a/src/vs/code/browser/workbench/workbench-dev.html b/src/vs/code/browser/workbench/workbench-dev.html index 910666edf08..b59b7a2b49b 100644 --- a/src/vs/code/browser/workbench/workbench-dev.html +++ b/src/vs/code/browser/workbench/workbench-dev.html @@ -14,7 +14,7 @@ default-src 'self'; img-src 'self' https: data: blob:; media-src 'none'; - script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https: 'sha256-AMRGFXNZ7mBnD/6F4lTV00XAjE5CBSM7ZeIv3DIp5YM=' 'sha256-meDZW3XhN5JmdjFUrWGhTouRKBiWYtXHltaKnqn/WMo='; + script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https: 'sha256-/Ua2yZoIzhImbjP5mnPF6fXTgzsTEtN8hPP1XAB1n6U=' 'sha256-meDZW3XhN5JmdjFUrWGhTouRKBiWYtXHltaKnqn/WMo='; child-src 'self'; frame-src 'self' https://*.vscode-webview-test.com; worker-src 'self'; @@ -50,7 +50,6 @@ 'xterm-addon-search': `${window.location.origin}/static/remote/web/node_modules/xterm-addon-search/lib/xterm-addon-search.js`, 'xterm-addon-web-links': `${window.location.origin}/static/remote/web/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`, 'semver-umd': `${window.location.origin}/static/remote/web/node_modules/semver-umd/lib/semver-umd.js`, - '@microsoft/applicationinsights-web': `${window.location.origin}/static/remote/web/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`, } }; diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 97d78ce7f9e..f3caa5350bf 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -14,7 +14,7 @@ default-src 'self'; img-src 'self' https: data: blob:; media-src 'none'; - script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https: 'sha256-4DqvCTjCHj2KW4QxC/Yt6uBwMRyYiEg7kOoykSEkonQ='; + script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https: 'sha256-lrlqPnPED1SjcFocGzCtf6ikbQdTUwJKs8VprSqhvS4='; child-src 'self'; frame-src 'self' https://*.vscode-webview-test.com; worker-src 'self'; @@ -37,7 +37,6 @@ - @@ -55,7 +54,6 @@ 'xterm-addon-search': `${window.location.origin}/static/node_modules/xterm-addon-search/lib/xterm-addon-search.js`, 'xterm-addon-web-links': `${window.location.origin}/static/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`, 'semver-umd': `${window.location.origin}/static/node_modules/semver-umd/lib/semver-umd.js`, - '@microsoft/applicationinsights-web': `${window.location.origin}/static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`, } }; diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts index 60e7d9a3ecc..1f0384a7424 100644 --- a/src/vs/code/browser/workbench/workbench.ts +++ b/src/vs/code/browser/workbench/workbench.ts @@ -103,10 +103,10 @@ class LocalStorageCredentialsProvider implements ICredentialsProvider { class PollingURLCallbackProvider extends Disposable implements IURLCallbackProvider { - static FETCH_INTERVAL = 500; // fetch every 500ms - static FETCH_TIMEOUT = 5 * 60 * 1000; // ...but stop after 5min + static readonly FETCH_INTERVAL = 500; // fetch every 500ms + static readonly FETCH_TIMEOUT = 5 * 60 * 1000; // ...but stop after 5min - static QUERY_KEYS = { + static readonly QUERY_KEYS = { REQUEST_ID: 'vscode-requestId', SCHEME: 'vscode-scheme', AUTHORITY: 'vscode-authority', diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index c65686451de..3191cdc737a 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -37,7 +37,6 @@ 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'; import { Button } from 'vs/base/browser/ui/button/button'; -import { withUndefinedAsNull } from 'vs/base/common/types'; import { SystemInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; @@ -232,7 +231,7 @@ export class IssueReporter extends Disposable { styleTag.innerHTML = content.join('\n'); document.head.appendChild(styleTag); - document.body.style.color = withUndefinedAsNull(styles.color); + document.body.style.color = styles.color || ''; } private handleExtensionData(extensions: IssueReporterExtensionData[]) { diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner.ts b/src/vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner.ts index d3a0e9dab87..a3899b854fb 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner.ts +++ b/src/vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner.ts @@ -13,7 +13,7 @@ import { IBackupWorkspacesFormat } from 'vs/platform/backup/node/backup'; export class StorageDataCleaner extends Disposable { // Workspace/Folder storage names are MD5 hashes (128bits / 4 due to hex presentation) - private static NON_EMPTY_WORKSPACE_ID_LENGTH = 128 / 4; + private static readonly NON_EMPTY_WORKSPACE_ID_LENGTH = 128 / 4; constructor( @IEnvironmentService private readonly environmentService: IEnvironmentService diff --git a/src/vs/editor/browser/controller/mouseHandler.ts b/src/vs/editor/browser/controller/mouseHandler.ts index dd8979daabc..357f1f542be 100644 --- a/src/vs/editor/browser/controller/mouseHandler.ts +++ b/src/vs/editor/browser/controller/mouseHandler.ts @@ -65,7 +65,7 @@ export interface IPointerHandlerHelper { export class MouseHandler extends ViewEventHandler { - static MOUSE_MOVE_MINIMUM_TIME = 100; // ms + static readonly MOUSE_MOVE_MINIMUM_TIME = 100; // ms protected _context: ViewContext; protected viewController: ViewController; diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index c025c958a0f..c396ab9b09d 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -972,7 +972,7 @@ export class MouseTargetFactory { // Thank you browsers for making this so 'easy' :) - if (document.caretRangeFromPoint) { + if (typeof document.caretRangeFromPoint === 'function') { return this._doHitTestWithCaretRangeFromPoint(ctx, request); diff --git a/src/vs/editor/browser/controller/textAreaHandler.ts b/src/vs/editor/browser/controller/textAreaHandler.ts index 7d5cab28c98..2a734c4adc8 100644 --- a/src/vs/editor/browser/controller/textAreaHandler.ts +++ b/src/vs/editor/browser/controller/textAreaHandler.ts @@ -66,7 +66,7 @@ interface LocalClipboardMetadata { * we can fetch the previous metadata. */ class LocalClipboardMetadataManager { - public static INSTANCE = new LocalClipboardMetadataManager(); + public static readonly INSTANCE = new LocalClipboardMetadataManager(); private _lastState: LocalClipboardMetadata | null; diff --git a/src/vs/editor/browser/editorExtensions.ts b/src/vs/editor/browser/editorExtensions.ts index c467768414b..ffccc8832bd 100644 --- a/src/vs/editor/browser/editorExtensions.ts +++ b/src/vs/editor/browser/editorExtensions.ts @@ -16,17 +16,17 @@ import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { CommandsRegistry, ICommandHandlerDescription } from 'vs/platform/commands/common/commands'; import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IConstructorSignature1, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { IConstructorSignature1, ServicesAccessor as InstantiationServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindings, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { Registry } from 'vs/platform/registry/common/platform'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { withNullAsUndefined } from 'vs/base/common/types'; -export type ServicesAccessor = ServicesAccessor; +export type ServicesAccessor = InstantiationServicesAccessor; export type IEditorContributionCtor = IConstructorSignature1; export type EditorTelemetryDataFragment = { - target: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; - snippet: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; + target: { classification: 'SystemMetaData', purpose: 'FeatureInsight', }; + snippet: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true, }; }; //#region Command @@ -224,8 +224,8 @@ export abstract class EditorAction extends EditorCommand { protected reportTelemetry(accessor: ServicesAccessor, editor: ICodeEditor) { type EditorActionInvokedClassification = { - name: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; - id: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + name: { classification: 'SystemMetaData', purpose: 'FeatureInsight', }; + id: { classification: 'SystemMetaData', purpose: 'FeatureInsight', }; }; type EditorActionInvokedEvent = { name: string; @@ -241,7 +241,7 @@ export abstract class EditorAction extends EditorCommand { // --- Registration of commands and actions -export function registerLanguageCommand(id: string, handler: (accessor: ServicesAccessor, args: Args) => any) { +export function registerLanguageCommand(id: string, handler: (accessor: ServicesAccessor, args: Args) => any) { CommandsRegistry.registerCommand(id, (accessor, args) => handler(accessor, args || {})); } diff --git a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts index a4e988745cb..9c1edf519e0 100644 --- a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts +++ b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts @@ -61,8 +61,8 @@ class Settings { const minimapOpts = options.get(EditorOption.minimap); const minimapEnabled = minimapOpts.enabled; const minimapSide = minimapOpts.side; - const backgroundColor = (minimapEnabled ? TokenizationRegistry.getDefaultBackground() : null); - if (backgroundColor === null || minimapSide === 'left') { + const backgroundColor = (minimapEnabled ? TokenizationRegistry.getDefaultBackground() : undefined); + if (typeof backgroundColor === 'undefined' || minimapSide === 'left') { this.backgroundColor = null; } else { this.backgroundColor = Color.Format.CSS.formatHex(backgroundColor); diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index c60e020b56f..a703cbafd2b 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -18,7 +18,7 @@ import { registerThemingParticipant } from 'vs/platform/theme/common/themeServic export class ViewCursors extends ViewPart { - static BLINK_INTERVAL = 500; + static readonly BLINK_INTERVAL = 500; private _readOnly: boolean; private _cursorBlinking: TextEditorCursorBlinkingStyle; diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index ef815de2219..f6b8b30bb9c 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -1562,7 +1562,7 @@ const DECORATIONS = { class DiffEditorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEditorWidgetStyle, IVerticalSashLayoutProvider { - static MINIMUM_EDITOR_WIDTH = 100; + static readonly MINIMUM_EDITOR_WIDTH = 100; private _disableSash: boolean; private readonly _sash: Sash; diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 1ec61ff9751..f017f7e5fcf 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -304,18 +304,6 @@ export abstract class CommonEditorConfiguration extends Disposable implements ed return EditorConfiguration2.computeOptions(this._validatedOptions, env); } - private static _primitiveArrayEquals(a: any[], b: any[]): boolean { - if (a.length !== b.length) { - return false; - } - for (let i = 0; i < a.length; i++) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - } - private static _subsetEquals(base: { [key: string]: any }, subset: { [key: string]: any }): boolean { for (const key in subset) { if (hasOwnProperty.call(subset, key)) { @@ -326,7 +314,7 @@ export abstract class CommonEditorConfiguration extends Disposable implements ed continue; } if (Array.isArray(baseValue) && Array.isArray(subsetValue)) { - if (!this._primitiveArrayEquals(baseValue, subsetValue)) { + if (!arrays.equals(baseValue, subsetValue)) { return false; } continue; diff --git a/src/vs/editor/common/controller/cursor.ts b/src/vs/editor/common/controller/cursor.ts index 4213345fc97..95be4c66153 100644 --- a/src/vs/editor/common/controller/cursor.ts +++ b/src/vs/editor/common/controller/cursor.ts @@ -21,14 +21,10 @@ import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; import { dispose } from 'vs/base/common/lifecycle'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; +import { equals } from 'vs/base/common/arrays'; -function containsLineMappingChanged(events: viewEvents.ViewEvent[]): boolean { - for (let i = 0, len = events.length; i < len; i++) { - if (events[i].type === viewEvents.ViewEventType.ViewLineMappingChanged) { - return true; - } - } - return false; +function containsLineMappingChanged(events: readonly viewEvents.ViewEvent[]): boolean { + return events.some(event => event.type === viewEvents.ViewEventType.ViewLineMappingChanged); } export class CursorStateChangedEvent { @@ -73,15 +69,7 @@ export class CursorModelState { if (this.modelVersionId !== other.modelVersionId) { return false; } - if (this.cursorState.length !== other.cursorState.length) { - return false; - } - for (let i = 0, len = this.cursorState.length; i < len; i++) { - if (!this.cursorState[i].equals(other.cursorState[i])) { - return false; - } - } - return true; + return equals(this.cursorState, other.cursorState, (a, b) => a.equals(b)); } } @@ -153,7 +141,7 @@ class AutoClosedAction { export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { - public static MAX_CURSOR_COUNT = 10000; + public static readonly MAX_CURSOR_COUNT = 10000; private readonly _onDidReachMaxCursorCount: Emitter = this._register(new Emitter()); public readonly onDidReachMaxCursorCount: Event = this._onDidReachMaxCursorCount.event; @@ -949,12 +937,7 @@ class CommandExecutor { } private static _arrayIsEmpty(commands: (editorCommon.ICommand | null)[]): boolean { - for (let i = 0, len = commands.length; i < len; i++) { - if (commands[i]) { - return false; - } - } - return true; + return commands.every(command => !command); } private static _getEditOperations(ctx: IExecContext, commands: (editorCommon.ICommand | null)[]): ICommandsData { diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 9fc69bc842e..0df564775fd 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -81,15 +81,12 @@ export class TypeOperations { const selection = selections[i]; let position = selection.getPosition(); + if (pasteOnNewLine && !selection.isEmpty()) { + pasteOnNewLine = false; + } if (pasteOnNewLine && text.indexOf('\n') !== text.length - 1) { pasteOnNewLine = false; } - if (pasteOnNewLine && selection.startLineNumber !== selection.endLineNumber) { - pasteOnNewLine = false; - } - if (pasteOnNewLine && selection.startColumn === model.getLineMinColumn(selection.startLineNumber) && selection.endColumn === model.getLineMaxColumn(selection.startLineNumber)) { - pasteOnNewLine = false; - } if (pasteOnNewLine) { // Paste entire line at the beginning of line diff --git a/src/vs/editor/common/core/rgba.ts b/src/vs/editor/common/core/rgba.ts index 0ce94359f31..3a19425bc4d 100644 --- a/src/vs/editor/common/core/rgba.ts +++ b/src/vs/editor/common/core/rgba.ts @@ -10,7 +10,7 @@ export class RGBA8 { _rgba8Brand: void; - static Empty = new RGBA8(0, 0, 0, 0); + static readonly Empty = new RGBA8(0, 0, 0, 0); /** * Red: integer in [0-255] diff --git a/src/vs/editor/common/core/selection.ts b/src/vs/editor/common/core/selection.ts index 80143cdf97a..b1776654e94 100644 --- a/src/vs/editor/common/core/selection.ts +++ b/src/vs/editor/common/core/selection.ts @@ -5,6 +5,7 @@ import { IPosition, Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; +import { equals } from 'vs/base/common/arrays'; /** * A selection in the editor. @@ -171,15 +172,7 @@ export class Selection extends Range { if (!a && !b) { return true; } - if (a.length !== b.length) { - return false; - } - for (let i = 0, len = a.length; i < len; i++) { - if (!this.selectionsEqual(a[i], b[i])) { - return false; - } - } - return true; + return equals(a, b, this.selectionsEqual); } /** diff --git a/src/vs/editor/common/diff/diffComputer.ts b/src/vs/editor/common/diff/diffComputer.ts index 67ccd7e5c4e..362ce26d72b 100644 --- a/src/vs/editor/common/diff/diffComputer.ts +++ b/src/vs/editor/common/diff/diffComputer.ts @@ -15,9 +15,9 @@ function computeDiff(originalSequence: ISequence, modifiedSequence: ISequence, c return diffAlgo.ComputeDiff(pretty); } -class LineMarkerSequence implements ISequence { +class LineSequence implements ISequence { - private readonly _lines: string[]; + public readonly lines: string[]; private readonly _startColumns: number[]; private readonly _endColumns: number[]; @@ -25,61 +25,37 @@ class LineMarkerSequence implements ISequence { let startColumns: number[] = []; let endColumns: number[] = []; for (let i = 0, length = lines.length; i < length; i++) { - startColumns[i] = LineMarkerSequence._getFirstNonBlankColumn(lines[i], 1); - endColumns[i] = LineMarkerSequence._getLastNonBlankColumn(lines[i], 1); + startColumns[i] = getFirstNonBlankColumn(lines[i], 1); + endColumns[i] = getLastNonBlankColumn(lines[i], 1); } - this._lines = lines; + this.lines = lines; this._startColumns = startColumns; this._endColumns = endColumns; } - public getLength(): number { - return this._lines.length; - } - - public getElementAtIndex(i: number): string { - return this._lines[i].substring(this._startColumns[i] - 1, this._endColumns[i] - 1); + public getElements(): Int32Array | number[] | string[] { + const elements: string[] = []; + for (let i = 0, len = this.lines.length; i < len; i++) { + elements[i] = this.lines[i].substring(this._startColumns[i] - 1, this._endColumns[i] - 1); + } + return elements; } public getStartLineNumber(i: number): number { return i + 1; } - public getStartColumn(i: number): number { - return this._startColumns[i]; - } - public getEndLineNumber(i: number): number { return i + 1; } - public getEndColumn(i: number): number { - return this._endColumns[i]; - } - - public static _getFirstNonBlankColumn(txt: string, defaultValue: number): number { - const r = strings.firstNonWhitespaceIndex(txt); - if (r === -1) { - return defaultValue; - } - return r + 1; - } - - public static _getLastNonBlankColumn(txt: string, defaultValue: number): number { - const r = strings.lastNonWhitespaceIndex(txt); - if (r === -1) { - return defaultValue; - } - return r + 2; - } - - public getCharSequence(shouldIgnoreTrimWhitespace: boolean, startIndex: number, endIndex: number): CharSequence { + public createCharSequence(shouldIgnoreTrimWhitespace: boolean, startIndex: number, endIndex: number): CharSequence { let charCodes: number[] = []; let lineNumbers: number[] = []; let columns: number[] = []; let len = 0; for (let index = startIndex; index <= endIndex; index++) { - const lineContent = this._lines[index]; + const lineContent = this.lines[index]; const startColumn = (shouldIgnoreTrimWhitespace ? this._startColumns[index] : 1); const endColumn = (shouldIgnoreTrimWhitespace ? this._endColumns[index] : lineContent.length + 1); for (let col = startColumn; col < endColumn; col++) { @@ -105,12 +81,8 @@ class CharSequence implements ISequence { this._columns = columns; } - public getLength(): number { - return this._charCodes.length; - } - - public getElementAtIndex(i: number): number { - return this._charCodes[i]; + public getElements(): Int32Array | number[] | string[] { + return this._charCodes; } public getStartLineNumber(i: number): number { @@ -254,7 +226,7 @@ class LineChange implements ILineChange { this.charChanges = charChanges; } - public static createFromDiffResult(shouldIgnoreTrimWhitespace: boolean, diffChange: IDiffChange, originalLineSequence: LineMarkerSequence, modifiedLineSequence: LineMarkerSequence, continueProcessingPredicate: () => boolean, shouldComputeCharChanges: boolean, shouldPostProcessCharChanges: boolean): LineChange { + public static createFromDiffResult(shouldIgnoreTrimWhitespace: boolean, diffChange: IDiffChange, originalLineSequence: LineSequence, modifiedLineSequence: LineSequence, continueProcessingPredicate: () => boolean, shouldComputeCharChanges: boolean, shouldPostProcessCharChanges: boolean): LineChange { let originalStartLineNumber: number; let originalEndLineNumber: number; let modifiedStartLineNumber: number; @@ -277,9 +249,10 @@ class LineChange implements ILineChange { modifiedEndLineNumber = modifiedLineSequence.getEndLineNumber(diffChange.modifiedStart + diffChange.modifiedLength - 1); } - if (shouldComputeCharChanges && diffChange.originalLength !== 0 && diffChange.modifiedLength !== 0 && continueProcessingPredicate()) { - const originalCharSequence = originalLineSequence.getCharSequence(shouldIgnoreTrimWhitespace, diffChange.originalStart, diffChange.originalStart + diffChange.originalLength - 1); - const modifiedCharSequence = modifiedLineSequence.getCharSequence(shouldIgnoreTrimWhitespace, diffChange.modifiedStart, diffChange.modifiedStart + diffChange.modifiedLength - 1); + if (shouldComputeCharChanges && diffChange.originalLength > 0 && diffChange.originalLength < 20 && diffChange.modifiedLength > 0 && diffChange.modifiedLength < 20 && continueProcessingPredicate()) { + // Compute character changes for diff chunks of at most 20 lines... + const originalCharSequence = originalLineSequence.createCharSequence(shouldIgnoreTrimWhitespace, diffChange.originalStart, diffChange.originalStart + diffChange.originalLength - 1); + const modifiedCharSequence = modifiedLineSequence.createCharSequence(shouldIgnoreTrimWhitespace, diffChange.modifiedStart, diffChange.modifiedStart + diffChange.modifiedLength - 1); let rawChanges = computeDiff(originalCharSequence, modifiedCharSequence, continueProcessingPredicate, true); @@ -313,8 +286,8 @@ export class DiffComputer { private readonly maximumRunTimeMs: number; private readonly originalLines: string[]; private readonly modifiedLines: string[]; - private readonly original: LineMarkerSequence; - private readonly modified: LineMarkerSequence; + private readonly original: LineSequence; + private readonly modified: LineSequence; private computationStartTime: number; @@ -326,21 +299,21 @@ export class DiffComputer { this.maximumRunTimeMs = MAXIMUM_RUN_TIME; this.originalLines = originalLines; this.modifiedLines = modifiedLines; - this.original = new LineMarkerSequence(originalLines); - this.modified = new LineMarkerSequence(modifiedLines); + this.original = new LineSequence(originalLines); + this.modified = new LineSequence(modifiedLines); this.computationStartTime = (new Date()).getTime(); } public computeDiff(): ILineChange[] { - if (this.original.getLength() === 1 && this.original.getElementAtIndex(0).length === 0) { + if (this.original.lines.length === 1 && this.original.lines[0].length === 0) { // empty original => fast path return [{ originalStartLineNumber: 1, originalEndLineNumber: 1, modifiedStartLineNumber: 1, - modifiedEndLineNumber: this.modified.getLength(), + modifiedEndLineNumber: this.modified.lines.length, charChanges: [{ modifiedEndColumn: 0, modifiedEndLineNumber: 0, @@ -354,11 +327,11 @@ export class DiffComputer { }]; } - if (this.modified.getLength() === 1 && this.modified.getElementAtIndex(0).length === 0) { + if (this.modified.lines.length === 1 && this.modified.lines[0].length === 0) { // empty modified => fast path return [{ originalStartLineNumber: 1, - originalEndLineNumber: this.original.getLength(), + originalEndLineNumber: this.original.lines.length, modifiedStartLineNumber: 1, modifiedEndLineNumber: 1, charChanges: [{ @@ -409,8 +382,8 @@ export class DiffComputer { // Check the leading whitespace { - let originalStartColumn = LineMarkerSequence._getFirstNonBlankColumn(originalLine, 1); - let modifiedStartColumn = LineMarkerSequence._getFirstNonBlankColumn(modifiedLine, 1); + let originalStartColumn = getFirstNonBlankColumn(originalLine, 1); + let modifiedStartColumn = getFirstNonBlankColumn(modifiedLine, 1); while (originalStartColumn > 1 && modifiedStartColumn > 1) { const originalChar = originalLine.charCodeAt(originalStartColumn - 2); const modifiedChar = modifiedLine.charCodeAt(modifiedStartColumn - 2); @@ -431,8 +404,8 @@ export class DiffComputer { // Check the trailing whitespace { - let originalEndColumn = LineMarkerSequence._getLastNonBlankColumn(originalLine, 1); - let modifiedEndColumn = LineMarkerSequence._getLastNonBlankColumn(modifiedLine, 1); + let originalEndColumn = getLastNonBlankColumn(originalLine, 1); + let modifiedEndColumn = getLastNonBlankColumn(modifiedLine, 1); const originalMaxColumn = originalLine.length + 1; const modifiedMaxColumn = modifiedLine.length + 1; while (originalEndColumn < originalMaxColumn && modifiedEndColumn < modifiedMaxColumn) { @@ -534,3 +507,19 @@ export class DiffComputer { } } + +function getFirstNonBlankColumn(txt: string, defaultValue: number): number { + const r = strings.firstNonWhitespaceIndex(txt); + if (r === -1) { + return defaultValue; + } + return r + 1; +} + +function getLastNonBlankColumn(txt: string, defaultValue: number): number { + const r = strings.lastNonWhitespaceIndex(txt); + if (r === -1) { + return defaultValue; + } + return r + 2; +} diff --git a/src/vs/editor/common/model/textModelTokens.ts b/src/vs/editor/common/model/textModelTokens.ts index 03e1c4bd6b7..7749d45b6ad 100644 --- a/src/vs/editor/common/model/textModelTokens.ts +++ b/src/vs/editor/common/model/textModelTokens.ts @@ -197,14 +197,13 @@ export class TextModelTokenization extends Disposable { private readonly _textModel: TextModel; private readonly _tokenizationStateStore: TokenizationStateStore; private _revalidateTokensTimeout: any; - private _tokenizationSupport: ITokenizationSupport | null; + private _tokenizationSupport: ITokenizationSupport | undefined; 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(); @@ -428,11 +427,11 @@ export class TextModelTokenization extends Disposable { } } -function initializeTokenization(textModel: TextModel): [ITokenizationSupport | null, IState | null] { +function initializeTokenization(textModel: TextModel): [ITokenizationSupport | undefined, IState | null] { const languageIdentifier = textModel.getLanguageIdentifier(); let tokenizationSupport = ( textModel.isTooLargeForTokenization() - ? null + ? undefined : TokenizationRegistry.get(languageIdentifier.language) ); let initialState: IState | null = null; @@ -441,7 +440,7 @@ function initializeTokenization(textModel: TextModel): [ITokenizationSupport | n initialState = tokenizationSupport.getInitialState(); } catch (e) { onUnexpectedError(e); - tokenizationSupport = null; + tokenizationSupport = undefined; } } return [tokenizationSupport, initialState]; diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index ede4308bd87..70feadc2677 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -1568,9 +1568,9 @@ export interface ITokenizationRegistry { /** * Get the tokenization support for a language. - * Returns `null` if not found. + * Returns `undefined` if not found. */ - get(language: string): ITokenizationSupport | null; + get(language: string): ITokenizationSupport | undefined; /** * Get the promise of a tokenization support for a language. @@ -1583,9 +1583,9 @@ export interface ITokenizationRegistry { */ setColorMap(colorMap: Color[]): void; - getColorMap(): Color[] | null; + getColorMap(): Color[] | undefined; - getDefaultBackground(): Color | null; + getDefaultBackground(): Color | undefined; } /** diff --git a/src/vs/editor/common/modes/languageConfiguration.ts b/src/vs/editor/common/modes/languageConfiguration.ts index ed8d2fdb4ae..686c7a0dab2 100644 --- a/src/vs/editor/common/modes/languageConfiguration.ts +++ b/src/vs/editor/common/modes/languageConfiguration.ts @@ -247,7 +247,7 @@ export class StandardAutoClosingPairConditional { if (Array.isArray(source.notIn)) { for (let i = 0, len = source.notIn.length; i < len; i++) { - let notIn = source.notIn[i]; + const notIn: string = source.notIn[i]; switch (notIn) { case 'string': this._standardTokenMask |= StandardTokenType.String; diff --git a/src/vs/editor/common/modes/tokenizationRegistry.ts b/src/vs/editor/common/modes/tokenizationRegistry.ts index fc3423047fb..d1492e39107 100644 --- a/src/vs/editor/common/modes/tokenizationRegistry.ts +++ b/src/vs/editor/common/modes/tokenizationRegistry.ts @@ -7,7 +7,6 @@ import { Color } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { ColorId, ITokenizationRegistry, ITokenizationSupport, ITokenizationSupportChangedEvent } from 'vs/editor/common/modes'; -import { withUndefinedAsNull } from 'vs/base/common/types'; import { keys } from 'vs/base/common/map'; export class TokenizationRegistryImpl implements ITokenizationRegistry { @@ -18,11 +17,7 @@ export class TokenizationRegistryImpl implements ITokenizationRegistry { private readonly _onDidChange = new Emitter(); public readonly onDidChange: Event = this._onDidChange.event; - private _colorMap: Color[] | null; - - constructor() { - this._colorMap = null; - } + private _colorMap: Color[] | undefined; public fire(languages: string[]): void { this._onDidChange.fire({ @@ -76,8 +71,8 @@ export class TokenizationRegistryImpl implements ITokenizationRegistry { return null; } - public get(language: string): ITokenizationSupport | null { - return withUndefinedAsNull(this._map.get(language)); + public get(language: string): ITokenizationSupport | undefined { + return this._map.get(language); } public setColorMap(colorMap: Color[]): void { @@ -88,14 +83,14 @@ export class TokenizationRegistryImpl implements ITokenizationRegistry { }); } - public getColorMap(): Color[] | null { + public getColorMap(): Color[] | undefined { return this._colorMap; } - public getDefaultBackground(): Color | null { + public getDefaultBackground(): Color | undefined { if (this._colorMap && this._colorMap.length > ColorId.DefaultBackground) { return this._colorMap[ColorId.DefaultBackground]; } - return null; + return undefined; } } diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts index 1c9d7a274a9..5b5070184ea 100644 --- a/src/vs/editor/common/services/modelServiceImpl.ts +++ b/src/vs/editor/common/services/modelServiceImpl.ts @@ -218,6 +218,10 @@ export class ModelServiceImpl extends Disposable implements IModelService { } private static _setModelOptionsForModel(model: ITextModel, newOptions: ITextModelCreationOptions, currentOptions: ITextModelCreationOptions): void { + if (currentOptions && currentOptions.defaultEOL !== newOptions.defaultEOL && model.getLineCount() === 1) { + model.setEOL(newOptions.defaultEOL === DefaultEndOfLine.LF ? EndOfLineSequence.LF : EndOfLineSequence.CRLF); + } + if (currentOptions && (currentOptions.detectIndentation === newOptions.detectIndentation) && (currentOptions.insertSpaces === newOptions.insertSpaces) diff --git a/src/vs/editor/common/viewLayout/lineDecorations.ts b/src/vs/editor/common/viewLayout/lineDecorations.ts index 5e79341a942..cae03bc9e46 100644 --- a/src/vs/editor/common/viewLayout/lineDecorations.ts +++ b/src/vs/editor/common/viewLayout/lineDecorations.ts @@ -6,6 +6,7 @@ import * as strings from 'vs/base/common/strings'; import { Constants } from 'vs/editor/common/core/uint'; import { InlineDecoration, InlineDecorationType } from 'vs/editor/common/viewModel/viewModel'; +import { equals } from 'vs/base/common/arrays'; export class LineDecoration { _lineDecorationBrand: void; @@ -27,18 +28,8 @@ export class LineDecoration { ); } - public static equalsArr(a: LineDecoration[], b: LineDecoration[]): boolean { - let aLen = a.length; - let bLen = b.length; - if (aLen !== bLen) { - return false; - } - for (let i = 0; i < aLen; i++) { - if (!LineDecoration._equals(a[i], b[i])) { - return false; - } - } - return true; + public static equalsArr(a: readonly LineDecoration[], b: readonly LineDecoration[]): boolean { + return equals(a, b, LineDecoration._equals); } public static filter(lineDecorations: InlineDecoration[], lineNumber: number, minLineColumn: number, maxLineColumn: number): LineDecoration[] { diff --git a/src/vs/editor/common/viewLayout/viewLineRenderer.ts b/src/vs/editor/common/viewLayout/viewLineRenderer.ts index bbb9b39cb8c..0b41b006f65 100644 --- a/src/vs/editor/common/viewLayout/viewLineRenderer.ts +++ b/src/vs/editor/common/viewLayout/viewLineRenderer.ts @@ -9,6 +9,7 @@ import { IViewLineTokens } from 'vs/editor/common/core/lineTokens'; import { IStringBuilder, createStringBuilder } from 'vs/editor/common/core/stringBuilder'; import { LineDecoration, LineDecorationsNormalizer } from 'vs/editor/common/viewLayout/lineDecorations'; import { InlineDecorationType } from 'vs/editor/common/viewModel/viewModel'; +import { equals } from 'vs/base/common/arrays'; export const enum RenderWhitespace { None = 0, @@ -131,17 +132,7 @@ export class RenderLineInput { return false; } - if (otherSelections.length !== this.selectionsOnLine.length) { - return false; - } - - for (let i = 0; i < this.selectionsOnLine.length; i++) { - if (!this.selectionsOnLine[i].equals(otherSelections[i])) { - return false; - } - } - - return true; + return equals(this.selectionsOnLine, otherSelections, (a, b) => a.equals(b)); } public equals(other: RenderLineInput): boolean { diff --git a/src/vs/editor/contrib/codelens/codelensWidget.ts b/src/vs/editor/contrib/codelens/codelensWidget.ts index 42cf0deb06e..5465476d6ed 100644 --- a/src/vs/editor/contrib/codelens/codelensWidget.ts +++ b/src/vs/editor/contrib/codelens/codelensWidget.ts @@ -6,7 +6,7 @@ import 'vs/css!./codelensWidget'; import * as dom from 'vs/base/browser/dom'; import { coalesce, isFalsyOrEmpty } from 'vs/base/common/arrays'; -import { escape } from 'vs/base/common/strings'; +import { renderOcticons } from 'vs/base/browser/ui/octiconLabel/octiconLabel'; import * as editorBrowser from 'vs/editor/browser/editorBrowser'; import { Range } from 'vs/editor/common/core/range'; import { IModelDecorationsChangeAccessor, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; @@ -104,7 +104,7 @@ class CodeLensContentWidget implements editorBrowser.IContentWidget { for (let i = 0; i < symbols.length; i++) { const command = symbols[i].command; if (command) { - const title = escape(command.title); + const title = renderOcticons(command.title); let part: string; if (command.id) { part = `${title}`; diff --git a/src/vs/editor/contrib/colorPicker/colorDetector.ts b/src/vs/editor/contrib/colorPicker/colorDetector.ts index c1460b7650d..7e2b9e03de4 100644 --- a/src/vs/editor/contrib/colorPicker/colorDetector.ts +++ b/src/vs/editor/contrib/colorPicker/colorDetector.ts @@ -27,7 +27,7 @@ export class ColorDetector extends Disposable implements IEditorContribution { private static readonly ID: string = 'editor.contrib.colorDetector'; - static RECOMPUTE_TIME = 1000; // ms + static readonly RECOMPUTE_TIME = 1000; // ms private readonly _localToDispose = this._register(new DisposableStore()); private _computePromise: CancelablePromise | null; diff --git a/src/vs/editor/contrib/cursorUndo/cursorUndo.ts b/src/vs/editor/contrib/cursorUndo/cursorUndo.ts index 0d9ea4ea21e..e4568052f62 100644 --- a/src/vs/editor/contrib/cursorUndo/cursorUndo.ts +++ b/src/vs/editor/contrib/cursorUndo/cursorUndo.ts @@ -12,6 +12,7 @@ import { Selection } from 'vs/editor/common/core/selection'; import { IEditorContribution, ScrollType } from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { equals } from 'vs/base/common/arrays'; class CursorState { readonly selections: readonly Selection[]; @@ -21,17 +22,7 @@ class CursorState { } public equals(other: CursorState): boolean { - const thisLen = this.selections.length; - const otherLen = other.selections.length; - if (thisLen !== otherLen) { - return false; - } - for (let i = 0; i < thisLen; i++) { - if (!this.selections[i].equalsSelection(other.selections[i])) { - return false; - } - } - return true; + return equals(this.selections, other.selections, (a, b) => a.equalsSelection(b)); } } diff --git a/src/vs/editor/contrib/dnd/dnd.ts b/src/vs/editor/contrib/dnd/dnd.ts index bbf3df37d01..044ea027dc3 100644 --- a/src/vs/editor/contrib/dnd/dnd.ts +++ b/src/vs/editor/contrib/dnd/dnd.ts @@ -38,7 +38,7 @@ export class DragAndDropController extends Disposable implements editorCommon.IE private _dndDecorationIds: string[]; private _mouseDown: boolean; private _modifierPressed: boolean; - static TRIGGER_KEY_VALUE = isMacintosh ? KeyCode.Alt : KeyCode.Ctrl; + static readonly TRIGGER_KEY_VALUE = isMacintosh ? KeyCode.Alt : KeyCode.Ctrl; static get(editor: ICodeEditor): DragAndDropController { return editor.getContribution(DragAndDropController.ID); diff --git a/src/vs/editor/contrib/documentSymbols/outlineTree.ts b/src/vs/editor/contrib/documentSymbols/outlineTree.ts index 84ac8bb704c..4b96ccf9240 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineTree.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineTree.ts @@ -44,7 +44,7 @@ export class OutlineIdentityProvider implements IIdentityProvider { } export class OutlineGroupTemplate { - static id = 'OutlineGroupTemplate'; + static readonly id = 'OutlineGroupTemplate'; constructor( readonly labelContainer: HTMLElement, readonly label: HighlightedLabel, @@ -52,7 +52,7 @@ export class OutlineGroupTemplate { } export class OutlineElementTemplate { - static id = 'OutlineElementTemplate'; + static readonly id = 'OutlineElementTemplate'; constructor( readonly container: HTMLElement, readonly iconLabel: IconLabel, diff --git a/src/vs/editor/contrib/folding/folding.ts b/src/vs/editor/contrib/folding/folding.ts index eb550be02fb..87fa92fb892 100644 --- a/src/vs/editor/contrib/folding/folding.ts +++ b/src/vs/editor/contrib/folding/folding.ts @@ -50,7 +50,7 @@ interface FoldingStateMemento { export class FoldingController extends Disposable implements IEditorContribution { - static MAX_FOLDING_REGIONS = 5000; + static readonly MAX_FOLDING_REGIONS = 5000; public static get(editor: ICodeEditor): FoldingController { diff --git a/src/vs/editor/contrib/folding/foldingDecorations.ts b/src/vs/editor/contrib/folding/foldingDecorations.ts index 44554ac1300..333ad459db0 100644 --- a/src/vs/editor/contrib/folding/foldingDecorations.ts +++ b/src/vs/editor/contrib/folding/foldingDecorations.ts @@ -10,18 +10,18 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; export class FoldingDecorationProvider implements IDecorationProvider { - private static COLLAPSED_VISUAL_DECORATION = ModelDecorationOptions.register({ + private static readonly COLLAPSED_VISUAL_DECORATION = ModelDecorationOptions.register({ stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, afterContentClassName: 'inline-folded', linesDecorationsClassName: 'codicon codicon-chevron-right' }); - private static EXPANDED_AUTO_HIDE_VISUAL_DECORATION = ModelDecorationOptions.register({ + private static readonly EXPANDED_AUTO_HIDE_VISUAL_DECORATION = ModelDecorationOptions.register({ stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, linesDecorationsClassName: 'codicon codicon-chevron-down' }); - private static EXPANDED_VISUAL_DECORATION = ModelDecorationOptions.register({ + private static readonly EXPANDED_VISUAL_DECORATION = ModelDecorationOptions.register({ stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, linesDecorationsClassName: 'codicon codicon-chevron-down alwaysShowFoldIcons' }); diff --git a/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts b/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts index 7d0dd7ce4e1..589e552e225 100644 --- a/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts +++ b/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts @@ -30,7 +30,7 @@ import { withNullAsUndefined } from 'vs/base/common/types'; class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorContribution { private static readonly ID = 'editor.contrib.gotodefinitionwithmouse'; - static MAX_SOURCE_PREVIEW_LINES = 8; + static readonly MAX_SOURCE_PREVIEW_LINES = 8; private readonly editor: ICodeEditor; private readonly toUnhook = new DisposableStore(); diff --git a/src/vs/editor/contrib/gotoError/gotoError.ts b/src/vs/editor/contrib/gotoError/gotoError.ts index c552b5f4406..291b30cbb25 100644 --- a/src/vs/editor/contrib/gotoError/gotoError.ts +++ b/src/vs/editor/contrib/gotoError/gotoError.ts @@ -20,7 +20,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { MarkerNavigationWidget } from './gotoErrorWidget'; import { compare } from 'vs/base/common/strings'; -import { binarySearch } from 'vs/base/common/arrays'; +import { binarySearch, find } from 'vs/base/common/arrays'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { onUnexpectedError } from 'vs/base/common/errors'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; @@ -173,12 +173,7 @@ class MarkerModel { } public findMarkerAtPosition(pos: Position): IMarker | undefined { - for (const marker of this._markers) { - if (Range.containsPosition(marker, pos)) { - return marker; - } - } - return undefined; + return find(this._markers, marker => Range.containsPosition(marker, pos)); } public get total() { diff --git a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts index 3c94a3b561a..a8aa26cb3a9 100644 --- a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts +++ b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts @@ -283,7 +283,7 @@ export class MarkerNavigationWidget extends PeekViewWidget { : nls.localize('change', "{0} of {1} problem", markerIdx, markerCount); this.setTitle(basename(model.uri), detail); } - this._icon.className = SeverityIcon.className(MarkerSeverity.toSeverity(this._severity)); + this._icon.className = `codicon ${SeverityIcon.className(MarkerSeverity.toSeverity(this._severity))}`; this.editor.revealPositionInCenter(position, ScrollType.Smooth); } diff --git a/src/vs/editor/contrib/links/links.ts b/src/vs/editor/contrib/links/links.ts index 1eee5898a96..a387d6cd9db 100644 --- a/src/vs/editor/contrib/links/links.ts +++ b/src/vs/editor/contrib/links/links.ts @@ -106,7 +106,7 @@ class LinkDetector implements editorCommon.IEditorContribution { return editor.getContribution(LinkDetector.ID); } - static RECOMPUTE_TIME = 1000; // ms + static readonly RECOMPUTE_TIME = 1000; // ms private readonly editor: ICodeEditor; private enabled: boolean; diff --git a/src/vs/editor/contrib/message/messageController.ts b/src/vs/editor/contrib/message/messageController.ts index e57a0987498..311a922e7da 100644 --- a/src/vs/editor/contrib/message/messageController.ts +++ b/src/vs/editor/contrib/message/messageController.ts @@ -23,7 +23,7 @@ export class MessageController extends Disposable implements editorCommon.IEdito private static readonly _id = 'editor.contrib.messageController'; - static MESSAGE_VISIBLE = new RawContextKey('messageVisible', false); + static readonly MESSAGE_VISIBLE = new RawContextKey('messageVisible', false); static get(editor: ICodeEditor): MessageController { return editor.getContribution(MessageController._id); diff --git a/src/vs/editor/contrib/referenceSearch/media/peekViewWidget.css b/src/vs/editor/contrib/referenceSearch/media/peekViewWidget.css index b0d1fefcf21..091c6cd70e7 100644 --- a/src/vs/editor/contrib/referenceSearch/media/peekViewWidget.css +++ b/src/vs/editor/contrib/referenceSearch/media/peekViewWidget.css @@ -60,3 +60,7 @@ border-top: 1px solid; position: relative; } + +.monaco-editor .peekview-widget .head .peekview-title .codicon { + margin-right: 4px; +} diff --git a/src/vs/editor/contrib/smartSelect/test/smartSelect.test.ts b/src/vs/editor/contrib/smartSelect/test/smartSelect.test.ts index b918921b059..f0eedb8324d 100644 --- a/src/vs/editor/contrib/smartSelect/test/smartSelect.test.ts +++ b/src/vs/editor/contrib/smartSelect/test/smartSelect.test.ts @@ -12,33 +12,11 @@ import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageCo import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { javascriptOnEnterRules } from 'vs/editor/test/common/modes/supports/javascriptOnEnterRules'; -import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { isLinux, isMacintosh } from 'vs/base/common/platform'; import { BracketSelectionRangeProvider } from 'vs/editor/contrib/smartSelect/bracketSelections'; import { provideSelectionRanges } from 'vs/editor/contrib/smartSelect/smartSelect'; import { CancellationToken } from 'vs/base/common/cancellation'; import { WordSelectionRangeProvider } from 'vs/editor/contrib/smartSelect/wordSelections'; - -class TestTextResourcePropertiesService implements ITextResourcePropertiesService { - - _serviceBrand: undefined; - - constructor( - @IConfigurationService private readonly configurationService: IConfigurationService, - ) { - } - - getEOL(resource: URI | undefined): string { - const filesConfiguration = this.configurationService.getValue<{ eol: string }>('files'); - if (filesConfiguration && filesConfiguration.eol) { - if (filesConfiguration.eol !== 'auto') { - return filesConfiguration.eol; - } - } - return (isLinux || isMacintosh) ? '\n' : '\r\n'; - } -} +import { TestTextResourcePropertiesService } from 'vs/editor/test/common/services/modelService.test'; class MockJSMode extends MockMode { diff --git a/src/vs/editor/contrib/snippet/snippetController2.ts b/src/vs/editor/contrib/snippet/snippetController2.ts index cec786f46fe..021310ed839 100644 --- a/src/vs/editor/contrib/snippet/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/snippetController2.ts @@ -44,9 +44,9 @@ export class SnippetController2 implements IEditorContribution { return editor.getContribution('snippetController2'); } - static InSnippetMode = new RawContextKey('inSnippetMode', false); - static HasNextTabstop = new RawContextKey('hasNextTabstop', false); - static HasPrevTabstop = new RawContextKey('hasPrevTabstop', false); + static readonly InSnippetMode = new RawContextKey('inSnippetMode', false); + static readonly HasNextTabstop = new RawContextKey('hasNextTabstop', false); + static readonly HasPrevTabstop = new RawContextKey('hasPrevTabstop', false); private readonly _inSnippet: IContextKey; private readonly _hasNextTabstop: IContextKey; diff --git a/src/vs/editor/contrib/suggest/suggestAlternatives.ts b/src/vs/editor/contrib/suggest/suggestAlternatives.ts index e8a6ea1a338..6c9a148e618 100644 --- a/src/vs/editor/contrib/suggest/suggestAlternatives.ts +++ b/src/vs/editor/contrib/suggest/suggestAlternatives.ts @@ -11,7 +11,7 @@ import { ISelectedSuggestion } from './suggestWidget'; export class SuggestAlternatives { - static OtherSuggestions = new RawContextKey('hasOtherSuggestions', false); + static readonly OtherSuggestions = new RawContextKey('hasOtherSuggestions', false); private readonly _ckOtherSuggestions: IContextKey; diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index 372ceb0deab..121167d45ef 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -515,12 +515,10 @@ export class SimpleResourcePropertiesService implements ITextResourcePropertiesS ) { } - getEOL(resource: URI): string { - const filesConfiguration = this.configurationService.getValue<{ eol: string }>('files'); - if (filesConfiguration && filesConfiguration.eol) { - if (filesConfiguration.eol !== 'auto') { - return filesConfiguration.eol; - } + getEOL(resource: URI, language?: string): string { + const eol = this.configurationService.getValue('files.eol', { overrideIdentifier: language, resource }); + if (eol && eol !== 'auto') { + return eol; } return (isLinux || isMacintosh) ? '\n' : '\r\n'; } @@ -551,7 +549,7 @@ export class SimpleWorkspaceContextService implements IWorkspaceContextService { public _serviceBrand: undefined; - private static SCHEME = 'inmemory'; + private static readonly SCHEME = 'inmemory'; private readonly _onDidChangeWorkspaceName = new Emitter(); public readonly onDidChangeWorkspaceName: Event = this._onDidChangeWorkspaceName.event; diff --git a/src/vs/editor/standalone/common/monarch/monarchCompile.ts b/src/vs/editor/standalone/common/monarch/monarchCompile.ts index 2c98c6ba429..62f0d4313c6 100644 --- a/src/vs/editor/standalone/common/monarch/monarchCompile.ts +++ b/src/vs/editor/standalone/common/monarch/monarchCompile.ts @@ -21,18 +21,7 @@ import { IMonarchLanguage, IMonarchLanguageBracket } from 'vs/editor/standalone/ */ function isArrayOf(elemType: (x: any) => boolean, obj: any): boolean { - if (!obj) { - return false; - } - if (!(Array.isArray(obj))) { - return false; - } - for (const el of obj) { - if (!(elemType(el))) { - return false; - } - } - return true; + return Array.isArray(obj) && obj.every(elemType); } function bool(prop: any, defValue: boolean): boolean { diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index 984a1e23856..0a8680d8557 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -1494,6 +1494,25 @@ suite('Editor Controller - Regression tests', () => { }); }); + test('issue #74722: Pasting whole line does not replace selection', () => { + usingCursor({ + text: [ + 'line1', + 'line sel 2', + 'line3' + ], + }, (model, cursor) => { + cursor.setSelections('test', [new Selection(2, 6, 2, 9)]); + + cursorCommand(cursor, H.Paste, { text: 'line1\n', pasteOnNewLine: true }); + + assert.equal(model.getLineContent(1), 'line1'); + assert.equal(model.getLineContent(2), 'line line1'); + assert.equal(model.getLineContent(3), ' 2'); + assert.equal(model.getLineContent(4), 'line3'); + }); + }); + test('issue #4996: Multiple cursor paste pastes contents of all cursors', () => { usingCursor({ text: [ diff --git a/src/vs/editor/test/common/core/viewLineToken.ts b/src/vs/editor/test/common/core/viewLineToken.ts index 340157110ae..d91fe77bcf0 100644 --- a/src/vs/editor/test/common/core/viewLineToken.ts +++ b/src/vs/editor/test/common/core/viewLineToken.ts @@ -5,6 +5,7 @@ import { IViewLineTokens } from 'vs/editor/common/core/lineTokens'; import { ColorId, TokenMetadata } from 'vs/editor/common/modes'; +import { equals } from 'vs/base/common/arrays'; /** * A token on a line. @@ -42,18 +43,8 @@ export class ViewLineToken { ); } - public static equalsArr(a: ViewLineToken[], b: ViewLineToken[]): boolean { - const aLen = a.length; - const bLen = b.length; - if (aLen !== bLen) { - return false; - } - for (let i = 0; i < aLen; i++) { - if (!this._equals(a[i], b[i])) { - return false; - } - } - return true; + public static equalsArr(a: readonly ViewLineToken[], b: readonly ViewLineToken[]): boolean { + return equals(a, b, this._equals); } } diff --git a/src/vs/editor/test/common/modes/supports/characterPair.test.ts b/src/vs/editor/test/common/modes/supports/characterPair.test.ts index 3f3f6880450..ed059c8a0cb 100644 --- a/src/vs/editor/test/common/modes/supports/characterPair.test.ts +++ b/src/vs/editor/test/common/modes/supports/characterPair.test.ts @@ -8,6 +8,7 @@ import { StandardTokenType } from 'vs/editor/common/modes'; import { CharacterPairSupport } from 'vs/editor/common/modes/supports/characterPair'; import { TokenText, createFakeScopedLineTokens } from 'vs/editor/test/common/modesTestUtils'; import { StandardAutoClosingPairConditional } from 'vs/editor/common/modes/languageConfiguration'; +import { find } from 'vs/base/common/arrays'; suite('CharacterPairSupport', () => { @@ -53,13 +54,8 @@ suite('CharacterPairSupport', () => { assert.deepEqual(characaterPairSupport.getSurroundingPairs(), []); }); - function findAutoClosingPair(characterPairSupport: CharacterPairSupport, character: string): StandardAutoClosingPairConditional | null { - for (const autoClosingPair of characterPairSupport.getAutoClosingPairs()) { - if (autoClosingPair.open === character) { - return autoClosingPair; - } - } - return null; + function findAutoClosingPair(characterPairSupport: CharacterPairSupport, character: string): StandardAutoClosingPairConditional | undefined { + return find(characterPairSupport.getAutoClosingPairs(), autoClosingPair => autoClosingPair.open === character); } function testShouldAutoClose(characterPairSupport: CharacterPairSupport, line: TokenText[], character: string, column: number): boolean { diff --git a/src/vs/editor/test/common/services/modelService.test.ts b/src/vs/editor/test/common/services/modelService.test.ts index 20d3b7d3312..0a28a285b38 100644 --- a/src/vs/editor/test/common/services/modelService.test.ts +++ b/src/vs/editor/test/common/services/modelService.test.ts @@ -365,7 +365,7 @@ assertComputeEdits(file1, file2); } } -class TestTextResourcePropertiesService implements ITextResourcePropertiesService { +export class TestTextResourcePropertiesService implements ITextResourcePropertiesService { _serviceBrand: undefined; @@ -375,11 +375,9 @@ class TestTextResourcePropertiesService implements ITextResourcePropertiesServic } getEOL(resource: URI, language?: string): string { - const filesConfiguration = this.configurationService.getValue<{ eol: string }>('files', { overrideIdentifier: language, resource }); - if (filesConfiguration && filesConfiguration.eol) { - if (filesConfiguration.eol !== 'auto') { - return filesConfiguration.eol; - } + const eol = this.configurationService.getValue('files.eol', { overrideIdentifier: language, resource }); + if (eol && eol !== 'auto') { + return eol; } return (platform.isLinux || platform.isMacintosh) ? '\n' : '\r\n'; } diff --git a/src/vs/platform/configuration/common/configurationModels.ts b/src/vs/platform/configuration/common/configurationModels.ts index c4749186815..452e41724c4 100644 --- a/src/vs/platform/configuration/common/configurationModels.ts +++ b/src/vs/platform/configuration/common/configurationModels.ts @@ -518,14 +518,14 @@ export class Configuration { return folderConsolidatedConfiguration; } - private getFolderConfigurationModelForResource(resource: URI | null | undefined, workspace: Workspace | undefined): ConfigurationModel | null { + private getFolderConfigurationModelForResource(resource: URI | null | undefined, workspace: Workspace | undefined): ConfigurationModel | undefined { if (workspace && resource) { const root = workspace.getFolder(resource); if (root) { - return types.withUndefinedAsNull(this._folderConfigurations.get(root.uri)); + return this._folderConfigurations.get(root.uri); } } - return null; + return undefined; } toData(): IConfigurationData { @@ -663,13 +663,7 @@ export class ConfigurationChangeEvent extends AbstractConfigurationChangeEvent i configurationModelsToSearch.push(...this._changedConfigurationByResource.values()); } - for (const configuration of configurationModelsToSearch) { - if (this.doesConfigurationContains(configuration, config)) { - return true; - } - } - - return false; + return configurationModelsToSearch.some(configuration => this.doesConfigurationContains(configuration, config)); } private changeWithKeys(keys: string[], resource?: URI): void { diff --git a/src/vs/platform/contextkey/browser/contextKeyService.ts b/src/vs/platform/contextkey/browser/contextKeyService.ts index 8efe90bd137..41707f15c71 100644 --- a/src/vs/platform/contextkey/browser/contextKeyService.ts +++ b/src/vs/platform/contextkey/browser/contextKeyService.ts @@ -87,7 +87,7 @@ class NullContext extends Context { class ConfigAwareContextValuesContainer extends Context { - private static _keyPrefix = 'config.'; + private static readonly _keyPrefix = 'config.'; private readonly _values = new Map(); private readonly _listener: IDisposable; @@ -203,24 +203,14 @@ class SimpleContextKeyChangeEvent implements IContextKeyChangeEvent { class ArrayContextKeyChangeEvent implements IContextKeyChangeEvent { constructor(readonly keys: string[]) { } affectsSome(keys: IReadableSet): boolean { - for (const key of this.keys) { - if (keys.has(key)) { - return true; - } - } - return false; + return this.keys.some(key => keys.has(key)); } } class CompositeContextKeyChangeEvent implements IContextKeyChangeEvent { constructor(readonly events: IContextKeyChangeEvent[]) { } affectsSome(keys: IReadableSet): boolean { - for (const e of this.events) { - if (e.affectsSome(keys)) { - return true; - } - } - return false; + return this.events.some(e => e.affectsSome(keys)); } } diff --git a/src/vs/platform/contextkey/common/contextkey.ts b/src/vs/platform/contextkey/common/contextkey.ts index 16e79df476f..ed418e1d89f 100644 --- a/src/vs/platform/contextkey/common/contextkey.ts +++ b/src/vs/platform/contextkey/common/contextkey.ts @@ -6,6 +6,7 @@ import { Event } from 'vs/base/common/event'; import { isFalsyOrWhitespace } from 'vs/base/common/strings'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { equals } from 'vs/base/common/arrays'; export const enum ContextKeyExprType { Defined = 1, @@ -574,15 +575,7 @@ export class ContextKeyAndExpr implements ContextKeyExpr { public equals(other: ContextKeyExpr): boolean { if (other instanceof ContextKeyAndExpr) { - if (this.expr.length !== other.expr.length) { - return false; - } - for (let i = 0, len = this.expr.length; i < len; i++) { - if (!this.expr[i].equals(other.expr[i])) { - return false; - } - } - return true; + return equals(this.expr, other.expr, (a, b) => a.equals(b)); } return false; } @@ -674,15 +667,7 @@ export class ContextKeyOrExpr implements ContextKeyExpr { public equals(other: ContextKeyExpr): boolean { if (other instanceof ContextKeyOrExpr) { - if (this.expr.length !== other.expr.length) { - return false; - } - for (let i = 0, len = this.expr.length; i < len; i++) { - if (!this.expr[i].equals(other.expr[i])) { - return false; - } - } - return true; + return equals(this.expr, other.expr, (a, b) => a.equals(b)); } return false; } diff --git a/src/vs/platform/files/node/watcher/unix/chokidarWatcherService.ts b/src/vs/platform/files/node/watcher/unix/chokidarWatcherService.ts index d129ec844a9..3fff232b834 100644 --- a/src/vs/platform/files/node/watcher/unix/chokidarWatcherService.ts +++ b/src/vs/platform/files/node/watcher/unix/chokidarWatcherService.ts @@ -17,6 +17,7 @@ import { isMacintosh, isLinux } from 'vs/base/common/platform'; import { IDiskFileChange, normalizeFileChanges, ILogMessage } from 'vs/platform/files/node/watcher/watcher'; import { IWatcherRequest, IWatcherService, IWatcherOptions } from 'vs/platform/files/node/watcher/unix/watcher'; import { Emitter, Event } from 'vs/base/common/event'; +import { equals } from 'vs/base/common/arrays'; interface IWatcher { requests: ExtendedWatcherRequest[]; @@ -351,26 +352,10 @@ export function normalizeRoots(requests: IWatcherRequest[]): { [basePath: string return result; } -function isEqualRequests(r1: IWatcherRequest[], r2: IWatcherRequest[]) { - if (r1.length !== r2.length) { - return false; - } - for (let k = 0; k < r1.length; k++) { - if (r1[k].path !== r2[k].path || !isEqualIgnore(r1[k].excludes, r2[k].excludes)) { - return false; - } - } - return true; +function isEqualRequests(r1: readonly IWatcherRequest[], r2: readonly IWatcherRequest[]) { + return equals(r1, r2, (a, b) => a.path === b.path && isEqualIgnore(a.excludes, b.excludes)); } -function isEqualIgnore(i1: string[], i2: string[]) { - if (i1.length !== i2.length) { - return false; - } - for (let k = 0; k < i1.length; k++) { - if (i1[k] !== i2[k]) { - return false; - } - } - return true; +function isEqualIgnore(i1: readonly string[], i2: readonly string[]) { + return equals(i1, i2); } diff --git a/src/vs/platform/files/test/node/diskFileService.test.ts b/src/vs/platform/files/test/node/diskFileService.test.ts index 3f5c57ec1a8..5c69ce8fdcb 100644 --- a/src/vs/platform/files/test/node/diskFileService.test.ts +++ b/src/vs/platform/files/test/node/diskFileService.test.ts @@ -21,19 +21,13 @@ import { isLinux, isWindows } from 'vs/base/common/platform'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { isEqual } from 'vs/base/common/resources'; import { VSBuffer, VSBufferReadable, toVSBufferReadableStream, VSBufferReadableStream, bufferToReadable, bufferToStream } from 'vs/base/common/buffer'; +import { find } from 'vs/base/common/arrays'; -function getByName(root: IFileStat, name: string): IFileStat | null { +function getByName(root: IFileStat, name: string): IFileStat | undefined { if (root.children === undefined) { - return null; + return undefined; } - - for (const child of root.children) { - if (child.name === name) { - return child; - } - } - - return null; + return find(root.children, child => child.name === name); } function toLineByLineReadable(content: string): VSBufferReadable { diff --git a/src/vs/platform/instantiation/common/instantiationService.ts b/src/vs/platform/instantiation/common/instantiationService.ts index 5345229bdc1..44be0d24797 100644 --- a/src/vs/platform/instantiation/common/instantiationService.ts +++ b/src/vs/platform/instantiation/common/instantiationService.ts @@ -219,13 +219,23 @@ export class InstantiationService implements IInstantiationService { // Return a proxy object that's backed by an idle value. That // strategy is to instantiate services in our idle time or when actually // needed but not when injected into a consumer - const idle = new IdleValue(() => this._createInstance(ctor, args, _trace)); + const idle = new IdleValue(() => this._createInstance(ctor, args, _trace)); return new Proxy(Object.create(null), { - get(_target: T, prop: PropertyKey): any { - return (idle.getValue() as any)[prop]; + get(target: any, key: PropertyKey): any { + if (key in target) { + return target[key]; + } + let obj = idle.getValue(); + let prop = obj[key]; + if (typeof prop !== 'function') { + return prop; + } + prop = prop.bind(obj); + target[key] = prop; + return prop; }, set(_target: T, p: PropertyKey, value: any): boolean { - (idle.getValue() as any)[p] = value; + idle.getValue()[p] = value; return true; } }); @@ -241,7 +251,7 @@ const enum TraceType { class Trace { - private static _None = new class extends Trace { + private static readonly _None = new class extends Trace { constructor() { super(-1, null); } stop() { } branch() { return this; } diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index e70bf539f65..c0a6c5b2c0d 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -881,9 +881,9 @@ export class WorkbenchAsyncDataTree extends Async ) { const { options: treeOptions, getAutomaticKeyboardNavigation, disposable } = workbenchTreeDataPreamble(container, options, contextKeyService, themeService, configurationService, keybindingService, accessibilityService); super(user, container, delegate, renderers, dataSource, treeOptions); - this.disposables.push(disposable); + this.disposables.add(disposable); this.internals = new WorkbenchTreeInternals(this, treeOptions, getAutomaticKeyboardNavigation, contextKeyService, listService, themeService, configurationService, accessibilityService); - this.disposables.push(this.internals); + this.disposables.add(this.internals); } } @@ -910,9 +910,9 @@ export class WorkbenchCompressibleAsyncDataTree e ) { const { options: treeOptions, getAutomaticKeyboardNavigation, disposable } = workbenchTreeDataPreamble(container, options, contextKeyService, themeService, configurationService, keybindingService, accessibilityService); super(user, container, virtualDelegate, compressionDelegate, renderers, dataSource, treeOptions); - this.disposables.push(disposable); + this.disposables.add(disposable); this.internals = new WorkbenchTreeInternals(this, treeOptions, getAutomaticKeyboardNavigation, contextKeyService, listService, themeService, configurationService, accessibilityService); - this.disposables.push(this.internals); + this.disposables.add(this.internals); } } diff --git a/src/vs/platform/severityIcon/common/severityIcon.ts b/src/vs/platform/severityIcon/common/severityIcon.ts index 52eae1a08cc..946313a389e 100644 --- a/src/vs/platform/severityIcon/common/severityIcon.ts +++ b/src/vs/platform/severityIcon/common/severityIcon.ts @@ -4,70 +4,57 @@ *--------------------------------------------------------------------------------------------*/ import Severity from 'vs/base/common/severity'; -import { registerThemingParticipant, ITheme, LIGHT } from 'vs/platform/theme/common/themeService'; -import { Color } from 'vs/base/common/color'; - -const errorStart = encodeURIComponent(``); -const errorDarkStart = encodeURIComponent(``); - -const warningStart = encodeURIComponent(``); -const warningDarkStart = encodeURIComponent(``); - -const infoStart = encodeURIComponent(``); -const infoDarkStart = encodeURIComponent(``); +import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { problemsErrorIconForeground, problemsInfoIconForeground, problemsWarningIconForeground } from 'vs/platform/theme/common/colorRegistry'; export namespace SeverityIcon { - export function getSVGData(severity: Severity, theme: ITheme): string { - switch (severity) { - case Severity.Ignore: - const ignoreColor = theme.type === LIGHT ? Color.fromHex('#75BEFF') : Color.fromHex('#007ACC'); - return theme.type === LIGHT ? infoStart + encodeURIComponent(ignoreColor.toString()) + infoEnd - : infoDarkStart + encodeURIComponent(ignoreColor.toString()) + infoDarkEnd; - case Severity.Info: - const infoColor = theme.type === LIGHT ? Color.fromHex('#007ACC') : Color.fromHex('#75BEFF'); - return theme.type === LIGHT ? infoStart + encodeURIComponent(infoColor.toString()) + infoEnd - : infoDarkStart + encodeURIComponent(infoColor.toString()) + infoDarkEnd; - case Severity.Warning: - const warningColor = theme.type === LIGHT ? Color.fromHex('#DDB100') : Color.fromHex('#fc0'); - return theme.type === LIGHT ? warningStart + encodeURIComponent(warningColor.toString()) + warningEnd - : warningDarkStart + encodeURIComponent(warningColor.toString()) + warningDarkEnd; - case Severity.Error: - const errorColor = theme.type === LIGHT ? Color.fromHex('#A1260D') : Color.fromHex('#F48771'); - return theme.type === LIGHT ? errorStart + encodeURIComponent(errorColor.toString()) + errorEnd - : errorDarkStart + encodeURIComponent(errorColor.toString()) + errorDarkEnd; - } - return ''; - } - export function className(severity: Severity): string { switch (severity) { case Severity.Ignore: - return 'severity-icon severity-ignore'; + return 'severity-ignore codicon-info'; case Severity.Info: - return 'severity-icon severity-info'; + return 'codicon-info'; case Severity.Warning: - return 'severity-icon severity-warning'; + return 'codicon-warning'; case Severity.Error: - return 'severity-icon severity-error'; + return 'codicon-error'; } return ''; } } -function getCSSRule(severity: Severity, theme: ITheme): string { - return `.${SeverityIcon.className(severity).split(' ').join('.')} { background: url("data:image/svg+xml,${SeverityIcon.getSVGData(severity, theme)}") center center no-repeat; height: 16px; width: 16px; }`; -} - registerThemingParticipant((theme, collector) => { - collector.addRule(getCSSRule(Severity.Error, theme)); - collector.addRule(getCSSRule(Severity.Warning, theme)); - collector.addRule(getCSSRule(Severity.Info, theme)); - collector.addRule(getCSSRule(Severity.Ignore, theme)); -}); \ No newline at end of file + + const errorIconForeground = theme.getColor(problemsErrorIconForeground); + if (errorIconForeground) { + collector.addRule(` + .monaco-workbench .zone-widget .codicon-error, + .monaco-workbench .markers-panel .marker-icon.codicon-error, + .monaco-workbench .extensions-viewlet > .extensions .codicon-error { + color: ${errorIconForeground}; + } + `); + } + + const warningIconForeground = theme.getColor(problemsWarningIconForeground); + if (errorIconForeground) { + collector.addRule(` + .monaco-workbench .zone-widget .codicon-warning, + .monaco-workbench .markers-panel .marker-icon.codicon-warning, + .monaco-workbench .extensions-viewlet > .extensions .codicon-warning { + color: ${warningIconForeground}; + } + `); + } + + const infoIconForeground = theme.getColor(problemsInfoIconForeground); + if (errorIconForeground) { + collector.addRule(` + .monaco-workbench .zone-widget .codicon-info, + .monaco-workbench .markers-panel .marker-icon.codicon-info { + color: ${infoIconForeground}; + } + `); + } +}); diff --git a/src/vs/platform/state/node/stateService.ts b/src/vs/platform/state/node/stateService.ts index 5f0a6d0cdc3..d5146ec25ac 100644 --- a/src/vs/platform/state/node/stateService.ts +++ b/src/vs/platform/state/node/stateService.ts @@ -127,7 +127,7 @@ export class StateService implements IStateService { _serviceBrand: undefined; - private static STATE_FILE = 'storage.json'; + private static readonly STATE_FILE = 'storage.json'; private fileStorage: FileStorage; diff --git a/src/vs/platform/storage/node/storageIpc.ts b/src/vs/platform/storage/node/storageIpc.ts index f74005b5ed4..b0a2b3752a5 100644 --- a/src/vs/platform/storage/node/storageIpc.ts +++ b/src/vs/platform/storage/node/storageIpc.ts @@ -29,7 +29,7 @@ interface ISerializableItemsChangeEvent { export class GlobalStorageDatabaseChannel extends Disposable implements IServerChannel { - private static STORAGE_CHANGE_DEBOUNCE_TIME = 100; + private static readonly STORAGE_CHANGE_DEBOUNCE_TIME = 100; private readonly _onDidChangeItems: Emitter = this._register(new Emitter()); readonly onDidChangeItems: Event = this._onDidChangeItems.event; diff --git a/src/vs/platform/storage/node/storageMainService.ts b/src/vs/platform/storage/node/storageMainService.ts index 70cdeef730d..81c9511a239 100644 --- a/src/vs/platform/storage/node/storageMainService.ts +++ b/src/vs/platform/storage/node/storageMainService.ts @@ -87,7 +87,7 @@ export class StorageMainService extends Disposable implements IStorageMainServic _serviceBrand: undefined; - private static STORAGE_NAME = 'state.vscdb'; + private static readonly STORAGE_NAME = 'state.vscdb'; private readonly _onDidChangeStorage: Emitter = this._register(new Emitter()); readonly onDidChangeStorage: Event = this._onDidChangeStorage.event; diff --git a/src/vs/platform/storage/node/storageService.ts b/src/vs/platform/storage/node/storageService.ts index bd4bbd98a22..bdd7b454af1 100644 --- a/src/vs/platform/storage/node/storageService.ts +++ b/src/vs/platform/storage/node/storageService.ts @@ -21,8 +21,8 @@ export class NativeStorageService extends Disposable implements IStorageService _serviceBrand: undefined; - private static WORKSPACE_STORAGE_NAME = 'state.vscdb'; - private static WORKSPACE_META_NAME = 'workspace.json'; + private static readonly WORKSPACE_STORAGE_NAME = 'state.vscdb'; + private static readonly WORKSPACE_META_NAME = 'workspace.json'; private readonly _onDidChangeStorage: Emitter = this._register(new Emitter()); readonly onDidChangeStorage: Event = this._onDidChangeStorage.event; diff --git a/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts b/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts index ac0da4361f7..d70af9beefb 100644 --- a/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts +++ b/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts @@ -13,8 +13,16 @@ export const lastSessionDateStorageKey = 'telemetry.lastSessionDate'; import * as Platform from 'vs/base/common/platform'; import * as uuid from 'vs/base/common/uuid'; import { cleanRemoteAuthority } from 'vs/platform/telemetry/common/telemetryUtils'; +import { mixin } from 'vs/base/common/objects'; -export async function resolveWorkbenchCommonProperties(storageService: IStorageService, commit: string | undefined, version: string | undefined, machineId: string, remoteAuthority?: string): Promise<{ [name: string]: string | undefined }> { +export async function resolveWorkbenchCommonProperties( + storageService: IStorageService, + commit: string | undefined, + version: string | undefined, + machineId: string, + remoteAuthority?: string, + resolveAdditionalProperties?: () => { [key: string]: any } +): Promise<{ [name: string]: string | undefined }> { const result: { [name: string]: string | undefined; } = Object.create(null); const firstSessionDate = storageService.get(firstSessionDateStorageKey, StorageScope.GLOBAL)!; const lastSessionDate = storageService.get(lastSessionDateStorageKey, StorageScope.GLOBAL)!; @@ -68,6 +76,10 @@ export async function resolveWorkbenchCommonProperties(storageService: IStorageS } }); + if (resolveAdditionalProperties) { + mixin(result, resolveAdditionalProperties()); + } + return result; } diff --git a/src/vs/platform/telemetry/common/telemetryService.ts b/src/vs/platform/telemetry/common/telemetryService.ts index 1e468a2018d..8e64e8e045a 100644 --- a/src/vs/platform/telemetry/common/telemetryService.ts +++ b/src/vs/platform/telemetry/common/telemetryService.ts @@ -24,8 +24,8 @@ export interface ITelemetryServiceConfig { export class TelemetryService implements ITelemetryService { - static IDLE_START_EVENT_NAME = 'UserIdleStart'; - static IDLE_STOP_EVENT_NAME = 'UserIdleStop'; + static readonly IDLE_START_EVENT_NAME = 'UserIdleStart'; + static readonly IDLE_STOP_EVENT_NAME = 'UserIdleStop'; _serviceBrand: undefined; diff --git a/src/vs/platform/telemetry/node/commonProperties.ts b/src/vs/platform/telemetry/node/commonProperties.ts index 4d5c2cfd1b7..567bc8e9db8 100644 --- a/src/vs/platform/telemetry/node/commonProperties.ts +++ b/src/vs/platform/telemetry/node/commonProperties.ts @@ -7,7 +7,6 @@ import * as Platform from 'vs/base/common/platform'; import * as os from 'os'; import * as uuid from 'vs/base/common/uuid'; import { readFile } from 'vs/base/node/pfs'; -import { mixin } from 'vs/base/common/objects'; export async function resolveCommonProperties( commit: string | undefined, @@ -15,8 +14,7 @@ export async function resolveCommonProperties( machineId: string | undefined, msftInternalDomains: string[] | undefined, installSourcePath: string, - product?: string, - resolveAdditionalProperties?: () => { [key: string]: any } + product?: string ): Promise<{ [name: string]: string | boolean | undefined; }> { const result: { [name: string]: string | boolean | undefined; } = Object.create(null); @@ -80,24 +78,14 @@ export async function resolveCommonProperties( // ignore error } - if (resolveAdditionalProperties) { - mixin(result, resolveAdditionalProperties()); - } - return result; } -function verifyMicrosoftInternalDomain(domainList: string[]): boolean { +function verifyMicrosoftInternalDomain(domainList: readonly string[]): boolean { if (!process || !process.env || !process.env['USERDNSDOMAIN']) { return false; } const domain = process.env['USERDNSDOMAIN']!.toLowerCase(); - for (let msftDomain of domainList) { - if (domain === msftDomain) { - return true; - } - } - - return false; + return domainList.some(msftDomain => domain === msftDomain); } diff --git a/src/vs/platform/telemetry/node/workbenchCommonProperties.ts b/src/vs/platform/telemetry/node/workbenchCommonProperties.ts index 637090a6896..41b8fffcfc4 100644 --- a/src/vs/platform/telemetry/node/workbenchCommonProperties.ts +++ b/src/vs/platform/telemetry/node/workbenchCommonProperties.ts @@ -15,10 +15,9 @@ export async function resolveWorkbenchCommonProperties( machineId: string, msftInternalDomains: string[] | undefined, installSourcePath: string, - remoteAuthority?: string, - resolveAdditionalProperties?: () => { [key: string]: any } + remoteAuthority?: string ): Promise<{ [name: string]: string | boolean | undefined }> { - const result = await resolveCommonProperties(commit, version, machineId, msftInternalDomains, installSourcePath, undefined, resolveAdditionalProperties); + const result = await resolveCommonProperties(commit, version, machineId, msftInternalDomains, installSourcePath, undefined); const instanceId = storageService.get(instanceStorageKey, StorageScope.GLOBAL)!; const firstSessionDate = storageService.get(firstSessionDateStorageKey, StorageScope.GLOBAL)!; const lastSessionDate = storageService.get(lastSessionDateStorageKey, StorageScope.GLOBAL)!; diff --git a/src/vs/platform/telemetry/test/browser/commonProperties.test.ts b/src/vs/platform/telemetry/test/browser/commonProperties.test.ts new file mode 100644 index 00000000000..6355efaaac4 --- /dev/null +++ b/src/vs/platform/telemetry/test/browser/commonProperties.test.ts @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/browser/workbenchCommonProperties'; +import { IStorageService, InMemoryStorageService } from 'vs/platform/storage/common/storage'; + +suite('Browser Telemetry - common properties', function () { + + const commit: string = (undefined)!; + const version: string = (undefined)!; + let testStorageService: IStorageService; + + setup(() => { + testStorageService = new InMemoryStorageService(); + }); + + test('mixes in additional properties', async function () { + const resolveCommonTelemetryProperties = () => { + return { + 'userId': '1' + }; + }; + + const props = await resolveWorkbenchCommonProperties(testStorageService, commit, version, 'someMachineId', undefined, resolveCommonTelemetryProperties); + + assert.ok('commitHash' in props); + assert.ok('sessionID' in props); + assert.ok('timestamp' in props); + assert.ok('common.platform' in props); + assert.ok('common.timesincesessionstart' in props); + assert.ok('common.sequence' in props); + assert.ok('version' in props); + assert.ok('common.firstSessionDate' in props, 'firstSessionDate'); + assert.ok('common.lastSessionDate' in props, 'lastSessionDate'); + assert.ok('common.isNewSession' in props, 'isNewSession'); + assert.ok('common.machineId' in props, 'machineId'); + + assert.equal(props['userId'], '1'); + }); + + test('mixes in additional dyanmic properties', async function () { + let i = 1; + const resolveCommonTelemetryProperties = () => { + return Object.defineProperties({}, { + 'userId': { + get: () => { + return i++; + }, + enumerable: true + } + }); + }; + + const props = await resolveWorkbenchCommonProperties(testStorageService, commit, version, 'someMachineId', undefined, resolveCommonTelemetryProperties); + assert.equal(props['userId'], '1'); + + const props2 = await resolveWorkbenchCommonProperties(testStorageService, commit, version, 'someMachineId', undefined, resolveCommonTelemetryProperties); + assert.equal(props2['userId'], '2'); + }); +}); diff --git a/src/vs/platform/telemetry/test/electron-browser/commonProperties.test.ts b/src/vs/platform/telemetry/test/electron-browser/commonProperties.test.ts index 138cd35a1fa..ee49c04ba3f 100644 --- a/src/vs/platform/telemetry/test/electron-browser/commonProperties.test.ts +++ b/src/vs/platform/telemetry/test/electron-browser/commonProperties.test.ts @@ -81,52 +81,4 @@ suite('Telemetry - common properties', function () { value2 = props['common.timesincesessionstart']; assert.ok(value1 !== value2, 'timesincesessionstart'); }); - - test('mixes in additional properties', async function () { - const resolveCommonTelemetryProperties = () => { - return { - 'userId': '1' - }; - }; - - const props = await resolveWorkbenchCommonProperties(testStorageService, commit, version, 'someMachineId', undefined, installSource, undefined, resolveCommonTelemetryProperties); - - assert.ok('commitHash' in props); - assert.ok('sessionID' in props); - assert.ok('timestamp' in props); - assert.ok('common.platform' in props); - assert.ok('common.nodePlatform' in props); - assert.ok('common.nodeArch' in props); - assert.ok('common.timesincesessionstart' in props); - assert.ok('common.sequence' in props); - assert.ok('common.platformVersion' in props, 'platformVersion'); - assert.ok('version' in props); - assert.ok('common.firstSessionDate' in props, 'firstSessionDate'); - assert.ok('common.lastSessionDate' in props, 'lastSessionDate'); - assert.ok('common.isNewSession' in props, 'isNewSession'); - assert.ok('common.instanceId' in props, 'instanceId'); - assert.ok('common.machineId' in props, 'machineId'); - - assert.equal(props['userId'], '1'); - }); - - test('mixes in additional dyanmic properties', async function () { - let i = 1; - const resolveCommonTelemetryProperties = () => { - return Object.defineProperties({}, { - 'userId': { - get: () => { - return i++; - }, - enumerable: true - } - }); - }; - - const props = await resolveWorkbenchCommonProperties(testStorageService, commit, version, 'someMachineId', undefined, installSource, undefined, resolveCommonTelemetryProperties); - assert.equal(props['userId'], '1'); - - const props2 = await resolveWorkbenchCommonProperties(testStorageService, commit, version, 'someMachineId', undefined, installSource, undefined, resolveCommonTelemetryProperties); - assert.equal(props2['userId'], '2'); - }); }); diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index fe1403f4ede..6d8af22abb9 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -406,6 +406,9 @@ export const overviewRulerSelectionHighlightForeground = registerColor('editorOv export const minimapFindMatch = registerColor('minimap.findMatchHighlight', { light: '#d18616', dark: '#d18616', hc: '#AB5A00' }, nls.localize('minimapFindMatchHighlight', 'Minimap marker color for find matches.'), true); export const minimapSelection = registerColor('minimap.selectionHighlight', { light: '#ADD6FF', dark: '#264F78', hc: '#ffffff' }, nls.localize('minimapSelectionHighlight', 'Minimap marker color for the editor selection.'), true); +export const problemsErrorIconForeground = registerColor('problemsErrorIcon.foreground', { dark: editorErrorForeground, light: editorErrorForeground, hc: editorErrorForeground }, nls.localize('problemsErrorIconForeground', "The color used for the problems error icon.")); +export const problemsWarningIconForeground = registerColor('problemsWarningIcon.foreground', { dark: editorWarningForeground, light: editorWarningForeground, hc: editorWarningForeground }, nls.localize('problemsWarningIconForeground', "The color used for the problems warning icon.")); +export const problemsInfoIconForeground = registerColor('problemsInfoIcon.foreground', { dark: editorInfoForeground, light: editorInfoForeground, hc: editorInfoForeground }, nls.localize('problemsInfoIconForeground', "The color used for the problems info icon.")); // ----- color functions diff --git a/src/vs/platform/update/electron-main/updateService.darwin.ts b/src/vs/platform/update/electron-main/updateService.darwin.ts index cd73a5cd95a..d25c577b66e 100644 --- a/src/vs/platform/update/electron-main/updateService.darwin.ts +++ b/src/vs/platform/update/electron-main/updateService.darwin.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as electron from 'electron'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { Event } from 'vs/base/common/event'; import { memoize } from 'vs/base/common/decorators'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -20,7 +20,7 @@ export class DarwinUpdateService extends AbstractUpdateService { _serviceBrand: undefined; - private disposables: IDisposable[] = []; + private readonly disposables = new DisposableStore(); @memoize private get onRawError(): Event { return Event.fromNodeEventEmitter(electron.autoUpdater, 'error', (_, message) => message); } @memoize private get onRawUpdateNotAvailable(): Event { return Event.fromNodeEventEmitter(electron.autoUpdater, 'update-not-available'); } @@ -104,6 +104,6 @@ export class DarwinUpdateService extends AbstractUpdateService { } dispose(): void { - this.disposables = dispose(this.disposables); + this.disposables.dispose(); } } diff --git a/src/vs/platform/workspaces/common/workspaces.ts b/src/vs/platform/workspaces/common/workspaces.ts index 974a8c87527..3c09c3a7259 100644 --- a/src/vs/platform/workspaces/common/workspaces.ts +++ b/src/vs/platform/workspaces/common/workspaces.ts @@ -294,12 +294,7 @@ function doParseStoredWorkspace(path: URI, contents: string): IStoredWorkspace { export function useSlashForPath(storedFolders: IStoredWorkspaceFolder[]): boolean { if (isWindows) { - for (const folder of storedFolders) { - if (isRawFileWorkspaceFolder(folder) && folder.path.indexOf(SLASH) >= 0) { - return true; - } - } - return false; + return storedFolders.some(folder => isRawFileWorkspaceFolder(folder) && folder.path.indexOf(SLASH) >= 0); } return true; } diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 99ddb4674fd..93afe709fbb 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -59,15 +59,15 @@ declare module 'vscode' { } export class CallHierarchyIncomingCall { - source: CallHierarchyItem; - sourceRanges: Range[]; - constructor(item: CallHierarchyItem, sourceRanges: Range[]); + from: CallHierarchyItem; + fromRanges: Range[]; + constructor(item: CallHierarchyItem, fromRanges: Range[]); } export class CallHierarchyOutgoingCall { - sourceRanges: Range[]; - target: CallHierarchyItem; - constructor(item: CallHierarchyItem, sourceRanges: Range[]); + fromRanges: Range[]; + to: CallHierarchyItem; + constructor(item: CallHierarchyItem, fromRanges: Range[]); } export interface CallHierarchyItemProvider { diff --git a/src/vs/workbench/api/browser/mainThreadEditor.ts b/src/vs/workbench/api/browser/mainThreadEditor.ts index 520801babe6..239f87096f1 100644 --- a/src/vs/workbench/api/browser/mainThreadEditor.ts +++ b/src/vs/workbench/api/browser/mainThreadEditor.ts @@ -16,6 +16,7 @@ import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2 import { IApplyEditsOptions, IEditorPropertiesChangeData, IResolvedTextEditorConfiguration, ITextEditorConfigurationUpdate, IUndoStopOptions, TextEditorRevealType } from 'vs/workbench/api/common/extHost.protocol'; import { IEditor } from 'vs/workbench/common/editor'; import { withNullAsUndefined } from 'vs/base/common/types'; +import { equals } from 'vs/base/common/arrays'; export interface IFocusTracker { onGainedFocus(): void; @@ -124,28 +125,12 @@ export class MainThreadTextEditorProperties { return null; } - private static _selectionsEqual(a: Selection[], b: Selection[]): boolean { - if (a.length !== b.length) { - return false; - } - for (let i = 0; i < a.length; i++) { - if (!a[i].equalsSelection(b[i])) { - return false; - } - } - return true; + private static _selectionsEqual(a: readonly Selection[], b: readonly Selection[]): boolean { + return equals(a, b, (aValue, bValue) => aValue.equalsSelection(bValue)); } - private static _rangesEqual(a: Range[], b: Range[]): boolean { - if (a.length !== b.length) { - return false; - } - for (let i = 0; i < a.length; i++) { - if (!a[i].equalsRange(b[i])) { - return false; - } - } - return true; + private static _rangesEqual(a: readonly Range[], b: readonly Range[]): boolean { + return equals(a, b, (aValue, bValue) => aValue.equalsRange(bValue)); } private static _optionsEqual(a: IResolvedTextEditorConfiguration, b: IResolvedTextEditorConfiguration): boolean { diff --git a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts index 0ea4d540b11..05bc4303f3e 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts @@ -499,10 +499,10 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha if (!outgoing) { return outgoing; } - return outgoing.map(([item, sourceRanges]): callh.OutgoingCall => { + return outgoing.map(([item, fromRanges]): callh.OutgoingCall => { return { - target: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(item), - sourceRanges + to: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(item), + fromRanges }; }); }, @@ -511,10 +511,10 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha if (!incoming) { return incoming; } - return incoming.map(([item, sourceRanges]): callh.IncomingCall => { + return incoming.map(([item, fromRanges]): callh.IncomingCall => { return { - source: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(item), - sourceRanges + from: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(item), + fromRanges }; }); } diff --git a/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts b/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts index c849ba99630..9bf1db3fe1c 100644 --- a/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts +++ b/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts @@ -50,7 +50,7 @@ class TrimWhitespaceParticipant implements ISaveParticipantParticipant { // Nothing } - async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise { if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { this.doTrimTrailingWhitespace(model.textEditorModel, env.reason === SaveReason.AUTO); } @@ -112,7 +112,7 @@ export class FinalNewLineParticipant implements ISaveParticipantParticipant { // Nothing } - async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise { if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { this.doInsertFinalNewLine(model.textEditorModel); } @@ -146,7 +146,7 @@ export class TrimFinalNewLinesParticipant implements ISaveParticipantParticipant // Nothing } - async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise { if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { this.doTrimFinalNewLines(model.textEditorModel, env.reason === SaveReason.AUTO); } @@ -216,7 +216,7 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant { // Nothing } - async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise { const model = editorModel.textEditorModel; const overrides = { overrideIdentifier: model.getLanguageIdentifier().language, resource: model.uri }; @@ -250,7 +250,7 @@ class CodeActionOnSaveParticipant implements ISaveParticipant { @IInstantiationService private readonly _instantiationService: IInstantiationService, ) { } - async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise { if (env.reason === SaveReason.AUTO) { return undefined; } @@ -333,7 +333,7 @@ class ExtHostSaveParticipant implements ISaveParticipantParticipant { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocumentSaveParticipant); } - async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise { if (!shouldSynchronizeModel(editorModel.textEditorModel)) { // the model never made it to the extension @@ -344,10 +344,8 @@ class ExtHostSaveParticipant implements ISaveParticipantParticipant { return new Promise((resolve, reject) => { setTimeout(() => reject(localize('timeout.onWillSave', "Aborted onWillSaveTextDocument-event after 1750ms")), 1750); this._proxy.$participateInSave(editorModel.getResource(), env.reason).then(values => { - for (const success of values) { - if (!success) { - return Promise.reject(new Error('listener failed')); - } + if (!values.every(success => success)) { + return Promise.reject(new Error('listener failed')); } return undefined; }).then(resolve, reject); @@ -384,7 +382,7 @@ export class SaveParticipant implements ISaveParticipant { this._saveParticipants.dispose(); } - async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise { return this._progressService.withProgress({ location: ProgressLocation.Window }, progress => { progress.report({ message: localize('saveParticipants', "Running Save Participants...") }); const promiseFactory = this._saveParticipants.getValue().map(p => () => { diff --git a/src/vs/workbench/api/common/apiCommands.ts b/src/vs/workbench/api/common/apiCommands.ts index a1f752a77a0..01581c2c7c2 100644 --- a/src/vs/workbench/api/common/apiCommands.ts +++ b/src/vs/workbench/api/common/apiCommands.ts @@ -39,7 +39,7 @@ interface IOpenFolderAPICommandOptions { } export class OpenFolderAPICommand { - public static ID = 'vscode.openFolder'; + public static readonly ID = 'vscode.openFolder'; public static execute(executor: ICommandsExecutor, uri?: URI, forceNewWindow?: boolean): Promise; public static execute(executor: ICommandsExecutor, uri?: URI, options?: IOpenFolderAPICommandOptions): Promise; public static execute(executor: ICommandsExecutor, uri?: URI, arg: boolean | IOpenFolderAPICommandOptions = {}): Promise { @@ -73,7 +73,7 @@ interface INewWindowAPICommandOptions { } export class NewWindowAPICommand { - public static ID = 'vscode.newWindow'; + public static readonly ID = 'vscode.newWindow'; public static execute(executor: ICommandsExecutor, options?: INewWindowAPICommandOptions): Promise { const commandOptions: IOpenEmptyWindowOptions = { forceReuseWindow: options && options.reuseWindow, @@ -94,7 +94,7 @@ CommandsRegistry.registerCommand({ }); export class DiffAPICommand { - public static ID = 'vscode.diff'; + public static readonly ID = 'vscode.diff'; public static execute(executor: ICommandsExecutor, left: URI, right: URI, label: string, options?: vscode.TextDocumentShowOptions): Promise { return executor.executeCommand('_workbench.diff', [ left, right, @@ -108,7 +108,7 @@ export class DiffAPICommand { CommandsRegistry.registerCommand(DiffAPICommand.ID, adjustHandler(DiffAPICommand.execute)); export class OpenAPICommand { - public static ID = 'vscode.open'; + public static readonly ID = 'vscode.open'; public static execute(executor: ICommandsExecutor, resource: URI, columnOrOptions?: vscode.ViewColumn | vscode.TextDocumentShowOptions, label?: string): Promise { let options: ITextEditorOptions | undefined; let position: EditorViewColumn | undefined; @@ -138,7 +138,7 @@ CommandsRegistry.registerCommand('_workbench.removeFromRecentlyOpened', function }); export class RemoveFromRecentlyOpenedAPICommand { - public static ID = 'vscode.removeFromRecentlyOpened'; + public static readonly ID = 'vscode.removeFromRecentlyOpened'; public static execute(executor: ICommandsExecutor, path: string | URI): Promise { if (typeof path === 'string') { path = path.match(/^[^:/?#]+:\/\//) ? URI.parse(path) : URI.file(path); @@ -151,7 +151,7 @@ export class RemoveFromRecentlyOpenedAPICommand { CommandsRegistry.registerCommand(RemoveFromRecentlyOpenedAPICommand.ID, adjustHandler(RemoveFromRecentlyOpenedAPICommand.execute)); export class OpenIssueReporter { - public static ID = 'vscode.openIssueReporter'; + public static readonly ID = 'vscode.openIssueReporter'; public static execute(executor: ICommandsExecutor, extensionId: string): Promise { return executor.executeCommand('workbench.action.openIssueReporter', [extensionId]); } @@ -185,7 +185,7 @@ CommandsRegistry.registerCommand('_workbench.getRecentlyOpened', async function }); export class SetEditorLayoutAPICommand { - public static ID = 'vscode.setEditorLayout'; + public static readonly ID = 'vscode.setEditorLayout'; public static execute(executor: ICommandsExecutor, layout: EditorGroupLayout): Promise { return executor.executeCommand('layoutEditorGroups', layout); } diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index 1cf22a6fad6..ebe9352c103 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { URI } from 'vs/base/common/uri'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import * as vscode from 'vscode'; import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import * as types from 'vs/workbench/api/common/extHostTypes'; @@ -27,7 +27,7 @@ export class ExtHostApiCommands { } private _commands: ExtHostCommands; - private _disposables: IDisposable[] = []; + private readonly _disposables = new DisposableStore(); private constructor(commands: ExtHostCommands) { this._commands = commands; @@ -288,7 +288,7 @@ export class ExtHostApiCommands { private _register(id: string, handler: (...args: any[]) => any, description?: ICommandHandlerDescription): void { const disposable = this._commands.registerCommand(false, id, handler, this, description); - this._disposables.push(disposable); + this._disposables.add(disposable); } /** @@ -576,30 +576,30 @@ export class ExtHostApiCommands { private async _executeCallHierarchyIncomingCallsProvider(resource: URI, position: types.Position): Promise { type IncomingCallDto = { - source: ICallHierarchyItemDto; - sourceRanges: IRange[]; + from: ICallHierarchyItemDto; + fromRanges: IRange[]; }; const args = { resource, position: typeConverters.Position.from(position) }; const calls = await this._commands.executeCommand('_executeCallHierarchyIncomingCalls', args); const result: vscode.CallHierarchyIncomingCall[] = []; for (const call of calls) { - result.push(new types.CallHierarchyIncomingCall(typeConverters.CallHierarchyItem.to(call.source), call.sourceRanges.map(typeConverters.Range.to))); + result.push(new types.CallHierarchyIncomingCall(typeConverters.CallHierarchyItem.to(call.from), call.fromRanges.map(typeConverters.Range.to))); } return result; } private async _executeCallHierarchyOutgoingCallsProvider(resource: URI, position: types.Position): Promise { type OutgoingCallDto = { - sourceRanges: IRange[]; - target: ICallHierarchyItemDto; + fromRanges: IRange[]; + to: ICallHierarchyItemDto; }; const args = { resource, position: typeConverters.Position.from(position) }; const calls = await this._commands.executeCommand('_executeCallHierarchyOutgoingCalls', args); const result: vscode.CallHierarchyOutgoingCall[] = []; for (const call of calls) { - result.push(new types.CallHierarchyOutgoingCall(typeConverters.CallHierarchyItem.to(call.target), call.sourceRanges.map(typeConverters.Range.to))); + result.push(new types.CallHierarchyOutgoingCall(typeConverters.CallHierarchyItem.to(call.to), call.fromRanges.map(typeConverters.Range.to))); } return result; } diff --git a/src/vs/workbench/api/common/extHostDocumentData.ts b/src/vs/workbench/api/common/extHostDocumentData.ts index b44527a2b51..3a166503923 100644 --- a/src/vs/workbench/api/common/extHostDocumentData.ts +++ b/src/vs/workbench/api/common/extHostDocumentData.ts @@ -12,6 +12,7 @@ import { ensureValidWordDefinition, getWordAtText } from 'vs/editor/common/model import { MainThreadDocumentsShape } from 'vs/workbench/api/common/extHost.protocol'; import { EndOfLine, Position, Range } from 'vs/workbench/api/common/extHostTypes'; import * as vscode from 'vscode'; +import { equals } from 'vs/base/common/arrays'; const _modeId2WordDefinition = new Map(); export function setWordDefinitionFor(modeId: string, wordDefinition: RegExp | undefined): void { @@ -48,17 +49,8 @@ export class ExtHostDocumentData extends MirrorTextModel { this._isDirty = false; } - equalLines(lines: string[]): boolean { - const len = lines.length; - if (len !== this._lines.length) { - return false; - } - for (let i = 0; i < len; i++) { - if (lines[i] !== this._lines[i]) { - return false; - } - } - return true; + equalLines(lines: readonly string[]): boolean { + return equals(this._lines, lines); } get document(): vscode.TextDocument { diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index 94636f78be5..df94581ec5d 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -1021,7 +1021,7 @@ class CallHierarchyAdapter { if (!calls) { return undefined; } - return calls.map(call => (<[extHostProtocol.ICallHierarchyItemDto, IRange[]]>[typeConvert.CallHierarchyItem.from(call.source), call.sourceRanges.map(typeConvert.Range.from)])); + return calls.map(call => (<[extHostProtocol.ICallHierarchyItemDto, IRange[]]>[typeConvert.CallHierarchyItem.from(call.from), call.fromRanges.map(typeConvert.Range.from)])); } async provideCallsFrom(uri: URI, position: IPosition, token: CancellationToken): Promise<[extHostProtocol.ICallHierarchyItemDto, IRange[]][] | undefined> { @@ -1031,7 +1031,7 @@ class CallHierarchyAdapter { if (!calls) { return undefined; } - return calls.map(call => (<[extHostProtocol.ICallHierarchyItemDto, IRange[]]>[typeConvert.CallHierarchyItem.from(call.target), call.sourceRanges.map(typeConvert.Range.from)])); + return calls.map(call => (<[extHostProtocol.ICallHierarchyItemDto, IRange[]]>[typeConvert.CallHierarchyItem.from(call.to), call.fromRanges.map(typeConvert.Range.from)])); } } diff --git a/src/vs/workbench/api/common/extHostSCM.ts b/src/vs/workbench/api/common/extHostSCM.ts index 769d90c8d17..6bc3d01ff2c 100644 --- a/src/vs/workbench/api/common/extHostSCM.ts +++ b/src/vs/workbench/api/common/extHostSCM.ts @@ -10,7 +10,7 @@ import { DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; import { asPromise } from 'vs/base/common/async'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { MainContext, MainThreadSCMShape, SCMRawResource, SCMRawResourceSplice, SCMRawResourceSplices, IMainContext, ExtHostSCMShape, ICommandDto } from './extHost.protocol'; -import { sortedDiff } from 'vs/base/common/arrays'; +import { sortedDiff, equals } from 'vs/base/common/arrays'; import { comparePaths } from 'vs/base/common/comparers'; import * as vscode from 'vscode'; import { ISplice } from 'vs/base/common/sequence'; @@ -126,18 +126,8 @@ function commandEquals(a: vscode.Command, b: vscode.Command): boolean { && (a.arguments && b.arguments ? compareArgs(a.arguments, b.arguments) : a.arguments === b.arguments); } -function commandListEquals(a: vscode.Command[], b: vscode.Command[]): boolean { - if (a.length !== b.length) { - return false; - } - - for (let i = 0; i < a.length; i++) { - if (!commandEquals(a[i], b[i])) { - return false; - } - } - - return true; +function commandListEquals(a: readonly vscode.Command[], b: readonly vscode.Command[]): boolean { + return equals(a, b, commandEquals); } export interface IValidateInput { diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index 95dc89564a1..24b55f765df 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -166,8 +166,8 @@ interface TreeNode extends IDisposable { class ExtHostTreeView extends Disposable { - private static LABEL_HANDLE_PREFIX = '0'; - private static ID_HANDLE_PREFIX = '1'; + private static readonly LABEL_HANDLE_PREFIX = '0'; + private static readonly ID_HANDLE_PREFIX = '1'; private readonly dataProvider: vscode.TreeDataProvider; diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 28b7f5ae205..1d3a41a2f1d 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -614,12 +614,7 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit { } has(uri: URI): boolean { - for (const edit of this._edits) { - if (edit._type === 2 && edit.uri.toString() === uri.toString()) { - return true; - } - } - return false; + return this._edits.some(edit => edit._type === 2 && edit.uri.toString() === uri.toString()); } set(uri: URI, edits: TextEdit[]): void { @@ -1166,22 +1161,22 @@ export class CallHierarchyItem { export class CallHierarchyIncomingCall { - source: vscode.CallHierarchyItem; - sourceRanges: vscode.Range[]; + from: vscode.CallHierarchyItem; + fromRanges: vscode.Range[]; - constructor(item: vscode.CallHierarchyItem, sourceRanges: vscode.Range[]) { - this.sourceRanges = sourceRanges; - this.source = item; + constructor(item: vscode.CallHierarchyItem, fromRanges: vscode.Range[]) { + this.fromRanges = fromRanges; + this.from = item; } } export class CallHierarchyOutgoingCall { - target: vscode.CallHierarchyItem; - sourceRanges: vscode.Range[]; + to: vscode.CallHierarchyItem; + fromRanges: vscode.Range[]; - constructor(item: vscode.CallHierarchyItem, sourceRanges: vscode.Range[]) { - this.sourceRanges = sourceRanges; - this.target = item; + constructor(item: vscode.CallHierarchyItem, fromRanges: vscode.Range[]) { + this.fromRanges = fromRanges; + this.to = item; } } diff --git a/src/vs/workbench/api/common/extHostWebview.ts b/src/vs/workbench/api/common/extHostWebview.ts index 763f79dc5f6..6526b1361d4 100644 --- a/src/vs/workbench/api/common/extHostWebview.ts +++ b/src/vs/workbench/api/common/extHostWebview.ts @@ -18,7 +18,7 @@ import { Disposable } from './extHostTypes'; type IconPath = URI | { light: URI, dark: URI }; export class ExtHostWebview implements vscode.Webview { - private _html: string; + private _html: string = ''; private _isDisposed: boolean = false; private _hasCalledAsWebviewUri = false; diff --git a/src/vs/workbench/api/common/menusExtensionPoint.ts b/src/vs/workbench/api/common/menusExtensionPoint.ts index 0dd6facb692..3133acfba2c 100644 --- a/src/vs/workbench/api/common/menusExtensionPoint.ts +++ b/src/vs/workbench/api/common/menusExtensionPoint.ts @@ -12,7 +12,7 @@ import { IExtensionPointUser, ExtensionMessageCollector, ExtensionsRegistry } fr import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { MenuId, MenuRegistry, ILocalizedString, IMenuItem } from 'vs/platform/actions/common/actions'; import { URI } from 'vs/base/common/uri'; -import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; namespace schema { @@ -387,7 +387,7 @@ commandsExtensionPoint.setHandler(extensions => { } }); -let _menuRegistrations: IDisposable[] = []; +const _menuRegistrations = new DisposableStore(); ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyMenuItem[] }>({ extensionPoint: 'menus', @@ -395,7 +395,7 @@ ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyM }).setHandler(extensions => { // remove all previous menu registrations - _menuRegistrations = dispose(_menuRegistrations); + _menuRegistrations.clear(); for (let extension of extensions) { const { value, collector } = extension; @@ -450,7 +450,7 @@ ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyM order, when: ContextKeyExpr.deserialize(item.when) } as IMenuItem); - _menuRegistrations.push(registration); + _menuRegistrations.add(registration); } }); } diff --git a/src/vs/workbench/browser/actions.ts b/src/vs/workbench/browser/actions.ts index 6e9909e2633..2cf27b60ae6 100644 --- a/src/vs/workbench/browser/actions.ts +++ b/src/vs/workbench/browser/actions.ts @@ -57,13 +57,7 @@ export class ContributableActionProvider implements IActionProvider { const context = this.toContext(tree, element); const contributors = this.registry.getActionBarContributors(Scope.VIEWER); - for (const contributor of contributors) { - if (contributor.hasActions(context)) { - return true; - } - } - - return false; + return contributors.some(contributor => contributor.hasActions(context)); } getActions(tree: ITree, element: unknown): ReadonlyArray { diff --git a/src/vs/workbench/browser/actions/developerActions.ts b/src/vs/workbench/browser/actions/developerActions.ts index 1447d3f1b77..051b58f56ad 100644 --- a/src/vs/workbench/browser/actions/developerActions.ts +++ b/src/vs/workbench/browser/actions/developerActions.ts @@ -29,7 +29,7 @@ import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'v class InspectContextKeysAction extends Action { static readonly ID = 'workbench.action.inspectContextKeys'; - static LABEL = nls.localize('inspect context keys', "Inspect Context Keys"); + static readonly LABEL = nls.localize('inspect context keys', "Inspect Context Keys"); constructor( id: string, @@ -91,7 +91,7 @@ class InspectContextKeysAction extends Action { class ToggleScreencastModeAction extends Action { static readonly ID = 'workbench.action.toggleScreencastMode'; - static LABEL = nls.localize('toggle screencast mode', "Toggle Screencast Mode"); + static readonly LABEL = nls.localize('toggle screencast mode', "Toggle Screencast Mode"); static disposable: IDisposable | undefined; @@ -195,7 +195,7 @@ class ToggleScreencastModeAction extends Action { class LogStorageAction extends Action { static readonly ID = 'workbench.action.logStorage'; - static LABEL = nls.localize({ key: 'logStorage', comment: ['A developer only action to log the contents of the storage for the current window.'] }, "Log Storage Database Contents"); + static readonly LABEL = nls.localize({ key: 'logStorage', comment: ['A developer only action to log the contents of the storage for the current window.'] }, "Log Storage Database Contents"); constructor( id: string, diff --git a/src/vs/workbench/browser/actions/layoutActions.ts b/src/vs/workbench/browser/actions/layoutActions.ts index 05cd78e5a87..a10a3d58b9c 100644 --- a/src/vs/workbench/browser/actions/layoutActions.ts +++ b/src/vs/workbench/browser/actions/layoutActions.ts @@ -396,7 +396,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ export class ToggleMenuBarAction extends Action { static readonly ID = 'workbench.action.toggleMenuBar'; - static LABEL = nls.localize('toggleMenuBar', "Toggle Menu Bar"); + static readonly LABEL = nls.localize('toggleMenuBar', "Toggle Menu Bar"); private static readonly menuBarVisibilityKey = 'window.menuBarVisibility'; @@ -446,7 +446,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, { export abstract class BaseResizeViewAction extends Action { - protected static RESIZE_INCREMENT = 6.5; // This is a media-size percentage + protected static readonly RESIZE_INCREMENT = 6.5; // This is a media-size percentage constructor( id: string, diff --git a/src/vs/workbench/browser/actions/navigationActions.ts b/src/vs/workbench/browser/actions/navigationActions.ts index aa46d31242f..fae9742c7bf 100644 --- a/src/vs/workbench/browser/actions/navigationActions.ts +++ b/src/vs/workbench/browser/actions/navigationActions.ts @@ -94,8 +94,8 @@ abstract class BaseNavigationAction extends Action { } const activeViewletId = activeViewlet.getId(); - const value = await this.viewletService.openViewlet(activeViewletId, true); - return value === null ? false : value; + const viewlet = await this.viewletService.openViewlet(activeViewletId, true); + return !!viewlet; } protected navigateAcrossEditorGroup(direction: GroupDirection): boolean { diff --git a/src/vs/workbench/browser/actions/windowActions.ts b/src/vs/workbench/browser/actions/windowActions.ts index cb60384a583..55a96615e36 100644 --- a/src/vs/workbench/browser/actions/windowActions.ts +++ b/src/vs/workbench/browser/actions/windowActions.ts @@ -193,7 +193,7 @@ class QuickOpenRecentAction extends BaseOpenRecentAction { class ToggleFullScreenAction extends Action { static readonly ID = 'workbench.action.toggleFullScreen'; - static LABEL = nls.localize('toggleFullScreen', "Toggle Full Screen"); + static readonly LABEL = nls.localize('toggleFullScreen', "Toggle Full Screen"); constructor( id: string, @@ -211,7 +211,7 @@ class ToggleFullScreenAction extends Action { export class ReloadWindowAction extends Action { static readonly ID = 'workbench.action.reloadWindow'; - static LABEL = nls.localize('reloadWindow', "Reload Window"); + static readonly LABEL = nls.localize('reloadWindow', "Reload Window"); constructor( id: string, @@ -249,7 +249,7 @@ class ShowAboutDialogAction extends Action { export class NewWindowAction extends Action { static readonly ID = 'workbench.action.newWindow'; - static LABEL = nls.localize('newWindow', "New Window"); + static readonly LABEL = nls.localize('newWindow', "New Window"); constructor( id: string, diff --git a/src/vs/workbench/browser/actions/workspaceActions.ts b/src/vs/workbench/browser/actions/workspaceActions.ts index d0305aa9dde..b7d74392423 100644 --- a/src/vs/workbench/browser/actions/workspaceActions.ts +++ b/src/vs/workbench/browser/actions/workspaceActions.ts @@ -26,7 +26,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ export class OpenFileAction extends Action { static readonly ID = 'workbench.action.files.openFile'; - static LABEL = nls.localize('openFile', "Open File..."); + static readonly LABEL = nls.localize('openFile', "Open File..."); constructor( id: string, @@ -44,7 +44,7 @@ export class OpenFileAction extends Action { export class OpenFolderAction extends Action { static readonly ID = 'workbench.action.files.openFolder'; - static LABEL = nls.localize('openFolder', "Open Folder..."); + static readonly LABEL = nls.localize('openFolder', "Open Folder..."); constructor( id: string, @@ -62,7 +62,7 @@ export class OpenFolderAction extends Action { export class OpenFileFolderAction extends Action { static readonly ID = 'workbench.action.files.openFileFolder'; - static LABEL = nls.localize('openFileFolder', "Open..."); + static readonly LABEL = nls.localize('openFileFolder', "Open..."); constructor( id: string, @@ -80,7 +80,7 @@ export class OpenFileFolderAction extends Action { export class OpenWorkspaceAction extends Action { static readonly ID = 'workbench.action.openWorkspace'; - static LABEL = nls.localize('openWorkspaceAction', "Open Workspace..."); + static readonly LABEL = nls.localize('openWorkspaceAction', "Open Workspace..."); constructor( id: string, @@ -98,7 +98,7 @@ export class OpenWorkspaceAction extends Action { export class CloseWorkspaceAction extends Action { static readonly ID = 'workbench.action.closeFolder'; - static LABEL = nls.localize('closeWorkspace', "Close Workspace"); + static readonly LABEL = nls.localize('closeWorkspace', "Close Workspace"); constructor( id: string, @@ -150,7 +150,7 @@ export class OpenWorkspaceConfigFileAction extends Action { export class AddRootFolderAction extends Action { static readonly ID = 'workbench.action.addRootFolder'; - static LABEL = ADD_ROOT_FOLDER_LABEL; + static readonly LABEL = ADD_ROOT_FOLDER_LABEL; constructor( id: string, @@ -168,7 +168,7 @@ export class AddRootFolderAction extends Action { export class GlobalRemoveRootFolderAction extends Action { static readonly ID = 'workbench.action.removeRootFolder'; - static LABEL = nls.localize('globalRemoveFolderFromWorkspace', "Remove Folder from Workspace..."); + static readonly LABEL = nls.localize('globalRemoveFolderFromWorkspace', "Remove Folder from Workspace..."); constructor( id: string, diff --git a/src/vs/workbench/browser/composite.ts b/src/vs/workbench/browser/composite.ts index 38dde654626..6414496a6d3 100644 --- a/src/vs/workbench/browser/composite.ts +++ b/src/vs/workbench/browser/composite.ts @@ -15,6 +15,7 @@ import { trackFocus, Dimension } from 'vs/base/browser/dom'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { Disposable } from 'vs/base/common/lifecycle'; import { assertIsDefined } from 'vs/base/common/types'; +import { find } from 'vs/base/common/arrays'; /** * Composites are layed out in the sidebar and panel part of the workbench. At a time only one composite @@ -258,7 +259,7 @@ export abstract class CompositeRegistry extends Disposable private composites: CompositeDescriptor[] = []; protected registerComposite(descriptor: CompositeDescriptor): void { - if (this.compositeById(descriptor.id) !== null) { + if (this.compositeById(descriptor.id)) { return; } @@ -276,7 +277,7 @@ export abstract class CompositeRegistry extends Disposable this._onDidDeregister.fire(descriptor); } - getComposite(id: string): CompositeDescriptor | null { + getComposite(id: string): CompositeDescriptor | undefined { return this.compositeById(id); } @@ -284,13 +285,7 @@ export abstract class CompositeRegistry extends Disposable return this.composites.slice(0); } - private compositeById(id: string): CompositeDescriptor | null { - for (const composite of this.composites) { - if (composite.id === id) { - return composite; - } - } - - return null; + private compositeById(id: string): CompositeDescriptor | undefined { + return find(this.composites, composite => composite.id === id); } } diff --git a/src/vs/workbench/browser/editor.ts b/src/vs/workbench/browser/editor.ts index a8b4de85142..d441fb2f0d9 100644 --- a/src/vs/workbench/browser/editor.ts +++ b/src/vs/workbench/browser/editor.ts @@ -8,6 +8,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { Registry } from 'vs/platform/registry/common/platform'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { IConstructorSignature0, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { find } from 'vs/base/common/arrays'; export interface IEditorDescriptor { instantiate(instantiationService: IInstantiationService): BaseEditor; @@ -140,13 +141,7 @@ class EditorRegistry implements IEditorRegistry { } getEditorById(editorId: string): EditorDescriptor | undefined { - for (const editor of this.editors) { - if (editor.getId() === editorId) { - return editor; - } - } - - return undefined; + return find(this.editors, editor => editor.getId() === editorId); } getEditors(): readonly EditorDescriptor[] { diff --git a/src/vs/workbench/browser/panel.ts b/src/vs/workbench/browser/panel.ts index 35da00194aa..b4cbfb337cc 100644 --- a/src/vs/workbench/browser/panel.ts +++ b/src/vs/workbench/browser/panel.ts @@ -45,7 +45,7 @@ export class PanelRegistry extends CompositeRegistry { /** * Returns a panel by id. */ - getPanel(id: string): PanelDescriptor | null { + getPanel(id: string): PanelDescriptor | undefined { return this.getComposite(id); } diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts index 4757e8efca6..dfb216aa75e 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts @@ -163,15 +163,19 @@ export class GlobalActivityActionViewItem extends ActivityActionViewItem { export class PlaceHolderViewletActivityAction extends ViewletActivityAction { constructor( - id: string, name: string, iconUrl: URI, + id: string, + name: string, + iconUrl: URI | undefined, @IViewletService viewletService: IViewletService, @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, @ITelemetryService telemetryService: ITelemetryService ) { super({ id, name: id, cssClass: `extensionViewlet-placeholder-${id.replace(/\./g, '-')}` }, viewletService, layoutService, telemetryService); - const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${this.class}`; // Generate Placeholder CSS to show the icon in the activity bar - DOM.createCSSRule(iconClass, `-webkit-mask: ${DOM.asCSSUrl(iconUrl)} no-repeat 50% 50%; -webkit-mask-size: 24px;`); + if (iconUrl) { + const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${this.class}`; // Generate Placeholder CSS to show the icon in the activity bar + DOM.createCSSRule(iconClass, `-webkit-mask: ${DOM.asCSSUrl(iconUrl)} no-repeat 50% 50%; -webkit-mask-size: 24px;`); + } } setActivity(activity: IActivity): void { @@ -222,7 +226,7 @@ class SwitchSideBarViewAction extends Action { export class PreviousSideBarViewAction extends SwitchSideBarViewAction { static readonly ID = 'workbench.action.previousSideBarView'; - static LABEL = nls.localize('previousSideBarView', 'Previous Side Bar View'); + static readonly LABEL = nls.localize('previousSideBarView', 'Previous Side Bar View'); constructor( id: string, @@ -241,7 +245,7 @@ export class PreviousSideBarViewAction extends SwitchSideBarViewAction { export class NextSideBarViewAction extends SwitchSideBarViewAction { static readonly ID = 'workbench.action.nextSideBarView'; - static LABEL = nls.localize('nextSideBarView', 'Next Side Bar View'); + static readonly LABEL = nls.localize('nextSideBarView', 'Next Side Bar View'); constructor( id: string, diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index f45b3f776f4..fc2f2bf42b8 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -110,7 +110,7 @@ export class ActivitybarPart extends Part implements IActivityBarService { openComposite: (compositeId: string) => this.viewletService.openViewlet(compositeId, true), getActivityAction: (compositeId: string) => this.getCompositeActions(compositeId).activityAction, getCompositePinnedAction: (compositeId: string) => this.getCompositeActions(compositeId).pinnedAction, - getOnCompositeClickAction: (compositeId: string) => this.instantiationService.createInstance(ToggleViewletAction, this.viewletService.getViewlet(compositeId)), + getOnCompositeClickAction: (compositeId: string) => this.instantiationService.createInstance(ToggleViewletAction, assertIsDefined(this.viewletService.getViewlet(compositeId))), getContextMenuActions: () => [this.instantiationService.createInstance(ToggleActivityBarVisibilityAction, ToggleActivityBarVisibilityAction.ID, nls.localize('hideActivitBar', "Hide Activity Bar"))], getDefaultCompositeId: () => this.viewletService.getDefaultViewletId(), hidePart: () => this.layoutService.setSideBarHidden(true), @@ -247,7 +247,7 @@ export class ActivitybarPart extends Part implements IActivityBarService { this.createGlobalActivityActionBar(globalActivities); - this.element.style.display = this.layoutService.isVisible(Parts.ACTIVITYBAR_PART) ? null : 'none'; + this.element.style.display = this.layoutService.isVisible(Parts.ACTIVITYBAR_PART) ? '' : 'none'; return this.content; } @@ -257,18 +257,18 @@ export class ActivitybarPart extends Part implements IActivityBarService { // Part container const container = assertIsDefined(this.getContainer()); - const background = this.getColor(ACTIVITY_BAR_BACKGROUND); + const background = this.getColor(ACTIVITY_BAR_BACKGROUND) || ''; container.style.backgroundColor = background; - const borderColor = this.getColor(ACTIVITY_BAR_BORDER) || this.getColor(contrastBorder); + const borderColor = this.getColor(ACTIVITY_BAR_BORDER) || this.getColor(contrastBorder) || ''; const isPositionLeft = this.layoutService.getSideBarPosition() === SideBarPosition.LEFT; container.style.boxSizing = borderColor && isPositionLeft ? 'border-box' : ''; - container.style.borderRightWidth = borderColor && isPositionLeft ? '1px' : null; - container.style.borderRightStyle = borderColor && isPositionLeft ? 'solid' : null; - container.style.borderRightColor = isPositionLeft ? borderColor : null; - container.style.borderLeftWidth = borderColor && !isPositionLeft ? '1px' : null; - container.style.borderLeftStyle = borderColor && !isPositionLeft ? 'solid' : null; - container.style.borderLeftColor = !isPositionLeft ? borderColor : null; + container.style.borderRightWidth = borderColor && isPositionLeft ? '1px' : ''; + container.style.borderRightStyle = borderColor && isPositionLeft ? 'solid' : ''; + container.style.borderRightColor = isPositionLeft ? borderColor : ''; + container.style.borderLeftWidth = borderColor && !isPositionLeft ? '1px' : ''; + container.style.borderLeftStyle = borderColor && !isPositionLeft ? 'solid' : ''; + container.style.borderLeftColor = !isPositionLeft ? borderColor : ''; } private getActivitybarItemColors(theme: ITheme): ICompositeBarColors { @@ -421,7 +421,7 @@ export class ActivitybarPart extends Part implements IActivityBarService { setVisible(visible: boolean): void { if (this.element) { - this.element.style.display = visible ? null : 'none'; + this.element.style.display = visible ? '' : 'none'; } } diff --git a/src/vs/workbench/browser/parts/compositeBarActions.ts b/src/vs/workbench/browser/parts/compositeBarActions.ts index 7485e7a8658..f59e024ded1 100644 --- a/src/vs/workbench/browser/parts/compositeBarActions.ts +++ b/src/vs/workbench/browser/parts/compositeBarActions.ts @@ -439,7 +439,7 @@ export class CompositeActionViewItem extends ActivityActionViewItem { constructor( private compositeActivityAction: ActivityAction, private toggleCompositePinnedAction: Action, - private contextMenuActionsProvider: () => Action[], + private contextMenuActionsProvider: () => ReadonlyArray, colors: (theme: ITheme) => ICompositeBarColors, icon: boolean, private compositeBar: ICompositeBar, diff --git a/src/vs/workbench/browser/parts/compositePart.ts b/src/vs/workbench/browser/parts/compositePart.ts index 1058b69e765..fbc33409d13 100644 --- a/src/vs/workbench/browser/parts/compositePart.ts +++ b/src/vs/workbench/browser/parts/compositePart.ts @@ -32,6 +32,7 @@ import { attachProgressBarStyler } from 'vs/platform/theme/common/styler'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { Dimension, append, $, addClass, hide, show, addClasses } from 'vs/base/browser/dom'; import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview'; +import { assertIsDefined } from 'vs/base/common/types'; export interface ICompositeTitleLabel { @@ -57,15 +58,15 @@ export abstract class CompositePart extends Part { protected readonly onDidCompositeOpen = this._register(new Emitter<{ composite: IComposite, focus: boolean }>()); protected readonly onDidCompositeClose = this._register(new Emitter()); - protected toolBar: ToolBar; + protected toolBar: ToolBar | undefined; private mapCompositeToCompositeContainer = new Map(); private mapActionsBindingToComposite = new Map void>(); - private activeComposite: Composite | null; + private activeComposite: Composite | undefined; private lastActiveCompositeId: string; private instantiatedCompositeItems: Map; - private titleLabel: ICompositeTitleLabel; - private progressBar: ProgressBar; + private titleLabel: ICompositeTitleLabel | undefined; + private progressBar: ProgressBar | undefined; private contentAreaSize: Dimension | undefined; private readonly telemetryActionsListener = this._register(new MutableDisposable()); private currentCompositeOpenToken: string | undefined; @@ -90,7 +91,6 @@ export abstract class CompositePart extends Part { ) { super(id, options, themeService, storageService, layoutService); - this.activeComposite = null; this.instantiatedCompositeItems = new Map(); this.lastActiveCompositeId = storageService.get(activeCompositeSettingsKey, StorageScope.WORKSPACE, this.defaultCompositeId); } @@ -234,7 +234,8 @@ export abstract class CompositePart extends Part { show(compositeContainer); // Setup action runner - this.toolBar.actionRunner = composite.getActionRunner(); + const toolBar = assertIsDefined(this.toolBar); + toolBar.actionRunner = composite.getActionRunner(); // Update title with composite title if it differs from descriptor const descriptor = this.registry.getComposite(composite.getId()); @@ -251,7 +252,7 @@ export abstract class CompositePart extends Part { actionsBinding(); // Action Run Handling - this.telemetryActionsListener.value = this.toolBar.actionRunner.onDidRun(e => { + this.telemetryActionsListener.value = toolBar.actionRunner.onDidRun(e => { // Check for Error if (e.error && !errors.isPromiseCanceledError(e.error)) { @@ -312,7 +313,8 @@ export abstract class CompositePart extends Part { this.titleLabel.updateTitle(compositeId, compositeTitle, (keybinding && keybinding.getLabel()) || undefined); - this.toolBar.setAriaLabel(nls.localize('ariaCompositeToolbarLabel', "{0} actions", compositeTitle)); + const toolBar = assertIsDefined(this.toolBar); + toolBar.setAriaLabel(nls.localize('ariaCompositeToolbarLabel', "{0} actions", compositeTitle)); } private collectCompositeActions(composite: Composite): () => void { @@ -326,13 +328,14 @@ export abstract class CompositePart extends Part { secondaryActions.push(...this.getSecondaryActions()); // Update context - this.toolBar.context = this.actionsContextProvider(); + const toolBar = assertIsDefined(this.toolBar); + toolBar.context = this.actionsContextProvider(); // Return fn to set into toolbar - return this.toolBar.setActions(prepareActions(primaryActions), prepareActions(secondaryActions)); + return toolBar.setActions(prepareActions(primaryActions), prepareActions(secondaryActions)); } - protected getActiveComposite(): IComposite | null { + protected getActiveComposite(): IComposite | undefined { return this.activeComposite; } @@ -346,7 +349,7 @@ export abstract class CompositePart extends Part { } const composite = this.activeComposite; - this.activeComposite = null; + this.activeComposite = undefined; const compositeContainer = this.mapCompositeToCompositeContainer.get(composite.getId()); @@ -360,10 +363,14 @@ export abstract class CompositePart extends Part { } // Clear any running Progress - this.progressBar.stop().hide(); + if (this.progressBar) { + this.progressBar.stop().hide(); + } // Empty Actions - this.toolBar.setActions([])(); + if (this.toolBar) { + this.toolBar.setActions([])(); + } this.onDidCompositeClose.fire(composite); return composite; @@ -413,7 +420,8 @@ export abstract class CompositePart extends Part { super.updateStyles(); // Forward to title label - this.titleLabel.updateStyles(); + const titleLabel = assertIsDefined(this.titleLabel); + titleLabel.updateStyles(); } protected actionViewItemProvider(action: IAction): IActionViewItem | undefined { @@ -446,10 +454,10 @@ export abstract class CompositePart extends Part { return contentContainer; } - getProgressIndicator(id: string): IProgressIndicator | null { + getProgressIndicator(id: string): IProgressIndicator | undefined { const compositeItem = this.instantiatedCompositeItems.get(id); - return compositeItem ? compositeItem.progress : null; + return compositeItem ? compositeItem.progress : undefined; } protected getActions(): ReadonlyArray { diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index 96a35f5a192..df27f82a684 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -66,14 +66,14 @@ export abstract class BreadcrumbsConfig { // internal } - static IsEnabled = BreadcrumbsConfig._stub('breadcrumbs.enabled'); - static UseQuickPick = BreadcrumbsConfig._stub('breadcrumbs.useQuickPick'); - static FilePath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.filePath'); - static SymbolPath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.symbolPath'); - static SymbolSortOrder = BreadcrumbsConfig._stub<'position' | 'name' | 'type'>('breadcrumbs.symbolSortOrder'); - static Icons = BreadcrumbsConfig._stub('breadcrumbs.icons'); + static readonly IsEnabled = BreadcrumbsConfig._stub('breadcrumbs.enabled'); + static readonly UseQuickPick = BreadcrumbsConfig._stub('breadcrumbs.useQuickPick'); + static readonly FilePath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.filePath'); + static readonly SymbolPath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.symbolPath'); + static readonly SymbolSortOrder = BreadcrumbsConfig._stub<'position' | 'name' | 'type'>('breadcrumbs.symbolSortOrder'); + static readonly Icons = BreadcrumbsConfig._stub('breadcrumbs.icons'); - static FileExcludes = BreadcrumbsConfig._stub('files.exclude'); + static readonly FileExcludes = BreadcrumbsConfig._stub('files.exclude'); private static _stub(name: string): { bindTo(service: IConfigurationService): BreadcrumbsConfig } { return { diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 4594e365427..81ff34d2a50 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -130,15 +130,15 @@ export interface IBreadcrumbsControlOptions { export class BreadcrumbsControl { - static HEIGHT = 22; + static readonly HEIGHT = 22; static readonly Payload_Reveal = {}; static readonly Payload_RevealAside = {}; static readonly Payload_Pick = {}; - static CK_BreadcrumbsPossible = new RawContextKey('breadcrumbsPossible', false); - static CK_BreadcrumbsVisible = new RawContextKey('breadcrumbsVisible', false); - static CK_BreadcrumbsActive = new RawContextKey('breadcrumbsActive', false); + static readonly CK_BreadcrumbsPossible = new RawContextKey('breadcrumbsPossible', false); + static readonly CK_BreadcrumbsVisible = new RawContextKey('breadcrumbsVisible', false); + static readonly CK_BreadcrumbsActive = new RawContextKey('breadcrumbsActive', false); private readonly _ckBreadcrumbsPossible: IContextKey; private readonly _ckBreadcrumbsVisible: IContextKey; diff --git a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts index da2fa254db3..94597ec5c07 100644 --- a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts +++ b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts @@ -16,6 +16,7 @@ import { GroupDirection, MergeGroupMode } from 'vs/workbench/services/editor/com import { toDisposable } from 'vs/base/common/lifecycle'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { RunOnceScheduler } from 'vs/base/common/async'; +import { find } from 'vs/base/common/arrays'; interface IDropOperation { splitDirection?: GroupDirection; @@ -23,7 +24,7 @@ interface IDropOperation { class DropOverlay extends Themable { - private static OVERLAY_ID = 'monaco-workbench-editor-drop-overlay'; + private static readonly OVERLAY_ID = 'monaco-workbench-editor-drop-overlay'; private container!: HTMLElement; private overlay!: HTMLElement; @@ -544,13 +545,7 @@ export class EditorDropTarget extends Themable { private findTargetGroupView(child: HTMLElement): IEditorGroupView | undefined { const groups = this.accessor.groups; - for (const groupView of groups) { - if (isAncestor(child, groupView.element)) { - return groupView; - } - } - - return undefined; + return find(groups, groupView => isAncestor(child, groupView.element)); } private updateContainer(isDraggedOver: boolean): void { diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 8f4e19ed022..3687fb2cba5 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -95,13 +95,13 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //#endregion private _group: EditorGroup; - private _disposed: boolean; + private _disposed = false; - private active: boolean; - private dimension: Dimension; + private active: boolean | undefined; + private dimension: Dimension | undefined; private _whenRestored: Promise; - private isRestored: boolean; + private isRestored = false; private scopedInstantiationService: IInstantiationService; @@ -143,7 +143,68 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this.disposedEditorsWorker = this._register(new RunOnceWorker(editors => this.handleDisposedEditors(editors), 0)); - this.create(); + //#region create() + { + // Container + addClasses(this.element, 'editor-group-container'); + + // Container listeners + this.registerContainerListeners(); + + // Container toolbar + this.createContainerToolbar(); + + // Container context menu + this.createContainerContextMenu(); + + // Letterpress container + const letterpressContainer = document.createElement('div'); + addClass(letterpressContainer, 'editor-group-letterpress'); + this.element.appendChild(letterpressContainer); + + // Progress bar + this.progressBar = this._register(new ProgressBar(this.element)); + this._register(attachProgressBarStyler(this.progressBar, this.themeService)); + this.progressBar.hide(); + + // Scoped services + const scopedContextKeyService = this._register(this.contextKeyService.createScoped(this.element)); + this.scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection( + [IContextKeyService, scopedContextKeyService], + [IEditorProgressService, new EditorProgressService(this.progressBar)] + )); + + // Context keys + this.handleGroupContextKeys(scopedContextKeyService); + + // Title container + this.titleContainer = document.createElement('div'); + addClass(this.titleContainer, 'title'); + this.element.appendChild(this.titleContainer); + + // Title control + this.titleAreaControl = this.createTitleAreaControl(); + + // Editor container + this.editorContainer = document.createElement('div'); + addClass(this.editorContainer, 'editor-container'); + this.element.appendChild(this.editorContainer); + + // Editor control + this.editorControl = this._register(this.scopedInstantiationService.createInstance(EditorControl, this.editorContainer, this)); + this._onDidChange.input = this.editorControl.onDidSizeConstraintsChange; + + // Track Focus + this.doTrackFocus(); + + // Update containers + this.updateTitleContainer(); + this.updateContainer(); + + // Update styles + this.updateStyles(); + } + //#endregion this._whenRestored = this.restoreEditors(from); this._whenRestored.then(() => this.isRestored = true); @@ -151,68 +212,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this.registerListeners(); } - private create(): void { - - // Container - addClasses(this.element, 'editor-group-container'); - - // Container listeners - this.registerContainerListeners(); - - // Container toolbar - this.createContainerToolbar(); - - // Container context menu - this.createContainerContextMenu(); - - // Letterpress container - const letterpressContainer = document.createElement('div'); - addClass(letterpressContainer, 'editor-group-letterpress'); - this.element.appendChild(letterpressContainer); - - // Progress bar - this.progressBar = this._register(new ProgressBar(this.element)); - this._register(attachProgressBarStyler(this.progressBar, this.themeService)); - this.progressBar.hide(); - - // Scoped services - const scopedContextKeyService = this._register(this.contextKeyService.createScoped(this.element)); - this.scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection( - [IContextKeyService, scopedContextKeyService], - [IEditorProgressService, new EditorProgressService(this.progressBar)] - )); - - // Context keys - this.handleGroupContextKeys(scopedContextKeyService); - - // Title container - this.titleContainer = document.createElement('div'); - addClass(this.titleContainer, 'title'); - this.element.appendChild(this.titleContainer); - - // Title control - this.createTitleAreaControl(); - - // Editor container - this.editorContainer = document.createElement('div'); - addClass(this.editorContainer, 'editor-container'); - this.element.appendChild(this.editorContainer); - - // Editor control - this.editorControl = this._register(this.scopedInstantiationService.createInstance(EditorControl, this.editorContainer, this)); - this._onDidChange.input = this.editorControl.onDidSizeConstraintsChange; - - // Track Focus - this.doTrackFocus(); - - // Update containers - this.updateTitleContainer(); - this.updateContainer(); - - // Update styles - this.updateStyles(); - } - private handleGroupContextKeys(contextKeyService: IContextKeyService): void { const groupActiveEditorDirtyContextKey = EditorGroupActiveEditorDirtyContext.bindTo(contextKeyService); const groupEditorsCountContext = EditorGroupEditorsCountContext.bindTo(contextKeyService); @@ -404,7 +403,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { toggleClass(this.titleContainer, 'show-file-icons', this.accessor.partOptions.showIcons); } - private createTitleAreaControl(): void { + private createTitleAreaControl(): TitleControl { // Clear old if existing if (this.titleAreaControl) { @@ -418,6 +417,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } else { this.titleAreaControl = this.scopedInstantiationService.createInstance(NoTabsTitleControl, this.titleContainer, this.accessor, this); } + + return this.titleAreaControl; } private async restoreEditors(from: IEditorGroupView | ISerializedEditorGroup | null): Promise { @@ -596,7 +597,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Recreate and layout control this.createTitleAreaControl(); - this.layoutTitleAreaControl(); + if (this.dimension) { + this.layoutTitleAreaControl(this.dimension.width); + } // Ensure to show active editor if any if (this._group.activeEditor) { @@ -1442,9 +1445,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Container if (isEmpty) { - this.element.style.backgroundColor = this.getColor(EDITOR_GROUP_EMPTY_BACKGROUND); + this.element.style.backgroundColor = this.getColor(EDITOR_GROUP_EMPTY_BACKGROUND) || ''; } else { - this.element.style.backgroundColor = null; + this.element.style.backgroundColor = ''; } // Title control @@ -1459,10 +1462,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this.titleContainer.style.removeProperty('--title-border-bottom-color'); } - this.titleContainer.style.backgroundColor = this.getColor(showTabs ? EDITOR_GROUP_HEADER_TABS_BACKGROUND : EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND); + this.titleContainer.style.backgroundColor = this.getColor(showTabs ? EDITOR_GROUP_HEADER_TABS_BACKGROUND : EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND) || ''; // Editor container - this.editorContainer.style.backgroundColor = this.getColor(editorBackground); + this.editorContainer.style.backgroundColor = this.getColor(editorBackground) || ''; } //#endregion @@ -1487,12 +1490,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this.editorContainer.style.height = `calc(100% - ${this.titleAreaControl.getPreferredHeight()}px)`; // Forward to controls - this.layoutTitleAreaControl(); + this.layoutTitleAreaControl(width); this.editorControl.layout(new Dimension(this.dimension.width, this.dimension.height - this.titleAreaControl.getPreferredHeight())); } - private layoutTitleAreaControl(): void { - this.titleAreaControl.layout(new Dimension(this.dimension.width, this.titleAreaControl.getPreferredHeight())); + private layoutTitleAreaControl(width: number): void { + this.titleAreaControl.layout(new Dimension(width, this.titleAreaControl.getPreferredHeight())); } relayout(): void { @@ -1520,7 +1523,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } class EditorOpeningEvent implements IEditorOpeningEvent { - private override: () => Promise; + private override: () => Promise | undefined; constructor( private _group: GroupIdentifier, @@ -1545,7 +1548,7 @@ class EditorOpeningEvent implements IEditorOpeningEvent { this.override = callback; } - isPrevented(): () => Promise { + isPrevented(): () => Promise | undefined { return this.override; } } diff --git a/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts b/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts index 77a4a66b55c..2bab7f303cf 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts @@ -26,7 +26,7 @@ import { assertAllDefined, assertIsDefined } from 'vs/base/common/types'; export class NotificationsCenter extends Themable { - private static MAX_DIMENSIONS = new Dimension(450, 400); + private static readonly MAX_DIMENSIONS = new Dimension(450, 400); private readonly _onDidChangeVisibility: Emitter = this._register(new Emitter()); readonly onDidChangeVisibility: Event = this._onDidChangeVisibility.event; @@ -227,16 +227,16 @@ export class NotificationsCenter extends Themable { protected updateStyles(): void { if (this.notificationsCenterContainer && this.notificationsCenterHeader) { const widgetShadowColor = this.getColor(widgetShadow); - this.notificationsCenterContainer.style.boxShadow = widgetShadowColor ? `0 0px 8px ${widgetShadowColor}` : null; + this.notificationsCenterContainer.style.boxShadow = widgetShadowColor ? `0 0px 8px ${widgetShadowColor}` : ''; const borderColor = this.getColor(NOTIFICATIONS_CENTER_BORDER); - this.notificationsCenterContainer.style.border = borderColor ? `1px solid ${borderColor}` : null; + this.notificationsCenterContainer.style.border = borderColor ? `1px solid ${borderColor}` : ''; const headerForeground = this.getColor(NOTIFICATIONS_CENTER_HEADER_FOREGROUND); this.notificationsCenterHeader.style.color = headerForeground ? headerForeground.toString() : null; const headerBackground = this.getColor(NOTIFICATIONS_CENTER_HEADER_BACKGROUND); - this.notificationsCenterHeader.style.background = headerBackground ? headerBackground.toString() : null; + this.notificationsCenterHeader.style.background = headerBackground ? headerBackground.toString() : ''; } } diff --git a/src/vs/workbench/browser/parts/notifications/notificationsList.ts b/src/vs/workbench/browser/parts/notifications/notificationsList.ts index b2993d52599..7a83faeacfb 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsList.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsList.ts @@ -221,7 +221,7 @@ export class NotificationsList extends Themable { this.listContainer.style.color = foreground ? foreground.toString() : null; const background = this.getColor(NOTIFICATIONS_BACKGROUND); - this.listContainer.style.background = background ? background.toString() : null; + this.listContainer.style.background = background ? background.toString() : ''; const outlineColor = this.getColor(contrastBorder); this.listContainer.style.outlineColor = outlineColor ? outlineColor.toString() : ''; diff --git a/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts b/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts index ae1d7024b7e..6a35cf36db8 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts @@ -41,8 +41,8 @@ enum ToastVisibility { export class NotificationsToasts extends Themable { - private static MAX_WIDTH = 450; - private static MAX_NOTIFICATIONS = 3; + private static readonly MAX_WIDTH = 450; + private static readonly MAX_NOTIFICATIONS = 3; private static PURGE_TIMEOUT: { [severity: number]: number } = (() => { const intervals = Object.create(null); diff --git a/src/vs/workbench/browser/parts/panel/panelActions.ts b/src/vs/workbench/browser/parts/panel/panelActions.ts index c8419eed7e7..30de9340067 100644 --- a/src/vs/workbench/browser/parts/panel/panelActions.ts +++ b/src/vs/workbench/browser/parts/panel/panelActions.ts @@ -21,7 +21,7 @@ import { ActivePanelContext, PanelPositionContext } from 'vs/workbench/common/pa export class ClosePanelAction extends Action { static readonly ID = 'workbench.action.closePanel'; - static LABEL = nls.localize('closePanel', "Close Panel"); + static readonly LABEL = nls.localize('closePanel', "Close Panel"); constructor( id: string, @@ -40,7 +40,7 @@ export class ClosePanelAction extends Action { export class TogglePanelAction extends Action { static readonly ID = 'workbench.action.togglePanel'; - static LABEL = nls.localize('togglePanel', "Toggle Panel"); + static readonly LABEL = nls.localize('togglePanel', "Toggle Panel"); constructor( id: string, @@ -209,7 +209,7 @@ export class SwitchPanelViewAction extends Action { export class PreviousPanelViewAction extends SwitchPanelViewAction { static readonly ID = 'workbench.action.previousPanelView'; - static LABEL = nls.localize('previousPanelView', 'Previous Panel View'); + static readonly LABEL = nls.localize('previousPanelView', 'Previous Panel View'); constructor( id: string, @@ -227,7 +227,7 @@ export class PreviousPanelViewAction extends SwitchPanelViewAction { export class NextPanelViewAction extends SwitchPanelViewAction { static readonly ID = 'workbench.action.nextPanelView'; - static LABEL = nls.localize('nextPanelView', 'Next Panel View'); + static readonly LABEL = nls.localize('nextPanelView', 'Next Panel View'); constructor( id: string, diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index bfec292330a..43b7f72a1ca 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -30,7 +30,7 @@ import { Dimension, trackFocus } from 'vs/base/browser/dom'; import { localize } from 'vs/nls'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { isUndefinedOrNull, withUndefinedAsNull, withNullAsUndefined, assertIsDefined } from 'vs/base/common/types'; +import { isUndefinedOrNull, assertIsDefined } from 'vs/base/common/types'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -71,7 +71,7 @@ export class PanelPart extends CompositePart implements IPanelService { //#endregion - get onDidPanelOpen(): Event<{ panel: IPanel, focus: boolean }> { return Event.map(this.onDidCompositeOpen.event, compositeOpen => ({ panel: compositeOpen.composite, focus: compositeOpen.focus })); } + get onDidPanelOpen(): Event<{ panel: IPanel, focus: boolean; }> { return Event.map(this.onDidCompositeOpen.event, compositeOpen => ({ panel: compositeOpen.composite, focus: compositeOpen.focus })); } readonly onDidPanelClose: Event = this.onDidCompositeClose.event; private _onDidVisibilityChange = this._register(new Emitter()); @@ -81,7 +81,7 @@ export class PanelPart extends CompositePart implements IPanelService { private panelFocusContextKey: IContextKey; private compositeBar: CompositeBar; - private compositeActions: Map = new Map(); + private compositeActions: Map = new Map(); private blockOpeningPanel = false; private _contentDimension: Dimension | undefined; @@ -123,7 +123,7 @@ export class PanelPart extends CompositePart implements IPanelService { openComposite: (compositeId: string) => Promise.resolve(this.openPanel(compositeId, true)), getActivityAction: (compositeId: string) => this.getCompositeActions(compositeId).activityAction, getCompositePinnedAction: (compositeId: string) => this.getCompositeActions(compositeId).pinnedAction, - getOnCompositeClickAction: (compositeId: string) => this.instantiationService.createInstance(PanelActivityAction, this.getPanel(compositeId)), + getOnCompositeClickAction: (compositeId: string) => this.instantiationService.createInstance(PanelActivityAction, assertIsDefined(this.getPanel(compositeId))), getContextMenuActions: () => [ this.instantiationService.createInstance(TogglePanelPositionAction, TogglePanelPositionAction.ID, TogglePanelPositionAction.LABEL), this.instantiationService.createInstance(TogglePanelAction, TogglePanelAction.ID, localize('hidePanel', "Hide Panel")) @@ -209,18 +209,18 @@ export class PanelPart extends CompositePart implements IPanelService { super.updateStyles(); const container = assertIsDefined(this.getContainer()); - container.style.backgroundColor = this.getColor(PANEL_BACKGROUND); - container.style.borderLeftColor = this.getColor(PANEL_BORDER) || this.getColor(contrastBorder); + container.style.backgroundColor = this.getColor(PANEL_BACKGROUND) || ''; + container.style.borderLeftColor = this.getColor(PANEL_BORDER) || this.getColor(contrastBorder) || ''; const title = this.getTitleArea(); if (title) { - title.style.borderTopColor = this.getColor(PANEL_BORDER) || this.getColor(contrastBorder); + title.style.borderTopColor = this.getColor(PANEL_BORDER) || this.getColor(contrastBorder) || ''; } } - openPanel(id: string, focus?: boolean): Panel | null { + openPanel(id: string, focus?: boolean): Panel | undefined { if (this.blockOpeningPanel) { - return null; // Workaround against a potential race condition + return undefined; // Workaround against a potential race condition } // First check if panel is hidden and show if so @@ -233,7 +233,7 @@ export class PanelPart extends CompositePart implements IPanelService { } } - return withUndefinedAsNull(this.openComposite(id, focus)); + return this.openComposite(id, focus); } showActivity(panelId: string, badge: IBadge, clazz?: string): IDisposable { @@ -241,15 +241,15 @@ export class PanelPart extends CompositePart implements IPanelService { } getPanel(panelId: string): IPanelIdentifier | undefined { - return withNullAsUndefined(Registry.as(PanelExtensions.Panels).getPanel(panelId)); + return Registry.as(PanelExtensions.Panels).getPanel(panelId); } - getPanels(): PanelDescriptor[] { + getPanels(): readonly PanelDescriptor[] { return Registry.as(PanelExtensions.Panels).getPanels() .sort((v1, v2) => typeof v1.order === 'number' && typeof v2.order === 'number' ? v1.order - v2.order : NaN); } - getPinnedPanels(): PanelDescriptor[] { + getPinnedPanels(): readonly PanelDescriptor[] { const pinnedCompositeIds = this.compositeBar.getPinnedComposites().map(c => c.id); return this.getPanels() .filter(p => pinnedCompositeIds.indexOf(p.id) !== -1) @@ -263,7 +263,7 @@ export class PanelPart extends CompositePart implements IPanelService { ]; } - getActivePanel(): IPanel | null { + getActivePanel(): IPanel | undefined { return this.getActiveComposite(); } @@ -326,11 +326,11 @@ export class PanelPart extends CompositePart implements IPanelService { } } - private getCompositeActions(compositeId: string): { activityAction: PanelActivityAction, pinnedAction: ToggleCompositePinnedAction } { + private getCompositeActions(compositeId: string): { activityAction: PanelActivityAction, pinnedAction: ToggleCompositePinnedAction; } { let compositeActions = this.compositeActions.get(compositeId); if (!compositeActions) { compositeActions = { - activityAction: this.instantiationService.createInstance(PanelActivityAction, this.getPanel(compositeId)), + activityAction: this.instantiationService.createInstance(PanelActivityAction, assertIsDefined(this.getPanel(compositeId))), pinnedAction: new ToggleCompositePinnedAction(this.getPanel(compositeId), this.compositeBar) }; @@ -357,7 +357,7 @@ export class PanelPart extends CompositePart implements IPanelService { private getToolbarWidth(): number { const activePanel = this.getActivePanel(); - if (!activePanel) { + if (!activePanel || !this.toolBar) { return 0; } diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 32c171d44a0..ddb957fee79 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -323,7 +323,7 @@ class QuickInput extends Disposable implements IQuickInput { class QuickPick extends QuickInput implements IQuickPick { - private static INPUT_BOX_ARIA_LABEL = localize('quickInputBox.ariaLabel', "Type to narrow down results."); + private static readonly INPUT_BOX_ARIA_LABEL = localize('quickInputBox.ariaLabel', "Type to narrow down results."); private _value = ''; private _placeholder: string; @@ -762,7 +762,7 @@ class QuickPick extends QuickInput implements IQuickPi class InputBox extends QuickInput implements IInputBox { - private static noPromptMessage = localize('inputModeEntry', "Press 'Enter' to confirm your input or 'Escape' to cancel"); + private static readonly noPromptMessage = localize('inputModeEntry', "Press 'Enter' to confirm your input or 'Escape' to cancel"); private _value = ''; private _valueSelection: Readonly<[number, number]>; diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index 4c992ffd94f..e94290fee50 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -159,7 +159,7 @@ class ListElementRenderer implements IListRenderer implements IViewletServi } const width = viewlet.getOptimalWidth(); - if (typeof width !== 'number') { return; } @@ -176,17 +175,17 @@ export class SidebarPart extends CompositePart implements IViewletServi // Part container const container = assertIsDefined(this.getContainer()); - container.style.backgroundColor = this.getColor(SIDE_BAR_BACKGROUND); + container.style.backgroundColor = this.getColor(SIDE_BAR_BACKGROUND) || ''; container.style.color = this.getColor(SIDE_BAR_FOREGROUND); const borderColor = this.getColor(SIDE_BAR_BORDER) || this.getColor(contrastBorder); const isPositionLeft = this.layoutService.getSideBarPosition() === SideBarPosition.LEFT; - container.style.borderRightWidth = borderColor && isPositionLeft ? '1px' : null; - container.style.borderRightStyle = borderColor && isPositionLeft ? 'solid' : null; - container.style.borderRightColor = isPositionLeft ? borderColor : null; - container.style.borderLeftWidth = borderColor && !isPositionLeft ? '1px' : null; - container.style.borderLeftStyle = borderColor && !isPositionLeft ? 'solid' : null; - container.style.borderLeftColor = !isPositionLeft ? borderColor : null; + container.style.borderRightWidth = borderColor && isPositionLeft ? '1px' : ''; + container.style.borderRightStyle = borderColor && isPositionLeft ? 'solid' : ''; + container.style.borderRightColor = isPositionLeft ? borderColor || '' : ''; + container.style.borderLeftWidth = borderColor && !isPositionLeft ? '1px' : ''; + container.style.borderLeftStyle = borderColor && !isPositionLeft ? 'solid' : ''; + container.style.borderLeftColor = !isPositionLeft ? borderColor || '' : ''; } layout(width: number, height: number): void { @@ -199,7 +198,7 @@ export class SidebarPart extends CompositePart implements IViewletServi // Viewlet service - getActiveViewlet(): IViewlet | null { + getActiveViewlet(): IViewlet | undefined { return this.getActiveComposite(); } @@ -211,7 +210,7 @@ export class SidebarPart extends CompositePart implements IViewletServi this.hideActiveComposite(); } - async openViewlet(id: string | undefined, focus?: boolean): Promise { + async openViewlet(id: string | undefined, focus?: boolean): Promise { if (typeof id === 'string' && this.getViewlet(id)) { return this.doOpenViewlet(id, focus); } @@ -222,7 +221,7 @@ export class SidebarPart extends CompositePart implements IViewletServi return this.doOpenViewlet(id, focus); } - return null; + return undefined; } getViewlets(): ViewletDescriptor[] { @@ -247,9 +246,9 @@ export class SidebarPart extends CompositePart implements IViewletServi return this.getViewlets().filter(viewlet => viewlet.id === id)[0]; } - private doOpenViewlet(id: string, focus?: boolean): Viewlet | null { + private doOpenViewlet(id: string, focus?: boolean): Viewlet | undefined { if (this.blockOpeningViewlet) { - return null; // Workaround against a potential race condition + return undefined; // Workaround against a potential race condition } // First check if sidebar is hidden and show if so @@ -318,7 +317,7 @@ class FocusSideBarAction extends Action { } // Focus into active viewlet - let viewlet = this.viewletService.getActiveViewlet(); + const viewlet = this.viewletService.getActiveViewlet(); if (viewlet) { viewlet.focus(); } diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts index 11ec913abd8..418c8b2a56f 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts @@ -27,7 +27,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage'; import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { coalesce } from 'vs/base/common/arrays'; +import { coalesce, find } from 'vs/base/common/arrays'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { ToggleStatusbarVisibilityAction } from 'vs/workbench/browser/actions/layoutActions'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; @@ -176,13 +176,7 @@ class StatusbarViewModel extends Disposable { } findEntry(container: HTMLElement): IStatusbarViewModelEntry | undefined { - for (const entry of this._entries) { - if (entry.container === container) { - return entry; - } - } - - return undefined; + return find(this._entries, entry => entry.container === container); } getEntries(alignment: StatusbarAlignment): IStatusbarViewModelEntry[] { @@ -578,7 +572,7 @@ export class StatusbarPart extends Part implements IStatusbarService { const container = assertIsDefined(this.getContainer()); // Background colors - const backgroundColor = this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_BACKGROUND : STATUS_BAR_NO_FOLDER_BACKGROUND); + const backgroundColor = this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_BACKGROUND : STATUS_BAR_NO_FOLDER_BACKGROUND) || ''; container.style.backgroundColor = backgroundColor; container.style.color = this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND); @@ -784,7 +778,7 @@ class StatusbarEntryItem extends Disposable { } if (isBackground) { - container.style.backgroundColor = colorResult; + container.style.backgroundColor = colorResult || ''; } else { container.style.color = colorResult; } diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index bd676c25d02..095b1c53211 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -81,7 +81,7 @@ export abstract class MenubarControl extends Disposable { protected menuUpdater: RunOnceScheduler; - protected static MAX_MENU_RECENT_ENTRIES = 10; + protected static readonly MAX_MENU_RECENT_ENTRIES = 10; constructor( protected readonly menuService: IMenuService, diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 1fc235927cb..bfc77a7aa5c 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -507,7 +507,7 @@ export class TitlebarPart extends Part implements ITitleService { removeClass(this.element, 'inactive'); } - const titleBackground = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_BACKGROUND : TITLE_BAR_ACTIVE_BACKGROUND); + const titleBackground = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_BACKGROUND : TITLE_BAR_ACTIVE_BACKGROUND) || ''; this.element.style.backgroundColor = titleBackground; if (titleBackground && Color.fromHex(titleBackground).isLighter()) { addClass(this.element, 'light'); @@ -519,7 +519,7 @@ export class TitlebarPart extends Part implements ITitleService { this.element.style.color = titleForeground; const titleBorder = this.getColor(TITLE_BAR_BORDER); - this.element.style.borderBottom = titleBorder ? `1px solid ${titleBorder}` : null; + this.element.style.borderBottom = titleBorder ? `1px solid ${titleBorder}` : ''; } } @@ -559,8 +559,8 @@ export class TitlebarPart extends Part implements ITitleService { // Center between menu and window controls if (leftMarker > (this.element.clientWidth - this.title.clientWidth) / 2 || rightMarker < (this.element.clientWidth + this.title.clientWidth) / 2) { - this.title.style.position = null; - this.title.style.left = null; + this.title.style.position = ''; + this.title.style.left = ''; this.title.style.transform = ''; return; } diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index 03c709a0e06..7872aae6f0c 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -753,6 +753,23 @@ class TreeRenderer extends Disposable implements ITreeRenderer { + if ((Math.abs(start) > label.length) || (Math.abs(end) >= label.length)) { + return ({ start: 0, end: 0 }); + } + if (start < 0) { + start = label.length + start; + } + if (end < 0) { + end = label.length + end; + } + if (start > end) { + const swap = start; + start = end; + end = swap; + } + return ({ start, end }); + }) : undefined; const icon = this.themeService.getTheme().type === LIGHT ? node.icon : node.iconDark; const iconUrl = icon ? URI.revive(icon) : null; const title = node.tooltip ? node.tooltip : resource ? undefined : label; @@ -762,9 +779,9 @@ class TreeRenderer extends Disposable implements ITreeRenderer('explorer.decorations'); - templateData.resourceLabel.setResource({ name: label, description, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, hideIcon: !!iconUrl, fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches: createMatches(element.filterData) }); + templateData.resourceLabel.setResource({ name: label, description, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, hideIcon: !!iconUrl, fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches: matches ? matches : createMatches(element.filterData) }); } else { - templateData.resourceLabel.setResource({ name: label, description }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches: createMatches(element.filterData) }); + templateData.resourceLabel.setResource({ name: label, description }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches: matches ? matches : createMatches(element.filterData) }); } templateData.icon.style.backgroundImage = iconUrl ? DOM.asCSSUrl(iconUrl) : ''; diff --git a/src/vs/workbench/browser/parts/views/panelViewlet.ts b/src/vs/workbench/browser/parts/views/panelViewlet.ts index fabd5818d2c..7a6e3e450ce 100644 --- a/src/vs/workbench/browser/parts/views/panelViewlet.ts +++ b/src/vs/workbench/browser/parts/views/panelViewlet.ts @@ -29,6 +29,7 @@ import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { IView, FocusedViewContext } from 'vs/workbench/common/views'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { assertIsDefined } from 'vs/base/common/types'; export interface IPanelColors extends IColorMapping { dropBackground?: ColorIdentifier; @@ -46,7 +47,7 @@ export interface IViewletPanelOptions extends IPanelOptions { export abstract class ViewletPanel extends Panel implements IView { - private static AlwaysShowActionsConfig = 'workbench.view.alwaysShowHeaderActions'; + private static readonly AlwaysShowActionsConfig = 'workbench.view.alwaysShowHeaderActions'; private _onDidFocus = this._register(new Emitter()); readonly onDidFocus: Event = this._onDidFocus.event; @@ -67,11 +68,11 @@ export abstract class ViewletPanel extends Panel implements IView { readonly title: string; protected actionRunner?: IActionRunner; - protected toolbar: ToolBar; + protected toolbar?: ToolBar; private readonly showActionsAlways: boolean = false; - private headerContainer: HTMLElement; - private titleContainer: HTMLElement; - protected twistiesContainer: HTMLElement; + private headerContainer?: HTMLElement; + private titleContainer?: HTMLElement; + protected twistiesContainer?: HTMLElement; constructor( options: IViewletPanelOptions, @@ -165,7 +166,9 @@ export abstract class ViewletPanel extends Panel implements IView { } protected updateTitle(title: string): void { - this.titleContainer.textContent = title; + if (this.titleContainer) { + this.titleContainer.textContent = title; + } this._onDidChangeTitleArea.fire(); } @@ -177,11 +180,16 @@ export abstract class ViewletPanel extends Panel implements IView { } private setActions(): void { - this.toolbar.setActions(prepareActions(this.getActions()), prepareActions(this.getSecondaryActions()))(); - this.toolbar.context = this.getActionsContext(); + if (this.toolbar) { + this.toolbar.setActions(prepareActions(this.getActions()), prepareActions(this.getSecondaryActions()))(); + this.toolbar.context = this.getActionsContext(); + } } private updateActionsVisibility(): void { + if (!this.headerContainer) { + return; + } const shouldAlwaysShowActions = this.configurationService.getValue('workbench.view.alwaysShowHeaderActions'); toggleClass(this.headerContainer, 'actions-always-visible', shouldAlwaysShowActions); } @@ -229,10 +237,10 @@ export class PanelViewlet extends Viewlet { private lastFocusedPanel: ViewletPanel | undefined; private panelItems: IViewletPanelItem[] = []; - private panelview: PanelView; + private panelview?: PanelView; get onDidSashChange(): Event { - return this.panelview.onDidSashChange; + return assertIsDefined(this.panelview).onDidSashChange; } protected get panels(): ViewletPanel[] { @@ -274,7 +282,7 @@ export class PanelViewlet extends Viewlet { event.stopPropagation(); event.preventDefault(); - let anchor: { x: number, y: number } = { x: event.posx, y: event.posy }; + let anchor: { x: number, y: number; } = { x: event.posx, y: event.posy }; this.contextMenuService.showContextMenu({ getAnchor: () => anchor, getActions: () => this.getContextMenuActions() @@ -332,7 +340,9 @@ export class PanelViewlet extends Viewlet { } layout(dimension: Dimension): void { - this.panelview.layout(dimension.height, dimension.width); + if (this.panelview) { + this.panelview.layout(dimension.height, dimension.width); + } } getOptimalWidth(): number { @@ -342,7 +352,7 @@ export class PanelViewlet extends Viewlet { return Math.max(...sizes); } - addPanels(panels: { panel: ViewletPanel, size: number, index?: number }[]): void { + addPanels(panels: { panel: ViewletPanel, size: number, index?: number; }[]): void { const wasSingleView = this.isSingleView(); for (const { panel, size, index } of panels) { @@ -378,7 +388,7 @@ export class PanelViewlet extends Viewlet { const panelItem: IViewletPanelItem = { panel, disposable }; this.panelItems.splice(index, 0, panelItem); - this.panelview.addPanel(panel, size, index); + assertIsDefined(this.panelview).addPanel(panel, size, index); } removePanels(panels: ViewletPanel[]): void { @@ -403,7 +413,7 @@ export class PanelViewlet extends Viewlet { this.lastFocusedPanel = undefined; } - this.panelview.removePanel(panel); + assertIsDefined(this.panelview).removePanel(panel); const [panelItem] = this.panelItems.splice(index, 1); panelItem.disposable.dispose(); @@ -424,15 +434,15 @@ export class PanelViewlet extends Viewlet { const [panelItem] = this.panelItems.splice(fromIndex, 1); this.panelItems.splice(toIndex, 0, panelItem); - this.panelview.movePanel(from, to); + assertIsDefined(this.panelview).movePanel(from, to); } resizePanel(panel: ViewletPanel, size: number): void { - this.panelview.resizePanel(panel, size); + assertIsDefined(this.panelview).resizePanel(panel, size); } getPanelSize(panel: ViewletPanel): number { - return this.panelview.getPanelSize(panel); + return assertIsDefined(this.panelview).getPanelSize(panel); } protected updateViewHeaders(): void { @@ -451,6 +461,8 @@ export class PanelViewlet extends Viewlet { dispose(): void { super.dispose(); this.panelItems.forEach(i => i.disposable.dispose()); - this.panelview.dispose(); + if (this.panelview) { + this.panelview.dispose(); + } } } diff --git a/src/vs/workbench/browser/parts/views/views.ts b/src/vs/workbench/browser/parts/views/views.ts index 87c08909cff..9a0a307dd5c 100644 --- a/src/vs/workbench/browser/parts/views/views.ts +++ b/src/vs/workbench/browser/parts/views/views.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./media/views'; -import { Disposable, IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IViewsService, IViewsViewlet, ViewContainer, IViewDescriptor, IViewContainersRegistry, Extensions as ViewExtensions, IView, IViewDescriptorCollection, IViewsRegistry } from 'vs/workbench/common/views'; import { Registry } from 'vs/platform/registry/common/platform'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; @@ -22,14 +22,14 @@ import { IFileIconTheme, IWorkbenchThemeService } from 'vs/workbench/services/th import { toggleClass, addClass } from 'vs/base/browser/dom'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -function filterViewRegisterEvent(container: ViewContainer, event: Event<{ viewContainer: ViewContainer, views: IViewDescriptor[] }>): Event { +function filterViewRegisterEvent(container: ViewContainer, event: Event<{ viewContainer: ViewContainer, views: IViewDescriptor[]; }>): Event { return Event.chain(event) .map(({ views, viewContainer }) => viewContainer === container ? views : []) .filter(views => views.length > 0) .event; } -function filterViewMoveEvent(container: ViewContainer, event: Event<{ from: ViewContainer, to: ViewContainer, views: IViewDescriptor[] }>): Event<{ added?: IViewDescriptor[], removed?: IViewDescriptor[] }> { +function filterViewMoveEvent(container: ViewContainer, event: Event<{ from: ViewContainer, to: ViewContainer, views: IViewDescriptor[]; }>): Event<{ added?: IViewDescriptor[], removed?: IViewDescriptor[]; }> { return Event.chain(event) .map(({ views, from, to }) => from === container ? { removed: views } : to === container ? { added: views } : {}) .filter(({ added, removed }) => isNonEmptyArray(added) || isNonEmptyArray(removed)) @@ -78,8 +78,8 @@ class ViewDescriptorCollection extends Disposable implements IViewDescriptorColl private contextKeys = new CounterSet(); private items: IViewItem[] = []; - private _onDidChange: Emitter<{ added: IViewDescriptor[], removed: IViewDescriptor[] }> = this._register(new Emitter<{ added: IViewDescriptor[], removed: IViewDescriptor[] }>()); - readonly onDidChangeActiveViews: Event<{ added: IViewDescriptor[], removed: IViewDescriptor[] }> = this._onDidChange.event; + private _onDidChange: Emitter<{ added: IViewDescriptor[], removed: IViewDescriptor[]; }> = this._register(new Emitter<{ added: IViewDescriptor[], removed: IViewDescriptor[]; }>()); + readonly onDidChangeActiveViews: Event<{ added: IViewDescriptor[], removed: IViewDescriptor[]; }> = this._onDidChange.event; get activeViewDescriptors(): IViewDescriptor[] { return this.items @@ -356,7 +356,7 @@ export class ContributableViewsModel extends Disposable { return viewDescriptor.workspace ? !!viewState.visibleWorkspace : !!viewState.visibleGlobal; } - private find(id: string): { index: number, visibleIndex: number, viewDescriptor: IViewDescriptor, state: IViewState } { + private find(id: string): { index: number, visibleIndex: number, viewDescriptor: IViewDescriptor, state: IViewState; } { for (let i = 0, visibleIndex = 0; i < this.viewDescriptors.length; i++) { const viewDescriptor = this.viewDescriptors[i]; const state = this.viewStates.get(viewDescriptor.id); @@ -436,8 +436,8 @@ export class ContributableViewsModel extends Disposable { (a, b) => a.id === b.id ? 0 : a.id < b.id ? -1 : 1 ).reverse(); - const toRemove: { index: number, viewDescriptor: IViewDescriptor }[] = []; - const toAdd: { index: number, viewDescriptor: IViewDescriptor, size?: number, collapsed: boolean }[] = []; + const toRemove: { index: number, viewDescriptor: IViewDescriptor; }[] = []; + const toAdd: { index: number, viewDescriptor: IViewDescriptor, size?: number, collapsed: boolean; }[] = []; for (const splice of splices) { const startViewDescriptor = this.viewDescriptors[splice.start]; @@ -521,7 +521,7 @@ export class PersistentContributableViewsModel extends ContributableViewsModel { } private saveWorkspaceViewsStates(): void { - const storedViewsStates: { [id: string]: IStoredWorkspaceViewState } = JSON.parse(this.storageService.get(this.workspaceViewsStateStorageId, StorageScope.WORKSPACE, '{}')); + const storedViewsStates: { [id: string]: IStoredWorkspaceViewState; } = JSON.parse(this.storageService.get(this.workspaceViewsStateStorageId, StorageScope.WORKSPACE, '{}')); for (const viewDescriptor of this.viewDescriptors) { const viewState = this.viewStates.get(viewDescriptor.id); if (viewState) { @@ -557,7 +557,7 @@ export class PersistentContributableViewsModel extends ContributableViewsModel { private static loadViewsStates(workspaceViewsStateStorageId: string, globalViewsStateStorageId: string, storageService: IStorageService): Map { const viewStates = new Map(); - const workspaceViewsStates = <{ [id: string]: IStoredWorkspaceViewState }>JSON.parse(storageService.get(workspaceViewsStateStorageId, StorageScope.WORKSPACE, '{}')); + const workspaceViewsStates = <{ [id: string]: IStoredWorkspaceViewState; }>JSON.parse(storageService.get(workspaceViewsStateStorageId, StorageScope.WORKSPACE, '{}')); for (const id of Object.keys(workspaceViewsStates)) { const workspaceViewState = workspaceViewsStates[id]; viewStates.set(id, { @@ -636,7 +636,7 @@ export class ViewsService extends Disposable implements IViewsService { _serviceBrand: undefined; - private readonly viewDescriptorCollections: Map; + private readonly viewDescriptorCollections: Map; private readonly viewDisposable: Map; private readonly activeViewContextKeys: Map>; @@ -646,7 +646,7 @@ export class ViewsService extends Disposable implements IViewsService { ) { super(); - this.viewDescriptorCollections = new Map(); + this.viewDescriptorCollections = new Map(); this.viewDisposable = new Map(); this.activeViewContextKeys = new Map>(); @@ -692,13 +692,13 @@ export class ViewsService extends Disposable implements IViewsService { } private onDidRegisterViewContainer(viewContainer: ViewContainer): void { - const viewDescriptorCollection = new ViewDescriptorCollection(viewContainer, this.contextKeyService); - const disposables: IDisposable[] = [viewDescriptorCollection]; + const disposables = new DisposableStore(); + const viewDescriptorCollection = disposables.add(new ViewDescriptorCollection(viewContainer, this.contextKeyService)); this.onDidChangeActiveViews({ added: viewDescriptorCollection.activeViewDescriptors, removed: [] }); viewDescriptorCollection.onDidChangeActiveViews(changed => this.onDidChangeActiveViews(changed), this, disposables); - this.viewDescriptorCollections.set(viewContainer, { viewDescriptorCollection, disposable: toDisposable(() => dispose(disposables)) }); + this.viewDescriptorCollections.set(viewContainer, { viewDescriptorCollection, disposable: disposables }); } private onDidDeregisterViewContainer(viewContainer: ViewContainer): void { @@ -709,7 +709,7 @@ export class ViewsService extends Disposable implements IViewsService { } } - private onDidChangeActiveViews({ added, removed }: { added: IViewDescriptor[], removed: IViewDescriptor[] }): void { + private onDidChangeActiveViews({ added, removed }: { added: IViewDescriptor[], removed: IViewDescriptor[]; }): void { added.forEach(viewDescriptor => this.getOrCreateActiveViewContextKey(viewDescriptor).set(true)); removed.forEach(viewDescriptor => this.getOrCreateActiveViewContextKey(viewDescriptor).set(false)); } @@ -717,7 +717,7 @@ export class ViewsService extends Disposable implements IViewsService { private onDidRegisterViews(container: ViewContainer, views: IViewDescriptor[]): void { const viewlet = this.viewletService.getViewlet(container.id); for (const viewDescriptor of views) { - const disposables: IDisposable[] = []; + const disposables = new DisposableStore(); const command: ICommandAction = { id: viewDescriptor.focusCommand ? viewDescriptor.focusCommand.id : `${viewDescriptor.id}.focus`, title: { original: `Focus on ${viewDescriptor.name} View`, value: localize('focus view', "Focus on {0} View", viewDescriptor.name) }, @@ -725,9 +725,9 @@ export class ViewsService extends Disposable implements IViewsService { }; const when = ContextKeyExpr.has(`${viewDescriptor.id}.active`); - disposables.push(CommandsRegistry.registerCommand(command.id, () => this.openView(viewDescriptor.id, true))); + disposables.add(CommandsRegistry.registerCommand(command.id, () => this.openView(viewDescriptor.id, true))); - disposables.push(MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + disposables.add(MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command, when })); @@ -745,7 +745,7 @@ export class ViewsService extends Disposable implements IViewsService { }); } - this.viewDisposable.set(viewDescriptor, toDisposable(() => dispose(disposables))); + this.viewDisposable.set(viewDescriptor, disposables); } } diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index 76d8302ca88..239514051a2 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -64,6 +64,9 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView super(id, { showHeaderInTitleWhenSingleView, dnd: new DefaultPanelDndController() }, configurationService, layoutService, contextMenuService, telemetryService, themeService, storageService); const container = Registry.as(ViewContainerExtensions.ViewContainersRegistry).get(id); + if (!container) { + throw new Error('Could not find container'); + } this.viewsModel = this._register(this.instantiationService.createInstance(PersistentContributableViewsModel, container, viewletStateStorageId)); this.viewletState = this.getMemento(StorageScope.WORKSPACE); diff --git a/src/vs/workbench/browser/viewlet.ts b/src/vs/workbench/browser/viewlet.ts index 35b8233db03..6ddf85eb74b 100644 --- a/src/vs/workbench/browser/viewlet.ts +++ b/src/vs/workbench/browser/viewlet.ts @@ -35,8 +35,8 @@ export abstract class Viewlet extends Composite implements IViewlet { super(id, telemetryService, themeService, storageService); } - getOptimalWidth(): number | null { - return null; + getOptimalWidth(): number | undefined { + return undefined; } getContextMenuActions(): IAction[] { diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index e5e351cf7d8..51194632b7d 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -303,7 +303,7 @@ class BrowserMain extends Disposable { return { id: 'empty-window' }; } - private getRemoteUserDataUri(): URI | null { + private getRemoteUserDataUri(): URI | undefined { const element = document.getElementById('vscode-remote-user-data-uri'); if (element) { const remoteUserDataPath = element.getAttribute('data-settings'); @@ -312,7 +312,7 @@ class BrowserMain extends Disposable { } } - return null; + return undefined; } } diff --git a/src/vs/workbench/common/notifications.ts b/src/vs/workbench/common/notifications.ts index 9546898f8c9..f0a492bad2c 100644 --- a/src/vs/workbench/common/notifications.ts +++ b/src/vs/workbench/common/notifications.ts @@ -12,6 +12,7 @@ import { Action } from 'vs/base/common/actions'; import { isErrorWithActions } from 'vs/base/common/errorsWithActions'; import { startsWith } from 'vs/base/common/strings'; import { localize } from 'vs/nls'; +import { find, equals } from 'vs/base/common/arrays'; export interface INotificationsModel { @@ -123,7 +124,7 @@ export class NotificationHandle implements INotificationHandle { export class NotificationsModel extends Disposable implements INotificationsModel { - private static NO_OP_NOTIFICATION = new NoOpNotification(); + private static readonly NO_OP_NOTIFICATION = new NoOpNotification(); private readonly _onDidNotificationChange: Emitter = this._register(new Emitter()); readonly onDidNotificationChange: Event = this._onDidNotificationChange.event; @@ -169,19 +170,13 @@ export class NotificationsModel extends Disposable implements INotificationsMode } private findNotification(item: INotificationViewItem): INotificationViewItem | undefined { - for (const notification of this._notifications) { - if (notification.equals(item)) { - return notification; - } - } - - return undefined; + return find(this._notifications, notification => notification.equals(item)); } - private createViewItem(notification: INotification): INotificationViewItem | null { + private createViewItem(notification: INotification): INotificationViewItem | undefined { const item = NotificationViewItem.create(notification); if (!item) { - return null; + return undefined; } // Item Events @@ -385,11 +380,11 @@ export interface INotificationMessage { export class NotificationViewItem extends Disposable implements INotificationViewItem { - private static MAX_MESSAGE_LENGTH = 1000; + private static readonly MAX_MESSAGE_LENGTH = 1000; // Example link: "Some message with [link text](http://link.href)." // RegEx: [, anything not ], ], (, http://|https://|command:, no whitespace) - private static LINK_REGEX = /\[([^\]]+)\]\(((?:https?:\/\/|command:)[^\)\s]+)(?: "([^"]+)")?\)/gi; + private static readonly LINK_REGEX = /\[([^\]]+)\]\(((?:https?:\/\/|command:)[^\)\s]+)(?: "([^"]+)")?\)/gi; private _expanded: boolean | undefined; @@ -405,9 +400,9 @@ export class NotificationViewItem extends Disposable implements INotificationVie private readonly _onDidLabelChange: Emitter = this._register(new Emitter()); readonly onDidLabelChange: Event = this._onDidLabelChange.event; - static create(notification: INotification): INotificationViewItem | null { + static create(notification: INotification): INotificationViewItem | undefined { if (!notification || !notification.message || isPromiseCanceledError(notification.message)) { - return null; // we need a message to show + return undefined; // we need a message to show } let severity: Severity; @@ -419,7 +414,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie const message = NotificationViewItem.parseNotificationMessage(notification.message); if (!message) { - return null; // we need a message to show + return undefined; // we need a message to show } let actions: INotificationActions | undefined; @@ -641,17 +636,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie const primaryActions = (this._actions && this._actions.primary) || []; const otherPrimaryActions = (other.actions && other.actions.primary) || []; - if (primaryActions.length !== otherPrimaryActions.length) { - return false; - } - - for (let i = 0; i < primaryActions.length; i++) { - if ((primaryActions[i].id + primaryActions[i].label) !== (otherPrimaryActions[i].id + otherPrimaryActions[i].label)) { - return false; - } - } - - return true; + return equals(primaryActions, otherPrimaryActions, (a, b) => (a.id + a.label) === (b.id + b.label)); } } @@ -690,9 +675,9 @@ export class ChoiceAction extends Action { class StatusMessageViewItem { - static create(notification: NotificationMessage, options?: IStatusMessageOptions): IStatusMessageViewItem | null { + static create(notification: NotificationMessage, options?: IStatusMessageOptions): IStatusMessageViewItem | undefined { if (!notification || isPromiseCanceledError(notification)) { - return null; // we need a message to show + return undefined; // we need a message to show } let message: string | undefined; @@ -703,7 +688,7 @@ class StatusMessageViewItem { } if (!message) { - return null; // we need a message to show + return undefined; // we need a message to show } return { message, options }; diff --git a/src/vs/workbench/common/resources.ts b/src/vs/workbench/common/resources.ts index f4f4ce7df80..c509716fc49 100644 --- a/src/vs/workbench/common/resources.ts +++ b/src/vs/workbench/common/resources.ts @@ -18,13 +18,13 @@ import { withNullAsUndefined } from 'vs/base/common/types'; export class ResourceContextKey extends Disposable implements IContextKey { - static Scheme = new RawContextKey('resourceScheme', undefined); - static Filename = new RawContextKey('resourceFilename', undefined); - static LangId = new RawContextKey('resourceLangId', undefined); - static Resource = new RawContextKey('resource', undefined); - static Extension = new RawContextKey('resourceExtname', undefined); - static HasResource = new RawContextKey('resourceSet', false); - static IsFileSystemResource = new RawContextKey('isFileSystemResource', false); + static readonly Scheme = new RawContextKey('resourceScheme', undefined); + static readonly Filename = new RawContextKey('resourceFilename', undefined); + static readonly LangId = new RawContextKey('resourceLangId', undefined); + static readonly Resource = new RawContextKey('resource', undefined); + static readonly Extension = new RawContextKey('resourceExtname', undefined); + static readonly HasResource = new RawContextKey('resourceSet', false); + static readonly IsFileSystemResource = new RawContextKey('isFileSystemResource', false); private readonly _resourceKey: IContextKey; private readonly _schemeKey: IContextKey; diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index 7d81c6c5e72..fc41153b077 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import { registerColor, editorBackground, contrastBorder, transparent, editorWidgetBackground, textLinkForeground, lighten, darken, focusBorder, activeContrastBorder, editorWidgetForeground } from 'vs/platform/theme/common/colorRegistry'; +import { registerColor, editorBackground, contrastBorder, transparent, editorWidgetBackground, textLinkForeground, lighten, darken, focusBorder, activeContrastBorder, editorWidgetForeground, editorErrorForeground, editorWarningForeground, editorInfoForeground } from 'vs/platform/theme/common/colorRegistry'; import { Disposable } from 'vs/base/common/lifecycle'; import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService'; import { Color } from 'vs/base/common/color'; @@ -560,21 +560,21 @@ export const NOTIFICATIONS_BORDER = registerColor('notifications.border', { }, nls.localize('notificationsBorder', "Notifications border color separating from other notifications in the notifications center. Notifications slide in from the bottom right of the window.")); export const NOTIFICATIONS_ERROR_ICON_FOREGROUND = registerColor('notificationsErrorIcon.foreground', { - dark: '#F48771', - light: '#A1260D', - hc: '#F48771' + dark: editorErrorForeground, + light: editorErrorForeground, + hc: editorErrorForeground }, nls.localize('notificationsErrorIconForeground', "The color used for the notification error icon.")); export const NOTIFICATIONS_WARNING_ICON_FOREGROUND = registerColor('notificationsWarningIcon.foreground', { - dark: '#FFCC00', - light: '#DDB100', - hc: '#FFCC00' + dark: editorWarningForeground, + light: editorWarningForeground, + hc: editorWarningForeground }, nls.localize('notificationsWarningIconForeground', "The color used for the notification warning icon.")); export const NOTIFICATIONS_INFO_ICON_FOREGROUND = registerColor('notificationsInfoIcon.foreground', { - dark: '#75BEFF', - light: '#007ACC', - hc: '#75BEFF' + dark: editorInfoForeground, + light: editorInfoForeground, + hc: editorInfoForeground }, nls.localize('notificationsInfoIconForeground', "The color used for the notification info icon.")); /** diff --git a/src/vs/workbench/common/viewlet.ts b/src/vs/workbench/common/viewlet.ts index ddb8340130c..01fafea5968 100644 --- a/src/vs/workbench/common/viewlet.ts +++ b/src/vs/workbench/common/viewlet.ts @@ -15,5 +15,5 @@ export interface IViewlet extends IComposite { /** * Returns the minimal width needed to avoid any content horizontal truncation */ - getOptimalWidth(): number | null; + getOptimalWidth(): number | undefined; } diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 6a4147042e3..2e733ef117c 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -7,7 +7,6 @@ import { Command } from 'vs/editor/common/modes'; import { UriComponents } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; -import { ITreeViewDataProvider } from 'vs/workbench/common/views'; import { localize } from 'vs/nls'; import { IViewlet } from 'vs/workbench/common/viewlet'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; diff --git a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.contribution.ts b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.contribution.ts index 1615bf30b86..d17090d01a3 100644 --- a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.contribution.ts +++ b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.contribution.ts @@ -26,13 +26,13 @@ const _ctxCallHierarchyVisible = new RawContextKey('callHierarchyVisibl class CallHierarchyController implements IEditorContribution { - static Id = 'callHierarchy'; + static readonly Id = 'callHierarchy'; static get(editor: ICodeEditor): CallHierarchyController { return editor.getContribution(CallHierarchyController.Id); } - private static _StorageDirection = 'callHierarchy/defaultDirection'; + private static readonly _StorageDirection = 'callHierarchy/defaultDirection'; private readonly _ctxHasProvider: IContextKey; private readonly _ctxIsVisible: IContextKey; diff --git a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.ts b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.ts index 160662e8ac2..06dbdc22a4b 100644 --- a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.ts +++ b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.ts @@ -29,13 +29,13 @@ export interface CallHierarchyItem { } export interface IncomingCall { - source: CallHierarchyItem; - sourceRanges: IRange[]; + from: CallHierarchyItem; + fromRanges: IRange[]; } export interface OutgoingCall { - sourceRanges: IRange[]; - target: CallHierarchyItem; + fromRanges: IRange[]; + to: CallHierarchyItem; } export interface CallHierarchyProvider { diff --git a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts index 7e4d4ac6dac..120633c77e4 100644 --- a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts +++ b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts @@ -295,29 +295,11 @@ export class CallHierarchyTreePeekWidget extends PeekViewWidget { } localDispose.add(value); - // update: title and subtitle - let node: callHTree.Call | undefined = element; - let names = [element.item.name]; - while (node) { - let parent = this._tree.getParentElement(node); - let name: string; - if (parent instanceof callHTree.Call) { - name = parent.item.name; - node = parent; - } else { - name = this._tree.getInput()!.word; - node = undefined; - } - if (this._direction === CallHierarchyDirection.CallsTo) { - names.push(name); - } else { - names.unshift(name); - } - } + // update: title const title = this._direction === CallHierarchyDirection.CallsFrom ? localize('callFrom', "Calls from '{0}'", this._tree.getInput()!.word) : localize('callsTo', "Callers of '{0}'", this._tree.getInput()!.word); - this.setTitle(title, names.join(' → ')); + this.setTitle(title); })); this._disposables.add(this._editor.onMouseDown(e => { diff --git a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyTree.ts b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyTree.ts index dbe1dee06ad..b35134d13ff 100644 --- a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyTree.ts +++ b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyTree.ts @@ -83,8 +83,8 @@ export class DataSource implements IAsyncDataSource { const outgoingCalls = await provideOutgoingCalls(model, position, CancellationToken.None); for (const call of outgoingCalls) { bucket.push(new Call( - call.target, - call.sourceRanges.map(range => ({ range, uri: model.uri })), + call.to, + call.fromRanges.map(range => ({ range, uri: model.uri })), parent )); } @@ -94,8 +94,8 @@ export class DataSource implements IAsyncDataSource { const incomingCalls = await provideIncomingCalls(model, position, CancellationToken.None); for (const call of incomingCalls) { bucket.push(new Call( - call.source, - call.sourceRanges.map(range => ({ range, uri: call.source.uri })), + call.from, + call.fromRanges.map(range => ({ range, uri: call.from.uri })), parent )); } @@ -122,7 +122,7 @@ class CallRenderingTemplate { export class CallRenderer implements ITreeRenderer { - static id = 'CallRenderer'; + static readonly id = 'CallRenderer'; templateId: string = CallRenderer.id; diff --git a/src/vs/workbench/contrib/cli/node/cli.contribution.ts b/src/vs/workbench/contrib/cli/node/cli.contribution.ts index 7da113bc27f..985be2476f9 100644 --- a/src/vs/workbench/contrib/cli/node/cli.contribution.ts +++ b/src/vs/workbench/contrib/cli/node/cli.contribution.ts @@ -41,7 +41,7 @@ function isAvailable(): Promise { class InstallAction extends Action { static readonly ID = 'workbench.action.installCommandLine'; - static LABEL = nls.localize('install', "Install '{0}' command in PATH", product.applicationName); + static readonly LABEL = nls.localize('install', "Install '{0}' command in PATH", product.applicationName); constructor( id: string, @@ -122,7 +122,7 @@ class InstallAction extends Action { class UninstallAction extends Action { static readonly ID = 'workbench.action.uninstallCommandLine'; - static LABEL = nls.localize('uninstall', "Uninstall '{0}' command from PATH", product.applicationName); + static readonly LABEL = nls.localize('uninstall', "Uninstall '{0}' command from PATH", product.applicationName); constructor( id: string, diff --git a/src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts b/src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts index 558d193d12a..b0f4b9c4894 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/languageConfigurationExtensionPoint.ts @@ -43,16 +43,7 @@ interface ILanguageConfiguration { } function isStringArr(something: string[] | null): something is string[] { - if (!Array.isArray(something)) { - return false; - } - for (let i = 0, len = something.length; i < len; i++) { - if (typeof something[i] !== 'string') { - return false; - } - } - return true; - + return Array.isArray(something) && something.every(value => typeof value === 'string'); } function isCharacterPair(something: CharacterPair | null): boolean { diff --git a/src/vs/workbench/contrib/codeEditor/browser/selectionClipboard.ts b/src/vs/workbench/contrib/codeEditor/browser/selectionClipboard.ts index ebf9955db2a..074e43dd377 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/selectionClipboard.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/selectionClipboard.ts @@ -17,7 +17,7 @@ import { EndOfLinePreference } from 'vs/editor/common/model'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; export class SelectionClipboard extends Disposable implements IEditorContribution { - private static SELECTION_LENGTH_LIMIT = 65536; + private static readonly SELECTION_LENGTH_LIMIT = 65536; private static readonly ID = 'editor.contrib.selectionClipboard'; constructor(editor: ICodeEditor, @IClipboardService clipboardService: IClipboardService) { diff --git a/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts b/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts index 09438e54175..a58e626db11 100644 --- a/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts +++ b/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts @@ -100,7 +100,7 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget editor: ICodeEditor, private _owner: string, private _commentThread: modes.CommentThread, - private _pendingComment: string, + private _pendingComment: string | null, @IInstantiationService private instantiationService: IInstantiationService, @IModeService private modeService: IModeService, @IModelService private modelService: IModelService, diff --git a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts index 4cdcb6a6895..299a7271b2b 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts @@ -56,8 +56,8 @@ interface ICommentThreadTemplateData { } export class CommentsModelVirualDelegate implements IListVirtualDelegate { - private static RESOURCE_ID = 'resource-with-comments'; - private static COMMENT_ID = 'comment-node'; + private static readonly RESOURCE_ID = 'resource-with-comments'; + private static readonly COMMENT_ID = 'comment-node'; getHeight(element: any): number { diff --git a/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts b/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts index 7653bcd4d64..381e6df69cc 100644 --- a/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts +++ b/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts @@ -122,8 +122,8 @@ export class StartDebugActionViewItem implements IActionViewItem { } })); this.toDispose.push(attachStylerCallback(this.themeService, { selectBorder }, colors => { - this.container.style.border = colors.selectBorder ? `1px solid ${colors.selectBorder}` : null; - selectBoxContainer.style.borderLeft = colors.selectBorder ? `1px solid ${colors.selectBorder}` : null; + this.container.style.border = colors.selectBorder ? `1px solid ${colors.selectBorder}` : ''; + selectBoxContainer.style.borderLeft = colors.selectBorder ? `1px solid ${colors.selectBorder}` : ''; })); this.updateOptions(); diff --git a/src/vs/workbench/contrib/debug/browser/debugActions.ts b/src/vs/workbench/contrib/debug/browser/debugActions.ts index 3a2c52b0193..1440892a8f9 100644 --- a/src/vs/workbench/contrib/debug/browser/debugActions.ts +++ b/src/vs/workbench/contrib/debug/browser/debugActions.ts @@ -15,20 +15,16 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { startDebugging } from 'vs/workbench/contrib/debug/common/debugUtils'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; export abstract class AbstractDebugAction extends Action { - protected toDispose: IDisposable[]; - constructor( id: string, label: string, cssClass: string, @IDebugService protected debugService: IDebugService, @IKeybindingService protected keybindingService: IKeybindingService, ) { super(id, label, cssClass, false); - this.toDispose = []; - this.toDispose.push(this.debugService.onDidChangeState(state => this.updateEnablement(state))); + this._register(this.debugService.onDidChangeState(state => this.updateEnablement(state))); this.updateLabel(label); this.updateEnablement(); @@ -56,16 +52,11 @@ export abstract class AbstractDebugAction extends Action { protected isEnabled(_: State): boolean { return true; } - - dispose(): void { - super.dispose(); - this.toDispose = dispose(this.toDispose); - } } export class ConfigureAction extends AbstractDebugAction { static readonly ID = 'workbench.action.debug.configure'; - static LABEL = nls.localize('openLaunchJson', "Open {0}", 'launch.json'); + static readonly LABEL = nls.localize('openLaunchJson', "Open {0}", 'launch.json'); constructor(id: string, label: string, @IDebugService debugService: IDebugService, @@ -74,7 +65,7 @@ export class ConfigureAction extends AbstractDebugAction { @IWorkspaceContextService private readonly contextService: IWorkspaceContextService ) { super(id, label, 'debug-action configure', debugService, keybindingService); - this.toDispose.push(debugService.getConfigurationManager().onDidSelectConfiguration(() => this.updateClass())); + this._register(debugService.getConfigurationManager().onDidSelectConfiguration(() => this.updateClass())); this.updateClass(); } @@ -120,10 +111,10 @@ export class StartAction extends AbstractDebugAction { ) { super(id, label, 'debug-action start', debugService, keybindingService); - this.toDispose.push(this.debugService.getConfigurationManager().onDidSelectConfiguration(() => this.updateEnablement())); - this.toDispose.push(this.debugService.onDidNewSession(() => this.updateEnablement())); - this.toDispose.push(this.debugService.onDidEndSession(() => this.updateEnablement())); - this.toDispose.push(this.contextService.onDidChangeWorkbenchState(() => this.updateEnablement())); + this._register(this.debugService.getConfigurationManager().onDidSelectConfiguration(() => this.updateEnablement())); + this._register(this.debugService.onDidNewSession(() => this.updateEnablement())); + this._register(this.debugService.onDidEndSession(() => this.updateEnablement())); + this._register(this.contextService.onDidChangeWorkbenchState(() => this.updateEnablement())); } run(): Promise { @@ -165,7 +156,7 @@ export class RunAction extends StartAction { export class SelectAndStartAction extends AbstractDebugAction { static readonly ID = 'workbench.action.debug.selectandstart'; - static LABEL = nls.localize('selectAndStartDebugging', "Select and Start Debugging"); + static readonly LABEL = nls.localize('selectAndStartDebugging', "Select and Start Debugging"); constructor(id: string, label: string, @IDebugService debugService: IDebugService, @@ -182,7 +173,7 @@ export class SelectAndStartAction extends AbstractDebugAction { export class RemoveBreakpointAction extends Action { static readonly ID = 'workbench.debug.viewlet.action.removeBreakpoint'; - static LABEL = nls.localize('removeBreakpoint', "Remove Breakpoint"); + static readonly LABEL = nls.localize('removeBreakpoint', "Remove Breakpoint"); constructor(id: string, label: string, @IDebugService private readonly debugService: IDebugService) { super(id, label, 'debug-action remove'); @@ -196,11 +187,11 @@ export class RemoveBreakpointAction extends Action { export class RemoveAllBreakpointsAction extends AbstractDebugAction { static readonly ID = 'workbench.debug.viewlet.action.removeAllBreakpoints'; - static LABEL = nls.localize('removeAllBreakpoints', "Remove All Breakpoints"); + static readonly LABEL = nls.localize('removeAllBreakpoints', "Remove All Breakpoints"); constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { super(id, label, 'debug-action remove-all', debugService, keybindingService); - this.toDispose.push(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); + this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); } run(): Promise { @@ -215,11 +206,11 @@ export class RemoveAllBreakpointsAction extends AbstractDebugAction { export class EnableAllBreakpointsAction extends AbstractDebugAction { static readonly ID = 'workbench.debug.viewlet.action.enableAllBreakpoints'; - static LABEL = nls.localize('enableAllBreakpoints', "Enable All Breakpoints"); + static readonly LABEL = nls.localize('enableAllBreakpoints', "Enable All Breakpoints"); constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { super(id, label, 'debug-action enable-all-breakpoints', debugService, keybindingService); - this.toDispose.push(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); + this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); } run(): Promise { @@ -234,11 +225,11 @@ export class EnableAllBreakpointsAction extends AbstractDebugAction { export class DisableAllBreakpointsAction extends AbstractDebugAction { static readonly ID = 'workbench.debug.viewlet.action.disableAllBreakpoints'; - static LABEL = nls.localize('disableAllBreakpoints', "Disable All Breakpoints"); + static readonly LABEL = nls.localize('disableAllBreakpoints', "Disable All Breakpoints"); constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { super(id, label, 'debug-action disable-all-breakpoints', debugService, keybindingService); - this.toDispose.push(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); + this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); } run(): Promise { @@ -253,14 +244,14 @@ export class DisableAllBreakpointsAction extends AbstractDebugAction { export class ToggleBreakpointsActivatedAction extends AbstractDebugAction { static readonly ID = 'workbench.debug.viewlet.action.toggleBreakpointsActivatedAction'; - static ACTIVATE_LABEL = nls.localize('activateBreakpoints', "Activate Breakpoints"); - static DEACTIVATE_LABEL = nls.localize('deactivateBreakpoints', "Deactivate Breakpoints"); + static readonly ACTIVATE_LABEL = nls.localize('activateBreakpoints', "Activate Breakpoints"); + static readonly DEACTIVATE_LABEL = nls.localize('deactivateBreakpoints', "Deactivate Breakpoints"); constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { super(id, label, 'debug-action breakpoints-activate', debugService, keybindingService); this.updateLabel(this.debugService.getModel().areBreakpointsActivated() ? ToggleBreakpointsActivatedAction.DEACTIVATE_LABEL : ToggleBreakpointsActivatedAction.ACTIVATE_LABEL); - this.toDispose.push(this.debugService.getModel().onDidChangeBreakpoints(() => { + this._register(this.debugService.getModel().onDidChangeBreakpoints(() => { this.updateLabel(this.debugService.getModel().areBreakpointsActivated() ? ToggleBreakpointsActivatedAction.DEACTIVATE_LABEL : ToggleBreakpointsActivatedAction.ACTIVATE_LABEL); this.updateEnablement(); })); @@ -277,11 +268,11 @@ export class ToggleBreakpointsActivatedAction extends AbstractDebugAction { export class ReapplyBreakpointsAction extends AbstractDebugAction { static readonly ID = 'workbench.debug.viewlet.action.reapplyBreakpointsAction'; - static LABEL = nls.localize('reapplyAllBreakpoints', "Reapply All Breakpoints"); + static readonly LABEL = nls.localize('reapplyAllBreakpoints', "Reapply All Breakpoints"); constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { super(id, label, '', debugService, keybindingService); - this.toDispose.push(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); + this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); } run(): Promise { @@ -297,11 +288,11 @@ export class ReapplyBreakpointsAction extends AbstractDebugAction { export class AddFunctionBreakpointAction extends AbstractDebugAction { static readonly ID = 'workbench.debug.viewlet.action.addFunctionBreakpointAction'; - static LABEL = nls.localize('addFunctionBreakpoint', "Add Function Breakpoint"); + static readonly LABEL = nls.localize('addFunctionBreakpoint', "Add Function Breakpoint"); constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { super(id, label, 'debug-action add-function-breakpoint', debugService, keybindingService); - this.toDispose.push(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); + this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); } run(): Promise { @@ -317,12 +308,12 @@ export class AddFunctionBreakpointAction extends AbstractDebugAction { export class AddWatchExpressionAction extends AbstractDebugAction { static readonly ID = 'workbench.debug.viewlet.action.addWatchExpression'; - static LABEL = nls.localize('addWatchExpression', "Add Expression"); + static readonly LABEL = nls.localize('addWatchExpression', "Add Expression"); constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { super(id, label, 'debug-action add-watch-expression', debugService, keybindingService); - this.toDispose.push(this.debugService.getModel().onDidChangeWatchExpressions(() => this.updateEnablement())); - this.toDispose.push(this.debugService.getViewModel().onDidSelectExpression(() => this.updateEnablement())); + this._register(this.debugService.getModel().onDidChangeWatchExpressions(() => this.updateEnablement())); + this._register(this.debugService.getViewModel().onDidSelectExpression(() => this.updateEnablement())); } run(): Promise { @@ -338,11 +329,11 @@ export class AddWatchExpressionAction extends AbstractDebugAction { export class RemoveAllWatchExpressionsAction extends AbstractDebugAction { static readonly ID = 'workbench.debug.viewlet.action.removeAllWatchExpressions'; - static LABEL = nls.localize('removeAllWatchExpressions', "Remove All Expressions"); + static readonly LABEL = nls.localize('removeAllWatchExpressions', "Remove All Expressions"); constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { super(id, label, 'debug-action remove-all', debugService, keybindingService); - this.toDispose.push(this.debugService.getModel().onDidChangeWatchExpressions(() => this.updateEnablement())); + this._register(this.debugService.getModel().onDidChangeWatchExpressions(() => this.updateEnablement())); } run(): Promise { @@ -357,7 +348,7 @@ export class RemoveAllWatchExpressionsAction extends AbstractDebugAction { export class FocusSessionAction extends AbstractDebugAction { static readonly ID = 'workbench.action.debug.focusProcess'; - static LABEL = nls.localize('focusSession', "Focus Session"); + static readonly LABEL = nls.localize('focusSession', "Focus Session"); constructor(id: string, label: string, @IDebugService debugService: IDebugService, @@ -367,8 +358,8 @@ export class FocusSessionAction extends AbstractDebugAction { super(id, label, '', debugService, keybindingService); } - run(session: IDebugSession): Promise { - this.debugService.focusStackFrame(undefined, undefined, session, true); + async run(session: IDebugSession): Promise { + await this.debugService.focusStackFrame(undefined, undefined, session, true); const stackFrame = this.debugService.getViewModel().focusedStackFrame; if (stackFrame) { return stackFrame.openInEditor(this.editorService, true); @@ -380,7 +371,7 @@ export class FocusSessionAction extends AbstractDebugAction { export class CopyValueAction extends Action { static readonly ID = 'workbench.debug.viewlet.action.copyValue'; - static LABEL = nls.localize('copyValue', "Copy Value"); + static readonly LABEL = nls.localize('copyValue', "Copy Value"); constructor( id: string, label: string, private value: any, private context: string, diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts index 784694a387a..ea6cc952742 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts @@ -104,8 +104,8 @@ class LogPointAction extends EditorAction { export class RunToCursorAction extends EditorAction { - public static ID = 'editor.debug.action.runToCursor'; - public static LABEL = nls.localize('runToCursor', "Run to Cursor"); + public static readonly ID = 'editor.debug.action.runToCursor'; + public static readonly LABEL = nls.localize('runToCursor', "Run to Cursor"); constructor() { super({ diff --git a/src/vs/workbench/contrib/debug/browser/debugHover.ts b/src/vs/workbench/contrib/debug/browser/debugHover.ts index 506aafc1781..13f6651d59b 100644 --- a/src/vs/workbench/contrib/debug/browser/debugHover.ts +++ b/src/vs/workbench/contrib/debug/browser/debugHover.ts @@ -94,12 +94,12 @@ export class DebugHoverWidget implements IContentWidget { if (colors.editorHoverBackground) { this.domNode.style.backgroundColor = colors.editorHoverBackground.toString(); } else { - this.domNode.style.backgroundColor = null; + this.domNode.style.backgroundColor = ''; } if (colors.editorHoverBorder) { this.domNode.style.border = `1px solid ${colors.editorHoverBorder}`; } else { - this.domNode.style.border = null; + this.domNode.style.border = ''; } })); this.toDispose.push(this.tree.onDidChangeContentHeight(() => this.layoutTreeAndContainer())); @@ -174,7 +174,7 @@ export class DebugHoverWidget implements IContentWidget { return this.doShow(pos, expression, focus); } - private static _HOVER_HIGHLIGHT_DECORATION_OPTIONS = ModelDecorationOptions.register({ + private static readonly _HOVER_HIGHLIGHT_DECORATION_OPTIONS = ModelDecorationOptions.register({ className: 'hoverHighlight' }); diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index ccb8004fccc..cdef1b6d531 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -24,7 +24,6 @@ import * as debugactions from 'vs/workbench/contrib/debug/browser/debugActions'; import { ConfigurationManager } from 'vs/workbench/contrib/debug/browser/debugConfigurationManager'; import Constants from 'vs/workbench/contrib/markers/browser/constants'; import { ITaskService, ITaskSummary } from 'vs/workbench/contrib/tasks/common/taskService'; -import { TaskError } from 'vs/workbench/contrib/tasks/common/taskSystem'; import { VIEWLET_ID as EXPLORER_VIEWLET_ID } from 'vs/workbench/contrib/files/common/files'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; @@ -144,13 +143,13 @@ export class DebugService implements IDebugService { session.configuration.request = 'attach'; session.configuration.port = event.port; session.setSubId(event.subId); - this.launchOrAttachToSession(session).then(undefined, errors.onUnexpectedError); + this.launchOrAttachToSession(session); } })); this.toDispose.push(this.extensionHostDebugService.onTerminateSession(event => { const session = this.model.getSession(event.sessionId); if (session && session.subId === event.subId) { - session.disconnect().then(undefined, errors.onUnexpectedError); + session.disconnect(); } })); this.toDispose.push(this.extensionHostDebugService.onLogToSession(event => { @@ -253,96 +252,99 @@ export class DebugService implements IDebugService { * main entry point * properly manages compounds, checks for errors and handles the initializing state. */ - startDebugging(launch: ILaunch | undefined, configOrName?: IConfig | string, options?: IDebugSessionOptions): Promise { + async startDebugging(launch: ILaunch | undefined, configOrName?: IConfig | string, options?: IDebugSessionOptions): Promise { this.startInitializingState(); - // make sure to save all files and that the configuration is up to date - return this.extensionService.activateByEvent('onDebug').then(() => { - return this.textFileService.saveAll().then(() => this.configurationService.reloadConfiguration(launch ? launch.workspace : undefined).then(() => { - return this.extensionService.whenInstalledExtensionsRegistered().then(() => { + try { + // make sure to save all files and that the configuration is up to date + await this.extensionService.activateByEvent('onDebug'); + await this.textFileService.saveAll(); + await this.configurationService.reloadConfiguration(launch ? launch.workspace : undefined); + await this.extensionService.whenInstalledExtensionsRegistered(); - let config: IConfig | undefined; - let compound: ICompound | undefined; - if (!configOrName) { - configOrName = this.configurationManager.selectedConfiguration.name; + let config: IConfig | undefined; + let compound: ICompound | undefined; + if (!configOrName) { + configOrName = this.configurationManager.selectedConfiguration.name; + } + if (typeof configOrName === 'string' && launch) { + config = launch.getConfiguration(configOrName); + compound = launch.getCompound(configOrName); + + const sessions = this.model.getSessions(); + const alreadyRunningMessage = nls.localize('configurationAlreadyRunning', "There is already a debug configuration \"{0}\" running.", configOrName); + if (sessions.some(s => s.configuration.name === configOrName && (!launch || !launch.workspace || !s.root || s.root.uri.toString() === launch.workspace.uri.toString()))) { + throw new Error(alreadyRunningMessage); + } + if (compound && compound.configurations && sessions.some(p => compound!.configurations.indexOf(p.configuration.name) !== -1)) { + throw new Error(alreadyRunningMessage); + } + } else if (typeof configOrName !== 'string') { + config = configOrName; + } + + if (compound) { + // we are starting a compound debug, first do some error checking and than start each configuration in the compound + if (!compound.configurations) { + throw new Error(nls.localize({ key: 'compoundMustHaveConfigurations', comment: ['compound indicates a "compounds" configuration item', '"configurations" is an attribute and should not be localized'] }, + "Compound must have \"configurations\" attribute set in order to start multiple configurations.")); + } + + const values = await Promise.all(compound.configurations.map(configData => { + const name = typeof configData === 'string' ? configData : configData.name; + if (name === compound!.name) { + return Promise.resolve(false); } - if (typeof configOrName === 'string' && launch) { - config = launch.getConfiguration(configOrName); - compound = launch.getCompound(configOrName); - const sessions = this.model.getSessions(); - const alreadyRunningMessage = nls.localize('configurationAlreadyRunning', "There is already a debug configuration \"{0}\" running.", configOrName); - if (sessions.some(s => s.configuration.name === configOrName && (!launch || !launch.workspace || !s.root || s.root.uri.toString() === launch.workspace.uri.toString()))) { - return Promise.reject(new Error(alreadyRunningMessage)); + let launchForName: ILaunch | undefined; + if (typeof configData === 'string') { + const launchesContainingName = this.configurationManager.getLaunches().filter(l => !!l.getConfiguration(name)); + if (launchesContainingName.length === 1) { + launchForName = launchesContainingName[0]; + } else if (launch && launchesContainingName.length > 1 && launchesContainingName.indexOf(launch) >= 0) { + // If there are multiple launches containing the configuration give priority to the configuration in the current launch + launchForName = launch; + } else { + throw new Error(launchesContainingName.length === 0 ? nls.localize('noConfigurationNameInWorkspace', "Could not find launch configuration '{0}' in the workspace.", name) + : nls.localize('multipleConfigurationNamesInWorkspace', "There are multiple launch configurations '{0}' in the workspace. Use folder name to qualify the configuration.", name)); } - if (compound && compound.configurations && sessions.some(p => compound!.configurations.indexOf(p.configuration.name) !== -1)) { - return Promise.reject(new Error(alreadyRunningMessage)); + } else if (configData.folder) { + const launchesMatchingConfigData = this.configurationManager.getLaunches().filter(l => l.workspace && l.workspace.name === configData.folder && !!l.getConfiguration(configData.name)); + if (launchesMatchingConfigData.length === 1) { + launchForName = launchesMatchingConfigData[0]; + } else { + throw new Error(nls.localize('noFolderWithName', "Can not find folder with name '{0}' for configuration '{1}' in compound '{2}'.", configData.folder, configData.name, compound!.name)); } - } else if (typeof configOrName !== 'string') { - config = configOrName; } - if (compound) { - // we are starting a compound debug, first do some error checking and than start each configuration in the compound - if (!compound.configurations) { - return Promise.reject(new Error(nls.localize({ key: 'compoundMustHaveConfigurations', comment: ['compound indicates a "compounds" configuration item', '"configurations" is an attribute and should not be localized'] }, - "Compound must have \"configurations\" attribute set in order to start multiple configurations."))); - } + return this.createSession(launchForName, launchForName!.getConfiguration(name), options); + })); - return Promise.all(compound.configurations.map(configData => { - const name = typeof configData === 'string' ? configData : configData.name; - if (name === compound!.name) { - return Promise.resolve(false); - } + const result = values.every(success => !!success); // Compound launch is a success only if each configuration launched successfully + this.endInitializingState(); + return result; + } - let launchForName: ILaunch | undefined; - if (typeof configData === 'string') { - const launchesContainingName = this.configurationManager.getLaunches().filter(l => !!l.getConfiguration(name)); - if (launchesContainingName.length === 1) { - launchForName = launchesContainingName[0]; - } else if (launch && launchesContainingName.length > 1 && launchesContainingName.indexOf(launch) >= 0) { - // If there are multiple launches containing the configuration give priority to the configuration in the current launch - launchForName = launch; - } else { - return Promise.reject(new Error(launchesContainingName.length === 0 ? nls.localize('noConfigurationNameInWorkspace', "Could not find launch configuration '{0}' in the workspace.", name) - : nls.localize('multipleConfigurationNamesInWorkspace', "There are multiple launch configurations '{0}' in the workspace. Use folder name to qualify the configuration.", name))); - } - } else if (configData.folder) { - const launchesMatchingConfigData = this.configurationManager.getLaunches().filter(l => l.workspace && l.workspace.name === configData.folder && !!l.getConfiguration(configData.name)); - if (launchesMatchingConfigData.length === 1) { - launchForName = launchesMatchingConfigData[0]; - } else { - return Promise.reject(new Error(nls.localize('noFolderWithName', "Can not find folder with name '{0}' for configuration '{1}' in compound '{2}'.", configData.folder, configData.name, compound!.name))); - } - } + if (configOrName && !config) { + const message = !!launch ? nls.localize('configMissing', "Configuration '{0}' is missing in 'launch.json'.", typeof configOrName === 'string' ? configOrName : JSON.stringify(configOrName)) : + nls.localize('launchJsonDoesNotExist', "'launch.json' does not exist."); + throw new Error(message); + } - return this.createSession(launchForName, launchForName!.getConfiguration(name), options); - })).then(values => values.every(success => !!success)); // Compound launch is a success only if each configuration launched successfully - } - - if (configOrName && !config) { - const message = !!launch ? nls.localize('configMissing', "Configuration '{0}' is missing in 'launch.json'.", typeof configOrName === 'string' ? configOrName : JSON.stringify(configOrName)) : - nls.localize('launchJsonDoesNotExist', "'launch.json' does not exist."); - return Promise.reject(new Error(message)); - } - - return this.createSession(launch, config, options); - }); - })); - }).then(success => { + const result = await this.createSession(launch, config, options); + this.endInitializingState(); + return result; + } catch (err) { // make sure to get out of initializing state, and propagate the result - this.endInitializingState(); - return success; - }, err => { this.endInitializingState(); return Promise.reject(err); - }); + } } /** * gets the debugger for the type, resolves configurations by providers, substitutes variables and runs prelaunch tasks */ - private createSession(launch: ILaunch | undefined, config: IConfig | undefined, options?: IDebugSessionOptions): Promise { + private async createSession(launch: ILaunch | undefined, config: IConfig | undefined, options?: IDebugSessionOptions): Promise { // We keep the debug type in a separate variable 'type' so that a no-folder config has no attributes. // Storing the type in the config would break extensions that assume that the no-folder case is indicated by an empty config. let type: string | undefined; @@ -358,66 +360,71 @@ export class DebugService implements IDebugService { config!.noDebug = true; } - const debuggerThenable: Promise = type ? Promise.resolve() : this.configurationManager.guessDebugger().then(dbgr => { type = dbgr && dbgr.type; }); - return debuggerThenable.then(() => { - this.initCancellationToken = new CancellationTokenSource(); - return this.configurationManager.resolveConfigurationByProviders(launch && launch.workspace ? launch.workspace.uri : undefined, type, config!, this.initCancellationToken.token).then(config => { - // a falsy config indicates an aborted launch - if (config && config.type) { - return this.substituteVariables(launch, config).then(resolvedConfig => { + if (!type) { + const guess = await this.configurationManager.guessDebugger(); + if (guess) { + type = guess.type; + } + } - if (!resolvedConfig) { - // User canceled resolving of interactive variables, silently return - return false; - } + this.initCancellationToken = new CancellationTokenSource(); + const configByProviders = await this.configurationManager.resolveConfigurationByProviders(launch && launch.workspace ? launch.workspace.uri : undefined, type, config!, this.initCancellationToken.token); + // a falsy config indicates an aborted launch + if (configByProviders && configByProviders.type) { + try { + const resolvedConfig = await this.substituteVariables(launch, configByProviders); - if (!this.configurationManager.getDebugger(resolvedConfig.type) || (config.request !== 'attach' && config.request !== 'launch')) { - let message: string; - if (config.request !== 'attach' && config.request !== 'launch') { - message = config.request ? nls.localize('debugRequestNotSupported', "Attribute '{0}' has an unsupported value '{1}' in the chosen debug configuration.", 'request', config.request) - : nls.localize('debugRequesMissing', "Attribute '{0}' is missing from the chosen debug configuration.", 'request'); - - } else { - message = resolvedConfig.type ? nls.localize('debugTypeNotSupported', "Configured debug type '{0}' is not supported.", resolvedConfig.type) : - nls.localize('debugTypeMissing', "Missing property 'type' for the chosen launch configuration."); - } - - return this.showError(message).then(() => false); - } - - const workspace = launch ? launch.workspace : undefined; - return this.runTaskAndCheckErrors(workspace, resolvedConfig.preLaunchTask).then(result => { - if (result === TaskRunResult.Success) { - return this.doCreateSession(workspace, { resolved: resolvedConfig, unresolved: unresolvedConfig }, options); - } - return false; - }); - }, err => { - if (err && err.message) { - return this.showError(err.message).then(() => false); - } - if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) { - return this.showError(nls.localize('noFolderWorkspaceDebugError', "The active file can not be debugged. Make sure it is saved and that you have a debug extension installed for that file type.")) - .then(() => false); - } - - return !!launch && launch.openConfigFile(false, true, undefined, this.initCancellationToken ? this.initCancellationToken.token : undefined).then(() => false); - }); + if (!resolvedConfig) { + // User canceled resolving of interactive variables, silently return + return false; } - if (launch && type && config === null) { // show launch.json only for "config" being "null". - return launch.openConfigFile(false, true, type, this.initCancellationToken ? this.initCancellationToken.token : undefined).then(() => false); + if (!this.configurationManager.getDebugger(resolvedConfig.type) || (configByProviders.request !== 'attach' && configByProviders.request !== 'launch')) { + let message: string; + if (configByProviders.request !== 'attach' && configByProviders.request !== 'launch') { + message = configByProviders.request ? nls.localize('debugRequestNotSupported', "Attribute '{0}' has an unsupported value '{1}' in the chosen debug configuration.", 'request', configByProviders.request) + : nls.localize('debugRequesMissing', "Attribute '{0}' is missing from the chosen debug configuration.", 'request'); + + } else { + message = resolvedConfig.type ? nls.localize('debugTypeNotSupported', "Configured debug type '{0}' is not supported.", resolvedConfig.type) : + nls.localize('debugTypeMissing', "Missing property 'type' for the chosen launch configuration."); + } + + await this.showError(message); + return false; + } + + const workspace = launch ? launch.workspace : undefined; + const taskResult = await this.runTaskAndCheckErrors(workspace, resolvedConfig.preLaunchTask); + if (taskResult === TaskRunResult.Success) { + return this.doCreateSession(workspace, { resolved: resolvedConfig, unresolved: unresolvedConfig }, options); + } + return false; + } catch (err) { + if (err && err.message) { + await this.showError(err.message); + } else if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) { + await this.showError(nls.localize('noFolderWorkspaceDebugError', "The active file can not be debugged. Make sure it is saved and that you have a debug extension installed for that file type.")); + } + if (launch) { + await launch.openConfigFile(false, true, undefined, this.initCancellationToken ? this.initCancellationToken.token : undefined); } return false; - }); - }); + } + } + + if (launch && type && configByProviders === null) { // show launch.json only for "config" being "null". + await launch.openConfigFile(false, true, type, this.initCancellationToken ? this.initCancellationToken.token : undefined); + } + + return false; } /** * instantiates the new session, initializes the session, registers session listeners and reports telemetry */ - private doCreateSession(root: IWorkspaceFolder | undefined, configuration: { resolved: IConfig, unresolved: IConfig | undefined }, options?: IDebugSessionOptions): Promise { + private async doCreateSession(root: IWorkspaceFolder | undefined, configuration: { resolved: IConfig, unresolved: IConfig | undefined }, options?: IDebugSessionOptions): Promise { const session = this.instantiationService.createInstance(DebugSession, configuration, root, this.model, options); this.model.addSession(session); @@ -431,10 +438,11 @@ export class DebugService implements IDebugService { const openDebug = this.configurationService.getValue('debug').openDebug; // Open debug viewlet based on the visibility of the side bar and openDebug setting. Do not open for 'run without debug' if (!configuration.resolved.noDebug && (openDebug === 'openOnSessionStart' || (openDebug === 'openOnFirstSessionStart' && this.viewModel.firstSessionStart))) { - this.viewletService.openViewlet(VIEWLET_ID).then(undefined, errors.onUnexpectedError); + await this.viewletService.openViewlet(VIEWLET_ID); } - return this.launchOrAttachToSession(session).then(() => { + try { + await this.launchOrAttachToSession(session); const internalConsoleOptions = session.configuration.internalConsoleOptions || this.configurationService.getValue('debug').internalConsoleOptions; if (internalConsoleOptions === 'openOnSessionStart' || (this.viewModel.firstSessionStart && internalConsoleOptions === 'openOnFirstSessionStart')) { @@ -452,12 +460,14 @@ export class DebugService implements IDebugService { // since the initialized response has arrived announce the new Session (including extensions) this._onDidNewSession.fire(session); - return this.telemetryDebugSessionStart(root, session.configuration.type); - }).then(() => true, (error: Error | string) => { + await this.telemetryDebugSessionStart(root, session.configuration.type); + + return true; + } catch (error) { if (errors.isPromiseCanceledError(error)) { // don't show 'canceled' error messages to the user #7906 - return Promise.resolve(false); + return false; } // Show the repl if some error got logged there #5870 @@ -467,27 +477,29 @@ export class DebugService implements IDebugService { if (session.configuration && session.configuration.request === 'attach' && session.configuration.__autoAttach) { // ignore attach timeouts in auto attach mode - return Promise.resolve(false); + return false; } const errorMessage = error instanceof Error ? error.message : error; this.telemetryDebugMisconfiguration(session.configuration ? session.configuration.type : undefined, errorMessage); - return this.showError(errorMessage, isErrorWithActions(error) ? error.actions : []).then(() => false); - }); + + await this.showError(errorMessage, isErrorWithActions(error) ? error.actions : []); + return false; + } } - private launchOrAttachToSession(session: IDebugSession, forceFocus = false): Promise { + private async launchOrAttachToSession(session: IDebugSession, forceFocus = false): Promise { const dbgr = this.configurationManager.getDebugger(session.configuration.type); - return session.initialize(dbgr!).then(() => { - return session.launchOrAttach(session.configuration).then(() => { - if (forceFocus || !this.viewModel.focusedSession) { - this.focusStackFrame(undefined, undefined, session); - } - }); - }).then(undefined, err => { + try { + await session.initialize(dbgr!); + await session.launchOrAttach(session.configuration); + if (forceFocus || !this.viewModel.focusedSession) { + await this.focusStackFrame(undefined, undefined, session); + } + } catch (err) { session.shutdown(); return Promise.reject(err); - }); + } } private registerSessionListeners(session: IDebugSession): void { @@ -506,7 +518,7 @@ export class DebugService implements IDebugService { } })); - this.toDispose.push(session.onDidEndAdapter(adapterExitEvent => { + this.toDispose.push(session.onDidEndAdapter(async adapterExitEvent => { if (adapterExitEvent.error) { this.notificationService.error(nls.localize('debugAdapterCrash', "Debug adapter process has terminated unexpectedly ({0})", adapterExitEvent.error.message || adapterExitEvent.error.toString())); @@ -520,9 +532,11 @@ export class DebugService implements IDebugService { this.telemetryDebugSessionStop(session, adapterExitEvent); if (session.configuration.postDebugTask) { - this.runTask(session.root, session.configuration.postDebugTask).then(undefined, err => - this.notificationService.error(err) - ); + try { + await this.runTask(session.root, session.configuration.postDebugTask); + } catch (err) { + this.notificationService.error(err); + } } session.shutdown(); this.endInitializingState(); @@ -530,7 +544,7 @@ export class DebugService implements IDebugService { const focusedSession = this.viewModel.focusedSession; if (focusedSession && focusedSession.getId() === session.getId()) { - this.focusStackFrame(undefined); + await this.focusStackFrame(undefined); } if (this.model.getSessions().length === 0) { @@ -548,87 +562,93 @@ export class DebugService implements IDebugService { })); } - restartSession(session: IDebugSession, restartData?: any): Promise { - return this.textFileService.saveAll().then(() => { - const isAutoRestart = !!restartData; - const runTasks: () => Promise = () => { - if (isAutoRestart) { - // Do not run preLaunch and postDebug tasks for automatic restarts - return Promise.resolve(TaskRunResult.Success); + async restartSession(session: IDebugSession, restartData?: any): Promise { + await this.textFileService.saveAll(); + const isAutoRestart = !!restartData; + + const runTasks: () => Promise = async () => { + if (isAutoRestart) { + // Do not run preLaunch and postDebug tasks for automatic restarts + return Promise.resolve(TaskRunResult.Success); + } + + await this.runTask(session.root, session.configuration.postDebugTask); + return this.runTaskAndCheckErrors(session.root, session.configuration.preLaunchTask); + }; + + if (session.capabilities.supportsRestartRequest) { + const taskResult = await runTasks(); + if (taskResult === TaskRunResult.Success) { + await session.restart(); + } + + return; + } + + if (isExtensionHostDebugging(session.configuration)) { + const taskResult = await runTasks(); + if (taskResult === TaskRunResult.Success) { + this.extensionHostDebugService.reload(session.getId()); + } + + return; + } + + const shouldFocus = !!this.viewModel.focusedSession && session.getId() === this.viewModel.focusedSession.getId(); + // If the restart is automatic -> disconnect, otherwise -> terminate #55064 + if (isAutoRestart) { + await session.disconnect(true); + } else { + await session.terminate(true); + } + + return new Promise((c, e) => { + setTimeout(async () => { + const taskResult = await runTasks(); + if (taskResult !== TaskRunResult.Success) { + return; } - return this.runTask(session.root, session.configuration.postDebugTask) - .then(() => this.runTaskAndCheckErrors(session.root, session.configuration.preLaunchTask)); - }; + // Read the configuration again if a launch.json has been changed, if not just use the inmemory configuration + let needsToSubstitute = false; + let unresolved: IConfig | undefined; + const launch = session.root ? this.configurationManager.getLaunch(session.root.uri) : undefined; + if (launch) { + unresolved = launch.getConfiguration(session.configuration.name); + if (unresolved && !equals(unresolved, session.unresolvedConfiguration)) { + // Take the type from the session since the debug extension might overwrite it #21316 + unresolved.type = session.configuration.type; + unresolved.noDebug = session.configuration.noDebug; + needsToSubstitute = true; + } + } - if (session.capabilities.supportsRestartRequest) { - return runTasks().then(taskResult => taskResult === TaskRunResult.Success ? session.restart() : undefined); - } + let resolved: IConfig | undefined | null = session.configuration; + if (launch && needsToSubstitute && unresolved) { + this.initCancellationToken = new CancellationTokenSource(); + const resolvedByProviders = await this.configurationManager.resolveConfigurationByProviders(launch.workspace ? launch.workspace.uri : undefined, unresolved.type, unresolved, this.initCancellationToken.token); + if (resolvedByProviders) { + resolved = await this.substituteVariables(launch, resolvedByProviders); + } else { + resolved = resolvedByProviders; + } + } - if (isExtensionHostDebugging(session.configuration)) { - return runTasks().then(taskResult => taskResult === TaskRunResult.Success ? this.extensionHostDebugService.reload(session.getId()) : undefined); - } + if (!resolved) { + return c(undefined); + } - const shouldFocus = !!this.viewModel.focusedSession && session.getId() === this.viewModel.focusedSession.getId(); - // If the restart is automatic -> disconnect, otherwise -> terminate #55064 - return (isAutoRestart ? session.disconnect(true) : session.terminate(true)).then(() => { + session.setConfiguration({ resolved, unresolved }); + session.configuration.__restart = restartData; - return new Promise((c, e) => { - setTimeout(() => { - runTasks().then(taskResult => { - if (taskResult !== TaskRunResult.Success) { - return; - } - - // Read the configuration again if a launch.json has been changed, if not just use the inmemory configuration - let needsToSubstitute = false; - let unresolved: IConfig | undefined; - const launch = session.root ? this.configurationManager.getLaunch(session.root.uri) : undefined; - if (launch) { - unresolved = launch.getConfiguration(session.configuration.name); - if (unresolved && !equals(unresolved, session.unresolvedConfiguration)) { - // Take the type from the session since the debug extension might overwrite it #21316 - unresolved.type = session.configuration.type; - unresolved.noDebug = session.configuration.noDebug; - needsToSubstitute = true; - } - } - - let substitutionThenable: Promise = Promise.resolve(session.configuration); - if (launch && needsToSubstitute && unresolved) { - this.initCancellationToken = new CancellationTokenSource(); - substitutionThenable = this.configurationManager.resolveConfigurationByProviders(launch.workspace ? launch.workspace.uri : undefined, unresolved.type, unresolved, this.initCancellationToken.token) - .then(resolved => { - if (resolved) { - // start debugging - return this.substituteVariables(launch, resolved); - } else if (resolved === null) { - // abort debugging silently and open launch.json - return Promise.resolve(null); - } else { - // abort debugging silently - return Promise.resolve(undefined); - } - }); - } - substitutionThenable.then(resolved => { - - if (!resolved) { - return c(undefined); - } - - session.setConfiguration({ resolved, unresolved }); - session.configuration.__restart = restartData; - - this.launchOrAttachToSession(session, shouldFocus).then(() => { - this._onDidNewSession.fire(session); - c(undefined); - }, err => e(err)); - }); - }); - }, 300); - }); - }); + try { + await this.launchOrAttachToSession(session, shouldFocus); + this._onDidNewSession.fire(session); + c(undefined); + } catch (error) { + e(error); + } + }, 300); }); } @@ -646,7 +666,7 @@ export class DebugService implements IDebugService { return Promise.all(sessions.map(s => s.terminate())); } - private substituteVariables(launch: ILaunch | undefined, config: IConfig): Promise { + private async substituteVariables(launch: ILaunch | undefined, config: IConfig): Promise { const dbg = this.configurationManager.getDebugger(config.type); if (dbg) { let folder: IWorkspaceFolder | undefined = undefined; @@ -658,12 +678,12 @@ export class DebugService implements IDebugService { folder = folders[0]; } } - return dbg.substituteVariables(folder, config).then(config => { - return config; - }, (err: Error) => { + try { + return await dbg.substituteVariables(folder, config); + } catch (err) { this.showError(err.message); return undefined; // bail out - }); + } } return Promise.resolve(config); } @@ -681,9 +701,9 @@ export class DebugService implements IDebugService { //---- task management - private runTaskAndCheckErrors(root: IWorkspaceFolder | undefined, taskId: string | TaskIdentifier | undefined): Promise { - - return this.runTask(root, taskId).then((taskSummary: ITaskSummary) => { + private async runTaskAndCheckErrors(root: IWorkspaceFolder | undefined, taskId: string | TaskIdentifier | undefined): Promise { + try { + const taskSummary = await this.runTask(root, taskId); const errorCount = taskId ? this.markerService.getStatistics().errors : 0; const successExitCode = taskSummary && taskSummary.exitCode === 0; @@ -702,34 +722,35 @@ export class DebugService implements IDebugService { ? nls.localize('preLaunchTaskErrors', "Errors exist after running preLaunchTask '{0}'.", taskLabel) : errorCount === 1 ? nls.localize('preLaunchTaskError', "Error exists after running preLaunchTask '{0}'.", taskLabel) - : nls.localize('preLaunchTaskExitCode', "The preLaunchTask '{0}' terminated with exit code {1}.", taskLabel, taskSummary.exitCode); + : nls.localize('preLaunchTaskExitCode', "The preLaunchTask '{0}' terminated with exit code {1}.", taskLabel, taskSummary ? taskSummary.exitCode : 0); - return this.dialogService.show(severity.Warning, message, [nls.localize('debugAnyway', "Debug Anyway"), nls.localize('showErrors', "Show Errors"), nls.localize('cancel', "Cancel")], { + const result = await this.dialogService.show(severity.Warning, message, [nls.localize('debugAnyway', "Debug Anyway"), nls.localize('showErrors', "Show Errors"), nls.localize('cancel', "Cancel")], { checkbox: { label: nls.localize('remember', "Remember my choice in user settings"), }, cancelId: 2 - }).then(result => { - if (result.choice === 2) { - return Promise.resolve(TaskRunResult.Failure); - } - const debugAnyway = result.choice === 0; - if (result.checkboxChecked) { - this.configurationService.updateValue('debug.onTaskErrors', debugAnyway ? 'debugAnyway' : 'showErrors'); - } - if (debugAnyway) { - return TaskRunResult.Success; - } - - this.panelService.openPanel(Constants.MARKERS_PANEL_ID); - return Promise.resolve(TaskRunResult.Failure); }); - }, (err: TaskError) => { - return this.showError(err.message, [this.taskService.configureAction()]); - }); + + if (result.choice === 2) { + return Promise.resolve(TaskRunResult.Failure); + } + const debugAnyway = result.choice === 0; + if (result.checkboxChecked) { + this.configurationService.updateValue('debug.onTaskErrors', debugAnyway ? 'debugAnyway' : 'showErrors'); + } + if (debugAnyway) { + return TaskRunResult.Success; + } + + this.panelService.openPanel(Constants.MARKERS_PANEL_ID); + return Promise.resolve(TaskRunResult.Failure); + } catch (err) { + await this.showError(err.message, [this.taskService.configureAction()]); + return TaskRunResult.Failure; + } } - private runTask(root: IWorkspaceFolder | undefined, taskId: string | TaskIdentifier | undefined): Promise { + private async runTask(root: IWorkspaceFolder | undefined, taskId: string | TaskIdentifier | undefined): Promise { if (!taskId) { return Promise.resolve(null); } @@ -737,58 +758,57 @@ export class DebugService implements IDebugService { return Promise.reject(new Error(nls.localize('invalidTaskReference', "Task '{0}' can not be referenced from a launch configuration that is in a different workspace folder.", typeof taskId === 'string' ? taskId : taskId.type))); } // run a task before starting a debug session - return this.taskService.getTask(root, taskId).then(task => { - if (!task) { - const errorMessage = typeof taskId === 'string' - ? nls.localize('DebugTaskNotFoundWithTaskId', "Could not find the task '{0}'.", taskId) - : nls.localize('DebugTaskNotFound', "Could not find the specified task."); - return Promise.reject(createErrorWithActions(errorMessage)); + const task = await this.taskService.getTask(root, taskId); + if (!task) { + const errorMessage = typeof taskId === 'string' + ? nls.localize('DebugTaskNotFoundWithTaskId', "Could not find the task '{0}'.", taskId) + : nls.localize('DebugTaskNotFound', "Could not find the specified task."); + return Promise.reject(createErrorWithActions(errorMessage)); + } + + // If a task is missing the problem matcher the promise will never complete, so we need to have a workaround #35340 + let taskStarted = false; + const promise: Promise = this.taskService.getActiveTasks().then(tasks => { + if (tasks.filter(t => t._id === task._id).length) { + // task is already running - nothing to do. + return Promise.resolve(null); + } + once(e => ((e.kind === TaskEventKind.Active) || (e.kind === TaskEventKind.DependsOnStarted)) && e.taskId === task._id, this.taskService.onDidStateChange)(() => { + // Task is active, so everything seems to be fine, no need to prompt after 10 seconds + // Use case being a slow running task should not be prompted even though it takes more than 10 seconds + taskStarted = true; + }); + const taskPromise = this.taskService.run(task); + if (task.configurationProperties.isBackground) { + return new Promise((c, e) => once(e => e.kind === TaskEventKind.Inactive && e.taskId === task._id, this.taskService.onDidStateChange)(() => { + taskStarted = true; + c(null); + })); } - // If a task is missing the problem matcher the promise will never complete, so we need to have a workaround #35340 - let taskStarted = false; - const promise: Promise = this.taskService.getActiveTasks().then(tasks => { - if (tasks.filter(t => t._id === task._id).length) { - // task is already running - nothing to do. - return Promise.resolve(null); + return taskPromise; + }); + + return new Promise((c, e) => { + promise.then(result => { + taskStarted = true; + c(result); + }, error => e(error)); + + setTimeout(() => { + if (!taskStarted) { + const errorMessage = typeof taskId === 'string' + ? nls.localize('taskNotTrackedWithTaskId', "The specified task cannot be tracked.") + : nls.localize('taskNotTracked', "The task '{0}' cannot be tracked.", JSON.stringify(taskId)); + e({ severity: severity.Error, message: errorMessage }); } - once(e => ((e.kind === TaskEventKind.Active) || (e.kind === TaskEventKind.DependsOnStarted)) && e.taskId === task._id, this.taskService.onDidStateChange)(() => { - // Task is active, so everything seems to be fine, no need to prompt after 10 seconds - // Use case being a slow running task should not be prompted even though it takes more than 10 seconds - taskStarted = true; - }); - const taskPromise = this.taskService.run(task); - if (task.configurationProperties.isBackground) { - return new Promise((c, e) => once(e => e.kind === TaskEventKind.Inactive && e.taskId === task._id, this.taskService.onDidStateChange)(() => { - taskStarted = true; - c(null); - })); - } - - return taskPromise; - }); - - return new Promise((c, e) => { - promise.then(result => { - taskStarted = true; - c(result); - }, error => e(error)); - - setTimeout(() => { - if (!taskStarted) { - const errorMessage = typeof taskId === 'string' - ? nls.localize('taskNotTrackedWithTaskId', "The specified task cannot be tracked.") - : nls.localize('taskNotTracked', "The task '{0}' cannot be tracked.", JSON.stringify(taskId)); - e({ severity: severity.Error, message: errorMessage }); - } - }, 10000); - }); + }, 10000); }); } //---- focus management - focusStackFrame(stackFrame: IStackFrame | undefined, thread?: IThread, session?: IDebugSession, explicit?: boolean): void { + async focusStackFrame(stackFrame: IStackFrame | undefined, thread?: IThread, session?: IDebugSession, explicit?: boolean): Promise { if (!session) { if (stackFrame || thread) { session = stackFrame ? stackFrame.thread.session : thread!.session; @@ -817,18 +837,17 @@ export class DebugService implements IDebugService { } if (stackFrame) { - stackFrame.openInEditor(this.editorService, true).then(editor => { - if (editor) { - const control = editor.getControl(); - if (stackFrame && isCodeEditor(control) && control.hasModel()) { - const model = control.getModel(); - if (stackFrame.range.startLineNumber <= model.getLineCount()) { - const lineContent = control.getModel().getLineContent(stackFrame.range.startLineNumber); - aria.alert(nls.localize('debuggingPaused', "Debugging paused {0}, {1} {2} {3}", thread && thread.stoppedDetails ? `, reason ${thread.stoppedDetails.reason}` : '', stackFrame.source ? stackFrame.source.name : '', stackFrame.range.startLineNumber, lineContent)); - } + const editor = await stackFrame.openInEditor(this.editorService, true); + if (editor) { + const control = editor.getControl(); + if (stackFrame && isCodeEditor(control) && control.hasModel()) { + const model = control.getModel(); + if (stackFrame.range.startLineNumber <= model.getLineCount()) { + const lineContent = control.getModel().getLineContent(stackFrame.range.startLineNumber); + aria.alert(nls.localize('debuggingPaused', "Debugging paused {0}, {1} {2} {3}", thread && thread.stoppedDetails ? `, reason ${thread.stoppedDetails.reason}` : '', stackFrame.source ? stackFrame.source.name : '', stackFrame.range.startLineNumber, lineContent)); } } - }); + } } if (session) { this.debugType.set(session.configuration.type); @@ -949,12 +968,12 @@ export class DebugService implements IDebugService { this.storeBreakpoints(); } - sendAllBreakpoints(session?: IDebugSession): Promise { - return Promise.all(distinct(this.model.getBreakpoints(), bp => bp.uri.toString()).map(bp => this.sendBreakpoints(bp.uri, false, session))) - .then(() => this.sendFunctionBreakpoints(session)) - // send exception breakpoints at the end since some debug adapters rely on the order - .then(() => this.sendExceptionBreakpoints(session)) - .then(() => this.sendDataBreakpoints(session)); + async sendAllBreakpoints(session?: IDebugSession): Promise { + await Promise.all(distinct(this.model.getBreakpoints(), bp => bp.uri.toString()).map(bp => this.sendBreakpoints(bp.uri, false, session))); + await this.sendFunctionBreakpoints(session); + await this.sendDataBreakpoints(session); + // send exception breakpoints at the end since some debug adapters rely on the order + await this.sendExceptionBreakpoints(session); } private sendBreakpoints(modelUri: uri, sourceModified = false, session?: IDebugSession): Promise { @@ -989,11 +1008,12 @@ export class DebugService implements IDebugService { }); } - private sendToOneOrAllSessions(session: IDebugSession | undefined, send: (session: IDebugSession) => Promise): Promise { + private async sendToOneOrAllSessions(session: IDebugSession | undefined, send: (session: IDebugSession) => Promise): Promise { if (session) { - return send(session); + await send(session); + } else { + await Promise.all(this.model.getSessions().map(s => send(s))); } - return Promise.all(this.model.getSessions().map(s => send(s))).then(() => undefined); } private onFileChanges(fileChangesEvent: FileChangesEvent): void { diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index fcec6934cfb..bf8a93ef6de 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -727,9 +727,9 @@ export class DebugSession implements IDebugSession { // Call fetch call stack twice, the first only return the top stack frame. // Second retrieves the rest of the call stack. For performance reasons #25605 const promises = this.model.fetchCallStack(thread); - const focus = () => { + const focus = async () => { if (!event.body.preserveFocusHint && thread.getCallStack().length) { - this.debugService.focusStackFrame(undefined, thread); + await this.debugService.focusStackFrame(undefined, thread); if (thread.stoppedDetails) { if (this.configurationService.getValue('debug').openDebug === 'openOnDebugBreak') { this.viewletService.openViewlet(VIEWLET_ID); diff --git a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts index ba384a37df3..f20ab5d427a 100644 --- a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts +++ b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts @@ -192,10 +192,10 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution { super.updateStyles(); if (this.$el) { - this.$el.style.backgroundColor = this.getColor(debugToolBarBackground); + this.$el.style.backgroundColor = this.getColor(debugToolBarBackground) || ''; const widgetShadowColor = this.getColor(widgetShadow); - this.$el.style.boxShadow = widgetShadowColor ? `0 5px 8px ${widgetShadowColor}` : null; + this.$el.style.boxShadow = widgetShadowColor ? `0 5px 8px ${widgetShadowColor}` : ''; const contrastBorderColor = this.getColor(contrastBorder); const borderColor = this.getColor(debugToolBarBorder); diff --git a/src/vs/workbench/contrib/debug/browser/debugViewlet.ts b/src/vs/workbench/contrib/debug/browser/debugViewlet.ts index 10681dbeda0..01d0a2e96d2 100644 --- a/src/vs/workbench/contrib/debug/browser/debugViewlet.ts +++ b/src/vs/workbench/contrib/debug/browser/debugViewlet.ts @@ -214,7 +214,7 @@ export class DebugViewlet extends ViewContainerViewlet { class ToggleReplAction extends TogglePanelAction { static readonly ID = 'debug.toggleRepl'; - static LABEL = nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugConsoleAction' }, 'Debug Console'); + static readonly LABEL = nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugConsoleAction' }, 'Debug Console'); constructor(id: string, label: string, @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, diff --git a/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts b/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts index da8e4c728e8..a72473eef46 100644 --- a/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts +++ b/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts @@ -240,7 +240,7 @@ class RootTreeItem extends BaseTreeItem { class SessionTreeItem extends BaseTreeItem { - private static URL_REGEXP = /^(https?:\/\/[^/]+)(\/.*)$/; + private static readonly URL_REGEXP = /^(https?:\/\/[^/]+)(\/.*)$/; private _session: IDebugSession; private _initialized: boolean; diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index ea0f700bb49..c4774d5c30b 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -80,7 +80,7 @@ interface IPrivateReplService { } function revealLastElement(tree: WorkbenchAsyncDataTree) { - tree.scrollTop = Number.POSITIVE_INFINITY; + tree.scrollTop = tree.scrollHeight - tree.renderHeight; } const sessionsToIgnore = new Set(); @@ -799,6 +799,8 @@ class ReplDelegate implements IListVirtualDelegate { constructor(private configurationService: IConfigurationService) { } getHeight(element: IReplElement): number { + const countNumberOfLines = (str: string) => Math.max(1, (str && str.match(/\r\n|\n/g) || []).length); + // Give approximate heights. Repl has dynamic height so the tree will measure the actual height on its own. const config = this.configurationService.getValue('debug'); const fontSize = config.console.fontSize; @@ -817,13 +819,13 @@ class ReplDelegate implements IListVirtualDelegate { return rowHeight; } - let valueRows = value ? Math.ceil(value.length / 150) : 0; + let valueRows = value ? (countNumberOfLines(value) + Math.floor(value.length / 150)) : 0; return rowHeight * valueRows; } if (element instanceof SimpleReplElement || element instanceof ReplEvaluationInput) { let value = element.value; - let valueRows = Math.ceil(value.length / 150); + let valueRows = countNumberOfLines(value) + Math.floor(value.length / 150); return valueRows * rowHeight; } @@ -982,7 +984,7 @@ class SelectReplActionViewItem extends FocusSessionActionViewItem { class SelectReplAction extends Action { static readonly ID = 'workbench.action.debug.selectRepl'; - static LABEL = nls.localize('selectRepl', "Select Debug Console"); + static readonly LABEL = nls.localize('selectRepl', "Select Debug Console"); constructor(id: string, label: string, @IDebugService private readonly debugService: IDebugService, @@ -991,10 +993,10 @@ class SelectReplAction extends Action { super(id, label); } - run(session: IDebugSession): Promise { + async run(session: IDebugSession): Promise { // If session is already the focused session we need to manualy update the tree since view model will not send a focused change event if (session && session.state !== State.Inactive && session !== this.debugService.getViewModel().focusedSession) { - this.debugService.focusStackFrame(undefined, undefined, session, true); + await this.debugService.focusStackFrame(undefined, undefined, session, true); } else { this.replService.selectSession(session); } @@ -1005,7 +1007,7 @@ class SelectReplAction extends Action { export class ClearReplAction extends Action { static readonly ID = 'workbench.debug.panel.action.clearReplAction'; - static LABEL = nls.localize('clearRepl', "Clear Console"); + static readonly LABEL = nls.localize('clearRepl', "Clear Console"); constructor(id: string, label: string, @IPanelService private readonly panelService: IPanelService diff --git a/src/vs/workbench/contrib/debug/browser/variablesView.ts b/src/vs/workbench/contrib/debug/browser/variablesView.ts index 56483de1cb2..f7fb8d0f9eb 100644 --- a/src/vs/workbench/contrib/debug/browser/variablesView.ts +++ b/src/vs/workbench/contrib/debug/browser/variablesView.ts @@ -100,8 +100,10 @@ export class VariablesView extends ViewletPanel { CONTEXT_VARIABLES_FOCUSED.bindTo(this.tree.contextKeyService); - const collapseAction = new CollapseAction(this.tree, true, 'explorer-action collapse-explorer'); - this.toolbar.setActions([collapseAction])(); + if (this.toolbar) { + const collapseAction = new CollapseAction(this.tree, true, 'explorer-action collapse-explorer'); + this.toolbar.setActions([collapseAction])(); + } this.tree.updateChildren(); this._register(this.debugService.getViewModel().onDidFocusStackFrame(sf => { diff --git a/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts b/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts index b48786ed88b..db51214714d 100644 --- a/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts +++ b/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts @@ -74,10 +74,12 @@ export class WatchExpressionsView extends ViewletPanel { this.tree.setInput(this.debugService).then(undefined, onUnexpectedError); CONTEXT_WATCH_EXPRESSIONS_FOCUSED.bindTo(this.tree.contextKeyService); - const addWatchExpressionAction = new AddWatchExpressionAction(AddWatchExpressionAction.ID, AddWatchExpressionAction.LABEL, this.debugService, this.keybindingService); - const collapseAction = new CollapseAction(this.tree, true, 'explorer-action collapse-explorer'); - const removeAllWatchExpressionsAction = new RemoveAllWatchExpressionsAction(RemoveAllWatchExpressionsAction.ID, RemoveAllWatchExpressionsAction.LABEL, this.debugService, this.keybindingService); - this.toolbar.setActions([addWatchExpressionAction, collapseAction, removeAllWatchExpressionsAction])(); + if (this.toolbar) { + const addWatchExpressionAction = new AddWatchExpressionAction(AddWatchExpressionAction.ID, AddWatchExpressionAction.LABEL, this.debugService, this.keybindingService); + const collapseAction = new CollapseAction(this.tree, true, 'explorer-action collapse-explorer'); + const removeAllWatchExpressionsAction = new RemoveAllWatchExpressionsAction(RemoveAllWatchExpressionsAction.ID, RemoveAllWatchExpressionsAction.LABEL, this.debugService, this.keybindingService); + this.toolbar.setActions([addWatchExpressionAction, collapseAction, removeAllWatchExpressionsAction])(); + } this._register(this.tree.onContextMenu(e => this.onContextMenu(e))); this._register(this.tree.onMouseDblClick(e => this.onMouseDblClick(e))); diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index c68bc35d6ab..5438069c05a 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -732,7 +732,7 @@ export interface IDebugService { /** * Sets the focused stack frame and evaluates all expressions against the newly focused stack frame, */ - focusStackFrame(focusedStackFrame: IStackFrame | undefined, thread?: IThread, session?: IDebugSession, explicit?: boolean): void; + focusStackFrame(focusedStackFrame: IStackFrame | undefined, thread?: IThread, session?: IDebugSession, explicit?: boolean): Promise; /** * Adds new breakpoints to the model for the file specified with the uri. Notifies debug adapter of breakpoint changes. diff --git a/src/vs/workbench/contrib/debug/common/debugModel.ts b/src/vs/workbench/contrib/debug/common/debugModel.ts index ec8d05b8078..489315df4b7 100644 --- a/src/vs/workbench/contrib/debug/common/debugModel.ts +++ b/src/vs/workbench/contrib/debug/common/debugModel.ts @@ -27,7 +27,7 @@ import { mixin } from 'vs/base/common/objects'; export class ExpressionContainer implements IExpressionContainer { - public static allValues = new Map(); + public static readonly allValues = new Map(); // Use chunks to support variable paging #9537 private static readonly BASE_CHUNK_SIZE = 100; @@ -172,7 +172,7 @@ export class ExpressionContainer implements IExpressionContainer { } export class Expression extends ExpressionContainer implements IExpression { - static DEFAULT_VALUE = nls.localize('notAvailable', "not available"); + static readonly DEFAULT_VALUE = nls.localize('notAvailable', "not available"); public available: boolean; @@ -617,8 +617,7 @@ export class Breakpoint extends BaseBreakpoint implements IBreakpoint { } get column(): number | undefined { - // Only respect the column if the user explictly set the column to have an inline breakpoint - return this.verified && this.data && typeof this.data.column === 'number' && typeof this._column === 'number' ? this.data.column : this._column; + return this.verified && this.data && typeof this.data.column === 'number' ? this.data.column : this._column; } get message(): string | undefined { diff --git a/src/vs/workbench/contrib/debug/test/common/mockDebug.ts b/src/vs/workbench/contrib/debug/test/common/mockDebug.ts index 9ce2b7f792e..9178e857417 100644 --- a/src/vs/workbench/contrib/debug/test/common/mockDebug.ts +++ b/src/vs/workbench/contrib/debug/test/common/mockDebug.ts @@ -40,7 +40,8 @@ export class MockDebugService implements IDebugService { throw new Error('not implemented'); } - public focusStackFrame(focusedStackFrame: IStackFrame): void { + public focusStackFrame(focusedStackFrame: IStackFrame): Promise { + throw new Error('not implemented'); } sendAllBreakpoints(session?: IDebugSession): Promise { diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 94982ae98bb..3f53b905b71 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -143,8 +143,8 @@ export abstract class ExtensionAction extends Action implements IExtensionContai export class InstallAction extends ExtensionAction { - private static INSTALL_LABEL = localize('install', "Install"); - private static INSTALLING_LABEL = localize('installing', "Installing"); + private static readonly INSTALL_LABEL = localize('install', "Install"); + private static readonly INSTALLING_LABEL = localize('installing', "Installing"); private static readonly Class = 'extension-action prominent install'; private static readonly InstallingClass = 'extension-action install installing'; @@ -277,8 +277,8 @@ export class InstallAction extends ExtensionAction { export abstract class InstallInOtherServerAction extends ExtensionAction { - protected static INSTALL_LABEL = localize('install', "Install"); - protected static INSTALLING_LABEL = localize('installing', "Installing"); + protected static readonly INSTALL_LABEL = localize('install', "Install"); + protected static readonly INSTALLING_LABEL = localize('installing', "Installing"); private static readonly Class = 'extension-action prominent install'; private static readonly InstallingClass = 'extension-action install installing'; @@ -726,7 +726,7 @@ export class ManageExtensionAction extends ExtensionDropDownAction { export class InstallAnotherVersionAction extends ExtensionAction { static readonly ID = 'workbench.extensions.action.install.anotherVersion'; - static LABEL = localize('install another version', "Install Another Version..."); + static readonly LABEL = localize('install another version', "Install Another Version..."); constructor( @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @@ -832,7 +832,7 @@ export class ExtensionSettingsAction extends ExtensionAction { export class EnableForWorkspaceAction extends ExtensionAction { static readonly ID = 'extensions.enableForWorkspace'; - static LABEL = localize('enableForWorkspaceAction', "Enable (Workspace)"); + static readonly LABEL = localize('enableForWorkspaceAction', "Enable (Workspace)"); constructor( @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @@ -859,7 +859,7 @@ export class EnableForWorkspaceAction extends ExtensionAction { export class EnableGloballyAction extends ExtensionAction { static readonly ID = 'extensions.enableGlobally'; - static LABEL = localize('enableGloballyAction', "Enable"); + static readonly LABEL = localize('enableGloballyAction', "Enable"); constructor( @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @@ -886,7 +886,7 @@ export class EnableGloballyAction extends ExtensionAction { export class DisableForWorkspaceAction extends ExtensionAction { static readonly ID = 'extensions.disableForWorkspace'; - static LABEL = localize('disableForWorkspaceAction', "Disable (Workspace)"); + static readonly LABEL = localize('disableForWorkspaceAction', "Disable (Workspace)"); constructor(readonly runningExtensions: IExtensionDescription[], @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService, @@ -914,7 +914,7 @@ export class DisableForWorkspaceAction extends ExtensionAction { export class DisableGloballyAction extends ExtensionAction { static readonly ID = 'extensions.disableGlobally'; - static LABEL = localize('disableGloballyAction', "Disable"); + static readonly LABEL = localize('disableGloballyAction', "Disable"); constructor(readonly runningExtensions: IExtensionDescription[], @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @@ -1010,7 +1010,7 @@ export class DisableDropDownAction extends ExtensionEditorDropDownAction { export class CheckForUpdatesAction extends Action { static readonly ID = 'workbench.extensions.action.checkForUpdates'; - static LABEL = localize('checkForUpdates', "Check for Extension Updates"); + static readonly LABEL = localize('checkForUpdates', "Check for Extension Updates"); constructor( id = CheckForUpdatesAction.ID, @@ -1082,7 +1082,7 @@ export class ToggleAutoUpdateAction extends Action { export class EnableAutoUpdateAction extends ToggleAutoUpdateAction { static readonly ID = 'workbench.extensions.action.enableAutoUpdate'; - static LABEL = localize('enableAutoUpdate', "Enable Auto Updating Extensions"); + static readonly LABEL = localize('enableAutoUpdate', "Enable Auto Updating Extensions"); constructor( id = EnableAutoUpdateAction.ID, @@ -1096,7 +1096,7 @@ export class EnableAutoUpdateAction extends ToggleAutoUpdateAction { export class DisableAutoUpdateAction extends ToggleAutoUpdateAction { static readonly ID = 'workbench.extensions.action.disableAutoUpdate'; - static LABEL = localize('disableAutoUpdate', "Disable Auto Updating Extensions"); + static readonly LABEL = localize('disableAutoUpdate', "Disable Auto Updating Extensions"); constructor( id = EnableAutoUpdateAction.ID, @@ -1110,7 +1110,7 @@ export class DisableAutoUpdateAction extends ToggleAutoUpdateAction { export class UpdateAllAction extends Action { static readonly ID = 'workbench.extensions.action.updateAllExtensions'; - static LABEL = localize('updateAll', "Update All Extensions"); + static readonly LABEL = localize('updateAll', "Update All Extensions"); constructor( id = UpdateAllAction.ID, @@ -1417,7 +1417,7 @@ export class InstallExtensionsAction extends OpenExtensionsViewletAction { export class ShowEnabledExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.showEnabledExtensions'; - static LABEL = localize('showEnabledExtensions', "Show Enabled Extensions"); + static readonly LABEL = localize('showEnabledExtensions', "Show Enabled Extensions"); constructor( id: string, @@ -1440,7 +1440,7 @@ export class ShowEnabledExtensionsAction extends Action { export class ShowInstalledExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.showInstalledExtensions'; - static LABEL = localize('showInstalledExtensions', "Show Installed Extensions"); + static readonly LABEL = localize('showInstalledExtensions', "Show Installed Extensions"); constructor( id: string, @@ -1463,7 +1463,7 @@ export class ShowInstalledExtensionsAction extends Action { export class ShowDisabledExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.showDisabledExtensions'; - static LABEL = localize('showDisabledExtensions', "Show Disabled Extensions"); + static readonly LABEL = localize('showDisabledExtensions', "Show Disabled Extensions"); constructor( id: string, @@ -1486,7 +1486,7 @@ export class ShowDisabledExtensionsAction extends Action { export class ClearExtensionsInputAction extends Action { static readonly ID = 'workbench.extensions.action.clearExtensionsInput'; - static LABEL = localize('clearExtensionsInput', "Clear Extensions Input"); + static readonly LABEL = localize('clearExtensionsInput', "Clear Extensions Input"); constructor( id: string, @@ -1517,7 +1517,7 @@ export class ClearExtensionsInputAction extends Action { export class ShowBuiltInExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.listBuiltInExtensions'; - static LABEL = localize('showBuiltInExtensions', "Show Built-in Extensions"); + static readonly LABEL = localize('showBuiltInExtensions', "Show Built-in Extensions"); constructor( id: string, @@ -1540,7 +1540,7 @@ export class ShowBuiltInExtensionsAction extends Action { export class ShowOutdatedExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.listOutdatedExtensions'; - static LABEL = localize('showOutdatedExtensions', "Show Outdated Extensions"); + static readonly LABEL = localize('showOutdatedExtensions', "Show Outdated Extensions"); constructor( id: string, @@ -1563,7 +1563,7 @@ export class ShowOutdatedExtensionsAction extends Action { export class ShowPopularExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.showPopularExtensions'; - static LABEL = localize('showPopularExtensions', "Show Popular Extensions"); + static readonly LABEL = localize('showPopularExtensions', "Show Popular Extensions"); constructor( id: string, @@ -1586,7 +1586,7 @@ export class ShowPopularExtensionsAction extends Action { export class ShowRecommendedExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.showRecommendedExtensions'; - static LABEL = localize('showRecommendedExtensions', "Show Recommended Extensions"); + static readonly LABEL = localize('showRecommendedExtensions', "Show Recommended Extensions"); constructor( id: string, @@ -1609,7 +1609,7 @@ export class ShowRecommendedExtensionsAction extends Action { export class InstallWorkspaceRecommendedExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.installWorkspaceRecommendedExtensions'; - static LABEL = localize('installWorkspaceRecommendedExtensions', "Install All Workspace Recommended Extensions"); + static readonly LABEL = localize('installWorkspaceRecommendedExtensions', "Install All Workspace Recommended Extensions"); private _recommendations: IExtensionRecommendation[] = []; get recommendations(): IExtensionRecommendation[] { return this._recommendations; } @@ -1674,7 +1674,7 @@ export class InstallWorkspaceRecommendedExtensionsAction extends Action { export class InstallRecommendedExtensionAction extends Action { static readonly ID = 'workbench.extensions.action.installRecommendedExtension'; - static LABEL = localize('installRecommendedExtension', "Install Recommended Extension"); + static readonly LABEL = localize('installRecommendedExtension', "Install Recommended Extension"); private extensionId: string; @@ -1765,7 +1765,7 @@ export class UndoIgnoreExtensionRecommendationAction extends Action { export class ShowRecommendedKeymapExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.showRecommendedKeymapExtensions'; - static SHORT_LABEL = localize('showRecommendedKeymapExtensionsShort', "Keymaps"); + static readonly SHORT_LABEL = localize('showRecommendedKeymapExtensionsShort', "Keymaps"); constructor( id: string, @@ -1788,7 +1788,7 @@ export class ShowRecommendedKeymapExtensionsAction extends Action { export class ShowLanguageExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.showLanguageExtensions'; - static SHORT_LABEL = localize('showLanguageExtensionsShort', "Language Extensions"); + static readonly SHORT_LABEL = localize('showLanguageExtensionsShort', "Language Extensions"); constructor( id: string, @@ -1811,7 +1811,7 @@ export class ShowLanguageExtensionsAction extends Action { export class ShowAzureExtensionsAction extends Action { static readonly ID = 'workbench.extensions.action.showAzureExtensions'; - static SHORT_LABEL = localize('showAzureExtensionsShort', "Azure Extensions"); + static readonly SHORT_LABEL = localize('showAzureExtensionsShort', "Azure Extensions"); constructor( id: string, @@ -2153,7 +2153,7 @@ export abstract class AbstractConfigureRecommendedExtensionsAction extends Actio export class ConfigureWorkspaceRecommendedExtensionsAction extends AbstractConfigureRecommendedExtensionsAction { static readonly ID = 'workbench.extensions.action.configureWorkspaceRecommendedExtensions'; - static LABEL = localize('configureWorkspaceRecommendedExtensions', "Configure Recommended Extensions (Workspace)"); + static readonly LABEL = localize('configureWorkspaceRecommendedExtensions', "Configure Recommended Extensions (Workspace)"); constructor( @@ -2189,7 +2189,7 @@ export class ConfigureWorkspaceRecommendedExtensionsAction extends AbstractConfi export class ConfigureWorkspaceFolderRecommendedExtensionsAction extends AbstractConfigureRecommendedExtensionsAction { static readonly ID = 'workbench.extensions.action.configureWorkspaceFolderRecommendedExtensions'; - static LABEL = localize('configureWorkspaceFolderRecommendedExtensions', "Configure Recommended Extensions (Workspace Folder)"); + static readonly LABEL = localize('configureWorkspaceFolderRecommendedExtensions', "Configure Recommended Extensions (Workspace Folder)"); constructor( @@ -2662,7 +2662,7 @@ export class SystemDisabledWarningAction extends ExtensionAction { export class DisableAllAction extends Action { static readonly ID = 'workbench.extensions.action.disableAll'; - static LABEL = localize('disableAll', "Disable All Installed Extensions"); + static readonly LABEL = localize('disableAll', "Disable All Installed Extensions"); constructor( @@ -2687,7 +2687,7 @@ export class DisableAllAction extends Action { export class DisableAllWorkspaceAction extends Action { static readonly ID = 'workbench.extensions.action.disableAllWorkspace'; - static LABEL = localize('disableAllWorkspace', "Disable All Installed Extensions for this Workspace"); + static readonly LABEL = localize('disableAllWorkspace', "Disable All Installed Extensions for this Workspace"); constructor( @@ -2714,7 +2714,7 @@ export class DisableAllWorkspaceAction extends Action { export class EnableAllAction extends Action { static readonly ID = 'workbench.extensions.action.enableAll'; - static LABEL = localize('enableAll', "Enable All Extensions"); + static readonly LABEL = localize('enableAll', "Enable All Extensions"); constructor( @@ -2739,7 +2739,7 @@ export class EnableAllAction extends Action { export class EnableAllWorkspaceAction extends Action { static readonly ID = 'workbench.extensions.action.enableAllWorkspace'; - static LABEL = localize('enableAllWorkspace', "Enable All Extensions for this Workspace"); + static readonly LABEL = localize('enableAllWorkspace', "Enable All Extensions for this Workspace"); constructor( @@ -2766,7 +2766,7 @@ export class EnableAllWorkspaceAction extends Action { export class InstallVSIXAction extends Action { static readonly ID = 'workbench.extensions.action.installVSIX'; - static LABEL = localize('installVSIX', "Install from VSIX..."); + static readonly LABEL = localize('installVSIX', "Install from VSIX..."); constructor( id = InstallVSIXAction.ID, @@ -2818,7 +2818,7 @@ export class InstallVSIXAction extends Action { export class ReinstallAction extends Action { static readonly ID = 'workbench.extensions.action.reinstall'; - static LABEL = localize('reinstall', "Reinstall Extension..."); + static readonly LABEL = localize('reinstall', "Reinstall Extension..."); constructor( id: string = ReinstallAction.ID, label: string = ReinstallAction.LABEL, @@ -2884,7 +2884,7 @@ export class ReinstallAction extends Action { export class InstallSpecificVersionOfExtensionAction extends Action { static readonly ID = 'workbench.extensions.action.install.specificVersion'; - static LABEL = localize('install previous version', "Install Specific Version of Extension..."); + static readonly LABEL = localize('install previous version', "Install Specific Version of Extension..."); constructor( id: string = InstallSpecificVersionOfExtensionAction.ID, label: string = InstallSpecificVersionOfExtensionAction.LABEL, diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewer.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewer.ts index 919c3762319..41bb90eb632 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewer.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewer.ts @@ -213,7 +213,7 @@ export class ExtensionsTree extends WorkbenchAsyncDataTree { + this.disposables.add(this.onDidChangeSelection(event => { if (event.browserEvent && event.browserEvent instanceof KeyboardEvent) { extensionsWorkdbenchService.open(event.elements[0].extension, false); } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index 9230ee1708c..bb17633367f 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -708,10 +708,10 @@ export class ExtensionsListView extends ViewletPanel { if (count === 0 && this.isBodyVisible()) { if (error) { if (error instanceof ExtensionListViewWarning) { - this.bodyTemplate.messageSeverityIcon.className = SeverityIcon.className(Severity.Warning); + this.bodyTemplate.messageSeverityIcon.className = `codicon ${SeverityIcon.className(Severity.Warning)}`; this.bodyTemplate.messageBox.textContent = getErrorMessage(error); } else { - this.bodyTemplate.messageSeverityIcon.className = SeverityIcon.className(Severity.Error); + this.bodyTemplate.messageSeverityIcon.className = `codicon ${SeverityIcon.className(Severity.Error)}`; this.bodyTemplate.messageBox.textContent = localize('error', "Error while loading extensions. {0}", getErrorMessage(error)); } } else { diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts index b4185a6614f..871122fd967 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts @@ -14,7 +14,7 @@ import { Schemas } from 'vs/base/common/network'; export class OpenExtensionsFolderAction extends Action { static readonly ID = 'workbench.extensions.action.openExtensionsFolder'; - static LABEL = localize('openExtensionsFolder', "Open Extensions Folder"); + static readonly LABEL = localize('openExtensionsFolder', "Open Extensions Folder"); constructor( id: string, diff --git a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts index 54e11fc1507..003ab9fe360 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts @@ -459,7 +459,7 @@ export class RuntimeExtensionsEditor extends BaseEditor { export class ShowRuntimeExtensionsAction extends Action { static readonly ID = 'workbench.action.showRuntimeExtensions'; - static LABEL = nls.localize('showRuntimeExtensions', "Show Running Extensions"); + static readonly LABEL = nls.localize('showRuntimeExtensions', "Show Running Extensions"); constructor( id: string, label: string, @@ -477,7 +477,7 @@ export class ShowRuntimeExtensionsAction extends Action { export class ReportExtensionIssueAction extends Action { private static readonly _id = 'workbench.extensions.action.reportExtensionIssue'; - private static _label = nls.localize('reportExtensionIssue', "Report Issue"); + private static readonly _label = nls.localize('reportExtensionIssue', "Report Issue"); private readonly _url: string; @@ -533,8 +533,8 @@ export class ReportExtensionIssueAction extends Action { export class DebugExtensionHostAction extends Action { static readonly ID = 'workbench.extensions.action.debugExtensionHost'; - static LABEL = nls.localize('debugExtensionHost', "Start Debugging Extension Host"); - static CSS_CLASS = 'debug-extension-host'; + static readonly LABEL = nls.localize('debugExtensionHost', "Start Debugging Extension Host"); + static readonly CSS_CLASS = 'debug-extension-host'; constructor( @IDebugService private readonly _debugService: IDebugService, @@ -572,7 +572,7 @@ export class DebugExtensionHostAction extends Action { export class StartExtensionHostProfileAction extends Action { static readonly ID = 'workbench.extensions.action.extensionHostProfile'; - static LABEL = nls.localize('extensionHostProfileStart', "Start Extension Host Profile"); + static readonly LABEL = nls.localize('extensionHostProfileStart', "Start Extension Host Profile"); constructor( id: string = StartExtensionHostProfileAction.ID, label: string = StartExtensionHostProfileAction.LABEL, @@ -589,7 +589,7 @@ export class StartExtensionHostProfileAction extends Action { export class StopExtensionHostProfileAction extends Action { static readonly ID = 'workbench.extensions.action.stopExtensionHostProfile'; - static LABEL = nls.localize('stopExtensionHostProfileStart', "Stop Extension Host Profile"); + static readonly LABEL = nls.localize('stopExtensionHostProfileStart', "Stop Extension Host Profile"); constructor( id: string = StartExtensionHostProfileAction.ID, label: string = StartExtensionHostProfileAction.LABEL, @@ -606,7 +606,7 @@ export class StopExtensionHostProfileAction extends Action { export class SaveExtensionHostProfileAction extends Action { - static LABEL = nls.localize('saveExtensionHostProfile', "Save Extension Host Profile"); + static readonly LABEL = nls.localize('saveExtensionHostProfile', "Save Extension Host Profile"); static readonly ID = 'workbench.extensions.action.saveExtensionHostProfile'; constructor( diff --git a/src/vs/workbench/contrib/feedback/browser/feedback.ts b/src/vs/workbench/contrib/feedback/browser/feedback.ts index 2721433b39f..ae6f9bcbbd7 100644 --- a/src/vs/workbench/contrib/feedback/browser/feedback.ts +++ b/src/vs/workbench/contrib/feedback/browser/feedback.ts @@ -142,7 +142,7 @@ export class FeedbackDropdown extends Dropdown { })); disposables.add(dom.addDisposableListener(closeBtn, dom.EventType.MOUSE_OUT, () => { - closeBtn.style.backgroundColor = null; + closeBtn.style.backgroundColor = ''; })); this.invoke(closeBtn, disposables, () => this.hide()); @@ -276,17 +276,17 @@ export class FeedbackDropdown extends Dropdown { disposables.add(attachStylerCallback(this.themeService, { widgetShadow, editorWidgetBackground, editorWidgetForeground, inputBackground, inputForeground, inputBorder, editorBackground, contrastBorder }, colors => { if (this.feedbackForm) { - this.feedbackForm.style.backgroundColor = colors.editorWidgetBackground ? colors.editorWidgetBackground.toString() : null; + this.feedbackForm.style.backgroundColor = colors.editorWidgetBackground ? colors.editorWidgetBackground.toString() : ''; this.feedbackForm.style.color = colors.editorWidgetForeground ? colors.editorWidgetForeground.toString() : null; - this.feedbackForm.style.boxShadow = colors.widgetShadow ? `0 0 8px ${colors.widgetShadow}` : null; + this.feedbackForm.style.boxShadow = colors.widgetShadow ? `0 0 8px ${colors.widgetShadow}` : ''; } if (this.feedbackDescriptionInput) { - this.feedbackDescriptionInput.style.backgroundColor = colors.inputBackground ? colors.inputBackground.toString() : null; + this.feedbackDescriptionInput.style.backgroundColor = colors.inputBackground ? colors.inputBackground.toString() : ''; this.feedbackDescriptionInput.style.color = colors.inputForeground ? colors.inputForeground.toString() : null; this.feedbackDescriptionInput.style.border = `1px solid ${colors.inputBorder || 'transparent'}`; } - contactUsContainer.style.backgroundColor = colors.editorBackground ? colors.editorBackground.toString() : null; + contactUsContainer.style.backgroundColor = colors.editorBackground ? colors.editorBackground.toString() : ''; contactUsContainer.style.border = `1px solid ${colors.contrastBorder || 'transparent'}`; })); diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 3cdcb6c65e5..3768bc96d17 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -125,8 +125,8 @@ export class NewFolderAction extends Action { /* Create new file from anywhere: Open untitled */ export class GlobalNewUntitledFileAction extends Action { - public static readonly ID = 'workbench.action.files.newUntitledFile'; - public static readonly LABEL = nls.localize('newUntitledFile', "New Untitled File"); + static readonly ID = 'workbench.action.files.newUntitledFile'; + static readonly LABEL = nls.localize('newUntitledFile', "New Untitled File"); constructor( id: string, @@ -136,7 +136,7 @@ export class GlobalNewUntitledFileAction extends Action { super(id, label); } - public run(): Promise { + run(): Promise { return this.editorService.openEditor({ options: { pinned: true } }); // untitled are always pinned } } @@ -440,8 +440,8 @@ export function incrementFileName(name: string, isFolder: boolean, incrementalNa // Global Compare with export class GlobalCompareResourcesAction extends Action { - public static readonly ID = 'workbench.files.action.compareFileWith'; - public static readonly LABEL = nls.localize('globalCompareFile', "Compare Active File With..."); + static readonly ID = 'workbench.files.action.compareFileWith'; + static readonly LABEL = nls.localize('globalCompareFile', "Compare Active File With..."); constructor( id: string, @@ -453,7 +453,7 @@ export class GlobalCompareResourcesAction extends Action { super(id, label); } - public run(): Promise { + run(): Promise { const activeInput = this.editorService.activeEditor; const activeResource = activeInput ? activeInput.getResource() : undefined; if (activeResource) { @@ -491,8 +491,8 @@ export class GlobalCompareResourcesAction extends Action { } export class ToggleAutoSaveAction extends Action { - public static readonly ID = 'workbench.action.toggleAutoSave'; - public static readonly LABEL = nls.localize('toggleAutoSave', "Toggle Auto Save"); + static readonly ID = 'workbench.action.toggleAutoSave'; + static readonly LABEL = nls.localize('toggleAutoSave', "Toggle Auto Save"); constructor( id: string, @@ -502,7 +502,7 @@ export class ToggleAutoSaveAction extends Action { super(id, label); } - public run(): Promise { + run(): Promise { const setting = this.configurationService.inspect('files.autoSave'); let userAutoSaveConfig = setting.user; if (types.isUndefinedOrNull(userAutoSaveConfig)) { @@ -562,7 +562,7 @@ export abstract class BaseSaveAllAction extends Action { } } - public run(context?: any): Promise { + run(context?: any): Promise { return this.doRun(context).then(() => true, error => { onError(this.notificationService, error); return false; @@ -572,10 +572,10 @@ export abstract class BaseSaveAllAction extends Action { export class SaveAllAction extends BaseSaveAllAction { - public static readonly ID = 'workbench.action.files.saveAll'; - public static readonly LABEL = SAVE_ALL_LABEL; + static readonly ID = 'workbench.action.files.saveAll'; + static readonly LABEL = SAVE_ALL_LABEL; - public get class(): string { + get class(): string { return 'explorer-action codicon-save-all'; } @@ -590,10 +590,10 @@ export class SaveAllAction extends BaseSaveAllAction { export class SaveAllInGroupAction extends BaseSaveAllAction { - public static readonly ID = 'workbench.files.action.saveAllInGroup'; - public static readonly LABEL = nls.localize('saveAllInGroup', "Save All in Group"); + static readonly ID = 'workbench.files.action.saveAllInGroup'; + static readonly LABEL = nls.localize('saveAllInGroup', "Save All in Group"); - public get class(): string { + get class(): string { return 'explorer-action codicon-save-all'; } @@ -608,22 +608,22 @@ export class SaveAllInGroupAction extends BaseSaveAllAction { export class CloseGroupAction extends Action { - public static readonly ID = 'workbench.files.action.closeGroup'; - public static readonly LABEL = nls.localize('closeGroup', "Close Group"); + static readonly ID = 'workbench.files.action.closeGroup'; + static readonly LABEL = nls.localize('closeGroup', "Close Group"); constructor(id: string, label: string, @ICommandService private readonly commandService: ICommandService) { super(id, label, 'codicon-close-all'); } - public run(context?: any): Promise { + run(context?: any): Promise { return this.commandService.executeCommand(CLOSE_EDITORS_AND_GROUP_COMMAND_ID, {}, context); } } export class FocusFilesExplorer extends Action { - public static readonly ID = 'workbench.files.action.focusFilesExplorer'; - public static readonly LABEL = nls.localize('focusFilesExplorer', "Focus on Files Explorer"); + static readonly ID = 'workbench.files.action.focusFilesExplorer'; + static readonly LABEL = nls.localize('focusFilesExplorer', "Focus on Files Explorer"); constructor( id: string, @@ -633,15 +633,15 @@ export class FocusFilesExplorer extends Action { super(id, label); } - public run(): Promise { + run(): Promise { return this.viewletService.openViewlet(VIEWLET_ID, true); } } export class ShowActiveFileInExplorer extends Action { - public static readonly ID = 'workbench.files.action.showActiveFileInExplorer'; - public static readonly LABEL = nls.localize('showInExplorer', "Reveal Active File in Side Bar"); + static readonly ID = 'workbench.files.action.showActiveFileInExplorer'; + static readonly LABEL = nls.localize('showInExplorer', "Reveal Active File in Side Bar"); constructor( id: string, @@ -653,7 +653,7 @@ export class ShowActiveFileInExplorer extends Action { super(id, label); } - public run(): Promise { + run(): Promise { const resource = toResource(this.editorService.activeEditor, { supportSideBySide: SideBySideEditor.MASTER }); if (resource) { this.commandService.executeCommand(REVEAL_IN_EXPLORER_COMMAND_ID, resource); @@ -667,8 +667,8 @@ export class ShowActiveFileInExplorer extends Action { export class CollapseExplorerView extends Action { - public static readonly ID = 'workbench.files.action.collapseExplorerFolders'; - public static readonly LABEL = nls.localize('collapseExplorerFolders', "Collapse Folders in Explorer"); + static readonly ID = 'workbench.files.action.collapseExplorerFolders'; + static readonly LABEL = nls.localize('collapseExplorerFolders', "Collapse Folders in Explorer"); constructor(id: string, label: string, @@ -694,8 +694,8 @@ export class CollapseExplorerView extends Action { export class RefreshExplorerView extends Action { - public static readonly ID = 'workbench.files.action.refreshFilesExplorer'; - public static readonly LABEL = nls.localize('refreshExplorer', "Refresh Explorer"); + static readonly ID = 'workbench.files.action.refreshFilesExplorer'; + static readonly LABEL = nls.localize('refreshExplorer', "Refresh Explorer"); constructor( @@ -710,7 +710,7 @@ export class RefreshExplorerView extends Action { })); } - public run(): Promise { + run(): Promise { return this.viewletService.openViewlet(VIEWLET_ID).then(() => this.explorerService.refresh() ); @@ -719,8 +719,8 @@ export class RefreshExplorerView extends Action { export class ShowOpenedFileInNewWindow extends Action { - public static readonly ID = 'workbench.action.files.showOpenedFileInNewWindow'; - public static readonly LABEL = nls.localize('openFileInNewWindow', "Open Active File in New Window"); + static readonly ID = 'workbench.action.files.showOpenedFileInNewWindow'; + static readonly LABEL = nls.localize('openFileInNewWindow', "Open Active File in New Window"); constructor( id: string, @@ -733,7 +733,7 @@ export class ShowOpenedFileInNewWindow extends Action { super(id, label); } - public run(): Promise { + run(): Promise { const fileResource = toResource(this.editorService.activeEditor, { supportSideBySide: SideBySideEditor.MASTER }); if (fileResource) { if (this.fileService.canHandleResource(fileResource)) { @@ -808,8 +808,8 @@ export function getWellFormedFileName(filename: string): string { export class CompareWithClipboardAction extends Action { - public static readonly ID = 'workbench.files.action.compareWithClipboard'; - public static readonly LABEL = nls.localize('compareWithClipboard', "Compare Active File with Clipboard"); + static readonly ID = 'workbench.files.action.compareWithClipboard'; + static readonly LABEL = nls.localize('compareWithClipboard', "Compare Active File with Clipboard"); private static readonly SCHEME = 'clipboardCompare'; @@ -828,7 +828,7 @@ export class CompareWithClipboardAction extends Action { this.enabled = true; } - public run(): Promise { + run(): Promise { const resource = toResource(this.editorService.activeEditor, { supportSideBySide: SideBySideEditor.MASTER }); if (resource && (this.fileService.canHandleResource(resource) || resource.scheme === Schemas.untitled)) { if (!this.registrationDisposal) { @@ -848,7 +848,7 @@ export class CompareWithClipboardAction extends Action { return Promise.resolve(true); } - public dispose(): void { + dispose(): void { super.dispose(); dispose(this.registrationDisposal); diff --git a/src/vs/workbench/contrib/files/browser/files.contribution.ts b/src/vs/workbench/contrib/files/browser/files.contribution.ts index 1f4cd95f65d..8afe9ace396 100644 --- a/src/vs/workbench/contrib/files/browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.contribution.ts @@ -253,6 +253,7 @@ configurationRegistry.registerConfiguration({ }, 'files.eol': { 'type': 'string', + 'overridable': true, 'enum': [ '\n', '\r\n', diff --git a/src/vs/workbench/contrib/files/browser/views/emptyView.ts b/src/vs/workbench/contrib/files/browser/views/emptyView.ts index 60c0027a6df..f24f0128c6f 100644 --- a/src/vs/workbench/contrib/files/browser/views/emptyView.ts +++ b/src/vs/workbench/contrib/files/browser/views/emptyView.ts @@ -33,7 +33,6 @@ export class EmptyView extends ViewletPanel { private button!: Button; private messageElement!: HTMLElement; - private titleElement!: HTMLElement; constructor( options: IViewletViewOptions, @@ -52,19 +51,6 @@ export class EmptyView extends ViewletPanel { this._register(this.labelService.onDidChangeFormatters(() => this.setLabels())); } - renderHeader(container: HTMLElement): void { - const twisties = document.createElement('div'); - DOM.addClasses(twisties, 'twisties', 'codicon', 'codicon-chevron-right'); - container.appendChild(twisties); - - const titleContainer = document.createElement('div'); - DOM.addClass(titleContainer, 'title'); - container.appendChild(titleContainer); - - this.titleElement = document.createElement('span'); - titleContainer.appendChild(this.titleElement); - } - protected renderBody(container: HTMLElement): void { DOM.addClass(container, 'explorer-empty-view'); container.tabIndex = 0; @@ -129,7 +115,7 @@ export class EmptyView extends ViewletPanel { if (this.button) { this.button.label = nls.localize('addFolder', "Add Folder"); } - this.titleElement.textContent = EmptyView.NAME; + this.updateTitle(EmptyView.NAME); } else { if (this.environmentService.configuration.remoteAuthority && !isWeb) { const hostLabel = this.labelService.getHostLabel(Schemas.vscodeRemote, this.environmentService.configuration.remoteAuthority); @@ -140,7 +126,7 @@ export class EmptyView extends ViewletPanel { if (this.button) { this.button.label = nls.localize('openFolder', "Open Folder"); } - this.titleElement.textContent = this.title; + this.updateTitle(this.title); } } diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index b3955354dc1..6e943f670f7 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -49,7 +49,7 @@ export class OpenEditorsView extends ViewletPanel { private static readonly DEFAULT_VISIBLE_OPEN_EDITORS = 9; static readonly ID = 'workbench.explorer.openEditorsView'; - static NAME = nls.localize({ key: 'openEditors', comment: ['Open is an adjective'] }, "Open Editors"); + static readonly NAME = nls.localize({ key: 'openEditors', comment: ['Open is an adjective'] }, "Open Editors"); private dirtyCountElement!: HTMLElement; private listRefreshScheduler: RunOnceScheduler; diff --git a/src/vs/workbench/contrib/files/common/files.ts b/src/vs/workbench/contrib/files/common/files.ts index 8f5470bff77..a55bbfa8ed4 100644 --- a/src/vs/workbench/contrib/files/common/files.ts +++ b/src/vs/workbench/contrib/files/common/files.ts @@ -6,7 +6,7 @@ import { URI } from 'vs/base/common/uri'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IWorkbenchEditorConfiguration, IEditorIdentifier, IEditorInput, toResource, SideBySideEditor } from 'vs/workbench/common/editor'; -import { IFilesConfiguration, FileChangeType, IFileService } from 'vs/platform/files/common/files'; +import { IFilesConfiguration as PlatformIFilesConfiguration, FileChangeType, IFileService } from 'vs/platform/files/common/files'; import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ITextModelContentProvider } from 'vs/editor/common/services/resolverService'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; @@ -102,7 +102,7 @@ export const FILE_EDITOR_INPUT_ID = 'workbench.editors.files.fileEditorInput'; export const BINARY_FILE_EDITOR_ID = 'workbench.editors.files.binaryFileEditor'; -export interface IFilesConfiguration extends IFilesConfiguration, IWorkbenchEditorConfiguration { +export interface IFilesConfiguration extends PlatformIFilesConfiguration, IWorkbenchEditorConfiguration { explorer: { openEditors: { visible: number; diff --git a/src/vs/workbench/contrib/format/browser/formatActionsMultiple.ts b/src/vs/workbench/contrib/format/browser/formatActionsMultiple.ts index 4b726da442f..8142c039ed6 100644 --- a/src/vs/workbench/contrib/format/browser/formatActionsMultiple.ts +++ b/src/vs/workbench/contrib/format/browser/formatActionsMultiple.ts @@ -33,7 +33,7 @@ type FormattingEditProvider = DocumentFormattingEditProvider | DocumentRangeForm class DefaultFormatter extends Disposable implements IWorkbenchContribution { - static configName = 'editor.defaultFormatter'; + static readonly configName = 'editor.defaultFormatter'; static extensionIds: (string | null)[] = []; static extensionDescriptions: string[] = []; diff --git a/src/vs/workbench/contrib/logs/common/logsActions.ts b/src/vs/workbench/contrib/logs/common/logsActions.ts index 34e9eed4475..625a8d7836a 100644 --- a/src/vs/workbench/contrib/logs/common/logsActions.ts +++ b/src/vs/workbench/contrib/logs/common/logsActions.ts @@ -15,8 +15,8 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic export class SetLogLevelAction extends Action { - static ID = 'workbench.action.setLogLevel'; - static LABEL = nls.localize('setLogLevel', "Set Log Level..."); + static readonly ID = 'workbench.action.setLogLevel'; + static readonly LABEL = nls.localize('setLogLevel', "Set Log Level..."); constructor(id: string, label: string, @IQuickInputService private readonly quickInputService: IQuickInputService, @@ -60,8 +60,8 @@ export class SetLogLevelAction extends Action { export class OpenWindowSessionLogFileAction extends Action { - static ID = 'workbench.action.openSessionLogFile'; - static LABEL = nls.localize('openSessionLogFile', "Open Window Log File (Session)..."); + static readonly ID = 'workbench.action.openSessionLogFile'; + static readonly LABEL = nls.localize('openSessionLogFile', "Open Window Log File (Session)..."); constructor(id: string, label: string, @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, diff --git a/src/vs/workbench/contrib/logs/electron-browser/logsActions.ts b/src/vs/workbench/contrib/logs/electron-browser/logsActions.ts index 547558b7deb..f2287b85265 100644 --- a/src/vs/workbench/contrib/logs/electron-browser/logsActions.ts +++ b/src/vs/workbench/contrib/logs/electron-browser/logsActions.ts @@ -12,8 +12,8 @@ import { IElectronService } from 'vs/platform/electron/node/electron'; export class OpenLogsFolderAction extends Action { - static ID = 'workbench.action.openLogsFolder'; - static LABEL = nls.localize('openLogsFolder', "Open Logs Folder"); + static readonly ID = 'workbench.action.openLogsFolder'; + static readonly LABEL = nls.localize('openLogsFolder', "Open Logs Folder"); constructor(id: string, label: string, @IEnvironmentService private readonly environmentService: IEnvironmentService, diff --git a/src/vs/workbench/contrib/markers/browser/markersPanelActions.ts b/src/vs/workbench/contrib/markers/browser/markersPanelActions.ts index b2498c05d82..cfba514af3f 100644 --- a/src/vs/workbench/contrib/markers/browser/markersPanelActions.ts +++ b/src/vs/workbench/contrib/markers/browser/markersPanelActions.ts @@ -196,14 +196,14 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { private createBadge(container: HTMLElement): void { const filterBadge = this.filterBadge = DOM.append(container, DOM.$('.markers-panel-filter-badge')); this._register(attachStylerCallback(this.themeService, { badgeBackground, badgeForeground, contrastBorder }, colors => { - const background = colors.badgeBackground ? colors.badgeBackground.toString() : null; - const foreground = colors.badgeForeground ? colors.badgeForeground.toString() : null; - const border = colors.contrastBorder ? colors.contrastBorder.toString() : null; + const background = colors.badgeBackground ? colors.badgeBackground.toString() : ''; + const foreground = colors.badgeForeground ? colors.badgeForeground.toString() : ''; + const border = colors.contrastBorder ? colors.contrastBorder.toString() : ''; filterBadge.style.backgroundColor = background; - filterBadge.style.borderWidth = border ? '1px' : null; - filterBadge.style.borderStyle = border ? 'solid' : null; + filterBadge.style.borderWidth = border ? '1px' : ''; + filterBadge.style.borderStyle = border ? 'solid' : ''; filterBadge.style.borderColor = border; filterBadge.style.color = foreground; })); diff --git a/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts b/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts index 90158388b30..697bfbcff29 100644 --- a/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts +++ b/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts @@ -267,7 +267,7 @@ class MarkerWidget extends Disposable { this.disposables.clear(); dom.clearNode(this.messageAndDetailsContainer); - this.icon.className = `marker-icon ${SeverityIcon.className(MarkerSeverity.toSeverity(element.marker.severity))}`; + this.icon.className = `marker-icon codicon ${SeverityIcon.className(MarkerSeverity.toSeverity(element.marker.severity))}`; this.renderQuickfixActionbar(element); this.renderMultilineActionbar(element); diff --git a/src/vs/workbench/contrib/markers/browser/media/markers.css b/src/vs/workbench/contrib/markers/browser/media/markers.css index cdec9f47999..cf54727d396 100644 --- a/src/vs/workbench/contrib/markers/browser/media/markers.css +++ b/src/vs/workbench/contrib/markers/browser/media/markers.css @@ -132,9 +132,15 @@ margin-left: 6px; } -.markers-panel .monaco-tl-contents .marker-icon, -.markers-panel .monaco-tl-contents .actions .action-item { +.markers-panel .monaco-tl-contents .marker-icon { margin-right: 6px; + display: flex; + align-items: center; + justify-content: center; +} + +.markers-panel .monaco-tl-contents .actions .action-item { + margin-right: 2px; } .markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-source, diff --git a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts index 663ecfa53fb..5ce17f17da2 100644 --- a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts +++ b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts @@ -445,7 +445,6 @@ export class OutlinePanel extends ViewletPanel { private async _doUpdate(editor: ICodeEditor | undefined, event: IModelContentChangedEvent | undefined): Promise { this._editorDisposables.clear(); - this._progressBar.infinite().show(150); const oldModel = this._tree.getInput(); @@ -458,16 +457,16 @@ export class OutlinePanel extends ViewletPanel { return this._showMessage(localize('no-editor', "The active editor cannot provide outline information.")); } - let textModel = editor.getModel(); - let loadingMessage: IDisposable | undefined; - if (!oldModel) { - loadingMessage = new TimeoutTimer( - () => this._showMessage(localize('loading', "Loading document symbols for '{0}'...", basename(textModel.uri))), - 100 - ); - } + const textModel = editor.getModel(); + const loadingMessage = oldModel && new TimeoutTimer( + () => this._showMessage(localize('loading', "Loading document symbols for '{0}'...", basename(textModel.uri))), + 100 + ); - let createdModel = await OutlinePanel._createOutlineModel(textModel, this._editorDisposables); + const requestDelay = OutlineModel.getRequestDelay(textModel); + this._progressBar.infinite().show(requestDelay); + + const createdModel = await OutlinePanel._createOutlineModel(textModel, this._editorDisposables); dispose(loadingMessage); if (!createdModel) { return; @@ -517,7 +516,7 @@ export class OutlinePanel extends ViewletPanel { newModel = oldModel; } else { let state = this._treeStates.get(newModel.textModel.uri.toString()); - await this._tree.setInput(newModel, state); + this._tree.setInput(newModel, state); } // transfer focus from domNode to the tree diff --git a/src/vs/workbench/contrib/output/browser/outputActions.ts b/src/vs/workbench/contrib/output/browser/outputActions.ts index 3760d018bf5..88e7d5b6e96 100644 --- a/src/vs/workbench/contrib/output/browser/outputActions.ts +++ b/src/vs/workbench/contrib/output/browser/outputActions.ts @@ -213,8 +213,8 @@ export class OpenLogOutputFile extends Action { export class ShowLogsOutputChannelAction extends Action { - static ID = 'workbench.action.showLogs'; - static LABEL = nls.localize('showLogs', "Show Logs..."); + static readonly ID = 'workbench.action.showLogs'; + static readonly LABEL = nls.localize('showLogs', "Show Logs..."); constructor(id: string, label: string, @IQuickInputService private readonly quickInputService: IQuickInputService, @@ -243,8 +243,8 @@ interface IOutputChannelQuickPickItem extends IQuickPickItem { export class OpenOutputLogFileAction extends Action { - static ID = 'workbench.action.openLogFile'; - static LABEL = nls.localize('openLogFile', "Open Log File..."); + static readonly ID = 'workbench.action.openLogFile'; + static readonly LABEL = nls.localize('openLogFile', "Open Log File..."); constructor(id: string, label: string, @IQuickInputService private readonly quickInputService: IQuickInputService, diff --git a/src/vs/workbench/contrib/output/browser/outputServices.ts b/src/vs/workbench/contrib/output/browser/outputServices.ts index 1a3e692d6e7..940441708e4 100644 --- a/src/vs/workbench/contrib/output/browser/outputServices.ts +++ b/src/vs/workbench/contrib/output/browser/outputServices.ts @@ -155,7 +155,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo } } - private onDidPanelOpen(panel: IPanel | null, preserveFocus: boolean): Promise { + private onDidPanelOpen(panel: IPanel | undefined, preserveFocus: boolean): Promise { if (panel && panel.getId() === OUTPUT_PANEL_ID) { this._outputPanel = this.panelService.getActivePanel(); if (this.activeChannel) { diff --git a/src/vs/workbench/contrib/output/common/outputLinkComputer.ts b/src/vs/workbench/contrib/output/common/outputLinkComputer.ts index ee681d2dccf..b61cccb5e95 100644 --- a/src/vs/workbench/contrib/output/common/outputLinkComputer.ts +++ b/src/vs/workbench/contrib/output/common/outputLinkComputer.ts @@ -12,6 +12,7 @@ import * as strings from 'vs/base/common/strings'; import { Range } from 'vs/editor/common/core/range'; import { isWindows } from 'vs/base/common/platform'; import { Schemas } from 'vs/base/common/network'; +import { find } from 'vs/base/common/arrays'; export interface ICreateData { workspaceFolders: string[]; @@ -44,15 +45,9 @@ export class OutputLinkComputer { }); } - private getModel(uri: string): IMirrorModel | null { + private getModel(uri: string): IMirrorModel | undefined { const models = this.ctx.getMirrorModels(); - for (const model of models) { - if (model.uri.toString() === uri) { - return model; - } - } - - return null; + return find(models, model => model.uri.toString() === uri); } public computeLinks(uri: string): Promise { diff --git a/src/vs/workbench/contrib/preferences/browser/keybindingsEditorContribution.ts b/src/vs/workbench/contrib/preferences/browser/keybindingsEditorContribution.ts index dc77efc7ce5..006e90f2a76 100644 --- a/src/vs/workbench/contrib/preferences/browser/keybindingsEditorContribution.ts +++ b/src/vs/workbench/contrib/preferences/browser/keybindingsEditorContribution.ts @@ -29,6 +29,7 @@ import { IModelDeltaDecoration, ITextModel, TrackedRangeStickiness, OverviewRule import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeybindingParser } from 'vs/base/common/keybindingParser'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; +import { equals } from 'vs/base/common/arrays'; const NLS_LAUNCH_MESSAGE = nls.localize('defineKeybinding.start', "Define Keybinding"); const NLS_KB_LAYOUT_ERROR_MESSAGE = nls.localize('defineKeybinding.kbLayoutErrorMessage', "You won't be able to produce this key combination under your current keyboard layout."); @@ -265,18 +266,7 @@ export class KeybindingEditorDecorationsRenderer extends Disposable { const aParts = KeybindingParser.parseUserBinding(a); const bParts = KeybindingParser.parseUserBinding(b); - - if (aParts.length !== bParts.length) { - return false; - } - - for (let i = 0, len = aParts.length; i < len; i++) { - if (!this._userBindingEquals(aParts[i], bParts[i])) { - return false; - } - } - - return true; + return equals(aParts, bParts, (a, b) => this._userBindingEquals(a, b)); } private static _userBindingEquals(a: SimpleKeybinding | ScanCodeBinding, b: SimpleKeybinding | ScanCodeBinding): boolean { diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts b/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts index b93c9b2fd62..b7742712238 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Action } from 'vs/base/common/actions'; -import { dispose, IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { getIconClasses } from 'vs/editor/common/services/getIconClasses'; import { IModelService } from 'vs/editor/common/services/modelService'; @@ -198,9 +198,6 @@ export class OpenFolderSettingsAction extends Action { static readonly ID = 'workbench.action.openFolderSettings'; static readonly LABEL = OPEN_FOLDER_SETTINGS_LABEL; - private disposables: IDisposable[] = []; - - constructor( id: string, label: string, @@ -210,8 +207,8 @@ export class OpenFolderSettingsAction extends Action { ) { super(id, label); this.update(); - this.workspaceContextService.onDidChangeWorkbenchState(() => this.update(), this, this.disposables); - this.workspaceContextService.onDidChangeWorkspaceFolders(() => this.update(), this, this.disposables); + this._register(this.workspaceContextService.onDidChangeWorkbenchState(() => this.update(), this)); + this._register(this.workspaceContextService.onDidChangeWorkspaceFolders(() => this.update(), this)); } private update(): void { @@ -228,11 +225,6 @@ export class OpenFolderSettingsAction extends Action { return undefined; }); } - - dispose(): void { - this.disposables = dispose(this.disposables); - super.dispose(); - } } export class ConfigureLanguageBasedSettingsAction extends Action { diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts index 2881d09fec2..2b8d5a82f17 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts @@ -32,6 +32,7 @@ import { DefaultSettingsEditorModel, SettingsEditorModel, WorkspaceConfiguration import { IMarkerService, IMarkerData, MarkerSeverity, MarkerTag } from 'vs/platform/markers/common/markers'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; +import { find } from 'vs/base/common/arrays'; export interface IPreferencesRenderer extends IDisposable { readonly preferencesModel: IPreferencesEditorModel; @@ -321,12 +322,7 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR const { key, overrideOf } = setting; if (overrideOf) { const setting = this.getSetting(overrideOf); - for (const override of setting!.overrides!) { - if (override.key === key) { - return override; - } - } - return undefined; + return find(setting!.overrides!, override => override.key === key); } const settingsGroups = this.filterResult ? this.filterResult.filteredGroups : this.preferencesModel.settingsGroups; return this.getPreference(key, settingsGroups); diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts index eb76fe7dbd4..0ee5430c0e4 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts @@ -90,7 +90,7 @@ export class SettingsTreeNewExtensionsElement extends SettingsTreeElement { } export class SettingsTreeSettingElement extends SettingsTreeElement { - private static MAX_DESC_LINES = 20; + private static readonly MAX_DESC_LINES = 20; setting: ISetting; @@ -273,13 +273,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { return false; } - for (let extensionId of extensionFilters) { - if (extensionId.toLowerCase() === this.setting.extensionInfo.id.toLowerCase()) { - return true; - } - } - - return false; + return Array.from(extensionFilters).some(extensionId => extensionId.toLowerCase() === this.setting.extensionInfo!.id.toLowerCase()); } } @@ -409,7 +403,7 @@ function sanitizeId(id: string): string { return id.replace(/[\.\/]/, '_'); } -export function settingKeyToDisplayFormat(key: string, groupId = ''): { category: string, label: string } { +export function settingKeyToDisplayFormat(key: string, groupId = ''): { category: string, label: string; } { const lastDotIdx = key.lastIndexOf('.'); let category = ''; if (lastDotIdx >= 0) { diff --git a/src/vs/workbench/contrib/quickopen/browser/commandsHandler.ts b/src/vs/workbench/contrib/quickopen/browser/commandsHandler.ts index a0090bae844..334b144c0db 100644 --- a/src/vs/workbench/contrib/quickopen/browser/commandsHandler.ts +++ b/src/vs/workbench/contrib/quickopen/browser/commandsHandler.ts @@ -3,9 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vs/nls'; -import * as arrays from 'vs/base/common/arrays'; -import * as types from 'vs/base/common/types'; +import { localize } from 'vs/nls'; +import { distinct } from 'vs/base/common/arrays'; +import { withNullAsUndefined, isFunction } from 'vs/base/common/types'; import { Language } from 'vs/base/common/platform'; import { Action, WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions'; import { Mode, IEntryRunContext, IAutoFocus, IModel, IQuickNavigateConfiguration } from 'vs/base/parts/quickopen/common/quickOpen'; @@ -137,7 +137,7 @@ class CommandsHistory extends Disposable { export class ShowAllCommandsAction extends Action { static readonly ID = 'workbench.action.showCommands'; - static readonly LABEL = nls.localize('showTriggerActions', "Show All Commands"); + static readonly LABEL = localize('showTriggerActions', "Show All Commands"); constructor( id: string, @@ -167,7 +167,7 @@ export class ShowAllCommandsAction extends Action { export class ClearCommandHistoryAction extends Action { static readonly ID = 'workbench.action.clearCommandHistory'; - static readonly LABEL = nls.localize('clearCommandHistory', "Clear Command History"); + static readonly LABEL = localize('clearCommandHistory', "Clear Command History"); constructor( id: string, @@ -196,7 +196,7 @@ class CommandPaletteEditorAction extends EditorAction { constructor() { super({ id: ShowAllCommandsAction.ID, - label: nls.localize('showCommands.label', "Command Palette..."), + label: localize('showCommands.label', "Command Palette..."), alias: 'Command Palette', precondition: undefined, menuOpts: { @@ -224,10 +224,10 @@ abstract class BaseCommandEntry extends QuickOpenEntryGroup { constructor( private commandId: string, - private keybinding: ResolvedKeybinding, + private keybinding: ResolvedKeybinding | undefined, private label: string, - alias: string, - highlights: { label: IHighlight[], alias?: IHighlight[] }, + alias: string | undefined, + highlights: { label: IHighlight[] | null, alias: IHighlight[] | null }, private onBeforeRun: (commandId: string) => void, @INotificationService private readonly notificationService: INotificationService, @ITelemetryService protected telemetryService: ITelemetryService @@ -240,10 +240,10 @@ abstract class BaseCommandEntry extends QuickOpenEntryGroup { if (this.label !== alias) { this.alias = alias; } else { - highlights.alias = undefined; + highlights.alias = null; } - this.setHighlights(highlights.label, undefined, highlights.alias); + this.setHighlights(withNullAsUndefined(highlights.label), undefined, withNullAsUndefined(highlights.alias)); } getCommandId(): string { @@ -266,7 +266,7 @@ abstract class BaseCommandEntry extends QuickOpenEntryGroup { this.description = description; } - getKeybinding(): ResolvedKeybinding { + getKeybinding(): ResolvedKeybinding | undefined { return this.keybinding; } @@ -276,10 +276,10 @@ abstract class BaseCommandEntry extends QuickOpenEntryGroup { getAriaLabel(): string { if (this.keybindingAriaLabel) { - return nls.localize('entryAriaLabelWithKey', "{0}, {1}, commands", this.getLabel(), this.keybindingAriaLabel); + return localize('entryAriaLabelWithKey', "{0}, {1}, commands", this.getLabel(), this.keybindingAriaLabel); } - return nls.localize('entryAriaLabel', "{0}, commands", this.getLabel()); + return localize('entryAriaLabel', "{0}, commands", this.getLabel()); } run(mode: Mode, context: IEntryRunContext): boolean { @@ -319,7 +319,7 @@ abstract class BaseCommandEntry extends QuickOpenEntryGroup { this.onError(error); } } else { - this.notificationService.info(nls.localize('actionNotEnabled', "Command '{0}' is not enabled in the current context.", this.getLabel())); + this.notificationService.info(localize('actionNotEnabled', "Command '{0}' is not enabled in the current context.", this.getLabel())); } }, 50); } @@ -329,7 +329,7 @@ abstract class BaseCommandEntry extends QuickOpenEntryGroup { return; } - this.notificationService.error(error || nls.localize('canNotRun', "Command '{0}' resulted in an error.", this.label)); + this.notificationService.error(error || localize('canNotRun', "Command '{0}' resulted in an error.", this.label)); } } @@ -337,10 +337,10 @@ class EditorActionCommandEntry extends BaseCommandEntry { constructor( commandId: string, - keybinding: ResolvedKeybinding, + keybinding: ResolvedKeybinding | undefined, label: string, - meta: string, - highlights: { label: IHighlight[], alias: IHighlight[] }, + meta: string | undefined, + highlights: { label: IHighlight[] | null, alias: IHighlight[] | null }, private action: IEditorAction, onBeforeRun: (commandId: string) => void, @INotificationService notificationService: INotificationService, @@ -358,10 +358,10 @@ class ActionCommandEntry extends BaseCommandEntry { constructor( commandId: string, - keybinding: ResolvedKeybinding, + keybinding: ResolvedKeybinding | undefined, label: string, - alias: string, - highlights: { label: IHighlight[], alias: IHighlight[] }, + alias: string | undefined, + highlights: { label: IHighlight[] | null, alias: IHighlight[] | null }, private action: Action, onBeforeRun: (commandId: string) => void, @INotificationService notificationService: INotificationService, @@ -439,7 +439,7 @@ export class CommandsHandler extends QuickOpenHandler implements IDisposable { // Editor Actions const activeTextEditorWidget = this.editorService.activeTextEditorWidget; let editorActions: IEditorAction[] = []; - if (activeTextEditorWidget && types.isFunction(activeTextEditorWidget.getSupportedActions)) { + if (activeTextEditorWidget && isFunction(activeTextEditorWidget.getSupportedActions)) { editorActions = activeTextEditorWidget.getSupportedActions(); } @@ -456,7 +456,7 @@ export class CommandsHandler extends QuickOpenHandler implements IDisposable { let entries = [...editorEntries, ...commandEntries]; // Remove duplicates - entries = arrays.distinct(entries, entry => `${entry.getLabel()}${entry.getGroupLabel()}${entry.getCommandId()}`); + entries = distinct(entries, entry => `${entry.getLabel()}${entry.getGroupLabel()}${entry.getCommandId()}`); // Handle label clashes const commandLabels = new Set(); @@ -494,12 +494,12 @@ export class CommandsHandler extends QuickOpenHandler implements IDisposable { // only if we have recently used commands in the result set const firstEntry = entries[0]; if (firstEntry && this.commandsHistory.peek(firstEntry.getCommandId())) { - firstEntry.setGroupLabel(nls.localize('recentlyUsed', "recently used")); + firstEntry.setGroupLabel(localize('recentlyUsed', "recently used")); for (let i = 1; i < entries.length; i++) { const entry = entries[i]; if (!this.commandsHistory.peek(entry.getCommandId())) { entry.setShowBorder(true); - entry.setGroupLabel(nls.localize('morecCommands', "other commands")); + entry.setGroupLabel(localize('morecCommands', "other commands")); break; } } @@ -520,7 +520,7 @@ export class CommandsHandler extends QuickOpenHandler implements IDisposable { if (label) { // Alias for non default languages - const alias = !Language.isDefaultVariant() ? action.alias : null; + const alias = !Language.isDefaultVariant() ? action.alias : undefined; const labelHighlights = wordFilter(searchValue, label); const aliasHighlights = alias ? wordFilter(searchValue, alias) : null; @@ -547,15 +547,15 @@ export class CommandsHandler extends QuickOpenHandler implements IDisposable { let category, label = title; if (action.item.category) { category = typeof action.item.category === 'string' ? action.item.category : action.item.category.value; - label = nls.localize('cat.title', "{0}: {1}", category, title); + label = localize('cat.title', "{0}: {1}", category, title); } if (label) { const labelHighlights = wordFilter(searchValue, label); // Add an 'alias' in original language when running in different locale - const aliasTitle = (!Language.isDefaultVariant() && typeof action.item.title !== 'string') ? action.item.title.original : null; - const aliasCategory = (!Language.isDefaultVariant() && category && action.item.category && typeof action.item.category !== 'string') ? action.item.category.original : null; + const aliasTitle = (!Language.isDefaultVariant() && typeof action.item.title !== 'string') ? action.item.title.original : undefined; + const aliasCategory = (!Language.isDefaultVariant() && category && action.item.category && typeof action.item.category !== 'string') ? action.item.category.original : undefined; let alias; if (aliasTitle && category) { alias = aliasCategory ? `${aliasCategory}: ${aliasTitle}` : `${category}: ${aliasTitle}`; @@ -590,7 +590,7 @@ export class CommandsHandler extends QuickOpenHandler implements IDisposable { } getEmptyLabel(searchString: string): string { - return nls.localize('noCommandsMatching', "No commands matching"); + return localize('noCommandsMatching', "No commands matching"); } onClose(canceled: boolean): void { diff --git a/src/vs/workbench/contrib/quickopen/browser/gotoSymbolHandler.ts b/src/vs/workbench/contrib/quickopen/browser/gotoSymbolHandler.ts index 60a0a3da383..d6f0c2560da 100644 --- a/src/vs/workbench/contrib/quickopen/browser/gotoSymbolHandler.ts +++ b/src/vs/workbench/contrib/quickopen/browser/gotoSymbolHandler.ts @@ -195,7 +195,7 @@ class SymbolEntry extends EditorQuickOpenEntryGroup { return this.deprecated ? { extraClasses: ['deprecated'] } : undefined; } - getHighlights(): [IHighlight[], IHighlight[] | undefined, IHighlight[] | undefined] { + getHighlights(): [IHighlight[] | undefined, IHighlight[] | undefined, IHighlight[] | undefined] { return [ this.deprecated ? [] : filters.createMatches(this.score), undefined, diff --git a/src/vs/workbench/contrib/remote/browser/remote.ts b/src/vs/workbench/contrib/remote/browser/remote.ts index 14a04519113..bc4db1d2a9f 100644 --- a/src/vs/workbench/contrib/remote/browser/remote.ts +++ b/src/vs/workbench/contrib/remote/browser/remote.ts @@ -468,7 +468,7 @@ Registry.as(ViewletExtensions.Viewlets).registerViewlet(new Vie class OpenRemoteViewletAction extends ShowViewletAction { static readonly ID = VIEWLET_ID; - static LABEL = nls.localize('toggleRemoteViewlet', "Show Remote Explorer"); + static readonly LABEL = nls.localize('toggleRemoteViewlet', "Show Remote Explorer"); constructor(id: string, label: string, @IViewletService viewletService: IViewletService, @IEditorGroupsService editorGroupService: IEditorGroupsService, @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService) { super(id, label, VIEWLET_ID, viewletService, editorGroupService, layoutService); diff --git a/src/vs/workbench/contrib/scm/browser/mainPanel.ts b/src/vs/workbench/contrib/scm/browser/mainPanel.ts index 2e0f160671a..217ab0acc4b 100644 --- a/src/vs/workbench/contrib/scm/browser/mainPanel.ts +++ b/src/vs/workbench/contrib/scm/browser/mainPanel.ts @@ -10,7 +10,6 @@ import { basename } from 'vs/base/common/resources'; import { IDisposable, dispose, Disposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle'; import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { append, $, toggleClass } from 'vs/base/browser/dom'; -import { List } from 'vs/base/browser/ui/list/listWidget'; import { IListVirtualDelegate, IListRenderer, IListContextMenuEvent, IListEvent } from 'vs/base/browser/ui/list/list'; import { ISCMService, ISCMRepository } from 'vs/workbench/contrib/scm/common/scm'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; @@ -173,7 +172,7 @@ export class MainPanel extends ViewletPanel { static readonly ID = 'scm.mainPanel'; static readonly TITLE = localize('scm providers', "Source Control Providers"); - private list!: List; + private list!: WorkbenchList; constructor( protected viewModel: IViewModel, diff --git a/src/vs/workbench/contrib/scm/browser/repositoryPanel.ts b/src/vs/workbench/contrib/scm/browser/repositoryPanel.ts index 9566f4b1cba..d3e83e0d735 100644 --- a/src/vs/workbench/contrib/scm/browser/repositoryPanel.ts +++ b/src/vs/workbench/contrib/scm/browser/repositoryPanel.ts @@ -64,7 +64,7 @@ interface ResourceGroupTemplate { class ResourceGroupRenderer implements ICompressibleTreeRenderer { - static TEMPLATE_ID = 'resource group'; + static readonly TEMPLATE_ID = 'resource group'; get templateId(): string { return ResourceGroupRenderer.TEMPLATE_ID; } constructor( @@ -150,7 +150,7 @@ class MultipleSelectionActionRunner extends ActionRunner { class ResourceRenderer implements ICompressibleTreeRenderer, FuzzyScore, ResourceTemplate> { - static TEMPLATE_ID = 'resource'; + static readonly TEMPLATE_ID = 'resource'; get templateId(): string { return ResourceRenderer.TEMPLATE_ID; } constructor( diff --git a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts index 291d9386b1f..a8888407cb8 100644 --- a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts +++ b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts @@ -28,7 +28,7 @@ import { SCMService } from 'vs/workbench/contrib/scm/common/scmService'; class OpenSCMViewletAction extends ShowViewletAction { static readonly ID = VIEWLET_ID; - static LABEL = localize('toggleGitViewlet', "Show Git"); + static readonly LABEL = localize('toggleGitViewlet', "Show Git"); constructor(id: string, label: string, @IViewletService viewletService: IViewletService, @IEditorGroupsService editorGroupService: IEditorGroupsService, @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService) { super(id, label, VIEWLET_ID, viewletService, editorGroupService, layoutService); diff --git a/src/vs/workbench/contrib/search/browser/openSymbolHandler.ts b/src/vs/workbench/contrib/search/browser/openSymbolHandler.ts index c0bcedcb221..06bad345969 100644 --- a/src/vs/workbench/contrib/search/browser/openSymbolHandler.ts +++ b/src/vs/workbench/contrib/search/browser/openSymbolHandler.ts @@ -47,7 +47,7 @@ class SymbolEntry extends EditorQuickOpenEntry { this.score = score; } - getHighlights(): [IHighlight[] /* Label */, IHighlight[] | undefined /* Description */, IHighlight[] | undefined /* Detail */] { + getHighlights(): [IHighlight[] | undefined /* Label */, IHighlight[] | undefined /* Description */, IHighlight[] | undefined /* Detail */] { return [this.isDeprecated() ? [] : filters.createMatches(this.score), undefined, undefined]; } diff --git a/src/vs/workbench/contrib/search/browser/searchActions.ts b/src/vs/workbench/contrib/search/browser/searchActions.ts index 099312d3d98..c1dc5804ba3 100644 --- a/src/vs/workbench/contrib/search/browser/searchActions.ts +++ b/src/vs/workbench/contrib/search/browser/searchActions.ts @@ -494,7 +494,7 @@ export abstract class AbstractSearchAndReplaceAction extends Action { export class RemoveAction extends AbstractSearchAndReplaceAction { - static LABEL = nls.localize('RemoveAction.label', "Dismiss"); + static readonly LABEL = nls.localize('RemoveAction.label', "Dismiss"); constructor( private viewer: WorkbenchObjectTree, diff --git a/src/vs/workbench/contrib/snippets/browser/tabCompletion.ts b/src/vs/workbench/contrib/snippets/browser/tabCompletion.ts index 20f06e31a9e..9522f3006b1 100644 --- a/src/vs/workbench/contrib/snippets/browser/tabCompletion.ts +++ b/src/vs/workbench/contrib/snippets/browser/tabCompletion.ts @@ -24,7 +24,7 @@ import { EditorOption } from 'vs/editor/common/config/editorOptions'; export class TabCompletionController implements editorCommon.IEditorContribution { private static readonly ID = 'editor.tabCompletionController'; - static ContextKey = new RawContextKey('hasSnippetCompletions', undefined); + static readonly ContextKey = new RawContextKey('hasSnippetCompletions', undefined); public static get(editor: ICodeEditor): TabCompletionController { return editor.getContribution(TabCompletionController.ID); diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 6a3efa5fd4b..ec2a34ea079 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -77,6 +77,7 @@ import { applyEdits } from 'vs/base/common/jsonEdit'; import { ITextEditor } from 'vs/workbench/common/editor'; import { ITextEditorSelection } from 'vs/platform/editor/common/editor'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; +import { find } from 'vs/base/common/arrays'; export namespace ConfigureTaskAction { export const ID = 'workbench.action.tasks.configureTaskRunner'; @@ -515,12 +516,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (!values) { return undefined; } - for (const task of values) { - if (task.matches(key, compareId)) { - return task; - } - } - return undefined; + return find(values, task => task.matches(key, compareId)); }); } diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 1c45953acdf..4f33f892c3f 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -113,7 +113,7 @@ export class TerminalTaskSystem implements ITaskSystem { public static TelemetryEventName: string = 'taskService'; - private static ProcessVarName = '__process__'; + private static readonly ProcessVarName = '__process__'; private static shellQuotes: IStringDictionary = { 'cmd': { @@ -527,6 +527,10 @@ export class TerminalTaskSystem implements ITaskSystem { if (task.configurationProperties.isBackground) { const problemMatchers = this.resolveMatchers(resolver, task.configurationProperties.problemMatchers); let watchingProblemMatcher = new WatchingProblemCollector(problemMatchers, this.markerService, this.modelService, this.fileService); + if (!watchingProblemMatcher.isWatching()) { + this.appendOutput(nls.localize('TerminalTaskSystem.nonWatchingMatcher', 'Task {0} is a background task but uses a problem matcher without a background pattern', task._label)); + this.showOutput(); + } const toDispose = new DisposableStore(); let eventCounter: number = 0; toDispose.add(watchingProblemMatcher.onDidStateChange((event) => { @@ -983,6 +987,7 @@ export class TerminalTaskSystem implements ITaskSystem { throw new Error('Task shell launch configuration should not be undefined here.'); } + terminalToReuse.terminal.scrollToBottom(); terminalToReuse.terminal.reuseTerminal(launchConfigs); if (task.command.presentation && task.command.presentation.clear) { diff --git a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts index 30333ecdc3d..70e9d1b1fb5 100644 --- a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts +++ b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts @@ -524,4 +524,8 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement }); super.done(); } + + public isWatching(): boolean { + return this.backgroundPatterns.length > 0; + } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index d8b97df7808..9d167923792 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -408,14 +408,6 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // The panel is minimized if (!this._isVisible) { return TerminalInstance._lastKnownCanvasDimensions; - } else { - // Trigger scroll event manually so that the viewport's scroll area is synced. This - // needs to happen otherwise its scrollTop value is invalid when the panel is toggled as - // it gets removed and then added back to the DOM (resetting scrollTop to 0). - // Upstream issue: https://github.com/sourcelair/xterm.js/issues/291 - if (this._xterm && this._xtermCore) { - this._xtermCore._onScroll.fire(this._xterm.buffer.viewportY); - } } if (!this._wrapperElement) { @@ -569,7 +561,10 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // Attach the xterm object to the DOM, exposing it to the smoke tests this._wrapperElement.xterm = this._xterm; + this._wrapperElement.appendChild(this._xtermElement); + this._container.appendChild(this._wrapperElement); xterm.open(this._xtermElement); + xterm.textarea.addEventListener('focus', () => this._onFocus.fire(this)); xterm.attachCustomKeyEventHandler((event: KeyboardEvent): boolean => { // Disable all input if the terminal is exiting @@ -646,9 +641,6 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._refreshSelectionContextKey(); })); - this._wrapperElement.appendChild(this._xtermElement); - this._container.appendChild(this._wrapperElement); - const widgetManager = new TerminalWidgetManager(this._wrapperElement); this._widgetManager = widgetManager; this._processManager.onProcessReady(() => { @@ -902,6 +894,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // necessary if the number of rows in the terminal has decreased while it was in the // background since scrollTop changes take no effect but the terminal's position does // change since the number of visible rows decreases. + // This can likely be removed after https://github.com/xtermjs/xterm.js/issues/291 is + // fixed upstream. this._xtermCore._onScroll.fire(this._xterm.buffer.viewportY); if (this._container && this._container.parentElement) { // Force a layout when the instance becomes invisible. This is particularly important diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index a0772f91fd5..6bb7530ed79 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -29,6 +29,7 @@ import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/termi import { isWindows, isMacintosh, OperatingSystem } from 'vs/base/common/platform'; import { basename } from 'vs/base/common/path'; import { IOpenFileRequest } from 'vs/platform/windows/common/windows'; +import { find } from 'vs/base/common/arrays'; interface IExtHostReadyEntry { promise: Promise; @@ -414,13 +415,8 @@ export class TerminalService implements ITerminalService { instance.addDisposable(instance.onFocus(this._onActiveInstanceChanged.fire, this._onActiveInstanceChanged)); } - private _getTabForInstance(instance: ITerminalInstance): ITerminalTab | null { - for (const tab of this._terminalTabs) { - if (tab.terminalInstances.indexOf(instance) !== -1) { - return tab; - } - } - return null; + private _getTabForInstance(instance: ITerminalInstance): ITerminalTab | undefined { + return find(this._terminalTabs, tab => tab.terminalInstances.indexOf(instance) !== -1); } public showPanel(focus?: boolean): Promise { diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts index fefece531e3..bdaf6d62248 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts @@ -84,7 +84,9 @@ suite('Workbench - TerminalCommandTracker', () => { (window).matchMedia = () => { return { addListener: () => { } }; }; - xterm.open(document.createElement('div')); + const e = document.createElement('div'); + document.body.appendChild(e); + xterm.open(e); await writePromise(xterm, '\r0'); await writePromise(xterm, '\n\r1'); @@ -109,12 +111,16 @@ suite('Workbench - TerminalCommandTracker', () => { assert.equal(xterm.getSelection(), '2'); commandTracker.selectToNextCommand(); assert.equal(xterm.getSelection(), isWindows ? '\r\n' : '\n'); + + document.body.removeChild(e); }); test('should select to the next and previous lines & commands', async () => { (window).matchMedia = () => { return { addListener: () => { } }; }; - xterm.open(document.createElement('div')); + const e = document.createElement('div'); + document.body.appendChild(e); + xterm.open(e); await writePromise(xterm, '\r0'); await writePromise(xterm, '\n\r1'); @@ -144,6 +150,8 @@ suite('Workbench - TerminalCommandTracker', () => { assert.equal(xterm.getSelection(), isWindows ? '1\r\n2' : '1\n2'); commandTracker.selectToPreviousLine(); assert.equal(xterm.getSelection(), isWindows ? '0\r\n1\r\n2' : '0\n1\n2'); + + document.body.removeChild(e); }); }); }); diff --git a/src/vs/workbench/contrib/themes/browser/themes.contribution.ts b/src/vs/workbench/contrib/themes/browser/themes.contribution.ts index 5026e50adad..8dc089688b4 100644 --- a/src/vs/workbench/contrib/themes/browser/themes.contribution.ts +++ b/src/vs/workbench/contrib/themes/browser/themes.contribution.ts @@ -27,7 +27,7 @@ import { IQuickInputService, QuickPickInput } from 'vs/platform/quickinput/commo export class SelectColorThemeAction extends Action { static readonly ID = 'workbench.action.selectTheme'; - static LABEL = localize('selectTheme.label', "Color Theme"); + static readonly LABEL = localize('selectTheme.label', "Color Theme"); constructor( id: string, @@ -90,7 +90,7 @@ export class SelectColorThemeAction extends Action { class SelectIconThemeAction extends Action { static readonly ID = 'workbench.action.selectIconTheme'; - static LABEL = localize('selectIconTheme.label', "File Icon Theme"); + static readonly LABEL = localize('selectIconTheme.label', "File Icon Theme"); constructor( id: string, @@ -197,7 +197,7 @@ function toEntries(themes: Array, label?: string): class GenerateColorThemeAction extends Action { static readonly ID = 'workbench.action.generateColorTheme'; - static LABEL = localize('generateColorTheme.label', "Generate Color Theme From Current Settings"); + static readonly LABEL = localize('generateColorTheme.label', "Generate Color Theme From Current Settings"); constructor( id: string, @@ -288,4 +288,4 @@ MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { title: localize('themes.selectIconTheme.label', "File Icon Theme") }, order: 2 -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/contrib/update/browser/update.ts b/src/vs/workbench/contrib/update/browser/update.ts index c93c32fede6..fd18b8d852b 100644 --- a/src/vs/workbench/contrib/update/browser/update.ts +++ b/src/vs/workbench/contrib/update/browser/update.ts @@ -103,7 +103,7 @@ export class ShowReleaseNotesAction extends AbstractShowReleaseNotesAction { export class ShowCurrentReleaseNotesAction extends AbstractShowReleaseNotesAction { static readonly ID = ShowCurrentReleaseNotesActionId; - static LABEL = nls.localize('showReleaseNotes', "Show Release Notes"); + static readonly LABEL = nls.localize('showReleaseNotes', "Show Release Notes"); constructor( id = ShowCurrentReleaseNotesAction.ID, diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts index 9f341bbb06c..cb620c83d9d 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts @@ -21,7 +21,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic export class WebviewEditor extends BaseEditor { - public static ID = 'WebviewEditor'; + public static readonly ID = 'WebviewEditor'; private readonly _scopedContextKeyService = this._register(new MutableDisposable()); private _findWidgetVisible: IContextKey; diff --git a/src/vs/workbench/contrib/webview/browser/webviewService.ts b/src/vs/workbench/contrib/webview/browser/webviewService.ts index 0b8c5b01c69..44610b046b8 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewService.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewService.ts @@ -18,7 +18,7 @@ export class WebviewService implements IWebviewService { constructor( @IInstantiationService private readonly _instantiationService: IInstantiationService, ) { - this._instantiationService.createInstance(WebviewThemeDataProvider); + this._webviewThemeDataProvider = this._instantiationService.createInstance(WebviewThemeDataProvider); } createWebview( diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index ab5c8d3df87..41940cec8e3 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -37,6 +37,43 @@ interface IKeydownEvent { repeat: boolean; } +class WebviewTagHandle extends Disposable { + + private _webContents: undefined | WebContents | 'destroyed'; + + public constructor( + public readonly webview: WebviewTag, + ) { + super(); + + this._register(addDisposableListener(this.webview, 'destroyed', () => { + this._webContents = 'destroyed'; + })); + + this._register(addDisposableListener(this.webview, 'did-start-loading', once(() => { + const contents = this.webContents; + if (contents) { + this._onFirstLoad.fire(contents); + } + }))); + } + + private readonly _onFirstLoad = this._register(new Emitter()); + public readonly onFirstLoad = this._onFirstLoad.event; + + public get webContents(): WebContents | undefined { + if (this._webContents === 'destroyed') { + return undefined; + } + if (this._webContents) { + return this._webContents; + } + this._webContents = this.webview.getWebContents(); + return this._webContents; + } + +} + type OnBeforeRequestDelegate = (details: OnBeforeRequestDetails) => Promise; type OnHeadersReceivedDelegate = (details: OnHeadersReceivedDetails) => { cancel: boolean; } | undefined; @@ -46,16 +83,11 @@ class WebviewSession extends Disposable { private readonly _onHeadersReceivedDelegates: Array = []; public constructor( - webview: WebviewTag, + webviewHandle: WebviewTagHandle, ) { super(); - this._register(addDisposableListener(webview, 'did-start-loading', once(() => { - const contents = webview.getWebContents(); - if (!contents) { - return; - } - + this._register(webviewHandle.onFirstLoad(contents => { contents.session.webRequest.onBeforeRequest(async (details, callback) => { for (const delegate of this._onBeforeRequestDelegates) { const result = await delegate(details); @@ -77,7 +109,7 @@ class WebviewSession extends Disposable { } callback({ cancel: false, responseHeaders: details.responseHeaders }); }); - }))); + })); } public onBeforeRequest(delegate: OnBeforeRequestDelegate) { @@ -91,26 +123,19 @@ class WebviewSession extends Disposable { class WebviewProtocolProvider extends Disposable { constructor( - webview: WebviewTag, + handle: WebviewTagHandle, private readonly _getExtensionLocation: () => URI | undefined, private readonly _getLocalResourceRoots: () => ReadonlyArray, private readonly _fileService: IFileService, ) { super(); - this._register(addDisposableListener(webview, 'did-start-loading', once(() => { - const contents = webview.getWebContents(); - if (contents) { - this.registerProtocols(contents); - } - }))); + this._register(handle.onFirstLoad(contents => { + this.registerProtocols(contents); + })); } private registerProtocols(contents: WebContents) { - if (contents.isDestroyed()) { - return; - } - registerFileProtocol(contents, WebviewResourceScheme, this._fileService, this._getExtensionLocation(), () => this._getLocalResourceRoots() ); @@ -142,25 +167,22 @@ class WebviewKeyboardHandler extends Disposable { private _ignoreMenuShortcut = false; constructor( - private readonly _webview: WebviewTag + private readonly _webviewHandle: WebviewTagHandle ) { super(); if (this.shouldToggleMenuShortcutsEnablement) { - this._register(addDisposableListener(this._webview, 'did-start-loading', () => { - const contents = this.getWebContents(); - if (contents) { - contents.on('before-input-event', (_event, input) => { - if (input.type === 'keyDown' && document.activeElement === this._webview) { - this._ignoreMenuShortcut = input.control || input.meta; - this.setIgnoreMenuShortcuts(this._ignoreMenuShortcut); - } - }); - } + this._register(_webviewHandle.onFirstLoad(contents => { + contents.on('before-input-event', (_event, input) => { + if (input.type === 'keyDown' && document.activeElement === this._webviewHandle.webview) { + this._ignoreMenuShortcut = input.control || input.meta; + this.setIgnoreMenuShortcuts(this._ignoreMenuShortcut); + } + }); })); } - this._register(addDisposableListener(this._webview, 'ipc-message', (event) => { + this._register(addDisposableListener(this._webviewHandle.webview, 'ipc-message', (event) => { switch (event.channel) { case 'did-keydown': // Electron: workaround for https://github.com/electron/electron/issues/14258 @@ -188,26 +210,18 @@ class WebviewKeyboardHandler extends Disposable { if (!this.shouldToggleMenuShortcutsEnablement) { return; } - const contents = this.getWebContents(); + const contents = this._webviewHandle.webContents; if (contents) { contents.setIgnoreMenuShortcuts(value); } } - private getWebContents(): WebContents | undefined { - const contents = this._webview.getWebContents(); - if (contents && !contents.isDestroyed()) { - return contents; - } - return undefined; - } - private handleKeydown(event: IKeydownEvent): void { // Create a fake KeyboardEvent from the data provided const emulatedKeyboardEvent = new KeyboardEvent('keydown', event); // Force override the target Object.defineProperty(emulatedKeyboardEvent, 'target', { - get: () => this._webview + get: () => this._webviewHandle.webview }); // And re-dispatch window.dispatchEvent(emulatedKeyboardEvent); @@ -281,10 +295,12 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview, })); }); - const session = this._register(new WebviewSession(this._webview)); + const webviewAndContents = new WebviewTagHandle(this._webview); + + const session = this._register(new WebviewSession(webviewAndContents)); this._register(new WebviewProtocolProvider( - this._webview, + webviewAndContents, () => this.extension ? this.extension.location : undefined, () => (this.content.options.localResourceRoots || []), fileService)); @@ -296,7 +312,7 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview, tunnelService, )); - this._register(new WebviewKeyboardHandler(this._webview)); + this._register(new WebviewKeyboardHandler(webviewAndContents)); this._register(addDisposableListener(this._webview, 'console-message', function (e: { level: number; message: string; line: number; sourceId: string; }) { console.log(`[Embedded Page] ${e.message}`); @@ -567,24 +583,8 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview, } public layout(): void { - if (!this._webview || this._webview.style.width === '0px') { - return; - } - const contents = this._webview.getWebContents(); - if (!contents || contents.isDestroyed()) { - return; - } - const window = (contents as any).getOwnerBrowserWindow(); - if (!window || !window.webContents || window.webContents.isDestroyed()) { - return; - } - window.webContents.getZoomFactor((factor: number) => { - if (contents.isDestroyed()) { - return; - } + // noop - contents.setZoomFactor(factor); - }); } private readonly _hasFindResult = this._register(new Emitter()); diff --git a/src/vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.ts b/src/vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.ts index 4a84a56125d..50398d48086 100644 --- a/src/vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.ts +++ b/src/vs/workbench/contrib/welcome/telemetryOptOut/browser/telemetryOptOut.ts @@ -20,7 +20,7 @@ import { IHostService } from 'vs/workbench/services/host/browser/host'; export abstract class AbstractTelemetryOptOut implements IWorkbenchContribution { - private static TELEMETRY_OPT_OUT_SHOWN = 'workbench.telemetryOptOutShown'; + private static readonly TELEMETRY_OPT_OUT_SHOWN = 'workbench.telemetryOptOutShown'; private privacyUrl: string | undefined; constructor( diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index d9b50a3f494..a33bd626c5a 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -11,7 +11,7 @@ import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedPr export class ToggleDevToolsAction extends Action { static readonly ID = 'workbench.action.toggleDevTools'; - static LABEL = nls.localize('toggleDevTools', "Toggle Developer Tools"); + static readonly LABEL = nls.localize('toggleDevTools', "Toggle Developer Tools"); constructor(id: string, label: string, @IElectronService private readonly electronService: IElectronService) { super(id, label); @@ -25,7 +25,7 @@ export class ToggleDevToolsAction extends Action { export class ToggleSharedProcessAction extends Action { static readonly ID = 'workbench.action.toggleSharedProcess'; - static LABEL = nls.localize('toggleSharedProcess', "Toggle Shared Process"); + static readonly LABEL = nls.localize('toggleSharedProcess', "Toggle Shared Process"); constructor(id: string, label: string, @ISharedProcessService private readonly sharedProcessService: ISharedProcessService) { super(id, label); diff --git a/src/vs/workbench/electron-browser/actions/windowActions.ts b/src/vs/workbench/electron-browser/actions/windowActions.ts index 2efe92ef881..9bc18a02043 100644 --- a/src/vs/workbench/electron-browser/actions/windowActions.ts +++ b/src/vs/workbench/electron-browser/actions/windowActions.ts @@ -140,7 +140,7 @@ export class ZoomResetAction extends BaseZoomAction { export class ReloadWindowWithExtensionsDisabledAction extends Action { static readonly ID = 'workbench.action.reloadWindowWithExtensionsDisabled'; - static LABEL = nls.localize('reloadWindowWithExtensionsDisabled', "Reload With Extensions Disabled"); + static readonly LABEL = nls.localize('reloadWindowWithExtensionsDisabled', "Reload With Extensions Disabled"); constructor( id: string, @@ -217,7 +217,7 @@ export abstract class BaseSwitchWindow extends Action { export class SwitchWindow extends BaseSwitchWindow { static readonly ID = 'workbench.action.switchWindow'; - static LABEL = nls.localize('switchWindow', "Switch Window..."); + static readonly LABEL = nls.localize('switchWindow', "Switch Window..."); constructor( id: string, @@ -240,7 +240,7 @@ export class SwitchWindow extends BaseSwitchWindow { export class QuickSwitchWindow extends BaseSwitchWindow { static readonly ID = 'workbench.action.quickSwitchWindow'; - static LABEL = nls.localize('quickSwitchWindow', "Quick Switch Window..."); + static readonly LABEL = nls.localize('quickSwitchWindow', "Quick Switch Window..."); constructor( id: string, diff --git a/src/vs/workbench/electron-browser/actions/workspaceActions.ts b/src/vs/workbench/electron-browser/actions/workspaceActions.ts index ca7bcfab229..6647ac84756 100644 --- a/src/vs/workbench/electron-browser/actions/workspaceActions.ts +++ b/src/vs/workbench/electron-browser/actions/workspaceActions.ts @@ -14,7 +14,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ export class SaveWorkspaceAsAction extends Action { static readonly ID = 'workbench.action.saveWorkspaceAs'; - static LABEL = nls.localize('saveWorkspaceAsAction', "Save Workspace As..."); + static readonly LABEL = nls.localize('saveWorkspaceAsAction', "Save Workspace As..."); constructor( id: string, diff --git a/src/vs/workbench/services/clipboard/electron-browser/clipboardService.ts b/src/vs/workbench/services/clipboard/electron-browser/clipboardService.ts index 6962d84f471..623385c0a79 100644 --- a/src/vs/workbench/services/clipboard/electron-browser/clipboardService.ts +++ b/src/vs/workbench/services/clipboard/electron-browser/clipboardService.ts @@ -11,7 +11,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class NativeClipboardService implements IClipboardService { - private static FILE_FORMAT = 'code/file-list'; // Clipboard format for files + private static readonly FILE_FORMAT = 'code/file-list'; // Clipboard format for files _serviceBrand: undefined; diff --git a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts index a4eedf25bfb..220b9d988e9 100644 --- a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts @@ -25,7 +25,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export abstract class BaseConfigurationResolverService extends AbstractVariableResolverService { - static INPUT_OR_COMMAND_VARIABLES_PATTERN = /\${((input|command):(.*?))}/g; + static readonly INPUT_OR_COMMAND_VARIABLES_PATTERN = /\${((input|command):(.*?))}/g; constructor( envVariables: IProcessEnvironment, diff --git a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts index 32242293645..03f17d054c8 100644 --- a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts @@ -27,8 +27,8 @@ export interface IVariableResolveContext { export class AbstractVariableResolverService implements IConfigurationResolverService { - static VARIABLE_REGEXP = /\$\{(.*?)\}/g; - static VARIABLE_REGEXP_SINGLE = /\$\{(.*?)\}/; + static readonly VARIABLE_REGEXP = /\$\{(.*?)\}/g; + static readonly VARIABLE_REGEXP_SINGLE = /\$\{(.*?)\}/; _serviceBrand: undefined; diff --git a/src/vs/workbench/services/credentials/browser/credentialsService.ts b/src/vs/workbench/services/credentials/browser/credentialsService.ts index 20946f64ae1..d50c058d3aa 100644 --- a/src/vs/workbench/services/credentials/browser/credentialsService.ts +++ b/src/vs/workbench/services/credentials/browser/credentialsService.ts @@ -6,6 +6,7 @@ import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { find } from 'vs/base/common/arrays'; export interface ICredentialsProvider { getPassword(service: string, account: string): Promise; @@ -14,7 +15,7 @@ export interface ICredentialsProvider { deletePassword(service: string, account: string): Promise; findPassword(service: string): Promise; - findCredentials(service: string): Promise>; + findCredentials(service: string): Promise>; } export class BrowserCredentialsService implements ICredentialsService { @@ -47,7 +48,7 @@ export class BrowserCredentialsService implements ICredentialsService { return this.credentialsProvider.findPassword(service); } - findCredentials(service: string): Promise> { + findCredentials(service: string): Promise> { return this.credentialsProvider.findCredentials(service); } } @@ -88,17 +89,12 @@ class InMemoryCredentialsProvider implements ICredentialsProvider { return credential ? credential.password : null; } - private doFindPassword(service: string, account?: string): ICredential | null { - for (const credential of this.credentials) { - if (credential.service === service && (typeof account !== 'string' || credential.account === account)) { - return credential; - } - } - - return null; + private doFindPassword(service: string, account?: string): ICredential | undefined { + return find(this.credentials, credential => + credential.service === service && (typeof account !== 'string' || credential.account === account)); } - async findCredentials(service: string): Promise> { + async findCredentials(service: string): Promise> { return this.credentials .filter(credential => credential.service === service) .map(({ account, password }) => ({ account, password })); diff --git a/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts b/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts index f8f7325be35..e83748f5e23 100644 --- a/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts @@ -35,6 +35,7 @@ import { ICommandHandler } from 'vs/platform/commands/common/commands'; import { ITextFileService, ISaveOptions } from 'vs/workbench/services/textfile/common/textfiles'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { toResource } from 'vs/workbench/common/editor'; +import { normalizeDriveLetter } from 'vs/base/common/labels'; export namespace OpenLocalFileCommand { export const ID = 'workbench.action.files.openLocalFile'; @@ -255,16 +256,6 @@ export class SimpleFileDialog { homedir = resources.dirname(this.options.defaultUri); this.trailing = resources.basename(this.options.defaultUri); } - // append extension - if (isSave && !ext && this.options.filters) { - for (let i = 0; i < this.options.filters.length; i++) { - if (this.options.filters[i].extensions[0] !== '*') { - ext = '.' + this.options.filters[i].extensions[0]; - this.trailing = this.trailing ? this.trailing + ext : ext; - break; - } - } - } } return new Promise(async (resolve) => { @@ -486,7 +477,7 @@ export class SimpleFileDialog { const newPath = this.pathFromUri(item.uri); if (startsWithIgnoreCase(newPath, this.filePickBox.value) && (equalsIgnoreCase(item.label, resources.basename(item.uri)))) { this.filePickBox.valueSelection = [this.pathFromUri(this.currentFolder).length, this.filePickBox.value.length]; - this.insertText(newPath, item.label); + this.insertText(newPath, this.basenameWithTrailingSlash(item.uri)); } else if ((item.label === '..') && startsWithIgnoreCase(this.filePickBox.value, newPath)) { this.filePickBox.valueSelection = [newPath.length, this.filePickBox.value.length]; this.insertText(newPath, ''); @@ -602,7 +593,7 @@ export class SimpleFileDialog { this.autoCompletePathSegment = ''; return false; } - const itemBasename = this.trimTrailingSlash(quickPickItem.label); + const itemBasename = quickPickItem.label; // 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. @@ -621,7 +612,7 @@ export class SimpleFileDialog { this.autoCompletePathSegment = ''; this.filePickBox.activeItems = [quickPickItem]; return true; - } else if (force && (!equalsIgnoreCase(quickPickItem.label, (this.userEnteredPathSegment + this.autoCompletePathSegment)))) { + } else if (force && (!equalsIgnoreCase(this.basenameWithTrailingSlash(quickPickItem.uri), (this.userEnteredPathSegment + this.autoCompletePathSegment)))) { this.userEnteredPathSegment = ''; this.autoCompletePathSegment = this.trimTrailingSlash(itemBasename); this.activeItem = quickPickItem; @@ -807,7 +798,7 @@ export class SimpleFileDialog { } private pathFromUri(uri: URI, endWithSeparator: boolean = false): string { - let result: string = uri.fsPath.replace(/\n/g, ''); + let result: string = normalizeDriveLetter(uri.fsPath).replace(/\n/g, ''); if (this.separator === '/') { result = result.replace(/\\/g, this.separator); } else { @@ -913,7 +904,7 @@ export class SimpleFileDialog { try { const stat = await this.fileService.resolve(fullPath); if (stat.isDirectory) { - filename = this.basenameWithTrailingSlash(fullPath); + filename = resources.basename(fullPath); fullPath = resources.addTrailingPathSeparator(fullPath, this.separator); return { label: filename, uri: fullPath, isFolder: true, iconClasses: getIconClasses(this.modelService, this.modeService, fullPath || undefined, FileKind.FOLDER) }; } else if (!stat.isDirectory && this.allowFileSelection && this.filterFile(fullPath)) { diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index c67415584ef..9833bbfb888 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -459,9 +459,10 @@ class ProposedApiController { // Make enabled proposed API be lowercase for case insensitive comparison this.enableProposedApiFor = (environmentService.args['enable-proposed-api'] || []).map(id => id.toLowerCase()); - this.enableProposedApiForAll = !environmentService.isBuilt || - (!!environmentService.extensionDevelopmentLocationURI && productService.nameLong !== 'Visual Studio Code') || - (this.enableProposedApiFor.length === 0 && 'enable-proposed-api' in environmentService.args); + this.enableProposedApiForAll = + !environmentService.isBuilt || // always allow proposed API when running out of sources + (!!environmentService.extensionDevelopmentLocationURI && productService.quality !== 'stable') || // do not allow proposed API against stable builds when developing an extension + (this.enableProposedApiFor.length === 0 && 'enable-proposed-api' in environmentService.args); // always allow proposed API if --enable-proposed-api is provided without extension ID this.productAllowProposedApi = new Set(); if (isNonEmptyArray(productService.extensionAllowedProposedApi)) { diff --git a/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts b/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts index 38c4b63eda7..ab3477a4fc7 100644 --- a/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts +++ b/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts @@ -118,12 +118,7 @@ export class ExtensionDescriptionRegistry { hasOnlyGoodArcs(id: string, good: Set): boolean { const dependencies = G.getArcs(id); - for (let i = 0; i < dependencies.length; i++) { - if (!good.has(dependencies[i])) { - return false; - } - } - return true; + return dependencies.every(dependency => good.has(dependency)); } getNodes(): string[] { diff --git a/src/vs/workbench/services/extensions/common/rpcProtocol.ts b/src/vs/workbench/services/extensions/common/rpcProtocol.ts index ab46c17ec1e..4f5f086a3f9 100644 --- a/src/vs/workbench/services/extensions/common/rpcProtocol.ts +++ b/src/vs/workbench/services/extensions/common/rpcProtocol.ts @@ -58,7 +58,7 @@ const noop = () => { }; export class RPCProtocol extends Disposable implements IRPCProtocol { - private static UNRESPONSIVE_TIME = 3 * 1000; // 3s + private static readonly UNRESPONSIVE_TIME = 3 * 1000; // 3s private readonly _onDidChangeResponsiveState: Emitter = this._register(new Emitter()); public readonly onDidChangeResponsiveState: Event = this._onDidChangeResponsiveState.event; @@ -588,12 +588,7 @@ class MessageBuffer { class MessageIO { private static _arrayContainsBuffer(arr: any[]): boolean { - for (let i = 0, len = arr.length; i < len; i++) { - if (arr[i] instanceof VSBuffer) { - return true; - } - } - return false; + return arr.some(value => value instanceof VSBuffer); } public static serializeRequest(req: number, rpcId: number, method: string, args: any[], usesCancellationToken: boolean, replacer: JSONStringifyReplacer | null): VSBuffer { diff --git a/src/vs/workbench/services/extensions/node/extensionPoints.ts b/src/vs/workbench/services/extensions/node/extensionPoints.ts index 4d08f7645a0..17fdf323c7c 100644 --- a/src/vs/workbench/services/extensions/node/extensionPoints.ts +++ b/src/vs/workbench/services/extensions/node/extensionPoints.ts @@ -393,15 +393,7 @@ class ExtensionManifestValidator extends ExtensionManifestHandler { } private static _isStringArray(arr: string[]): boolean { - if (!Array.isArray(arr)) { - return false; - } - for (let i = 0, len = arr.length; i < len; i++) { - if (typeof arr[i] !== 'string') { - return false; - } - } - return true; + return Array.isArray(arr) && arr.every(value => typeof value === 'string'); } } 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 0b7b04823bd..97a9fcc913b 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 @@ -19,7 +19,6 @@ import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; @@ -49,6 +48,7 @@ import { FileUserDataProvider } from 'vs/workbench/services/userData/common/file import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv'; import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/node/environmentService'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; class TestEnvironmentService extends WorkbenchEnvironmentService { @@ -81,11 +81,12 @@ suite('KeybindingsEditing', () => { instantiationService = new TestInstantiationService(); const environmentService = new TestEnvironmentService(URI.file(testDir)); + + const configService = new TestConfigurationService(); + configService.setUserConfiguration('files', { 'eol': '\n' }); + instantiationService.stub(IEnvironmentService, environmentService); - instantiationService.stub(IConfigurationService, ConfigurationService); - instantiationService.stub(IConfigurationService, 'getValue', { 'eol': '\n' }); - instantiationService.stub(IConfigurationService, 'onDidUpdateConfiguration', () => { }); - instantiationService.stub(IConfigurationService, 'onDidChangeConfiguration', () => { }); + instantiationService.stub(IConfigurationService, configService); instantiationService.stub(IWorkspaceContextService, new TestContextService()); const lifecycleService = new TestLifecycleService(); instantiationService.stub(ILifecycleService, lifecycleService); diff --git a/src/vs/workbench/services/output/common/outputChannelModel.ts b/src/vs/workbench/services/output/common/outputChannelModel.ts index f3a8ec8ad94..2eade61f069 100644 --- a/src/vs/workbench/services/output/common/outputChannelModel.ts +++ b/src/vs/workbench/services/output/common/outputChannelModel.ts @@ -365,7 +365,7 @@ export class BufferredOutputChannel extends Disposable implements IOutputChannel class BufferedContent { - private static MAX_OUTPUT_LENGTH = 10000 /* Max. number of output lines to show in output */ * 100 /* Guestimated chars per line */; + private static readonly MAX_OUTPUT_LENGTH = 10000 /* Max. number of output lines to show in output */ * 100 /* Guestimated chars per line */; private data: string[] = []; private dataIds: number[] = []; diff --git a/src/vs/workbench/services/panel/common/panelService.ts b/src/vs/workbench/services/panel/common/panelService.ts index d686236e30a..ef626afef88 100644 --- a/src/vs/workbench/services/panel/common/panelService.ts +++ b/src/vs/workbench/services/panel/common/panelService.ts @@ -22,18 +22,18 @@ export interface IPanelService { _serviceBrand: undefined; - readonly onDidPanelOpen: Event<{ panel: IPanel, focus: boolean }>; + readonly onDidPanelOpen: Event<{ readonly panel: IPanel, readonly focus: boolean }>; readonly onDidPanelClose: Event; /** * Opens a panel with the given identifier and pass keyboard focus to it if specified. */ - openPanel(id: string, focus?: boolean): IPanel | null; + openPanel(id: string, focus?: boolean): IPanel | undefined; /** * Returns the current active panel or null if none */ - getActivePanel(): IPanel | null; + getActivePanel(): IPanel | undefined; /** * Returns the panel by id. @@ -43,17 +43,17 @@ export interface IPanelService { /** * Returns all built-in panels following the default order */ - getPanels(): IPanelIdentifier[]; + getPanels(): readonly IPanelIdentifier[]; /** * Returns pinned panels following the visual order */ - getPinnedPanels(): IPanelIdentifier[]; + getPinnedPanels(): readonly IPanelIdentifier[]; /** * Returns the progress indicator for the panel bar. */ - getProgressIndicator(id: string): IProgressIndicator | null; + getProgressIndicator(id: string): IProgressIndicator | undefined; /** * Show an activity in a panel. diff --git a/src/vs/workbench/services/progress/browser/progressService.ts b/src/vs/workbench/services/progress/browser/progressService.ts index 524a952bd02..6da68dca7a6 100644 --- a/src/vs/workbench/services/progress/browser/progressService.ts +++ b/src/vs/workbench/services/progress/browser/progressService.ts @@ -308,7 +308,7 @@ export class ProgressService extends Disposable implements IProgressService { return this.withCompositeProgress(this.panelService.getProgressIndicator(panelid), task, options); } - private withCompositeProgress

, R = unknown>(progressIndicator: IProgressIndicator | null, task: (progress: IProgress) => P, options: IProgressCompositeOptions): P { + private withCompositeProgress

, R = unknown>(progressIndicator: IProgressIndicator | undefined, task: (progress: IProgress) => P, options: IProgressCompositeOptions): P { let progressRunner: IProgressRunner | undefined = undefined; const promise = task({ diff --git a/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts b/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts index c889524ee61..93008e7624b 100644 --- a/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts +++ b/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts @@ -21,6 +21,7 @@ import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics import { Emitter } from 'vs/base/common/event'; import { ISignService } from 'vs/platform/sign/common/sign'; import { ILogService } from 'vs/platform/log/common/log'; +import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; export abstract class AbstractRemoteAgentService extends Disposable { @@ -69,6 +70,26 @@ export abstract class AbstractRemoteAgentService extends Disposable { return Promise.resolve(undefined); } + + logTelemetry(eventName: string, data: ITelemetryData): Promise { + const connection = this.getConnection(); + if (connection) { + const client = new RemoteExtensionEnvironmentChannelClient(connection.getChannel('remoteextensionsenvironment')); + return client.logTelemetry(eventName, data); + } + + return Promise.resolve(undefined); + } + + flushTelemetry(): Promise { + const connection = this.getConnection(); + if (connection) { + const client = new RemoteExtensionEnvironmentChannelClient(connection.getChannel('remoteextensionsenvironment')); + return client.flushTelemetry(); + } + + return Promise.resolve(undefined); + } } export class RemoteAgentConnection extends Disposable implements IRemoteAgentConnection { diff --git a/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts b/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts index a1877e037aa..93a0c25a574 100644 --- a/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts +++ b/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts @@ -10,6 +10,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions' import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics'; import { RemoteAuthorities } from 'vs/base/common/network'; +import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; export interface IGetEnvironmentDataArguments { language: string; @@ -70,4 +71,12 @@ export class RemoteExtensionEnvironmentChannelClient { disableTelemetry(): Promise { return this.channel.call('disableTelemetry'); } + + logTelemetry(eventName: string, data: ITelemetryData): Promise { + return this.channel.call('logTelemetry', { eventName, data }); + } + + flushTelemetry(): Promise { + return this.channel.call('flushTelemetry'); + } } diff --git a/src/vs/workbench/services/remote/common/remoteAgentService.ts b/src/vs/workbench/services/remote/common/remoteAgentService.ts index 1cda189b53e..9200f1be530 100644 --- a/src/vs/workbench/services/remote/common/remoteAgentService.ts +++ b/src/vs/workbench/services/remote/common/remoteAgentService.ts @@ -9,6 +9,7 @@ import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc'; import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics'; import { Event } from 'vs/base/common/event'; import { PersistenConnectionEvent as PersistentConnectionEvent, ISocketFactory } from 'vs/platform/remote/common/remoteAgentConnection'; +import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; export const RemoteExtensionLogFileName = 'remoteagent'; @@ -23,6 +24,8 @@ export interface IRemoteAgentService { getEnvironment(bail?: boolean): Promise; getDiagnosticInfo(options: IDiagnosticInfoOptions): Promise; disableTelemetry(): Promise; + logTelemetry(eventName: string, data?: ITelemetryData): Promise; + flushTelemetry(): Promise; } export interface IRemoteAgentConnection { diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index a33b25a0e3a..aaea9e997d8 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -15,52 +15,24 @@ import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/pla import { IStorageService } from 'vs/platform/storage/common/storage'; import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/browser/workbenchCommonProperties'; import { IProductService } from 'vs/platform/product/common/productService'; -import { ApplicationInsights } from '@microsoft/applicationinsights-web'; +import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; export class WebTelemetryAppender implements ITelemetryAppender { - private _aiClient?: ApplicationInsights; - constructor(aiKey: string, private _logService: ILogService) { - const initConfig = { - config: { - instrumentationKey: aiKey, - endpointUrl: 'https://vortex.data.microsoft.com/collect/v1', - emitLineDelimitedJson: true, - autoTrackPageVisitTime: false, - disableExceptionTracking: true, - disableAjaxTracking: true - } - }; - - this._aiClient = new ApplicationInsights(initConfig); - this._aiClient.loadAppInsights(); - } + constructor(private _logService: ILogService, private _appender: ITelemetryAppender) { } log(eventName: string, data: any): void { - if (!this._aiClient) { - return; - } - data = validateTelemetryData(data); this._logService.trace(`telemetry/${eventName}`, data); - this._aiClient.trackEvent({ - name: 'monacoworkbench/' + eventName, + this._appender.log('/monacoworkbench/' + eventName, { properties: data.properties, measurements: data.measurements }); } flush(): Promise { - if (this._aiClient) { - return new Promise(resolve => { - this._aiClient!.flush(); - this._aiClient = undefined; - resolve(undefined); - }); - } - - return Promise.resolve(); + return this._appender.flush(); } } @@ -75,14 +47,15 @@ export class TelemetryService extends Disposable implements ITelemetryService { @ILogService logService: ILogService, @IConfigurationService configurationService: IConfigurationService, @IStorageService storageService: IStorageService, - @IProductService productService: IProductService + @IProductService productService: IProductService, + @IRemoteAgentService remoteAgentService: IRemoteAgentService ) { super(); - const aiKey = productService.aiConfig && productService.aiConfig.asimovKey; - if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.enableTelemetry && !!aiKey) { + if (!environmentService.args['disable-telemetry'] && !!productService.enableTelemetry) { + const telemetryProvider = environmentService.options && environmentService.options.telemetryAppender || { log: remoteAgentService.logTelemetry, flush: remoteAgentService.flushTelemetry }; const config: ITelemetryServiceConfig = { - appender: combinedAppender(new WebTelemetryAppender(aiKey, logService), new LogAppender(logService)), + appender: combinedAppender(new WebTelemetryAppender(logService, telemetryProvider), new LogAppender(logService)), commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.configuration.machineId, environmentService.configuration.remoteAuthority), piiPaths: [environmentService.appRoot] }; diff --git a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts index a3e41e7f41e..84fac20658e 100644 --- a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts @@ -38,7 +38,7 @@ export class TelemetryService extends Disposable implements ITelemetryService { const channel = sharedProcessService.getChannel('telemetryAppender'); const config: ITelemetryServiceConfig = { appender: combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(logService)), - commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.configuration.machineId, productService.msftInternalDomains, environmentService.installSourcePath, environmentService.configuration.remoteAuthority, environmentService.options && environmentService.options.resolveCommonTelemetryProperties), + commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.configuration.machineId, productService.msftInternalDomains, environmentService.installSourcePath, environmentService.configuration.remoteAuthority), piiPaths: environmentService.extensionsPath ? [environmentService.appRoot, environmentService.extensionsPath] : [environmentService.appRoot] }; diff --git a/src/vs/workbench/services/textfile/common/textResourcePropertiesService.ts b/src/vs/workbench/services/textfile/common/textResourcePropertiesService.ts index 95495464e6d..ce6bc5f6eba 100644 --- a/src/vs/workbench/services/textfile/common/textResourcePropertiesService.ts +++ b/src/vs/workbench/services/textfile/common/textResourcePropertiesService.ts @@ -30,9 +30,9 @@ export class TextResourcePropertiesService implements ITextResourcePropertiesSer } getEOL(resource?: URI, language?: string): string { - const filesConfiguration = this.configurationService.getValue<{ eol: string }>('files', { overrideIdentifier: language, resource }); - if (filesConfiguration && filesConfiguration.eol && filesConfiguration.eol !== 'auto') { - return filesConfiguration.eol; + const eol = this.configurationService.getValue('files.eol', { overrideIdentifier: language, resource }); + if (eol && eol !== 'auto') { + return eol; } const os = this.getOS(resource); return os === OperatingSystem.Linux || os === OperatingSystem.Macintosh ? '\n' : '\r\n'; diff --git a/src/vs/workbench/services/textfile/test/textFileEditorModelManager.test.ts b/src/vs/workbench/services/textfile/test/textFileEditorModelManager.test.ts index 1b5f490f490..857096d4b0d 100644 --- a/src/vs/workbench/services/textfile/test/textFileEditorModelManager.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileEditorModelManager.test.ts @@ -311,4 +311,4 @@ suite('Files - TextFileEditorModelManager', () => { manager.disposeModel((model as TextFileEditorModel)); manager.dispose(); }); -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/services/themes/browser/fileIconThemeStore.ts b/src/vs/workbench/services/themes/browser/fileIconThemeStore.ts index e4eb557f54c..0afad15ee6c 100644 --- a/src/vs/workbench/services/themes/browser/fileIconThemeStore.ts +++ b/src/vs/workbench/services/themes/browser/fileIconThemeStore.ts @@ -14,6 +14,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { FileIconThemeData } from 'vs/workbench/services/themes/browser/fileIconThemeData'; import { URI } from 'vs/base/common/uri'; import { Disposable } from 'vs/base/common/lifecycle'; +import { find } from 'vs/base/common/arrays'; const iconThemeExtPoint = ExtensionsRegistry.registerExtensionPoint({ extensionPoint: 'iconThemes', @@ -62,7 +63,7 @@ export class FileIconThemeStore extends Disposable { private initialize() { iconThemeExtPoint.setHandler((extensions) => { - const previousIds: { [key: string]: boolean } = {}; + const previousIds: { [key: string]: boolean; } = {}; const added: FileIconThemeData[] = []; for (const theme of this.knownIconThemes) { previousIds[theme.id] = true; @@ -131,12 +132,7 @@ export class FileIconThemeStore extends Disposable { return Promise.resolve(FileIconThemeData.noIconTheme()); } return this.getFileIconThemes().then(allIconSets => { - for (let iconSet of allIconSets) { - if (iconSet.id === iconTheme) { - return iconSet; - } - } - return undefined; + return find(allIconSets, iconSet => iconSet.id === iconTheme); }); } @@ -145,12 +141,7 @@ export class FileIconThemeStore extends Disposable { return Promise.resolve(FileIconThemeData.noIconTheme()); } return this.getFileIconThemes().then(allIconSets => { - for (let iconSet of allIconSets) { - if (iconSet.settingsId === settingsId) { - return iconSet; - } - } - return undefined; + return find(allIconSets, iconSet => iconSet.settingsId === settingsId); }); } diff --git a/src/vs/workbench/services/viewlet/browser/viewlet.ts b/src/vs/workbench/services/viewlet/browser/viewlet.ts index ffc1a81d63a..deebb5b8584 100644 --- a/src/vs/workbench/services/viewlet/browser/viewlet.ts +++ b/src/vs/workbench/services/viewlet/browser/viewlet.ts @@ -23,12 +23,12 @@ export interface IViewletService { /** * Opens a viewlet with the given identifier and pass keyboard focus to it if specified. */ - openViewlet(id: string | undefined, focus?: boolean): Promise; + openViewlet(id: string | undefined, focus?: boolean): Promise; /** - * Returns the current active viewlet or null if none. + * Returns the current active viewlet if any. */ - getActiveViewlet(): IViewlet | null; + getActiveViewlet(): IViewlet | undefined; /** * Returns the id of the default viewlet. @@ -48,7 +48,7 @@ export interface IViewletService { /** * Returns the progress indicator for the side bar. */ - getProgressIndicator(id: string): IProgressIndicator | null; + getProgressIndicator(id: string): IProgressIndicator | undefined; /** * Hide the active viewlet. diff --git a/src/vs/workbench/services/workspaces/electron-browser/workspaceEditingService.ts b/src/vs/workbench/services/workspaces/electron-browser/workspaceEditingService.ts index 5c983b207b1..bc5c69825bd 100644 --- a/src/vs/workbench/services/workspaces/electron-browser/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspaces/electron-browser/workspaceEditingService.ts @@ -142,6 +142,8 @@ export class NativeWorkspaceEditingService extends AbstractWorkspaceEditingServi return false; } } + + return false; } async isValidTargetWorkspacePath(path: URI): Promise { 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 c01ed376683..9664bc68bd0 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -878,12 +878,12 @@ suite('ExtHostLanguageFeatureCommands', function () { let incoming = await commands.executeCommand('vscode.executeCallHierarchyProviderIncomingCalls', model.uri, new types.Position(0, 10)); assert.equal(incoming.length, 1); - assert.ok(incoming[0].source instanceof types.CallHierarchyItem); - assert.equal(incoming[0].source.name, 'IN'); + assert.ok(incoming[0].from instanceof types.CallHierarchyItem); + assert.equal(incoming[0].from.name, 'IN'); let outgoing = await commands.executeCommand('vscode.executeCallHierarchyProviderOutgoingCalls', model.uri, new types.Position(0, 10)); assert.equal(outgoing.length, 1); - assert.ok(outgoing[0].target instanceof types.CallHierarchyItem); - assert.equal(outgoing[0].target.name, 'OUT'); + assert.ok(outgoing[0].to instanceof types.CallHierarchyItem); + assert.equal(outgoing[0].to.name, 'OUT'); }); }); diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts index aa5453e5f6c..483d634e6ea 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts @@ -79,7 +79,7 @@ suite('MainThreadDocumentsAndEditors', () => { onDidPanelOpen = Event.None; onDidPanelClose = Event.None; getActivePanel() { - return null; + return undefined; } }, TestEnvironmentService diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts index bd1397d06fb..35fde4c61de 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts @@ -111,7 +111,7 @@ suite('MainThreadEditors', () => { onDidPanelOpen = Event.None; onDidPanelClose = Event.None; getActivePanel() { - return null; + return undefined; } }, TestEnvironmentService diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 19f35faaeaf..803ae1b59af 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -91,6 +91,7 @@ import { INativeOpenDialogOptions, MessageBoxReturnValue, SaveDialogReturnValue, import { IBackupMainService, IWorkspaceBackupInfo } from 'vs/platform/backup/electron-main/backup'; import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup'; import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; +import { find } from 'vs/base/common/arrays'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined); @@ -582,8 +583,8 @@ export class TestViewletService implements IViewletService { onDidViewletOpen = this.onDidViewletOpenEmitter.event; onDidViewletClose = this.onDidViewletCloseEmitter.event; - public openViewlet(id: string, focus?: boolean): Promise { - return Promise.resolve(null!); + public openViewlet(id: string, focus?: boolean): Promise { + return Promise.resolve(undefined); } public getViewlets(): ViewletDescriptor[] { @@ -610,7 +611,7 @@ export class TestViewletService implements IViewletService { } public getProgressIndicator(id: string) { - return null!; + return undefined; } public hideActiveViewlet(): void { } @@ -626,19 +627,19 @@ export class TestPanelService implements IPanelService { onDidPanelOpen = new Emitter<{ panel: IPanel, focus: boolean }>().event; onDidPanelClose = new Emitter().event; - public openPanel(id: string, focus?: boolean): IPanel { - return null!; + public openPanel(id: string, focus?: boolean): undefined { + return undefined; } public getPanel(id: string): any { return activeViewlet; } - public getPanels(): any[] { + public getPanels() { return []; } - public getPinnedPanels(): any[] { + public getPinnedPanels() { return []; } @@ -700,14 +701,8 @@ export class TestEditorGroupsService implements IEditorGroupsService { return this.groups; } - getGroup(identifier: number): IEditorGroup { - for (const group of this.groups) { - if (group.id === identifier) { - return group; - } - } - - return undefined!; + getGroup(identifier: number): IEditorGroup | undefined { + return find(this.groups, group => group.id === identifier); } getLabel(_identifier: number): string { @@ -1246,12 +1241,10 @@ export class TestTextResourcePropertiesService implements ITextResourcePropertie ) { } - getEOL(resource: URI): string { - const filesConfiguration = this.configurationService.getValue<{ eol: string }>('files'); - if (filesConfiguration && filesConfiguration.eol) { - if (filesConfiguration.eol !== 'auto') { - return filesConfiguration.eol; - } + getEOL(resource: URI, language?: string): string { + const eol = this.configurationService.getValue('files.eol', { overrideIdentifier: language, resource }); + if (eol && eol !== 'auto') { + return eol; } return (isLinux || isMacintosh) ? '\n' : '\r\n'; } diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index 4833155c493..3c30b2fd899 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -15,6 +15,7 @@ import { LogLevel } from 'vs/platform/log/common/log'; import { IUpdateProvider, IUpdate } from 'vs/workbench/services/update/browser/updateService'; import { Event, Emitter } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { ITelemetryAppender } from 'vs/platform/telemetry/common/telemetryUtils'; import { IWorkspaceProvider, IWorkspace } from 'vs/workbench/services/host/browser/browserHostService'; interface IWorkbenchConstructionOptions { @@ -82,11 +83,18 @@ interface IWorkbenchConstructionOptions { */ logLevel?: LogLevel; + /** * Experimental: Support for update reporting. */ updateProvider?: IUpdateProvider; + /** + * Experimental: If provided, will be called when logging telemetry events. + */ + telemetryAppender?: ITelemetryAppender; + + /** * Experimental: Support adding additional properties to telemetry. */ @@ -150,5 +158,8 @@ export { // Updates IUpdateProvider, - IUpdate + IUpdate, + + // Telemetry + ITelemetryAppender }; diff --git a/tslint.json b/tslint.json index 31adda1904b..a0feadaf2c0 100644 --- a/tslint.json +++ b/tslint.json @@ -472,8 +472,7 @@ "**/vs/workbench/api/{common,browser}/**", "**/vs/workbench/services/**/{common,browser}/**", "vscode-textmate", - "onigasm-umd", - "@microsoft/applicationinsights-web" + "onigasm-umd" ] }, { diff --git a/yarn.lock b/yarn.lock index 4304721fc4d..8b48f5f6231 100644 --- a/yarn.lock +++ b/yarn.lock @@ -95,69 +95,6 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" -"@microsoft/applicationinsights-analytics-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" - integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-channel-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" - integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-common@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" - integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== - dependencies: - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-core-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" - integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== - dependencies: - tslib "^1.9.3" - -"@microsoft/applicationinsights-dependencies-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" - integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-properties-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" - integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-web@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" - integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== - dependencies: - "@microsoft/applicationinsights-analytics-js" "2.1.1" - "@microsoft/applicationinsights-channel-js" "2.1.1" - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - "@microsoft/applicationinsights-dependencies-js" "2.1.1" - "@microsoft/applicationinsights-properties-js" "2.1.1" - "@types/commander@^2.11.0": version "2.12.2" resolved "https://registry.yarnpkg.com/@types/commander/-/commander-2.12.2.tgz#183041a23842d4281478fa5d23c5ca78e6fd08ae" @@ -1502,6 +1439,11 @@ chromium-pickle-js@^0.2.0: resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" integrity sha1-BKEGZywYsIWrd02YPfo+oTjyIgU= +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -3020,6 +2962,11 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" +find-parent-dir@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -3568,7 +3515,12 @@ glogg@^1.0.0: dependencies: sparkles "^1.0.0" -graceful-fs@4.1.11, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +graceful-fs@4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" + integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== + +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= @@ -4097,6 +4049,16 @@ https-proxy-agent@2.2.1, https-proxy-agent@^2.2.1: agent-base "^4.1.0" debug "^3.1.0" +husky@^0.13.1: + version "0.13.4" + resolved "https://registry.yarnpkg.com/husky/-/husky-0.13.4.tgz#48785c5028de3452a51c48c12c4f94b2124a1407" + integrity sha1-SHhcUCjeNFKlHEjBLE+UshJKFAc= + dependencies: + chalk "^1.1.3" + find-parent-dir "^0.3.0" + is-ci "^1.0.9" + normalize-path "^1.0.0" + iconv-lite@0.4.19, iconv-lite@^0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" @@ -4339,6 +4301,13 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" +is-ci@^1.0.9: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.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" @@ -5802,6 +5771,11 @@ normalize-package-data@^2.3.2: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" +normalize-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" + integrity sha1-MtDkcvkf80VwHBWoMRAY07CpA3k= + normalize-path@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" @@ -8452,11 +8426,6 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== -tslib@^1.9.3: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - tslint@^5.16.0: version "5.16.0" resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.16.0.tgz#ae61f9c5a98d295b9a4f4553b1b1e831c1984d67" @@ -9302,20 +9271,20 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" -xterm-addon-search@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0.tgz#46659c7c33f9fc268ad3e7e6c5824bb2fdb65852" - integrity sha512-C/v2VvFn3hb1qUgjJPo7LxzxNCLBgNJv8n6v/bH2NqPz32/PNUF+IHu0SFf1TaIH+pydUpKXCtob5a/UyZg/+Q== +xterm-addon-search@0.3.0-beta5: + version "0.3.0-beta5" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.3.0-beta5.tgz#fd53d33a77a0235018479c712be8c12f7c0d083a" + integrity sha512-3GkGc4hST35/4hzgnQPLLvQ29WH7MkZ0mUrBE/Vm1IQum7TnMvWPTkGemwM+wAl4tdBmynNccHJlFeQzaQtVUg== xterm-addon-web-links@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.2.0.tgz#b408a0be46211d8d4a0bb5e701d8f3c2bd07d473" integrity sha512-dq81c4Pzli2PgKVBgY2REte9sCVibR3df8AP3SEvCTM9uYFnUFxtxzMTplPnc7+rXabVhFdbU6x+rstIk8HNQg== -xterm@4.1.0-beta8: - version "4.1.0-beta8" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.1.0-beta8.tgz#c1ef323ba336d92f5b52302b66f672dfff75b3ef" - integrity sha512-6lf+XVv0qT285w49P92tSYoUB406jdbgdhnPKNzxCIGtGX8kcwK+pHZ8HncDwcEhmTmI4LZ/WXPGtOQJg+onwg== +xterm@4.2.0-beta4: + version "4.2.0-beta4" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.2.0-beta4.tgz#596577f94a1da372119d192363ea2b19d1f8b50c" + integrity sha512-BmkpxCpqdOJoNdIcddkRT8S65sGjgBbWI0uIJNSnzZvj81OKcraMSTmF/ODw0TF/MDLc33Fx9cpDx/D6lQgl8Q== y18n@^3.2.1: version "3.2.1"