From 5f79b5118143fbd9cbc00356f164d20d3e6eabea Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 4 Jul 2022 23:11:20 +0900 Subject: [PATCH 001/303] chore: bump electron@19.0.7 --- .yarnrc | 2 +- build/.cachesalt | 2 +- cgmanifest.json | 12 ++++++------ package.json | 2 +- remote/.yarnrc | 2 +- yarn.lock | 28 ++++++---------------------- 6 files changed, 16 insertions(+), 32 deletions(-) diff --git a/.yarnrc b/.yarnrc index 507a7bbdfff..ba7b67dc306 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,4 +1,4 @@ disturl "https://electronjs.org/headers" -target "18.3.5" +target "19.0.7" runtime "electron" build_from_source "true" diff --git a/build/.cachesalt b/build/.cachesalt index 11b63081f5a..e43bb7a858b 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2022-06-10T10:20:54.664Z +2022-07-04T14:08:01.150Z diff --git a/cgmanifest.json b/cgmanifest.json index 932f6d682aa..0073b3dc2e9 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "chromium", "repositoryUrl": "https://chromium.googlesource.com/chromium/src", - "commitHash": "59f4a82f7cf9fd0397aa7bf0273bf5b62433c5da" + "commitHash": "b5d9f1c49c2e0336d8efe62e6054170d5118ee5c" } }, "licenseDetail": [ @@ -40,7 +40,7 @@ "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ], "isOnlyProductionDependency": true, - "version": "100.0.4896.160" + "version": "102.0.5005.134" }, { "component": { @@ -48,11 +48,11 @@ "git": { "name": "nodejs", "repositoryUrl": "https://github.com/nodejs/node", - "commitHash": "acb71eab779fb56bf70e8a9e0cb2e82a089a87de" + "commitHash": "442e84a358d75152556b5d087e4dd6a51615330d" } }, "isOnlyProductionDependency": true, - "version": "16.13.2" + "version": "16.14.2" }, { "component": { @@ -60,12 +60,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "6165f6afc9af6f9ab4e32f4a7a8b0818f11e766a" + "commitHash": "2f4e7679f826c9c6d8ba08aa860f283e5d52e5ad" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "18.3.5" + "version": "19.0.7" }, { "component": { diff --git a/package.json b/package.json index 1cdc1dc30d1..ce27b6132ed 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,7 @@ "cssnano": "^4.1.11", "debounce": "^1.0.0", "deemon": "^1.4.0", - "electron": "18.3.5", + "electron": "19.0.7", "eslint": "8.7.0", "eslint-plugin-header": "3.1.1", "eslint-plugin-jsdoc": "^39.3.2", diff --git a/remote/.yarnrc b/remote/.yarnrc index 290849a6e63..3a3fbdc3350 100644 --- a/remote/.yarnrc +++ b/remote/.yarnrc @@ -1,4 +1,4 @@ disturl "http://nodejs.org/dist" -target "16.13.2" +target "16.14.2" runtime "node" build_from_source "true" diff --git a/yarn.lock b/yarn.lock index 9c823e24f88..b0e565c38b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -716,7 +716,7 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz#90420f9f9c6d3987f176a19a7d8e764271a2f55d" integrity sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g== -"@electron/get@^1.12.4": +"@electron/get@^1.12.4", "@electron/get@^1.14.1": version "1.14.1" resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.14.1.tgz#16ba75f02dffb74c23965e72d617adc721d27f40" integrity sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw== @@ -732,22 +732,6 @@ global-agent "^3.0.0" global-tunnel-ng "^2.7.1" -"@electron/get@^1.13.0": - version "1.13.1" - resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.13.1.tgz#42a0aa62fd1189638bd966e23effaebb16108368" - integrity sha512-U5vkXDZ9DwXtkPqlB45tfYnnYBN8PePp1z/XDCupnSpdrxT8/ThCv9WCwPLf9oqiSGZTkH6dx2jDUPuoXpjkcA== - dependencies: - debug "^4.1.1" - env-paths "^2.2.0" - fs-extra "^8.1.0" - got "^9.6.0" - progress "^2.0.3" - semver "^6.2.0" - sumchecker "^3.0.1" - optionalDependencies: - global-agent "^3.0.0" - global-tunnel-ng "^2.7.1" - "@es-joy/jsdoccomment@~0.31.0": version "0.31.0" resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz#dbc342cc38eb6878c12727985e693eaef34302bc" @@ -4193,12 +4177,12 @@ electron-to-chromium@^1.4.17: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.45.tgz#cf1144091d6683cbd45a231954a745f02fb24598" integrity sha512-czF9eYVuOmlY/vxyMQz2rGlNSjZpxNQYBe1gmQv7al171qOIhgyO9k7D5AKlgeTCSPKk+LHhj5ZyIdmEub9oNg== -electron@18.3.5: - version "18.3.5" - resolved "https://registry.yarnpkg.com/electron/-/electron-18.3.5.tgz#a589c2bfa3fe807914a055f54f665999329b739b" - integrity sha512-/GJ39X3ijpyZiOtYQ1ha5Ly0hWiIzF19CGEapM9euaM2AZrmt79x+MckQDXqJxOaVA9YHXju5Ho6b9pB9a/2pQ== +electron@19.0.7: + version "19.0.7" + resolved "https://registry.yarnpkg.com/electron/-/electron-19.0.7.tgz#c7a7841646adc6457de70b93661cc400bfdf9d38" + integrity sha512-Wyg+oGkY8cWYmm8tVka6CZmhJxnyUx+Us2ALyWiY4w73+dO9XUNB/c7vQNIm1Uk/DLMn9vFzgvcS9YtOOMqpbg== dependencies: - "@electron/get" "^1.13.0" + "@electron/get" "^1.14.1" "@types/node" "^16.11.26" extract-zip "^1.0.3" From a347bd1a11fa6b35074b2e936ed5106050c04dab Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 5 Jul 2022 00:00:28 +0900 Subject: [PATCH 002/303] chore: update github workflow cache --- .github/workflows/basic.yml | 12 ++++++------ .github/workflows/ci.yml | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml index 97daf8fd946..341a6d2c420 100644 --- a/.github/workflows/basic.yml +++ b/.github/workflows/basic.yml @@ -39,8 +39,8 @@ jobs: uses: actions/cache@v3 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules22-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules22- + key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} + restore-keys: ${{ runner.os }}-cacheNodeModules23- - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} @@ -92,8 +92,8 @@ jobs: uses: actions/cache@v3 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules22-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules22- + key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} + restore-keys: ${{ runner.os }}-cacheNodeModules23- - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} @@ -155,8 +155,8 @@ jobs: uses: actions/cache@v3 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules22-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules22- + key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} + restore-keys: ${{ runner.os }}-cacheNodeModules23- - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 088723285cf..4f2d290664b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -125,8 +125,8 @@ jobs: uses: actions/cache@v2 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules22-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules22- + key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} + restore-keys: ${{ runner.os }}-cacheNodeModules23- - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} @@ -197,8 +197,8 @@ jobs: uses: actions/cache@v2 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules22-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules22- + key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} + restore-keys: ${{ runner.os }}-cacheNodeModules23- - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} @@ -271,8 +271,8 @@ jobs: uses: actions/cache@v2 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules22-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules22- + key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} + restore-keys: ${{ runner.os }}-cacheNodeModules23- - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} From fd615ed9f3f0f47f4c7f43d5aee7ba651c491d07 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 5 Jul 2022 15:50:26 +0900 Subject: [PATCH 003/303] chore: update cachesalt --- build/.cachesalt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/.cachesalt b/build/.cachesalt index e43bb7a858b..07f2c6df012 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2022-07-04T14:08:01.150Z +2022-07-05T06:49:56.867Z From 8765ea4f9c4e3313dd2b0ed8b2622779861757e9 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 11 Jul 2022 17:09:45 +0900 Subject: [PATCH 004/303] chore: update cache --- build/.cachesalt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/.cachesalt b/build/.cachesalt index e1dfa0cafdb..4562fc5fe80 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2022-07-08T16:20:45.398Z +2022-07-11T08:08:31.388Z From 599241ad746b60436371c442f6e5e0341a3e5d5c Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 19 Jul 2022 17:57:54 +0900 Subject: [PATCH 005/303] chore: update electron@19.0.8 --- .yarnrc | 2 +- cgmanifest.json | 8 ++++---- package.json | 2 +- yarn.lock | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.yarnrc b/.yarnrc index ba7b67dc306..dc429531e37 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,4 +1,4 @@ disturl "https://electronjs.org/headers" -target "19.0.7" +target "19.0.8" runtime "electron" build_from_source "true" diff --git a/cgmanifest.json b/cgmanifest.json index 0073b3dc2e9..e552709b2fb 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "chromium", "repositoryUrl": "https://chromium.googlesource.com/chromium/src", - "commitHash": "b5d9f1c49c2e0336d8efe62e6054170d5118ee5c" + "commitHash": "c53c15c92c076f8d7593518ba99a9f8a6fc5ead6" } }, "licenseDetail": [ @@ -40,7 +40,7 @@ "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ], "isOnlyProductionDependency": true, - "version": "102.0.5005.134" + "version": "102.0.5005.148" }, { "component": { @@ -60,12 +60,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "2f4e7679f826c9c6d8ba08aa860f283e5d52e5ad" + "commitHash": "c67ca40ed6054aadcdfb901aa1abaee2ccc690f3" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "19.0.7" + "version": "19.0.8" }, { "component": { diff --git a/package.json b/package.json index 9f3d30b588a..5a345056c0e 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,7 @@ "cssnano": "^4.1.11", "debounce": "^1.0.0", "deemon": "^1.4.0", - "electron": "19.0.7", + "electron": "19.0.8", "eslint": "8.7.0", "eslint-plugin-header": "3.1.1", "eslint-plugin-jsdoc": "^39.3.2", diff --git a/yarn.lock b/yarn.lock index a1186c6710a..b49d8d2188d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4177,10 +4177,10 @@ electron-to-chromium@^1.4.17: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.45.tgz#cf1144091d6683cbd45a231954a745f02fb24598" integrity sha512-czF9eYVuOmlY/vxyMQz2rGlNSjZpxNQYBe1gmQv7al171qOIhgyO9k7D5AKlgeTCSPKk+LHhj5ZyIdmEub9oNg== -electron@19.0.7: - version "19.0.7" - resolved "https://registry.yarnpkg.com/electron/-/electron-19.0.7.tgz#c7a7841646adc6457de70b93661cc400bfdf9d38" - integrity sha512-Wyg+oGkY8cWYmm8tVka6CZmhJxnyUx+Us2ALyWiY4w73+dO9XUNB/c7vQNIm1Uk/DLMn9vFzgvcS9YtOOMqpbg== +electron@19.0.8: + version "19.0.8" + resolved "https://registry.yarnpkg.com/electron/-/electron-19.0.8.tgz#c4d4ba915de554f2926261eb37d3527d2b092d4c" + integrity sha512-OWK3P/NbDFfBUv+wbYv1/OV4jehY5DQPT7n1maQJfN9hsnrWTMktXS/bmS05eSUAjNAzHmKPKfiKH2c1Yr7nGw== dependencies: "@electron/get" "^1.14.1" "@types/node" "^16.11.26" From 3e5be58df983fb4b61f3d5c9062d97006be387b2 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sat, 23 Jul 2022 22:29:33 +0430 Subject: [PATCH 006/303] =?UTF-8?q?=F0=9F=8E=81=20Add=20`fish`=20shell=20h?= =?UTF-8?q?istory=20fetch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Babak K. Shandiz --- .../contrib/terminal/common/history.ts | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/vs/workbench/contrib/terminal/common/history.ts b/src/vs/workbench/contrib/terminal/common/history.ts index fb25868af81..e94aa44cd8b 100644 --- a/src/vs/workbench/contrib/terminal/common/history.ts +++ b/src/vs/workbench/contrib/terminal/common/history.ts @@ -362,6 +362,86 @@ export async function fetchPwshHistory(accessor: ServicesAccessor) { return result.values(); } +export async function fetchFishHistory(accessor: ServicesAccessor) { + const fileService = accessor.get(IFileService); + const remoteAgentService = accessor.get(IRemoteAgentService); + const remoteEnvironment = await remoteAgentService.getEnvironment(); + if (remoteEnvironment?.os === OperatingSystem.Windows || !remoteEnvironment && isWindows) { + return undefined; + } + + /** + * From `fish` docs: + * > The command history is stored in the file ~/.local/share/fish/fish_history + * (or $XDG_DATA_HOME/fish/fish_history if that variable is set) by default. + * + * (https://fishshell.com/docs/current/interactive.html#history-search) + */ + const overridenDataHome = env['XDG_DATA_HOME']; + + // TODO: Unchecked fish behavior: + // What if XDG_DATA_HOME was defined but somehow $XDG_DATA_HOME/fish/fish_history + // was not exist. Does fish fall back to ~/.local/share/fish/fish_history? + + const content = await (overridenDataHome + ? fetchFileContents(env['XDG_DATA_HOME'], 'fish/fish_history', false, fileService, remoteAgentService) + : fetchFileContents(env['HOME'], '.local/share/fish/fish_history', false, fileService, remoteAgentService)); + if (content === undefined) { + return undefined; + } + + /** + * These apply to `fish` v3.5.1: + * - It looks like YAML but it's not. It's, quoting, *"a broken psuedo-YAML"*. + * See these discussions for more details: + * - https://github.com/fish-shell/fish-shell/pull/6493 + * - https://github.com/fish-shell/fish-shell/issues/3341 + * - Every record should exactly start with `- cmd:` (the whitespace between `-` and `cmd` cannot be replaced with tab) + * - Both `- cmd: echo 1` and `- cmd:echo 1` are valid entries. + * - Backslashes are esacped as `\\`. + * - Multiline commands are joined with a `\n` sequence, hence they're read as single line commands. + * - Property `when` is optional. + * - History navigation respects the records order and ignore the actual `when` property values (chronological order). + * - If `cmd` value is multiline , it just takes the first line. Also YAML operators like `>-` or `|-` are not supported. + */ + const result: Set = new Set(); + const cmds = content.split('\n') + .filter(x => x.startsWith('- cmd:')) + .map(x => x.substring(6).trimStart()); + for (let i = 0; i < cmds.length; i++) { + /** + * NOTE + * This repeatedReplace() call can be eliminated by using look-ahead + * caluses in the original RegExp pattern: + * + * >>> ```ts + * >>> cmds[i].replace(/(?<=^|[^\\])((?:\\\\)*)(\\n)/g, '$1\n') + * >>> ``` + * + * But since not all browsers support look aheads we opted to a simple + * pattern and repeatedly calling replace method. + */ + const sanitized = repeatedReplace(/(^|[^\\])((?:\\\\)*)(\\n)/g, cmds[i], '$1$2\n') + .replace(/\\/g, '\\').trim(); + if (sanitized.length > 0) { + result.add(sanitized); + } + } + return result.values(); +} + +function repeatedReplace(pattern: RegExp, value: string, replaceValue: string): string { + let last; + let current = value; + while (true) { + last = current; + current = current.replace(pattern, replaceValue); + if (current === last) { + return current; + } + } +} + async function fetchFileContents( folderPrefix: string | undefined, filePath: string, From 07dfd5499814995f572eb5d98bf2d7ae6f23fd9e Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sat, 23 Jul 2022 22:30:38 +0430 Subject: [PATCH 007/303] =?UTF-8?q?=E2=9A=97=EF=B8=8F=20Add=20test=20to=20?= =?UTF-8?q?verify=20`fetchFishHistory`=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Babak K. Shandiz --- .../terminal/test/common/history.test.ts | 141 +++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/test/common/history.test.ts b/src/vs/workbench/contrib/terminal/test/common/history.test.ts index 325e352d713..860f5f075f9 100644 --- a/src/vs/workbench/contrib/terminal/test/common/history.test.ts +++ b/src/vs/workbench/contrib/terminal/test/common/history.test.ts @@ -16,7 +16,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; import { IStorageService } from 'vs/platform/storage/common/storage'; -import { fetchBashHistory, fetchPwshHistory, fetchZshHistory, ITerminalPersistedHistory, TerminalPersistedHistory } from 'vs/workbench/contrib/terminal/common/history'; +import { fetchBashHistory, fetchFishHistory, fetchPwshHistory, fetchZshHistory, ITerminalPersistedHistory, TerminalPersistedHistory } from 'vs/workbench/contrib/terminal/common/history'; import { IRemoteAgentConnection, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; @@ -399,4 +399,143 @@ suite('Terminal history', () => { }); }); }); + suite('fetchFishHistory', () => { + let fileScheme: string; + let filePath: string; + const fileContent: string = [ + '- cmd: single line command', + ' when: 1650000000', + '- cmd: git commit -m "A wrapped line in pwsh history\\n\\nSome commit description\\n\\nFixes #xyz"', + ' when: 1650000010', + '- cmd: git status', + ' when: 1650000020', + '- cmd: two "\\nline"', + ' when: 1650000030', + ].join('\n'); + + let instantiationService: TestInstantiationService; + let remoteConnection: Pick | null = null; + let remoteEnvironment: Pick | null = null; + + setup(() => { + instantiationService = new TestInstantiationService(); + instantiationService.stub(IFileService, { + async readFile(resource: URI) { + const expected = URI.from({ scheme: fileScheme, path: filePath }); + strictEqual(resource.scheme, expected.scheme); + strictEqual(resource.path, expected.path); + return { value: VSBuffer.fromString(fileContent) }; + } + } as Pick); + instantiationService.stub(IRemoteAgentService, { + async getEnvironment() { return remoteEnvironment; }, + getConnection() { return remoteConnection; } + } as Pick); + }); + + if (!isWindows) { + suite('local', () => { + let originalEnvValues: { HOME: string | undefined }; + setup(() => { + originalEnvValues = { HOME: env['HOME'] }; + env['HOME'] = '/home/user'; + remoteConnection = { remoteAuthority: 'some-remote' }; + fileScheme = Schemas.vscodeRemote; + filePath = '/home/user/.local/share/fish/fish_history'; + }); + teardown(() => { + if (originalEnvValues['HOME'] === undefined) { + delete env['HOME']; + } else { + env['HOME'] = originalEnvValues['HOME']; + } + }); + test('current OS', async () => { + filePath = '/home/user/.local/share/fish/fish_history'; + deepStrictEqual(Array.from((await instantiationService.invokeFunction(fetchFishHistory))!), expectedCommands); + }); + }); + + suite('local (overriden path)', () => { + let originalEnvValues: { XDG_DATA_HOME: string | undefined }; + setup(() => { + originalEnvValues = { XDG_DATA_HOME: env['XDG_DATA_HOME'] }; + env['XDG_DATA_HOME'] = '/home/user/data-home'; + remoteConnection = { remoteAuthority: 'some-remote' }; + fileScheme = Schemas.vscodeRemote; + filePath = '/home/user/data-home/fish/fish_history'; + }); + teardown(() => { + if (originalEnvValues['XDG_DATA_HOME'] === undefined) { + delete env['XDG_DATA_HOME']; + } else { + env['XDG_DATA_HOME'] = originalEnvValues['XDG_DATA_HOME']; + } + }); + test('current OS', async () => { + filePath = '/home/user/data-home/fish/fish_history'; + deepStrictEqual(Array.from((await instantiationService.invokeFunction(fetchFishHistory))!), expectedCommands); + }); + }); + } + suite('remote', () => { + let originalEnvValues: { HOME: string | undefined }; + setup(() => { + originalEnvValues = { HOME: env['HOME'] }; + env['HOME'] = '/home/user'; + remoteConnection = { remoteAuthority: 'some-remote' }; + fileScheme = Schemas.vscodeRemote; + filePath = '/home/user/.local/share/fish/fish_history'; + }); + teardown(() => { + if (originalEnvValues['HOME'] === undefined) { + delete env['HOME']; + } else { + env['HOME'] = originalEnvValues['HOME']; + } + }); + test('Windows', async () => { + remoteEnvironment = { os: OperatingSystem.Windows }; + strictEqual(await instantiationService.invokeFunction(fetchFishHistory), undefined); + }); + test('macOS', async () => { + remoteEnvironment = { os: OperatingSystem.Macintosh }; + deepStrictEqual(Array.from((await instantiationService.invokeFunction(fetchFishHistory))!), expectedCommands); + }); + test('Linux', async () => { + remoteEnvironment = { os: OperatingSystem.Linux }; + deepStrictEqual(Array.from((await instantiationService.invokeFunction(fetchFishHistory))!), expectedCommands); + }); + }); + + suite('remote (overriden path)', () => { + let originalEnvValues: { XDG_DATA_HOME: string | undefined }; + setup(() => { + originalEnvValues = { XDG_DATA_HOME: env['XDG_DATA_HOME'] }; + env['XDG_DATA_HOME'] = '/home/user/data-home'; + remoteConnection = { remoteAuthority: 'some-remote' }; + fileScheme = Schemas.vscodeRemote; + filePath = '/home/user/data-home/fish/fish_history'; + }); + teardown(() => { + if (originalEnvValues['XDG_DATA_HOME'] === undefined) { + delete env['XDG_DATA_HOME']; + } else { + env['XDG_DATA_HOME'] = originalEnvValues['XDG_DATA_HOME']; + } + }); + test('Windows', async () => { + remoteEnvironment = { os: OperatingSystem.Windows }; + strictEqual(await instantiationService.invokeFunction(fetchFishHistory), undefined); + }); + test('macOS', async () => { + remoteEnvironment = { os: OperatingSystem.Macintosh }; + deepStrictEqual(Array.from((await instantiationService.invokeFunction(fetchFishHistory))!), expectedCommands); + }); + test('Linux', async () => { + remoteEnvironment = { os: OperatingSystem.Linux }; + deepStrictEqual(Array.from((await instantiationService.invokeFunction(fetchFishHistory))!), expectedCommands); + }); + }); + }); }); From 82b518c2fb9a93bfbf1c685b0760f0c87c2bd94a Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sat, 23 Jul 2022 22:34:24 +0430 Subject: [PATCH 008/303] =?UTF-8?q?=F0=9F=94=A8=20Include=20`fish`=20shell?= =?UTF-8?q?=20in=20history=20fetch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Babak K. Shandiz --- src/vs/workbench/contrib/terminal/common/history.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/contrib/terminal/common/history.ts b/src/vs/workbench/contrib/terminal/common/history.ts index e94aa44cd8b..e84408622c6 100644 --- a/src/vs/workbench/contrib/terminal/common/history.ts +++ b/src/vs/workbench/contrib/terminal/common/history.ts @@ -90,6 +90,9 @@ export async function getShellFileHistory(accessor: ServicesAccessor, shellType: case PosixShellType.Zsh: result = await fetchZshHistory(accessor); break; + case PosixShellType.Fish: + result = await fetchFishHistory(accessor); + break; default: return []; } if (result === undefined) { From d53f4c55443653a8ff20b1f1034d09ccf324adde Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 25 Jul 2022 11:20:56 +0200 Subject: [PATCH 009/303] Improves performance of bracket pair colorization --- src/vs/base/common/arrays.ts | 70 ++++++ .../browser/viewParts/minimap/minimap.ts | 2 +- src/vs/editor/common/model.ts | 2 +- .../bracketPairsImpl.ts | 56 ++--- .../bracketPairsTree/bracketPairsTree.ts | 215 +++++++++--------- ...colorizedBracketPairsDecorationProvider.ts | 36 +-- .../editor/common/model/decorationProvider.ts | 2 +- .../common/model/guidesTextModelPart.ts | 4 +- src/vs/editor/common/model/textModel.ts | 4 +- src/vs/editor/common/textModelBracketPairs.ts | 7 +- src/vs/editor/common/viewModel.ts | 2 +- .../common/viewModel/viewModelDecorations.ts | 11 +- .../editor/common/viewModel/viewModelImpl.ts | 4 +- .../editor/common/viewModel/viewModelLines.ts | 14 +- .../getBracketPairsInRange.test.ts | 12 +- src/vs/monaco.d.ts | 2 +- 16 files changed, 264 insertions(+), 179 deletions(-) diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index d543fdd8f83..0b91b287247 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -829,3 +829,73 @@ export class ArrayQueue { return result; } } + +/** + * This class is faster than an iterator and array for lazy computed data. +*/ +export class CallbackIterable { + public static readonly empty = new CallbackIterable(_callback => { }); + + constructor( + /** + * Calls the callback for every item. + * Stops when the callback returns false. + */ + public readonly iterate: (callback: (item: T) => boolean) => void + ) { + } + + forEach(handler: (item: T) => void) { + this.iterate(item => { handler(item); return true; }); + } + + toArray(): T[] { + const result: T[] = []; + this.iterate(item => { result.push(item); return true; }); + return result; + } + + filter(predicate: (item: T) => boolean): CallbackIterable { + return new CallbackIterable(cb => this.iterate(item => predicate(item) ? cb(item) : true)); + } + + map(mapFn: (item: T) => TResult): CallbackIterable { + return new CallbackIterable(cb => this.iterate(item => cb(mapFn(item)))); + } + + findFirst(predicate: (item: T) => boolean): T | undefined { + let result: T | undefined; + this.iterate(item => { + if (predicate(item)) { + result = item; + return false; + } + return true; + }); + return result; + } + + findLast(predicate: (item: T) => boolean): T | undefined { + let result: T | undefined; + this.iterate(item => { + if (predicate(item)) { + result = item; + } + return true; + }); + return result; + } + + findLastMaxBy(comparator: Comparator): T | undefined { + let result: T | undefined; + let first = true; + this.iterate(item => { + if (first || CompareResult.isGreaterThan(comparator(item, result!))) { + first = false; + result = item; + } + return true; + }); + return result; + } +} diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index ab06570ed5f..12d68b9b527 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -1021,7 +1021,7 @@ export class Minimap extends ViewPart implements IMinimapModel { } else { visibleRange = new Range(startLineNumber, 1, endLineNumber, this._context.viewModel.getLineMaxColumn(endLineNumber)); } - const decorations = this._context.viewModel.getDecorationsInViewport(visibleRange); + const decorations = this._context.viewModel.getDecorationsInViewport(visibleRange, true); if (this._samplingState) { const result: ViewModelDecoration[] = []; diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index 354026fdcb5..c847c5ecd64 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -941,7 +941,7 @@ export interface ITextModel { * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). * @return An array with the decorations */ - getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean): IModelDecoration[]; /** * Gets all the decorations as an array. diff --git a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl.ts b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl.ts index d5c012141f6..853b1f1fe86 100644 --- a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl.ts +++ b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl.ts @@ -3,20 +3,20 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CallbackIterable, compareBy } from 'vs/base/common/arrays'; import { Emitter } from 'vs/base/common/event'; import { Disposable, DisposableStore, IDisposable, IReference, MutableDisposable } from 'vs/base/common/lifecycle'; -import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; -import { BracketPairsTree } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree'; -import { BracketInfo, BracketPairInfo, BracketPairWithMinIndentationInfo, IBracketPairsTextModelPart, IFoundBracket } from 'vs/editor/common/textModelBracketPairs'; -import { TextModel } from 'vs/editor/common/model/textModel'; -import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelOptionsChangedEvent, IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { ignoreBracketsInToken } from 'vs/editor/common/languages/supports'; -import { RichEditBrackets, BracketsUtils, RichEditBracket } from 'vs/editor/common/languages/supports/richEditBrackets'; -import { compareBy, findLast, findLastMaxBy } from 'vs/base/common/arrays'; import { LanguageBracketsConfiguration } from 'vs/editor/common/languages/supports/languageBracketsConfiguration'; +import { BracketsUtils, RichEditBracket, RichEditBrackets } from 'vs/editor/common/languages/supports/richEditBrackets'; +import { BracketPairsTree } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree'; +import { TextModel } from 'vs/editor/common/model/textModel'; +import { BracketInfo, BracketPairInfo, BracketPairWithMinIndentationInfo, IBracketPairsTextModelPart, IFoundBracket } from 'vs/editor/common/textModelBracketPairs'; +import { IModelContentChangedEvent, IModelLanguageChangedEvent, IModelOptionsChangedEvent, IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; +import { LineTokens } from 'vs/editor/common/tokens/lineTokens'; export class BracketPairsTextModelPart extends Disposable implements IBracketPairsTextModelPart { private readonly bracketPairsTree = this._register(new MutableDisposable>()); @@ -102,22 +102,22 @@ export class BracketPairsTextModelPart extends Disposable implements IBracketPai * Returns all bracket pairs that intersect the given range. * The result is sorted by the start position. */ - public getBracketPairsInRange(range: Range): BracketPairInfo[] { + public getBracketPairsInRange(range: Range): CallbackIterable { this.bracketsRequested = true; this.updateBracketPairsTree(); - return this.bracketPairsTree.value?.object.getBracketPairsInRange(range, false) || []; + return this.bracketPairsTree.value?.object.getBracketPairsInRange(range, false) || CallbackIterable.empty; } - public getBracketPairsInRangeWithMinIndentation(range: Range): BracketPairWithMinIndentationInfo[] { + public getBracketPairsInRangeWithMinIndentation(range: Range): CallbackIterable { this.bracketsRequested = true; this.updateBracketPairsTree(); - return this.bracketPairsTree.value?.object.getBracketPairsInRange(range, true) || []; + return this.bracketPairsTree.value?.object.getBracketPairsInRange(range, true) || CallbackIterable.empty; } - public getBracketsInRange(range: Range): BracketInfo[] { + public getBracketsInRange(range: Range): CallbackIterable { this.bracketsRequested = true; this.updateBracketPairsTree(); - return this.bracketPairsTree.value?.object.getBracketsInRange(range) || []; + return this.bracketPairsTree.value?.object.getBracketsInRange(range) || CallbackIterable.empty; } public findMatchingBracketUp(_bracket: string, _position: IPosition, maxDuration?: number): Range | null { @@ -133,7 +133,7 @@ export class BracketPairsTextModelPart extends Disposable implements IBracketPai return null; } - const bracketPair = findLast(this.getBracketPairsInRange(Range.fromPositions(_position, _position)) || [], (b) => + const bracketPair = this.getBracketPairsInRange(Range.fromPositions(_position, _position)).findLast((b) => closingBracketInfo.closes(b.openingBracketInfo) ); @@ -163,7 +163,7 @@ export class BracketPairsTextModelPart extends Disposable implements IBracketPai public matchBracket(position: IPosition, maxDuration?: number): [Range, Range] | null { if (this.canBuildAST) { - const bracketPair = findLastMaxBy( + const bracketPair = this.getBracketPairsInRange( Range.fromPositions(position, position) ).filter( @@ -171,15 +171,15 @@ export class BracketPairsTextModelPart extends Disposable implements IBracketPai item.closingBracketRange !== undefined && (item.openingBracketRange.containsPosition(position) || item.closingBracketRange.containsPosition(position)) - ), - compareBy( - (item) => - item.openingBracketRange.containsPosition(position) - ? item.openingBracketRange - : item.closingBracketRange, - Range.compareRangesUsingStarts - ) - ); + ).findLastMaxBy( + compareBy( + (item) => + item.openingBracketRange.containsPosition(position) + ? item.openingBracketRange + : item.closingBracketRange, + Range.compareRangesUsingStarts + ) + ); if (bracketPair) { return [bracketPair.openingBracketRange, bracketPair.closingBracketRange!]; } @@ -674,10 +674,10 @@ export class BracketPairsTextModelPart extends Disposable implements IBracketPai if (this.canBuildAST) { const range = Range.fromPositions(position); - const bracketPair = findLast( - this.getBracketPairsInRange(Range.fromPositions(position, position)), - (item) => item.closingBracketRange !== undefined && item.range.strictContainsRange(range) - ); + const bracketPair = + this.getBracketPairsInRange(Range.fromPositions(position, position)).findLast( + (item) => item.closingBracketRange !== undefined && item.range.strictContainsRange(range) + ); if (bracketPair) { return [bracketPair.openingBracketRange, bracketPair.closingBracketRange!]; } diff --git a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts index 9ea7e35847c..e79d4efb21b 100644 --- a/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts +++ b/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts @@ -20,6 +20,7 @@ import { DenseKeyProvider } from './smallImmutableSet'; import { FastTokenizer, TextBufferTokenizer } from './tokenizer'; import { BackgroundTokenizationState } from 'vs/editor/common/tokenizationTextModelPart'; import { Position } from 'vs/editor/common/core/position'; +import { CallbackIterable } from 'vs/base/common/arrays'; export class BracketPairsTree extends Disposable { private readonly didChangeEmitter = new Emitter(); @@ -125,26 +126,24 @@ export class BracketPairsTree extends Disposable { return result; } - public getBracketsInRange(range: Range): BracketInfo[] { + public getBracketsInRange(range: Range): CallbackIterable { const startOffset = toLength(range.startLineNumber - 1, range.startColumn - 1); const endOffset = toLength(range.endLineNumber - 1, range.endColumn - 1); - const result = new Array(); - const node = this.initialAstWithoutTokens || this.astWithTokens!; - collectBrackets(node, lengthZero, node.length, startOffset, endOffset, result, 0, new Map()); - return result; + return new CallbackIterable(cb => { + const node = this.initialAstWithoutTokens || this.astWithTokens!; + collectBrackets(node, lengthZero, node.length, startOffset, endOffset, cb, 0, new Map()); + }); } - public getBracketPairsInRange(range: Range, includeMinIndentation: boolean): BracketPairWithMinIndentationInfo[] { - const result = new Array(); - + public getBracketPairsInRange(range: Range, includeMinIndentation: boolean): CallbackIterable { const startLength = positionToLength(range.getStartPosition()); const endLength = positionToLength(range.getEndPosition()); - const node = this.initialAstWithoutTokens || this.astWithTokens!; - const context = new CollectBracketPairsContext(result, includeMinIndentation, this.textModel); - collectBracketPairs(node, lengthZero, node.length, startLength, endLength, context, 0, new Map()); - - return result; + return new CallbackIterable(cb => { + const node = this.initialAstWithoutTokens || this.astWithTokens!; + const context = new CollectBracketPairsContext(cb, includeMinIndentation, this.textModel); + collectBracketPairs(node, lengthZero, node.length, startLength, endLength, context, 0, new Map()); + }); } public getFirstBracketAfter(position: Position): IFoundBracket | null { @@ -219,108 +218,105 @@ function collectBrackets( nodeOffsetEnd: Length, startOffset: Length, endOffset: Length, - result: BracketInfo[], + push: (item: BracketInfo) => boolean, level: number, levelPerBracketType: Map -): void { +): boolean { if (level > 200) { - return; + return true; } - if (node.kind === AstNodeKind.List) { - for (const child of node.children) { - nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length); - if ( - lengthLessThanEqual(nodeOffsetStart, endOffset) && - lengthGreaterThanEqual(nodeOffsetEnd, startOffset) - ) { - collectBrackets( - child, - nodeOffsetStart, - nodeOffsetEnd, - startOffset, - endOffset, - result, - level, - levelPerBracketType - ); - } - nodeOffsetStart = nodeOffsetEnd; - } - } else if (node.kind === AstNodeKind.Pair) { - let levelPerBracket = 0; - if (levelPerBracketType) { - let existing = levelPerBracketType.get(node.openingBracket.text); - if (existing === undefined) { - existing = 0; - } - levelPerBracket = existing; - existing++; - levelPerBracketType.set(node.openingBracket.text, existing); - } + whileLoop: + while (true) { + switch (node.kind) { + case AstNodeKind.List: { + const childCount = node.childrenLength; + for (let i = 0; i < childCount; i++) { + const child = node.getChild(i); + if (!child) { + continue; + } + nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length); + if ( + lengthLessThanEqual(nodeOffsetStart, endOffset) && + lengthGreaterThanEqual(nodeOffsetEnd, startOffset) + ) { + const childEndsAfterEnd = lengthGreaterThanEqual(nodeOffsetEnd, endOffset); + if (childEndsAfterEnd) { + // No child after this child in the requested window, don't recurse + node = child; + continue whileLoop; + } - // Don't use node.children here to improve performance - { - const child = node.openingBracket; - nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length); - if ( - lengthLessThanEqual(nodeOffsetStart, endOffset) && - lengthGreaterThanEqual(nodeOffsetEnd, startOffset) - ) { + const shouldContinue = collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, push, level, levelPerBracketType); + if (!shouldContinue) { + return false; + } + } + nodeOffsetStart = nodeOffsetEnd; + } + return true; + } + case AstNodeKind.Pair: { + let levelPerBracket = 0; + if (levelPerBracketType) { + let existing = levelPerBracketType.get(node.openingBracket.text); + if (existing === undefined) { + existing = 0; + } + levelPerBracket = existing; + existing++; + levelPerBracketType.set(node.openingBracket.text, existing); + } + + const childCount = node.childrenLength; + for (let i = 0; i < childCount; i++) { + const child = node.getChild(i); + if (!child) { + continue; + } + nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length); + if ( + lengthLessThanEqual(nodeOffsetStart, endOffset) && + lengthGreaterThanEqual(nodeOffsetEnd, startOffset) + ) { + const childEndsAfterEnd = lengthGreaterThanEqual(nodeOffsetEnd, endOffset); + if (childEndsAfterEnd) { + // No child after this child in the requested window, don't recurse + node = child; + level++; + continue whileLoop; + } + + const shouldContinue = collectBrackets(child, nodeOffsetStart, nodeOffsetEnd, startOffset, endOffset, push, level + 1, levelPerBracketType); + if (!shouldContinue) { + return false; + } + } + nodeOffsetStart = nodeOffsetEnd; + } + + levelPerBracketType?.set(node.openingBracket.text, levelPerBracket); + + return true; + } + case AstNodeKind.UnexpectedClosingBracket: { const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd); - result.push( - new BracketInfo(range, level, levelPerBracket, !node.closingBracket) - ); + return push(new BracketInfo(range, level - 1, 0, true)); } - nodeOffsetStart = nodeOffsetEnd; - } - - if (node.child) { - const child = node.child; - nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length); - if ( - lengthLessThanEqual(nodeOffsetStart, endOffset) && - lengthGreaterThanEqual(nodeOffsetEnd, startOffset) - ) { - collectBrackets( - child, - nodeOffsetStart, - nodeOffsetEnd, - startOffset, - endOffset, - result, - level + 1, - levelPerBracketType - ); - } - nodeOffsetStart = nodeOffsetEnd; - } - if (node.closingBracket) { - const child = node.closingBracket; - nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length); - if ( - lengthLessThanEqual(nodeOffsetStart, endOffset) && - lengthGreaterThanEqual(nodeOffsetEnd, startOffset) - ) { + case AstNodeKind.Bracket: { const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd); - result.push(new BracketInfo(range, level, levelPerBracket, false)); + return push(new BracketInfo(range, level - 1, 0, false)); } - nodeOffsetStart = nodeOffsetEnd; + case AstNodeKind.Text: + return true; } - - levelPerBracketType?.set(node.openingBracket.text, levelPerBracket); - } else if (node.kind === AstNodeKind.UnexpectedClosingBracket) { - const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd); - result.push(new BracketInfo(range, level - 1, 0, true)); - } else if (node.kind === AstNodeKind.Bracket) { - const range = lengthsToRange(nodeOffsetStart, nodeOffsetEnd); - result.push(new BracketInfo(range, level - 1, 0, false)); } } class CollectBracketPairsContext { constructor( - public readonly result: BracketPairWithMinIndentationInfo[], + public readonly push: (item: BracketPairWithMinIndentationInfo) => boolean, public readonly includeMinIndentation: boolean, public readonly textModel: ITextModel, ) { @@ -336,11 +332,13 @@ function collectBracketPairs( context: CollectBracketPairsContext, level: number, levelPerBracketType: Map -) { +): boolean { if (level > 200) { - return; + return true; } + let shouldContinue = true; + if (node.kind === AstNodeKind.Pair) { let levelPerBracket = 0; if (levelPerBracketType) { @@ -362,7 +360,7 @@ function collectBracketPairs( ); } - context.result.push( + shouldContinue = context.push( new BracketPairWithMinIndentationInfo( lengthsToRange(nodeOffsetStart, nodeOffsetEnd), lengthsToRange(nodeOffsetStart, openingBracketEnd), @@ -380,14 +378,14 @@ function collectBracketPairs( ); nodeOffsetStart = openingBracketEnd; - if (node.child) { + if (shouldContinue && node.child) { const child = node.child; nodeOffsetEnd = lengthAdd(nodeOffsetStart, child.length); if ( lengthLessThanEqual(nodeOffsetStart, endOffset) && lengthGreaterThanEqual(nodeOffsetEnd, startOffset) ) { - collectBracketPairs( + shouldContinue = collectBracketPairs( child, nodeOffsetStart, nodeOffsetEnd, @@ -397,6 +395,9 @@ function collectBracketPairs( level + 1, levelPerBracketType ); + if (!shouldContinue) { + return false; + } } } @@ -411,7 +412,7 @@ function collectBracketPairs( lengthLessThanEqual(childOffset, endOffset) && lengthLessThanEqual(startOffset, curOffset) ) { - collectBracketPairs( + shouldContinue = collectBracketPairs( child, childOffset, curOffset, @@ -421,8 +422,12 @@ function collectBracketPairs( level, levelPerBracketType ); + if (!shouldContinue) { + return false; + } } } } + return shouldContinue; } diff --git a/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts b/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts index 1e4d0a0ed05..21d52586ae3 100644 --- a/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts +++ b/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts @@ -42,7 +42,11 @@ export class ColorizedBracketPairsDecorationProvider extends Disposable implemen //#endregion - getDecorationsInRange(range: Range, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[] { + getDecorationsInRange(range: Range, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean): IModelDecoration[] { + if (onlyMinimapDecorations) { + // Bracket pair colorization decorations are not rendered in the minimap + return []; + } if (ownerId === undefined) { return []; } @@ -50,22 +54,20 @@ export class ColorizedBracketPairsDecorationProvider extends Disposable implemen return []; } - const result = new Array(); - const bracketsInRange = this.textModel.bracketPairs.getBracketsInRange(range); - for (const bracket of bracketsInRange) { - result.push({ - id: `bracket${bracket.range.toString()}-${bracket.nestingLevel}`, - options: { - description: 'BracketPairColorization', - inlineClassName: this.colorProvider.getInlineClassName( - bracket, - this.colorizationOptions.independentColorPoolPerBracketType - ), - }, - ownerId: 0, - range: bracket.range, - }); - } + const result = this.textModel.bracketPairs.getBracketsInRange(range).map(bracket => + ({ + id: `bracket${bracket.range.toString()}-${bracket.nestingLevel}`, + options: { + description: 'BracketPairColorization', + inlineClassName: this.colorProvider.getInlineClassName( + bracket, + this.colorizationOptions.independentColorPoolPerBracketType + ), + }, + ownerId: 0, + range: bracket.range, + })).toArray(); + return result; } diff --git a/src/vs/editor/common/model/decorationProvider.ts b/src/vs/editor/common/model/decorationProvider.ts index c9ef6e3df0e..af8452a6101 100644 --- a/src/vs/editor/common/model/decorationProvider.ts +++ b/src/vs/editor/common/model/decorationProvider.ts @@ -23,7 +23,7 @@ export interface DecorationProvider { * @param ownerId If set, it will ignore decorations belonging to other owners. * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). */ - getAllDecorations(ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + getAllDecorations(ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean): IModelDecoration[]; onDidChange: Event; } diff --git a/src/vs/editor/common/model/guidesTextModelPart.ts b/src/vs/editor/common/model/guidesTextModelPart.ts index 9e7937f7ad6..8d99b36c026 100644 --- a/src/vs/editor/common/model/guidesTextModelPart.ts +++ b/src/vs/editor/common/model/guidesTextModelPart.ts @@ -292,7 +292,7 @@ export class GuidesTextModelPart extends TextModelPart implements IGuidesTextMod endLineNumber, this.textModel.getLineMaxColumn(endLineNumber) ) - ); + ).toArray(); let activeBracketPairRange: Range | undefined = undefined; if (activePosition && bracketPairs.length > 0) { @@ -303,7 +303,7 @@ export class GuidesTextModelPart extends TextModelPart implements IGuidesTextMod ? bracketPairs : this.textModel.bracketPairs.getBracketPairsInRange( Range.fromPositions(activePosition) - ) + ).toArray() ).filter((bp) => Range.strictContainsPosition(bp.range, activePosition)); activeBracketPairRange = findLast( diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 690a2eab09a..305b91eb369 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -1711,11 +1711,11 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati return decorations; } - public getDecorationsInRange(range: IRange, ownerId: number = 0, filterOutValidation: boolean = false): model.IModelDecoration[] { + public getDecorationsInRange(range: IRange, ownerId: number = 0, filterOutValidation: boolean = false, onlyMinimapDecorations: boolean = false): model.IModelDecoration[] { const validatedRange = this.validateRange(range); const decorations = this._getDecorationsInRange(validatedRange, ownerId, filterOutValidation); - pushMany(decorations, this._decorationProvider.getDecorationsInRange(validatedRange, ownerId, filterOutValidation)); + pushMany(decorations, this._decorationProvider.getDecorationsInRange(validatedRange, ownerId, filterOutValidation, onlyMinimapDecorations)); return decorations; } diff --git a/src/vs/editor/common/textModelBracketPairs.ts b/src/vs/editor/common/textModelBracketPairs.ts index 633b72fdd40..27df3befbb3 100644 --- a/src/vs/editor/common/textModelBracketPairs.ts +++ b/src/vs/editor/common/textModelBracketPairs.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CallbackIterable } from 'vs/base/common/arrays'; import { Event } from 'vs/base/common/event'; import { IPosition } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; @@ -19,15 +20,15 @@ export interface IBracketPairsTextModelPart { * Gets all bracket pairs that intersect the given position. * The result is sorted by the start position. */ - getBracketPairsInRange(range: IRange): BracketPairInfo[]; + getBracketPairsInRange(range: IRange): CallbackIterable; /** * Gets all bracket pairs that intersect the given position. * The result is sorted by the start position. */ - getBracketPairsInRangeWithMinIndentation(range: IRange): BracketPairWithMinIndentationInfo[]; + getBracketPairsInRangeWithMinIndentation(range: IRange): CallbackIterable; - getBracketsInRange(range: IRange): BracketInfo[]; + getBracketsInRange(range: IRange): CallbackIterable; /** * Find the matching bracket of `request` up, counting brackets. diff --git a/src/vs/editor/common/viewModel.ts b/src/vs/editor/common/viewModel.ts index e582f7dc719..4ed3be68bd6 100644 --- a/src/vs/editor/common/viewModel.ts +++ b/src/vs/editor/common/viewModel.ts @@ -40,7 +40,7 @@ export interface IViewModel extends ICursorSimpleModel { onCompositionStart(): void; onCompositionEnd(): void; - getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[]; + getDecorationsInViewport(visibleRange: Range, onlyMinimapDecorations?: boolean): ViewModelDecoration[]; getViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData; getViewLineData(lineNumber: number): ViewLineData; getMinimapLinesRenderingData(startLineNumber: number, endLineNumber: number, needed: boolean[]): MinimapLinesRenderingData; diff --git a/src/vs/editor/common/viewModel/viewModelDecorations.ts b/src/vs/editor/common/viewModel/viewModelDecorations.ts index 909d9f19bc3..95b7c3bfe30 100644 --- a/src/vs/editor/common/viewModel/viewModelDecorations.ts +++ b/src/vs/editor/common/viewModel/viewModelDecorations.ts @@ -36,6 +36,7 @@ export class ViewModelDecorations implements IDisposable { private _cachedModelDecorationsResolver: IDecorationsViewportData | null; private _cachedModelDecorationsResolverViewRange: Range | null; + private _cachedOnlyMinimapDecorations: boolean | null = null; constructor(editorId: number, model: ITextModel, configuration: IEditorConfiguration, linesCollection: IViewModelLines, coordinatesConverter: ICoordinatesConverter) { this.editorId = editorId; @@ -96,18 +97,20 @@ export class ViewModelDecorations implements IDisposable { return r; } - public getDecorationsViewportData(viewRange: Range): IDecorationsViewportData { + public getDecorationsViewportData(viewRange: Range, onlyMinimapDecorations: boolean = false): IDecorationsViewportData { let cacheIsValid = (this._cachedModelDecorationsResolver !== null); cacheIsValid = cacheIsValid && (viewRange.equalsRange(this._cachedModelDecorationsResolverViewRange)); + cacheIsValid = cacheIsValid && (this._cachedOnlyMinimapDecorations === onlyMinimapDecorations); if (!cacheIsValid) { - this._cachedModelDecorationsResolver = this._getDecorationsViewportData(viewRange); + this._cachedModelDecorationsResolver = this._getDecorationsViewportData(viewRange, onlyMinimapDecorations); this._cachedModelDecorationsResolverViewRange = viewRange; + this._cachedOnlyMinimapDecorations = onlyMinimapDecorations; } return this._cachedModelDecorationsResolver!; } - private _getDecorationsViewportData(viewportRange: Range): IDecorationsViewportData { - const modelDecorations = this._linesCollection.getDecorationsInRange(viewportRange, this.editorId, filterValidationDecorations(this.configuration.options)); + private _getDecorationsViewportData(viewportRange: Range, onlyMinimapDecorations: boolean): IDecorationsViewportData { + const modelDecorations = this._linesCollection.getDecorationsInRange(viewportRange, this.editorId, filterValidationDecorations(this.configuration.options), onlyMinimapDecorations); const startLineNumber = viewportRange.startLineNumber; const endLineNumber = viewportRange.endLineNumber; diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index c55cf3d02d1..86c8b8ce130 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -671,8 +671,8 @@ export class ViewModel extends Disposable implements IViewModel { return result + 2; } - public getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[] { - return this._decorations.getDecorationsViewportData(visibleRange).decorations; + public getDecorationsInViewport(visibleRange: Range, onlyMinimapDecorations: boolean = false): ViewModelDecoration[] { + return this._decorations.getDecorationsViewportData(visibleRange, onlyMinimapDecorations).decorations; } public getInjectedTextAt(viewPosition: Position): InjectedText | null { diff --git a/src/vs/editor/common/viewModel/viewModelLines.ts b/src/vs/editor/common/viewModel/viewModelLines.ts index 86b2010989f..7d766e8ee9f 100644 --- a/src/vs/editor/common/viewModel/viewModelLines.ts +++ b/src/vs/editor/common/viewModel/viewModelLines.ts @@ -45,7 +45,7 @@ export interface IViewModelLines extends IDisposable { getViewLineData(viewLineNumber: number): ViewLineData; getViewLinesData(viewStartLineNumber: number, viewEndLineNumber: number, needed: boolean[]): Array; - getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): IModelDecoration[]; + getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean, onlyMinimapDecorations: boolean): IModelDecoration[]; getInjectedTextAt(viewPosition: Position): InjectedText | null; @@ -888,14 +888,14 @@ export class ViewModelLinesFromProjectedModel implements IViewModelLines { return this.modelLineProjections[lineIndex].getViewLineNumberOfModelPosition(deltaLineNumber, this.model.getLineMaxColumn(lineIndex + 1)); } - public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): IModelDecoration[] { + public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean, onlyMinimapDecorations: boolean): IModelDecoration[] { const modelStart = this.convertViewPositionToModelPosition(range.startLineNumber, range.startColumn); const modelEnd = this.convertViewPositionToModelPosition(range.endLineNumber, range.endColumn); if (modelEnd.lineNumber - modelStart.lineNumber <= range.endLineNumber - range.startLineNumber) { // most likely there are no hidden lines => fast path // fetch decorations from column 1 to cover the case of wrapped lines that have whole line decorations at column 1 - return this.model.getDecorationsInRange(new Range(modelStart.lineNumber, 1, modelEnd.lineNumber, modelEnd.column), ownerId, filterOutValidation); + return this.model.getDecorationsInRange(new Range(modelStart.lineNumber, 1, modelEnd.lineNumber, modelEnd.column), ownerId, filterOutValidation, onlyMinimapDecorations); } let result: IModelDecoration[] = []; @@ -914,14 +914,14 @@ export class ViewModelLinesFromProjectedModel implements IViewModelLines { // hit invisible line => flush request if (reqStart !== null) { const maxLineColumn = this.model.getLineMaxColumn(modelLineIndex); - result = result.concat(this.model.getDecorationsInRange(new Range(reqStart.lineNumber, reqStart.column, modelLineIndex, maxLineColumn), ownerId, filterOutValidation)); + result = result.concat(this.model.getDecorationsInRange(new Range(reqStart.lineNumber, reqStart.column, modelLineIndex, maxLineColumn), ownerId, filterOutValidation, onlyMinimapDecorations)); reqStart = null; } } } if (reqStart !== null) { - result = result.concat(this.model.getDecorationsInRange(new Range(reqStart.lineNumber, reqStart.column, modelEnd.lineNumber, modelEnd.column), ownerId, filterOutValidation)); + result = result.concat(this.model.getDecorationsInRange(new Range(reqStart.lineNumber, reqStart.column, modelEnd.lineNumber, modelEnd.column), ownerId, filterOutValidation, onlyMinimapDecorations)); reqStart = null; } @@ -1221,8 +1221,8 @@ export class ViewModelLinesFromModelAsIs implements IViewModelLines { return result; } - public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean): IModelDecoration[] { - return this.model.getDecorationsInRange(range, ownerId, filterOutValidation); + public getDecorationsInRange(range: Range, ownerId: number, filterOutValidation: boolean, onlyMinimapDecorations: boolean): IModelDecoration[] { + return this.model.getDecorationsInRange(range, ownerId, filterOutValidation, onlyMinimapDecorations); } normalizePosition(position: Position, affinity: PositionAffinity): Position { diff --git a/src/vs/editor/test/common/model/bracketPairColorizer/getBracketPairsInRange.test.ts b/src/vs/editor/test/common/model/bracketPairColorizer/getBracketPairsInRange.test.ts index e74219407a6..5a631ed3d10 100644 --- a/src/vs/editor/test/common/model/bracketPairColorizer/getBracketPairsInRange.test.ts +++ b/src/vs/editor/test/common/model/bracketPairColorizer/getBracketPairsInRange.test.ts @@ -36,7 +36,8 @@ suite('Bracket Pair Colorizer - getBracketPairsInRange', () => { assert.deepStrictEqual( model.bracketPairs .getBracketPairsInRange(doc.range(1, 2)) - .map(bracketPairToJSON), + .map(bracketPairToJSON) + .toArray(), [ { level: 0, @@ -68,7 +69,8 @@ suite('Bracket Pair Colorizer - getBracketPairsInRange', () => { assert.deepStrictEqual( model.bracketPairs .getBracketPairsInRange(doc.range(1, 2)) - .map(bracketPairToJSON), + .map(bracketPairToJSON) + .toArray(), [ { level: 0, @@ -94,7 +96,8 @@ suite('Bracket Pair Colorizer - getBracketPairsInRange', () => { assert.deepStrictEqual( model.bracketPairs .getBracketPairsInRange(doc.range(1, 2)) - .map(bracketPairToJSON), + .map(bracketPairToJSON) + .toArray(), [] ); }); @@ -107,7 +110,8 @@ suite('Bracket Pair Colorizer - getBracketPairsInRange', () => { assert.deepStrictEqual( model.bracketPairs .getBracketPairsInRange(doc.range(1, 2)) - .map(bracketPairToJSON), + .map(bracketPairToJSON) + .toArray(), [ { level: 0, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index f608381f9e4..25bd5f50078 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1995,7 +1995,7 @@ declare namespace monaco.editor { * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). * @return An array with the decorations */ - getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean, onlyMinimapDecorations?: boolean): IModelDecoration[]; /** * Gets all the decorations as an array. * @param ownerId If set, it will ignore decorations belonging to other owners. From 6bb3909461539c26e609b6cacac37d6b0e138bfc Mon Sep 17 00:00:00 2001 From: "Jui Hanamshet (SHE/HER)" Date: Tue, 26 Jul 2022 09:10:57 -0700 Subject: [PATCH 010/303] If the brackets are removed, reduce the range. If the brackets are added, increase the range --- .../inlineCompletions/browser/inlineCompletionsModel.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts index b60a6dec142..4050b76b17b 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts @@ -699,7 +699,7 @@ export async function provideInlineCompletions( } for (const item of completions.items) { - const range = item.range ? Range.lift(item.range) : defaultReplaceRange; + let range = item.range ? Range.lift(item.range) : defaultReplaceRange; if (range.startLineNumber !== range.endLineNumber) { // Ignore invalid ranges. @@ -726,6 +726,12 @@ export async function provideInlineCompletions( ); } + // Modify range depending on if brackets are added or removed + if (insertText.length != item.insertText.length) { + const diff = insertText.length - item.insertText.length; + range = new Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn + diff); + } + snippetInfo = undefined; } else if ('snippet' in item.insertText) { const snippet = new SnippetParser().parse(item.insertText.snippet); From ce10de94db823cfda32a9103ee4d59e2cb38d218 Mon Sep 17 00:00:00 2001 From: "Jui Hanamshet (SHE/HER)" Date: Tue, 26 Jul 2022 09:31:24 -0700 Subject: [PATCH 011/303] fixing != to be !== --- .../contrib/inlineCompletions/browser/inlineCompletionsModel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts index 4050b76b17b..bb49228f345 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts @@ -727,7 +727,7 @@ export async function provideInlineCompletions( } // Modify range depending on if brackets are added or removed - if (insertText.length != item.insertText.length) { + if (insertText.length !== item.insertText.length) { const diff = insertText.length - item.insertText.length; range = new Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn + diff); } From 001843b0a87017ab3a96583bc87a4d79ffc113e9 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Tue, 26 Jul 2022 14:42:06 -0700 Subject: [PATCH 012/303] fix accidental hits on js/ts, added hovers, added keybdinings for refactor w/preview, fixed domFocus and important tags --- .../codeAction/browser/codeActionCommands.ts | 16 ++++++ .../codeAction/browser/codeActionMenu.ts | 50 ++++++++++++++++--- .../codeAction/browser/codeActionUi.ts | 13 ++++- .../codeAction/browser/media/action.css | 8 +-- 4 files changed, 76 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts b/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts index 62647863cf5..6c6f5fb306f 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts @@ -151,6 +151,10 @@ export class QuickFixController extends Disposable implements IEditorContributio } } + public selectedOptionWithPreview() { + this._ui.getValue().onPreviewEnter(); + } + public showCodeActions(trigger: CodeActionTrigger, actions: CodeActionSet, at: IAnchor | IPosition) { return this._ui.getValue().showCodeActionList(trigger, actions, at, { includeDisabledActions: false, fromLightbulb: false }); } @@ -566,4 +570,16 @@ registerEditorCommand(new CodeActionContribution({ } })); +registerEditorCommand(new CodeActionContribution({ + id: 'onEnterSelectCodeActionWithPreview', + precondition: Context.Visible, + handler(x) { + x.selectedOptionWithPreview(); + }, + kbOpts: { + weight: weight + 100000, + primary: KeyMod.CtrlCmd | KeyCode.Enter, + } +})); + diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts index f9b5b7b8547..0cc02fbc935 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts @@ -5,7 +5,7 @@ import * as dom from 'vs/base/browser/dom'; import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; -import { IListEvent, IListRenderer } from 'vs/base/browser/ui/list/list'; +import { IListEvent, IListMouseEvent, IListRenderer } from 'vs/base/browser/ui/list/list'; import { List } from 'vs/base/browser/ui/list/listWidget'; import { Action, IAction, Separator } from 'vs/base/common/actions'; import { canceled } from 'vs/base/common/errors'; @@ -69,6 +69,7 @@ export interface ICodeActionMenuItem { decoratorRight?: string; isSeparator?: boolean; isEnabled: boolean; + isDocumentation: boolean; index: number; disposables?: IDisposable[]; } @@ -93,6 +94,13 @@ const TEMPLATE_ID = 'codeActionWidget'; const codeActionLineHeight = 26; class CodeMenuRenderer implements IListRenderer { + + constructor( + @IKeybindingService private readonly keybindingService: IKeybindingService, + ) { + + } + get templateId(): string { return TEMPLATE_ID; } renderTemplate(container: HTMLElement): ICodeActionMenuTemplateData { @@ -114,6 +122,7 @@ class CodeMenuRenderer implements IListRenderer { + const [accept, preview] = [`onEnterSelectCodeAction`, `onEnterSelectCodeActionWithPreview`]; + data.root.title = this.keybindingService.lookupKeybinding(accept)?.getLabel() + ' to Refactor, ' + this.keybindingService.lookupKeybinding(preview)?.getLabel() + ' to Preview'; + }; + updateLabel(); + } + } disposeTemplate(templateData: ICodeActionMenuTemplateData): void { templateData.disposables = dispose(templateData.disposables); @@ -155,7 +172,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { } private readonly _keybindingResolver: CodeActionKeybindingResolver; - private listRenderer: CodeMenuRenderer = new CodeMenuRenderer(); + private listRenderer: CodeMenuRenderer; constructor( private readonly _editor: ICodeEditor, @@ -176,6 +193,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { }); this._ctxMenuWidgetVisible = Context.Visible.bindTo(this._contextKeyService); + this.listRenderer = new CodeMenuRenderer(keybindingService); } get isVisible(): boolean { @@ -200,6 +218,18 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { } + private _onListHover(e: IListMouseEvent): void { + if (!e.element) { + this.codeActionList.value?.setFocus([]); + } else { + if (e.element?.isEnabled) { + this.codeActionList.value?.setFocus([e.element.index]); + this.focusedEnabledItem = this.viewItems.indexOf(e.element); + this.currSelectedItem = e.element.index; + } + } + } + private renderCodeActionMenuList(element: HTMLElement, inputArray: IAction[]): IDisposable { const renderDisposables = new DisposableStore(); const renderMenu = document.createElement('div'); @@ -236,6 +266,8 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { }, [this.listRenderer], { keyboardSupport: false } ); + renderDisposables.add(this.codeActionList.value.onMouseOver(e => this._onListHover(e))); + renderDisposables.add(this.codeActionList.value.onDidChangeFocus(e => this.codeActionList.value?.domFocus())); renderDisposables.add(this.codeActionList.value.onDidChangeSelection(e => this._onListSelection(e))); renderDisposables.add(this._editor.onDidLayoutChange(e => this.hideCodeActionWidget())); @@ -243,11 +275,16 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { // Populating the list widget and tracking enabled options. inputArray.forEach((item, index) => { const currIsSeparator = item.class === 'separator'; + let isDocumentation = false; + if (item instanceof CodeActionAction) { + isDocumentation = item.action.kind === '_documentation'; + } + if (currIsSeparator) { // set to true forever this.hasSeperator = true; } - const menuItem = { title: item.label, detail: item.tooltip, action: inputArray[index], isEnabled: item.enabled, isSeparator: currIsSeparator, index }; + const menuItem = { title: item.label, detail: item.tooltip, action: inputArray[index], isEnabled: item.enabled, isSeparator: currIsSeparator, index, isDocumentation }; if (item.enabled) { this.viewItems.push(menuItem); } @@ -278,7 +315,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { this.codeActionList.value?.layout(height, maxWidth); // List selection - if (this.viewItems.length < 1) { + if (this.viewItems.length < 1 || (this.viewItems.length === 1 && this.viewItems[0].isDocumentation)) { this.currSelectedItem = 0; } else { this.focusedEnabledItem = 0; @@ -303,7 +340,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { protected focusPrevious() { if (typeof this.focusedEnabledItem === 'undefined') { this.focusedEnabledItem = this.viewItems[0].index; - } else if (this.viewItems.length < 1) { + } else if (this.viewItems.length < 1 || (this.viewItems.length === 1 && !this.viewItems[0].isDocumentation)) { return false; } @@ -326,7 +363,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { protected focusNext() { if (typeof this.focusedEnabledItem === 'undefined') { this.focusedEnabledItem = this.viewItems.length - 1; - } else if (this.viewItems.length < 1) { + } else if (this.viewItems.length < 1 || (this.viewItems.length === 1 && !this.viewItems[0].isDocumentation)) { return false; } @@ -474,6 +511,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { result.push(new Separator(), ...allDocumentation.map(command => toCodeActionAction(new CodeActionItem({ title: command.title, command: command, + kind: '_documentation' }, undefined)))); } diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionUi.ts b/src/vs/editor/contrib/codeAction/browser/codeActionUi.ts index e42d043ab5e..f8ac0210a73 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionUi.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionUi.ts @@ -23,6 +23,7 @@ export class CodeActionUi extends Disposable { private readonly _codeActionWidget: Lazy; private readonly _lightBulbWidget: Lazy; private readonly _activeCodeActions = this._register(new MutableDisposable()); + private previewOn: boolean = false; #disposed = false; @@ -40,7 +41,12 @@ export class CodeActionUi extends Disposable { this._codeActionWidget = new Lazy(() => { return this._register(instantiationService.createInstance(CodeActionMenu, this._editor, { onSelectCodeAction: async (action, trigger) => { - this.delegate.applyCodeAction(action, /* retrigger */ true, Boolean(trigger.preview)); + if (this.previewOn) { + this.delegate.applyCodeAction(action, /* retrigger */ true, Boolean(this.previewOn)); + } else { + this.delegate.applyCodeAction(action, /* retrigger */ true, Boolean(trigger.preview)); + } + this.previewOn = false; } })); }); @@ -70,6 +76,11 @@ export class CodeActionUi extends Disposable { } } + public onPreviewEnter() { + this.previewOn = true; + this.onEnter(); + } + public navigateList(navUp: Boolean) { if (this._codeActionWidget.hasValue()) { if (navUp) { diff --git a/src/vs/editor/contrib/codeAction/browser/media/action.css b/src/vs/editor/contrib/codeAction/browser/media/action.css index a32d77522f4..52faf076802 100644 --- a/src/vs/editor/contrib/codeAction/browser/media/action.css +++ b/src/vs/editor/contrib/codeAction/browser/media/action.css @@ -30,10 +30,10 @@ z-index: 5; /* make sure we are on top of the tree items */ content: ""; pointer-events: none; /* enable click through */ - outline: 0px solid; /* we still need to handle the empty tree or no focus item case */ - outline-width: 0px; - outline-style: none; - outline-offset: 0px; + outline: 0px solid !important; /* we still need to handle the empty tree or no focus item case */ + outline-width: 0px !important; + outline-style: none !important; + outline-offset: 0px !important; } .codeActionMenuWidget .monaco-list { From d31f53b5dc057aff1fe9513f62d283bd608e6100 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Tue, 26 Jul 2022 15:27:52 -0700 Subject: [PATCH 013/303] code clean up and fix on documentation type check --- .../codeAction/browser/codeActionCommands.ts | 5 ++++- .../codeAction/browser/codeActionMenu.ts | 18 +++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts b/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts index 6c6f5fb306f..7f106ceba40 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts @@ -152,7 +152,10 @@ export class QuickFixController extends Disposable implements IEditorContributio } public selectedOptionWithPreview() { - this._ui.getValue().onPreviewEnter(); + if (this._ui.hasValue()) { + this._ui.getValue().onPreviewEnter(); + } + } public showCodeActions(trigger: CodeActionTrigger, actions: CodeActionSet, at: IAnchor | IPosition) { diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts index 0cc02fbc935..8ce748081a0 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts @@ -96,10 +96,9 @@ const codeActionLineHeight = 26; class CodeMenuRenderer implements IListRenderer { constructor( + private readonly acceptKeybindings: [string, string], @IKeybindingService private readonly keybindingService: IKeybindingService, - ) { - - } + ) { } get templateId(): string { return TEMPLATE_ID; } @@ -141,8 +140,9 @@ class CodeMenuRenderer implements IListRenderer { - const [accept, preview] = [`onEnterSelectCodeAction`, `onEnterSelectCodeActionWithPreview`]; - data.root.title = this.keybindingService.lookupKeybinding(accept)?.getLabel() + ' to Refactor, ' + this.keybindingService.lookupKeybinding(preview)?.getLabel() + ' to Preview'; + const [accept, preview] = this.acceptKeybindings; + data.root.title = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Refactor, Shift+F2 to Preview"'] }, "{0} to Rename, {1} to Preview", this.keybindingService.lookupKeybinding(accept)?.getLabel(), this.keybindingService.lookupKeybinding(preview)?.getLabel()); + // data.root.title = this.keybindingService.lookupKeybinding(accept)?.getLabel() + ' to Refactor, ' + this.keybindingService.lookupKeybinding(preview)?.getLabel() + ' to Preview'; }; updateLabel(); } @@ -193,7 +193,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { }); this._ctxMenuWidgetVisible = Context.Visible.bindTo(this._contextKeyService); - this.listRenderer = new CodeMenuRenderer(keybindingService); + this.listRenderer = new CodeMenuRenderer([`onEnterSelectCodeAction`, `onEnterSelectCodeActionWithPreview`], keybindingService); } get isVisible(): boolean { @@ -315,7 +315,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { this.codeActionList.value?.layout(height, maxWidth); // List selection - if (this.viewItems.length < 1 || (this.viewItems.length === 1 && this.viewItems[0].isDocumentation)) { + if (this.viewItems.length < 1 || this.viewItems.every(item => item.isDocumentation)) { this.currSelectedItem = 0; } else { this.focusedEnabledItem = 0; @@ -340,7 +340,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { protected focusPrevious() { if (typeof this.focusedEnabledItem === 'undefined') { this.focusedEnabledItem = this.viewItems[0].index; - } else if (this.viewItems.length < 1 || (this.viewItems.length === 1 && !this.viewItems[0].isDocumentation)) { + } else if (this.viewItems.length < 1) { return false; } @@ -363,7 +363,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { protected focusNext() { if (typeof this.focusedEnabledItem === 'undefined') { this.focusedEnabledItem = this.viewItems.length - 1; - } else if (this.viewItems.length < 1 || (this.viewItems.length === 1 && !this.viewItems[0].isDocumentation)) { + } else if (this.viewItems.length < 1) { return false; } From 181df9e79298a6da0b955967295ba840de2fdaf2 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Tue, 26 Jul 2022 16:25:13 -0700 Subject: [PATCH 014/303] added global ID for documentation --- src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts index 8ce748081a0..dc1a9a5031b 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts @@ -165,6 +165,8 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { private hasSeperator: boolean = false; private block?: HTMLElement; + public static readonly documentationID: string = '_documentation'; + public static readonly ID: string = 'editor.contrib.codeActionMenu'; public static get(editor: ICodeEditor): CodeActionMenu | null { @@ -277,7 +279,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { const currIsSeparator = item.class === 'separator'; let isDocumentation = false; if (item instanceof CodeActionAction) { - isDocumentation = item.action.kind === '_documentation'; + isDocumentation = item.action.kind === CodeActionMenu.documentationID; } if (currIsSeparator) { @@ -511,7 +513,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { result.push(new Separator(), ...allDocumentation.map(command => toCodeActionAction(new CodeActionItem({ title: command.title, command: command, - kind: '_documentation' + kind: CodeActionMenu.documentationID }, undefined)))); } From a4b7d52ba133ad5fff17dc77602d540151a75a78 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 27 Jul 2022 14:18:15 +0200 Subject: [PATCH 015/303] Only adjust changes when bracket pairs are completed. --- .../inlineCompletions/browser/inlineCompletionsModel.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts index bb49228f345..02104cfe890 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts @@ -724,12 +724,12 @@ export async function provideInlineCompletions( model, languageConfigurationService ); - } - // Modify range depending on if brackets are added or removed - if (insertText.length !== item.insertText.length) { + // Modify range depending on if brackets are added or removed const diff = insertText.length - item.insertText.length; - range = new Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn + diff); + if (diff !== 0) { + range = new Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn + diff); + } } snippetInfo = undefined; From ff3a45d5be9dc9757b24e701d61b390e37fad865 Mon Sep 17 00:00:00 2001 From: aiday-mar Date: Wed, 27 Jul 2022 14:49:17 +0200 Subject: [PATCH 016/303] Calls onDidChangeModelTokens and updates when the range of update intersects with the line range of the sticky scroll widget --- .../contrib/stickyScroll/browser/stickyScroll.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index 7d9cbf358ed..183314bb276 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -17,6 +17,7 @@ import { RenderLineInput, renderViewLine } from 'vs/editor/common/viewLayout/vie import { SymbolKind } from 'vs/editor/common/languages'; import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations'; import { RunOnceScheduler } from 'vs/base/common/async'; +import { IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; const enum ScrollDirection { Down = 0, @@ -66,12 +67,24 @@ class StickyScrollController extends Disposable implements IEditorContribution { this._editor.addOverlayWidget(this.stickyScrollWidget); this._sessionStore.add(this._editor.onDidChangeModel(() => this._update(true))); this._sessionStore.add(this._editor.onDidScrollChange(() => this._update(false))); + this._sessionStore.add(this._editor.onDidChangeModelTokens((e) => this._onTokensChange(e))); this._sessionStore.add(this._editor.onDidChangeModelContent(() => this._updateSoon.schedule())); this._sessionStore.add(this._languageFeaturesService.documentSymbolProvider.onDidChange(() => this._update(true))); this._update(true); } } + private _onTokensChange(event: IModelTokensChangedEvent) { + const beginningLine = this._editor.getVisibleRanges()[0].getStartPosition().lineNumber - 1; + const endLine = beginningLine + this.stickyScrollWidget.codeLineCount + 1; + const fromLineNumber = event.ranges[0].fromLineNumber; + const toLineNumber = event.ranges[0].toLineNumber; + if (fromLineNumber > endLine || beginningLine > toLineNumber) { + return; + } + this._update(false); + } + private async _update(updateOutline: boolean = false): Promise { if (updateOutline) { this._cts?.dispose(true); From 241c77020385e27ead8398ae02a9aed2ee7fd160 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Jul 2022 06:32:07 -0700 Subject: [PATCH 017/303] Exclude esbuild files from build (#156362) --- extensions/ipynb/.vscodeignore | 2 +- extensions/markdown-language-features/.vscodeignore | 3 ++- extensions/simple-browser/.vscodeignore | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/extensions/ipynb/.vscodeignore b/extensions/ipynb/.vscodeignore index 08245c01482..f45314d0c1e 100644 --- a/extensions/ipynb/.vscodeignore +++ b/extensions/ipynb/.vscodeignore @@ -6,4 +6,4 @@ extension.webpack.config.js extension-browser.webpack.config.js yarn.lock .gitignore - +esbuild.js diff --git a/extensions/markdown-language-features/.vscodeignore b/extensions/markdown-language-features/.vscodeignore index 1046b7ec26b..fa12077f015 100644 --- a/extensions/markdown-language-features/.vscodeignore +++ b/extensions/markdown-language-features/.vscodeignore @@ -12,7 +12,8 @@ cgmanifest.json yarn.lock preview-src/** webpack.config.js -esbuild.js +esbuild-notebook.js +esbuild-preview.js .gitignore server/src/** server/extension.webpack.config.js diff --git a/extensions/simple-browser/.vscodeignore b/extensions/simple-browser/.vscodeignore index ec298ce1768..d1006b25b79 100644 --- a/extensions/simple-browser/.vscodeignore +++ b/extensions/simple-browser/.vscodeignore @@ -11,3 +11,4 @@ cgmanifest.json yarn.lock preview-src/** webpack.config.js +esbuild-preview.js From 079c49ed1277fc42d8a49823dc6fbab473223503 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 27 Jul 2022 15:32:53 +0200 Subject: [PATCH 018/303] fix the printed installed extension version (#156422) --- .../common/extensionManagementCLIService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/extensionManagementCLIService.ts b/src/vs/platform/extensionManagement/common/extensionManagementCLIService.ts index b36b6ea904d..65b2cea1af6 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementCLIService.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementCLIService.ts @@ -223,8 +223,8 @@ export class ExtensionManagementCLIService implements IExtensionManagementCLISer output.log(version ? localize('installing with version', "Installing extension '{0}' v{1}...", id, version) : localize('installing', "Installing extension '{0}'...", id)); } - await this.extensionManagementService.installFromGallery(galleryExtension, { ...installOptions, installGivenVersion: !!version }); - output.log(localize('successInstall', "Extension '{0}' v{1} was successfully installed.", id, galleryExtension.version)); + const local = await this.extensionManagementService.installFromGallery(galleryExtension, { ...installOptions, installGivenVersion: !!version }); + output.log(localize('successInstall', "Extension '{0}' v{1} was successfully installed.", id, local.manifest.version)); return manifest; } catch (error) { if (isCancellationError(error)) { From 2ad2cd4e718dd3b292cd423921bcccd371f2c4f0 Mon Sep 17 00:00:00 2001 From: aiday-mar Date: Wed, 27 Jul 2022 15:41:27 +0200 Subject: [PATCH 019/303] Iterating over all the ranges in the onDidChangeModelTokens function --- .../stickyScroll/browser/stickyScroll.ts | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index 183314bb276..0da33b17f98 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -75,14 +75,21 @@ class StickyScrollController extends Disposable implements IEditorContribution { } private _onTokensChange(event: IModelTokensChangedEvent) { - const beginningLine = this._editor.getVisibleRanges()[0].getStartPosition().lineNumber - 1; - const endLine = beginningLine + this.stickyScrollWidget.codeLineCount + 1; - const fromLineNumber = event.ranges[0].fromLineNumber; - const toLineNumber = event.ranges[0].toLineNumber; - if (fromLineNumber > endLine || beginningLine > toLineNumber) { - return; + const widgetLineRange = this.stickyScrollWidget.getCurrentLineRange(); + let rerender: boolean = false; + for (const range of event.ranges) { + const fromLineNumber = range.fromLineNumber; + const toLineNumber = range.toLineNumber; + const fromLineWidget = widgetLineRange[0]; + const toLineWidget = widgetLineRange[1]; + if (fromLineNumber <= toLineWidget && toLineNumber >= fromLineWidget) { + rerender = true; + break; + } + } + if (rerender === true) { + this._update(false); } - this._update(false); } private async _update(updateOutline: boolean = false): Promise { @@ -212,16 +219,16 @@ class StickyScrollController extends Disposable implements IEditorContribution { if (!beginningLinesConsidered.has(start)) { if (topOfElementAtDepth >= topOfEndLine - 1 && topOfElementAtDepth < bottomOfEndLine - 2) { beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth)); + this.stickyScrollWidget.pushCodeLine(start, new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth)); break; } else if (scrollDirection === ScrollDirection.Down && bottomOfElementAtDepth > bottomOfBeginningLine - 1 && bottomOfElementAtDepth < bottomOfEndLine - 1) { beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, 0, 0)); + this.stickyScrollWidget.pushCodeLine(start, new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, 0, 0)); } else if (scrollDirection === ScrollDirection.Up && scrollToBottomOfWidget > bottomOfBeginningLine - 1 && scrollToBottomOfWidget < bottomOfEndLine || scrollDirection === ScrollDirection.Up && bottomOfElementAtDepth > bottomOfBeginningLine && bottomOfElementAtDepth < topOfEndLine - 1) { beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, 0, 0)); + this.stickyScrollWidget.pushCodeLine(start, new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, 0, 0)); } } else { this._ranges.splice(index, 1); @@ -348,6 +355,7 @@ class StickyScrollCodeLine { class StickyScrollWidget implements IOverlayWidget { private readonly arrayOfCodeLines: StickyScrollCodeLine[] = []; + private readonly linesRange: number[] = []; private readonly rootDomNode: HTMLElement = document.createElement('div'); constructor(public readonly _editor: ICodeEditor) { @@ -360,7 +368,15 @@ class StickyScrollWidget implements IOverlayWidget { return this.arrayOfCodeLines.length; } - pushCodeLine(codeLine: StickyScrollCodeLine) { + getCurrentLineRange(): number[] { + const widgetLineRange = []; + widgetLineRange.push(this.linesRange[0]); + widgetLineRange.push(this.linesRange[this.linesRange.length - 1]); + return widgetLineRange; + } + + pushCodeLine(codeLineNumber: number, codeLine: StickyScrollCodeLine) { + this.linesRange.push(codeLineNumber); this.arrayOfCodeLines.push(codeLine); } From 878271b95f78398ca807a70e5f8ae888977494f6 Mon Sep 17 00:00:00 2001 From: aiday-mar Date: Wed, 27 Jul 2022 16:10:41 +0200 Subject: [PATCH 020/303] Updates model only if a sticky line is contained in a range of the model token change event --- .../stickyScroll/browser/stickyScroll.ts | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index 0da33b17f98..002828096d5 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -74,20 +74,20 @@ class StickyScrollController extends Disposable implements IEditorContribution { } } - private _onTokensChange(event: IModelTokensChangedEvent) { - const widgetLineRange = this.stickyScrollWidget.getCurrentLineRange(); - let rerender: boolean = false; - for (const range of event.ranges) { - const fromLineNumber = range.fromLineNumber; - const toLineNumber = range.toLineNumber; - const fromLineWidget = widgetLineRange[0]; - const toLineWidget = widgetLineRange[1]; - if (fromLineNumber <= toLineWidget && toLineNumber >= fromLineWidget) { - rerender = true; - break; + private _needsUpdate(event: IModelTokensChangedEvent) { + const stickyLineNumbers = this.stickyScrollWidget.getCurrentLines(); + for (const stickyLineNumber of stickyLineNumbers) { + for (const range of event.ranges) { + if (stickyLineNumber >= range.fromLineNumber && stickyLineNumber <= range.toLineNumber) { + return true; + } } } - if (rerender === true) { + return false; + } + + private _onTokensChange(event: IModelTokensChangedEvent) { + if (this._needsUpdate(event)) { this._update(false); } } @@ -219,16 +219,16 @@ class StickyScrollController extends Disposable implements IEditorContribution { if (!beginningLinesConsidered.has(start)) { if (topOfElementAtDepth >= topOfEndLine - 1 && topOfElementAtDepth < bottomOfEndLine - 2) { beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(start, new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth)); + this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth)); break; } else if (scrollDirection === ScrollDirection.Down && bottomOfElementAtDepth > bottomOfBeginningLine - 1 && bottomOfElementAtDepth < bottomOfEndLine - 1) { beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(start, new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, 0, 0)); + this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, 0, 0)); } else if (scrollDirection === ScrollDirection.Up && scrollToBottomOfWidget > bottomOfBeginningLine - 1 && scrollToBottomOfWidget < bottomOfEndLine || scrollDirection === ScrollDirection.Up && bottomOfElementAtDepth > bottomOfBeginningLine && bottomOfElementAtDepth < topOfEndLine - 1) { beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(start, new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, 0, 0)); + this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, 0, 0)); } } else { this._ranges.splice(index, 1); @@ -255,6 +255,10 @@ class StickyScrollCodeLine { this.effectiveLineHeight = this._editor.getOption(EditorOption.lineHeight) + this._relativePosition; } + get lineNumber() { + return this._lineNumber; + } + getDomNode() { const root: HTMLElement = document.createElement('div'); @@ -355,7 +359,6 @@ class StickyScrollCodeLine { class StickyScrollWidget implements IOverlayWidget { private readonly arrayOfCodeLines: StickyScrollCodeLine[] = []; - private readonly linesRange: number[] = []; private readonly rootDomNode: HTMLElement = document.createElement('div'); constructor(public readonly _editor: ICodeEditor) { @@ -368,15 +371,15 @@ class StickyScrollWidget implements IOverlayWidget { return this.arrayOfCodeLines.length; } - getCurrentLineRange(): number[] { - const widgetLineRange = []; - widgetLineRange.push(this.linesRange[0]); - widgetLineRange.push(this.linesRange[this.linesRange.length - 1]); + getCurrentLines(): number[] { + const widgetLineRange: number[] = []; + for (const codeLine of this.arrayOfCodeLines) { + widgetLineRange.push(codeLine.lineNumber); + } return widgetLineRange; } - pushCodeLine(codeLineNumber: number, codeLine: StickyScrollCodeLine) { - this.linesRange.push(codeLineNumber); + pushCodeLine(codeLine: StickyScrollCodeLine) { this.arrayOfCodeLines.push(codeLine); } From a3b712e04e4e35ae3bd10676e219ba2b82c95fb7 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 27 Jul 2022 16:55:08 +0200 Subject: [PATCH 021/303] Create a `insiders.vscode.dev` link when I use insiders for sharing (#156436) Fixes #156255 --- extensions/github/src/commands.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/extensions/github/src/commands.ts b/extensions/github/src/commands.ts index 40a6927146d..af3484580fd 100644 --- a/extensions/github/src/commands.ts +++ b/extensions/github/src/commands.ts @@ -9,9 +9,13 @@ import { publishRepository } from './publish'; import { DisposableStore } from './util'; import { getPermalink } from './links'; +function getVscodeDevHost(): string { + return `https://${vscode.env.appName.toLowerCase().includes('insiders') ? 'insiders.' : ''}vscode.dev/github`; +} + async function copyVscodeDevLink(gitAPI: GitAPI, useSelection: boolean) { try { - const permalink = getPermalink(gitAPI, useSelection, 'https://vscode.dev/github'); + const permalink = getPermalink(gitAPI, useSelection, getVscodeDevHost()); if (permalink) { return vscode.env.clipboard.writeText(permalink); } @@ -22,7 +26,7 @@ async function copyVscodeDevLink(gitAPI: GitAPI, useSelection: boolean) { async function openVscodeDevLink(gitAPI: GitAPI): Promise { try { - const permalink = getPermalink(gitAPI, true, 'https://vscode.dev/github'); + const permalink = getPermalink(gitAPI, true, getVscodeDevHost()); return permalink ? vscode.Uri.parse(permalink) : undefined; } catch (err) { vscode.window.showErrorMessage(err.message); From e572968d23fa5c80d407bac507143a6f60e2c0f8 Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Wed, 27 Jul 2022 17:10:06 +0200 Subject: [PATCH 022/303] Retry up to 5 times the initial authority resolving and also retry up to 5 times the initial connection (#156444) Fixes #127565: Retry up to 5 times the initial authority resolving and retry up to 5 times the initial connection --- .../remote/common/remoteAgentConnection.ts | 60 ++++++++++++------- .../electronExtensionService.ts | 33 ++++++++-- 2 files changed, 66 insertions(+), 27 deletions(-) diff --git a/src/vs/platform/remote/common/remoteAgentConnection.ts b/src/vs/platform/remote/common/remoteAgentConnection.ts index 2335efbde29..fde30c2d8a6 100644 --- a/src/vs/platform/remote/common/remoteAgentConnection.ts +++ b/src/vs/platform/remote/common/remoteAgentConnection.ts @@ -417,30 +417,48 @@ export interface IAddressProvider { } export async function connectRemoteAgentManagement(options: IConnectionOptions, remoteAuthority: string, clientId: string): Promise { - try { - const reconnectionToken = generateUuid(); - const simpleOptions = await resolveConnectionOptions(options, reconnectionToken, null); - const { protocol } = await doConnectRemoteAgentManagement(simpleOptions, CancellationToken.None); - return new ManagementPersistentConnection(options, remoteAuthority, clientId, reconnectionToken, protocol); - } catch (err) { - options.logService.error(`[remote-connection] An error occurred in the very first connect attempt, it will be treated as a permanent error! Error:`); - options.logService.error(err); - PersistentConnection.triggerPermanentFailure(0, 0, RemoteAuthorityResolverError.isHandled(err)); - throw err; - } + return createInitialConnection( + options, + async (simpleOptions) => { + const { protocol } = await doConnectRemoteAgentManagement(simpleOptions, CancellationToken.None); + return new ManagementPersistentConnection(options, remoteAuthority, clientId, simpleOptions.reconnectionToken, protocol); + } + ); } export async function connectRemoteAgentExtensionHost(options: IConnectionOptions, startArguments: IRemoteExtensionHostStartParams): Promise { - try { - const reconnectionToken = generateUuid(); - const simpleOptions = await resolveConnectionOptions(options, reconnectionToken, null); - const { protocol, debugPort } = await doConnectRemoteAgentExtensionHost(simpleOptions, startArguments, CancellationToken.None); - return new ExtensionHostPersistentConnection(options, startArguments, reconnectionToken, protocol, debugPort); - } catch (err) { - options.logService.error(`[remote-connection] An error occurred in the very first connect attempt, it will be treated as a permanent error! Error:`); - options.logService.error(err); - PersistentConnection.triggerPermanentFailure(0, 0, RemoteAuthorityResolverError.isHandled(err)); - throw err; + return createInitialConnection( + options, + async (simpleOptions) => { + const { protocol, debugPort } = await doConnectRemoteAgentExtensionHost(simpleOptions, startArguments, CancellationToken.None); + return new ExtensionHostPersistentConnection(options, startArguments, simpleOptions.reconnectionToken, protocol, debugPort); + } + ); +} + +/** + * Will attempt to connect 5 times. If it fails 5 consecutive times, it will give up. + */ +async function createInitialConnection(options: IConnectionOptions, connectionFactory: (simpleOptions: ISimpleConnectionOptions) => Promise): Promise { + const MAX_ATTEMPTS = 5; + + for (let attempt = 1; ; attempt++) { + try { + const reconnectionToken = generateUuid(); + const simpleOptions = await resolveConnectionOptions(options, reconnectionToken, null); + const result = await connectionFactory(simpleOptions); + return result; + } catch (err) { + if (attempt < MAX_ATTEMPTS) { + options.logService.error(`[remote-connection][attempt ${attempt}] An error occurred in initial connection! Will retry... Error:`); + options.logService.error(err); + } else { + options.logService.error(`[remote-connection][attempt ${attempt}] An error occurred in initial connection! It will be treated as a permanent error. Error:`); + options.logService.error(err); + PersistentConnection.triggerPermanentFailure(0, 0, RemoteAuthorityResolverError.isHandled(err)); + throw err; + } + } } } diff --git a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts index 34cb13522aa..ee051e3d1f1 100644 --- a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts +++ b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts @@ -413,6 +413,32 @@ export abstract class ElectronExtensionService extends AbstractExtensionService throw new Error(`Cannot get canonical URI because no extension is installed to resolve ${getRemoteAuthorityPrefix(remoteAuthority)}`); } + private async _resolveAuthorityInitial(remoteAuthority: string): Promise { + const MAX_ATTEMPTS = 5; + + for (let attempt = 1; ; attempt++) { + const sw = StopWatch.create(false); + this._logService.info(`[attempt ${attempt}] Invoking resolveAuthority(${getRemoteAuthorityPrefix(remoteAuthority)})`); + try { + const resolverResult = await this._resolveAuthority(remoteAuthority); + this._logService.info(`[attempt ${attempt}] resolveAuthority(${getRemoteAuthorityPrefix(remoteAuthority)}) returned '${resolverResult.authority.host}:${resolverResult.authority.port}' after ${sw.elapsed()} ms`); + return resolverResult; + } catch (err) { + this._logService.error(`[attempt ${attempt}] resolveAuthority(${getRemoteAuthorityPrefix(remoteAuthority)}) returned an error after ${sw.elapsed()} ms`, err); + + if (RemoteAuthorityResolverError.isNoResolverFound(err)) { + // There is no point in retrying if there is no resolver found + throw err; + } + + if (attempt >= MAX_ATTEMPTS) { + // Too many failed attempts, give up + throw err; + } + } + } + } + private async _resolveAuthorityAgain(): Promise { const remoteAuthority = this._environmentService.remoteAuthority; if (!remoteAuthority) { @@ -473,14 +499,9 @@ export abstract class ElectronExtensionService extends AbstractExtensionService } let resolverResult: ResolverResult; - - const sw = StopWatch.create(false); - this._logService.info(`Invoking resolveAuthority(${getRemoteAuthorityPrefix(remoteAuthority)})`); try { - resolverResult = await this._resolveAuthority(remoteAuthority); - this._logService.info(`resolveAuthority(${getRemoteAuthorityPrefix(remoteAuthority)}) returned '${resolverResult.authority.host}:${resolverResult.authority.port}' after ${sw.elapsed()} ms`); + resolverResult = await this._resolveAuthorityInitial(remoteAuthority); } catch (err) { - this._logService.error(`resolveAuthority(${getRemoteAuthorityPrefix(remoteAuthority)}) returned an error after ${sw.elapsed()} ms`, err); if (RemoteAuthorityResolverError.isNoResolverFound(err)) { err.isHandled = await this._handleNoResolverFound(remoteAuthority); } else { From 18fb2dde5d56a464b39f7b93e40dd5e2f38fc74a Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Wed, 27 Jul 2022 08:38:12 -0700 Subject: [PATCH 023/303] Set initial debug session pick and edit pick prompt (#156387) Initially selected session/console in the quickpick should match the currently selected one Fixes #156310 --- .../debug/browser/debugSessionPicker.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugSessionPicker.ts b/src/vs/workbench/contrib/debug/browser/debugSessionPicker.ts index 98dfb2e82f5..9e3b5b7efff 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSessionPicker.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSessionPicker.ts @@ -24,11 +24,14 @@ export async function showDebugSessionMenu(accessor: ServicesAccessor, selectAnd const quickPick = quickInputService.createQuickPick(); localDisposableStore.add(quickPick); quickPick.matchOnLabel = quickPick.matchOnDescription = quickPick.matchOnDetail = quickPick.sortByLabel = false; - quickPick.placeholder = nls.localize('moveFocusedView.selectView', 'Search for debug session by name'); - quickPick.items = _getPicks(quickPick.value, selectAndStartID, debugService, viewsService, commandService); + quickPick.placeholder = nls.localize('moveFocusedView.selectView', 'Search debug sessions by name'); + + const pickItems = _getPicksAndActiveItem(quickPick.value, selectAndStartID, debugService, viewsService, commandService); + quickPick.items = pickItems.picks; + quickPick.activeItems = pickItems.activeItems; localDisposableStore.add(quickPick.onDidChangeValue(async () => { - quickPick.items = _getPicks(quickPick.value, selectAndStartID, debugService, viewsService, commandService); + quickPick.items = _getPicksAndActiveItem(quickPick.value, selectAndStartID, debugService, viewsService, commandService).picks; })); localDisposableStore.add(quickPick.onDidAccept(() => { const selectedItem = quickPick.selectedItems[0]; @@ -39,11 +42,13 @@ export async function showDebugSessionMenu(accessor: ServicesAccessor, selectAnd quickPick.show(); } -function _getPicks(filter: string, selectAndStartID: string, debugService: IDebugService, viewsService: IViewsService, commandService: ICommandService): Array { +function _getPicksAndActiveItem(filter: string, selectAndStartID: string, debugService: IDebugService, viewsService: IViewsService, commandService: ICommandService): { picks: Array; activeItems: Array } { const debugConsolePicks: Array = []; const headerSessions: IDebugSession[] = []; + const currSession = debugService.getViewModel().focusedSession; const sessions = debugService.getModel().getSessions(false); + const activeItems: Array = []; sessions.forEach((session) => { if (session.compact && session.parentSession) { @@ -61,6 +66,9 @@ function _getPicks(filter: string, selectAndStartID: string, debugService: IDebu const pick = _createPick(session, filter, debugService, viewsService, commandService); if (pick) { debugConsolePicks.push(pick); + if (session.getId() === currSession?.getId()) { + activeItems.push(pick); + } } } }); @@ -76,7 +84,7 @@ function _getPicks(filter: string, selectAndStartID: string, debugService: IDebu accept: () => commandService.executeCommand(selectAndStartID) }); - return debugConsolePicks; + return { picks: debugConsolePicks, activeItems }; } From 4474dab2fa8dcc12ece25e27b6422d3963e70fd6 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 27 Jul 2022 17:40:15 +0200 Subject: [PATCH 024/303] Fix #156369 (#156433) --- src/vs/workbench/browser/web.main.ts | 5 +++++ .../relauncher/browser/relauncher.contribution.ts | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index a307a64ec7e..02ea6a2b6cb 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -295,6 +295,11 @@ export class BrowserMain extends Disposable { ]); userDataProfilesService.setEnablement(!!configurationService.getValue(PROFILES_ENABLEMENT_CONFIG)); + this._register(configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(PROFILES_ENABLEMENT_CONFIG)) { + userDataProfilesService.setEnablement(!!configurationService.getValue(PROFILES_ENABLEMENT_CONFIG)); + } + })); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // diff --git a/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts b/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts index 1680881aeb1..2f96395016a 100644 --- a/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts +++ b/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts @@ -102,12 +102,6 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo changed = true; } - // Profiles - if (typeof config.workbench?.experimental?.settingsProfiles?.enabled === 'boolean' && config.workbench.experimental.settingsProfiles.enabled !== this.settingsProfilesEnabled) { - this.settingsProfilesEnabled = config.workbench.experimental.settingsProfiles.enabled; - changed = true; - } - // On linux turning on accessibility support will also pass this flag to the chrome renderer, thus a restart is required if (isLinux && typeof config.editor?.accessibilitySupport === 'string' && config.editor.accessibilitySupport !== this.accessibilitySupport) { this.accessibilitySupport = config.editor.accessibilitySupport; @@ -123,6 +117,12 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo } } + // Profiles + if (typeof config.workbench?.experimental?.settingsProfiles?.enabled === 'boolean' && config.workbench.experimental.settingsProfiles.enabled !== this.settingsProfilesEnabled) { + this.settingsProfilesEnabled = config.workbench.experimental.settingsProfiles.enabled; + changed = true; + } + // Notify only when changed and we are the focused window (avoids notification spam across windows) if (notify && changed) { this.doConfirm( From c6990190a4a670a32d89d1f7cf5f21a9a1af8e2a Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 27 Jul 2022 17:50:38 +0200 Subject: [PATCH 025/303] Fixes https://github.com/microsoft/monaco-editor/issues/3070 (#156449) --- src/vs/editor/common/config/editorOptions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 943a8b7e018..b50d0d0e112 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -880,7 +880,7 @@ function applyUpdate(value: T | undefined, update: T): ApplyUpdateResult { } if (Array.isArray(value) || Array.isArray(update)) { const arrayEquals = Array.isArray(value) && Array.isArray(update) && arrays.equals(value, update); - return new ApplyUpdateResult(update, arrayEquals); + return new ApplyUpdateResult(update, !arrayEquals); } let didChange = false; for (const key in update) { From 482da8664a8e28e86439bd6eb9a8c743b9997ada Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 27 Jul 2022 17:53:47 +0200 Subject: [PATCH 026/303] Re-Enables bracket pair matching/colorization for monarch (#156450) --- src/vs/editor/common/languages/supports/tokenization.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/editor/common/languages/supports/tokenization.ts b/src/vs/editor/common/languages/supports/tokenization.ts index 7fa14b20a5c..19d637e2e2e 100644 --- a/src/vs/editor/common/languages/supports/tokenization.ts +++ b/src/vs/editor/common/languages/supports/tokenization.ts @@ -230,10 +230,12 @@ export class TokenTheme { if (typeof result === 'undefined') { const rule = this._match(token); const standardToken = toStandardTokenType(token); + result = ( rule.metadata | (standardToken << MetadataConsts.TOKEN_TYPE_OFFSET) ) >>> 0; + result |= MetadataConsts.BALANCED_BRACKETS_MASK; this._cache.set(token, result); } From 2e697a4a5f32c382e1e91d8715db0b19c5f62afd Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 27 Jul 2022 17:58:32 +0200 Subject: [PATCH 027/303] Revert "Re-Enables bracket pair matching/colorization for monarch (#156450)" This reverts commit 482da8664a8e28e86439bd6eb9a8c743b9997ada. --- src/vs/editor/common/languages/supports/tokenization.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/editor/common/languages/supports/tokenization.ts b/src/vs/editor/common/languages/supports/tokenization.ts index 19d637e2e2e..7fa14b20a5c 100644 --- a/src/vs/editor/common/languages/supports/tokenization.ts +++ b/src/vs/editor/common/languages/supports/tokenization.ts @@ -230,12 +230,10 @@ export class TokenTheme { if (typeof result === 'undefined') { const rule = this._match(token); const standardToken = toStandardTokenType(token); - result = ( rule.metadata | (standardToken << MetadataConsts.TOKEN_TYPE_OFFSET) ) >>> 0; - result |= MetadataConsts.BALANCED_BRACKETS_MASK; this._cache.set(token, result); } From 43bce132f90421f58e8b83e6cbdc708bf9feffd3 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 27 Jul 2022 08:58:49 -0700 Subject: [PATCH 028/303] fix shell integration link (#156455) --- .../workbench/contrib/terminal/browser/xterm/decorationAddon.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts index 964be5b8eb5..54373968a49 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts @@ -442,7 +442,7 @@ export class DecorationAddon extends Disposable implements ITerminalAddon { const labelAbout = localize("terminal.learnShellIntegration", 'Learn About Shell Integration'); actions.push({ class: undefined, tooltip: labelAbout, dispose: () => { }, id: 'terminal.learnShellIntegration', label: labelAbout, enabled: true, - run: () => this._openerService.open('https://code.visualstudio.com/docs/editor/integrated-terminal#_shell-integration') + run: () => this._openerService.open('https://code.visualstudio.com/docs/terminal/shell-integration') }); return actions; } From 3cd638046c65a47a604ad995954b5fdda29ccce6 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 27 Jul 2022 18:05:02 +0200 Subject: [PATCH 029/303] Quick Diff editor gutter decoration hidden by comment gutter icon (diamond) (#156448) * Quick Diff editor gutter decoration hidden by comment gutter icon (diamond) Fixes #156264 * Update doc --- .../browser/commentsEditorContribution.ts | 22 +++++++++++++------ src/vscode-dts/vscode.d.ts | 2 +- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts index 41ed64d6d55..5f859a45b0a 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts @@ -664,6 +664,7 @@ export class CommentController implements IEditorContribution { const pendingCommentText = this._pendingCommentCache[e.owner] && this._pendingCommentCache[e.owner][thread.threadId!]; this.displayCommentThread(e.owner, thread, pendingCommentText); this._commentInfos.filter(info => info.owner === e.owner)[0].threads.push(thread); + this.tryUpdateReservedSpace(); }); this._commentThreadRangeDecorator.update(this.editor, commentInfo); })); @@ -841,15 +842,14 @@ export class CommentController implements IEditorContribution { return; } - private setComments(commentInfos: ICommentInfo[]): void { - if (!this.editor || !this.commentService.isCommentingEnabled) { - return; - } - - this._commentInfos = commentInfos; + private tryUpdateReservedSpace() { let lineDecorationsWidth: number = this.editor.getLayoutInfo().decorationsWidth; + const hasCommentsOrRanges = this._commentInfos.some(info => { + const hasRanges = Boolean(info.commentingRanges && (Array.isArray(info.commentingRanges) ? info.commentingRanges : info.commentingRanges.ranges).length); + return hasRanges || (info.threads.length > 0); + }); - if (this._commentInfos.some(info => Boolean(info.commentingRanges && (Array.isArray(info.commentingRanges) ? info.commentingRanges : info.commentingRanges.ranges).length))) { + if (hasCommentsOrRanges) { this._workspaceHasCommenting.set(true); if (!this._commentingRangeSpaceReserved) { this._commentingRangeSpaceReserved = true; @@ -879,7 +879,15 @@ export class CommentController implements IEditorContribution { }); } } + } + private setComments(commentInfos: ICommentInfo[]): void { + if (!this.editor || !this.commentService.isCommentingEnabled) { + return; + } + + this._commentInfos = commentInfos; + this.tryUpdateReservedSpace(); // create viewzones this.removeCommentWidgetsAndStoreCache(); diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index d0c64ae91ae..4938a81b628 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -15061,7 +15061,7 @@ declare module 'vscode' { /** * Optional commenting range provider. Provide a list {@link Range ranges} which support commenting to any given resource uri. * - * If not provided, users can leave comments in any document opened in the editor. + * If not provided, users cannot leave any comments. */ commentingRangeProvider?: CommentingRangeProvider; From ab836c829b6f73cc64fd78146d5c91e1f60924ac Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 27 Jul 2022 18:16:27 +0200 Subject: [PATCH 030/303] Fixes #153961 by checking if models are disposed. --- .../contrib/mergeEditor/browser/model/diffComputer.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts b/src/vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts index 06401136b7a..2f769dadd9b 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts @@ -24,6 +24,10 @@ export class EditorWorkerServiceDiffComputer implements IDiffComputer { async computeDiff(textModel1: ITextModel, textModel2: ITextModel): Promise { const diffs = await this.editorWorkerService.computeDiff(textModel1.uri, textModel2.uri, false, 1000); + if (textModel1.isDisposed() || textModel2.isDisposed()) { + // In the meantime, models could be disposed -> early return + return { diffs: null }; + } if (!diffs) { return { diffs: null }; } From e617076801f6716fee88418c8414984560bf0dd4 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Wed, 27 Jul 2022 09:34:22 -0700 Subject: [PATCH 031/303] added `ipynb/esbuild.js` to the media scripts when building extensions --- build/lib/extensions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 89aa014a0d6..ddcb25483fb 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -486,6 +486,7 @@ const esbuildMediaScripts = [ 'markdown-language-features/esbuild-preview.js', 'markdown-math/esbuild.js', 'notebook-renderers/esbuild.js', + 'ipynb/esbuild.js', 'simple-browser/esbuild-preview.js', ]; From 31266e21424152d9146f32ee74bc6a4bc6e91c0c Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 27 Jul 2022 18:34:26 +0200 Subject: [PATCH 032/303] Fixes #156180 by tweaking merge editor result shadow & gutter width (#156463) --- .../browser/view/editors/resultCodeEditorView.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts index e1557eb0c9a..844c64db291 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { CompareResult } from 'vs/base/common/arrays'; +import { BugIndicatingError } from 'vs/base/common/errors'; import { autorun, derived } from 'vs/base/common/observable'; import { IModelDeltaDecoration, MinimapPosition, OverviewRulerLane } from 'vs/editor/common/model'; import { localize } from 'vs/nls'; @@ -11,6 +12,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange'; import { applyObservableDecorations, join } from 'vs/workbench/contrib/mergeEditor/browser/utils'; import { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors'; +import { EditorGutter } from 'vs/workbench/contrib/mergeEditor/browser/view/editorGutter'; import { CodeEditorView } from './codeEditorView'; export class ResultCodeEditorView extends CodeEditorView { @@ -106,6 +108,14 @@ export class ResultCodeEditorView extends CodeEditorView { this._register(applyObservableDecorations(this.editor, this.decorations)); + this.htmlElements.gutterDiv.style.width = '5px'; + + this._register( + new EditorGutter(this.editor, this.htmlElements.gutterDiv, { + getIntersectingGutterItems: (range, reader) => [], + createView: (item, target) => { throw new BugIndicatingError(); }, + }) + ); this._register(autorun('update remainingConflicts label', reader => { const model = this.model.read(reader); From ed78fe5771e2406e1a928239ce2f065f521d4f31 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 27 Jul 2022 09:50:29 -0700 Subject: [PATCH 033/303] Hide Open in Local Folder on web --- .../contrib/editSessions/browser/editSessions.contribution.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts index 0602d52a480..8ff2bb4f106 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -46,6 +46,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { EditSessionsDataViews } from 'vs/workbench/contrib/editSessions/browser/editSessionsViews'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { EditSessionsContentProvider } from 'vs/workbench/contrib/editSessions/browser/editSessionsContentProvider'; +import { isNative } from 'vs/base/common/platform'; registerSingleton(IEditSessionsLogService, EditSessionsLogService); registerSingleton(IEditSessionsWorkbenchService, EditSessionsWorkbenchService); @@ -529,7 +530,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo private createPickItems(): ContinueEditSessionItem[] { const items = [...this.continueEditSessionOptions].filter((option) => option.when === undefined || this.contextKeyService.contextMatchesRules(option.when)); - if (getVirtualWorkspaceLocation(this.contextService.getWorkspace()) !== undefined) { + if (getVirtualWorkspaceLocation(this.contextService.getWorkspace()) !== undefined && isNative) { items.push(new ContinueEditSessionItem( localize('continueEditSessionItem.openInLocalFolder', 'Open In Local Folder'), openLocalFolderCommand.id, From 8e49136c91044737516f2491c4e39f6d48e544d2 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 27 Jul 2022 09:59:58 -0700 Subject: [PATCH 034/303] Account menu to sign out of edit sessions should be specific to edit sessions --- .../editSessions/browser/editSessionsWorkbenchService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts index d8dbac59900..36f51b145a0 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts @@ -355,7 +355,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes constructor() { super({ id: 'workbench.editSessions.actions.resetAuth', - title: localize('reset auth', 'Sign Out'), + title: localize('reset auth.v2', 'Sign Out of Edit Sessions'), category: EDIT_SESSION_SYNC_CATEGORY, precondition: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), menu: [{ From 04dd05c0ed64e5d57075788b69e29a713a359516 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 27 Jul 2022 10:03:53 -0700 Subject: [PATCH 035/303] Hide Continue Edit Session when not in a folder --- .../contrib/editSessions/browser/editSessions.contribution.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts index 8ff2bb4f106..06a991fd12d 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -47,6 +47,7 @@ import { EditSessionsDataViews } from 'vs/workbench/contrib/editSessions/browser import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { EditSessionsContentProvider } from 'vs/workbench/contrib/editSessions/browser/editSessionsContentProvider'; import { isNative } from 'vs/base/common/platform'; +import { WorkspaceFolderCountContext } from 'vs/workbench/common/contextkeys'; registerSingleton(IEditSessionsLogService, EditSessionsLogService); registerSingleton(IEditSessionsWorkbenchService, EditSessionsWorkbenchService); @@ -55,6 +56,7 @@ const continueEditSessionCommand: IAction2Options = { id: '_workbench.experimental.editSessions.actions.continueEditSession', title: { value: localize('continue edit session', "Continue Edit Session..."), original: 'Continue Edit Session...' }, category: EDIT_SESSION_SYNC_CATEGORY, + precondition: WorkspaceFolderCountContext.notEqualsTo('0'), f1: true }; const openLocalFolderCommand: IAction2Options = { From 6fccf5d16e2359f6dde9f772166c6ff2f04872f0 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Wed, 27 Jul 2022 10:09:41 -0700 Subject: [PATCH 036/303] "To" shouldn't be capitalized in the command "Go to Running Cell" (#156471) to should be capitalized in the command "Go to..." Fixes #156297 --- .../contrib/notebook/browser/controller/executeActions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/controller/executeActions.ts b/src/vs/workbench/contrib/notebook/browser/controller/executeActions.ts index 7b190d89c14..70d6930241c 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/executeActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/executeActions.ts @@ -544,8 +544,8 @@ registerAction2(class RevealRunningCellAction extends NotebookAction { constructor() { super({ id: REVEAL_RUNNING_CELL, - title: localize('revealRunningCell', "Go To Running Cell"), - tooltip: localize('revealRunningCell', "Go To Running Cell"), + title: localize('revealRunningCell', "Go to Running Cell"), + tooltip: localize('revealRunningCell', "Go to Running Cell"), shortTitle: localize('revealRunningCellShort', "Go To"), precondition: NOTEBOOK_HAS_RUNNING_CELL, menu: [ From bcba69611f62af31be86c7703caa8f5af003e9ab Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 27 Jul 2022 10:14:14 -0700 Subject: [PATCH 037/303] show all tasks when no tasks are found for given filter and go back is selected (#156458) fix #156286 --- src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 9df0e983136..3a0c564b42b 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -2828,6 +2828,10 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer taskQuickPick.dispose(); return; } else { + if (!!filter) { + // filter yielded no results, so show all + this._runTaskCommand(); + } return; } } else { From 3c0dba1c00ef7c7ae55078a5fc0d5b03319c29b9 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Wed, 27 Jul 2022 10:30:01 -0700 Subject: [PATCH 038/303] oh. had to run yarn compile from within the /build/ folder --- build/lib/extensions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 168cf8a5d00..808d817b815 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -399,6 +399,7 @@ const esbuildMediaScripts = [ 'markdown-language-features/esbuild-preview.js', 'markdown-math/esbuild.js', 'notebook-renderers/esbuild.js', + 'ipynb/esbuild.js', 'simple-browser/esbuild-preview.js', ]; async function webpackExtensions(taskName, isWatch, webpackConfigLocations) { From ead6a6f34feb4a2e566e39f367831c806f99c385 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Jul 2022 10:52:03 -0700 Subject: [PATCH 039/303] Revert "Temporarily comment out tuple type annotations (#156213)" (#156478) This reverts commit 8f10b21033161e235e9c14767c21efb550319848. --- src/vscode-dts/vscode.d.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index 4938a81b628..d421e29ec0a 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -6019,7 +6019,7 @@ declare module 'vscode' { * To get an instance of a `DiagnosticCollection` use * {@link languages.createDiagnosticCollection createDiagnosticCollection}. */ - export interface DiagnosticCollection extends Iterable<[/*uri:*/ Uri, /*diagnostics:*/ readonly Diagnostic[]]> { + export interface DiagnosticCollection extends Iterable<[uri: Uri, diagnostics: readonly Diagnostic[]]> { /** * The name of this diagnostic collection, for instance `typescript`. Every diagnostic @@ -10159,7 +10159,7 @@ declare module 'vscode' { * data transfer. These additional mime types will only be included in the `handleDrop` when the the drag was initiated from * an element in the same drag and drop controller. */ - export class DataTransfer implements Iterable<[/*mimeType:*/ string, /*item:*/ DataTransferItem]> { + export class DataTransfer implements Iterable<[mimeType: string, item: DataTransferItem]> { /** * Retrieves the data transfer item for a given mime type. * @@ -10189,7 +10189,7 @@ declare module 'vscode' { /** * Get a new iterator with the `[mime, item]` pairs for each element in this data transfer. */ - [Symbol.iterator](): IterableIterator<[/*mimeType:*/ string, /*item:*/ DataTransferItem]>; + [Symbol.iterator](): IterableIterator<[mimeType: string, item: DataTransferItem]>; } /** @@ -10858,7 +10858,7 @@ declare module 'vscode' { /** * A collection of mutations that an extension can apply to a process environment. */ - export interface EnvironmentVariableCollection extends Iterable<[/*variable:*/ string, /*mutator:*/ EnvironmentVariableMutator]> { + export interface EnvironmentVariableCollection extends Iterable<[variable: string, mutator: EnvironmentVariableMutator]> { /** * Whether the collection should be cached for the workspace and applied to the terminal * across window reloads. When true the collection will be active immediately such when the @@ -15737,7 +15737,7 @@ declare module 'vscode' { * Collection of test items, found in {@link TestItem.children} and * {@link TestController.items}. */ - export interface TestItemCollection extends Iterable<[/*id:*/ string, /*testItem:*/ TestItem]> { + export interface TestItemCollection extends Iterable<[id: string, testItem: TestItem]> { /** * Gets the number of items in the collection. */ From be910fd929b84234fa2100ea9b01b5b509c7cbc0 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Jul 2022 11:12:45 -0700 Subject: [PATCH 040/303] Use clearer parameter name (#156479) Fixes #156431 --- src/vscode-dts/vscode.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index d421e29ec0a..423ac8e7a4d 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -10184,7 +10184,7 @@ declare module 'vscode' { * @param callbackfn Callback for iteration through the data transfer items. * @param thisArg The `this` context used when invoking the handler function. */ - forEach(callbackfn: (value: DataTransferItem, key: string, dataTransfer: DataTransfer) => void, thisArg?: any): void; + forEach(callbackfn: (item: DataTransferItem, mimeType: string, dataTransfer: DataTransfer) => void, thisArg?: any): void; /** * Get a new iterator with the `[mime, item]` pairs for each element in this data transfer. From c8cf34a36f6ee3dcc5f75fdcc175e0346bf12b54 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 27 Jul 2022 20:13:13 +0200 Subject: [PATCH 041/303] Fixes #156037 by not highlighting non-conflicting changes. (#156482) --- .../view/editors/inputCodeEditorView.ts | 44 ++++++++++--------- .../view/editors/resultCodeEditorView.ts | 41 +++++++++-------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts index 14e739314c3..29e74d70adf 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts @@ -65,37 +65,39 @@ export class InputCodeEditorView extends CodeEditorView { position: MinimapPosition.Gutter, color: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor }, }, - overviewRuler: { + overviewRuler: modifiedBaseRange.isConflicting ? { position: OverviewRulerLane.Center, color: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor }, - } + } : undefined } }); - const inputDiffs = modifiedBaseRange.getInputDiffs(this.inputNumber); - for (const diff of inputDiffs) { - const range = diff.outputRange.toInclusiveRange(); - if (range) { - result.push({ - range, - options: { - className: `merge-editor-diff ${inputClassName}`, - description: 'Merge Editor', - isWholeLine: true, - } - }); - } - - if (diff.rangeMappings) { - for (const d of diff.rangeMappings) { + if (modifiedBaseRange.isConflicting) { + const inputDiffs = modifiedBaseRange.getInputDiffs(this.inputNumber); + for (const diff of inputDiffs) { + const range = diff.outputRange.toInclusiveRange(); + if (range) { result.push({ - range: d.outputRange, + range, options: { - className: `merge-editor-diff-word ${inputClassName}`, - description: 'Merge Editor' + className: `merge-editor-diff ${inputClassName}`, + description: 'Merge Editor', + isWholeLine: true, } }); } + + if (diff.rangeMappings) { + for (const d of diff.rangeMappings) { + result.push({ + range: d.outputRange, + options: { + className: `merge-editor-diff-word ${inputClassName}`, + description: 'Merge Editor' + } + }); + } + } } } } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts index 844c64db291..04ee5e94264 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts @@ -63,38 +63,41 @@ export class ResultCodeEditorView extends CodeEditorView { position: MinimapPosition.Gutter, color: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor }, }, - overviewRuler: { + overviewRuler: modifiedBaseRange.isConflicting ? { position: OverviewRulerLane.Center, color: { id: isHandled ? handledConflictMinimapOverViewRulerColor : unhandledConflictMinimapOverViewRulerColor }, - } + } : undefined } }); } } - for (const diff of m.rights) { - const range = diff.outputRange.toInclusiveRange(); - if (range) { - result.push({ - range, - options: { - className: `merge-editor-diff result`, - description: 'Merge Editor', - isWholeLine: true, - } - }); - } - if (diff.rangeMappings) { - for (const d of diff.rangeMappings) { + if (!modifiedBaseRange || modifiedBaseRange.isConflicting) { + for (const diff of m.rights) { + const range = diff.outputRange.toInclusiveRange(); + if (range) { result.push({ - range: d.outputRange, + range, options: { - className: `merge-editor-diff-word result`, - description: 'Merge Editor' + className: `merge-editor-diff result`, + description: 'Merge Editor', + isWholeLine: true, } }); } + + if (diff.rangeMappings) { + for (const d of diff.rangeMappings) { + result.push({ + range: d.outputRange, + options: { + className: `merge-editor-diff-word result`, + description: 'Merge Editor' + } + }); + } + } } } } From 93340ffab96937ef7b0f49822ccec067cef0c16e Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Jul 2022 11:14:27 -0700 Subject: [PATCH 042/303] Log when encountering invalid json in vscode-context (#156485) Fixes #156416 --- .../contrib/webview/browser/pre/index-no-csp.html | 6 ++++-- src/vs/workbench/contrib/webview/browser/pre/index.html | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html b/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html index 8bba582ed17..d0ce103adc8 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html +++ b/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html @@ -1070,8 +1070,10 @@ } try { - context = { ...JSON.parse(el.getAttribute('data-vscode-context')), ...context }; - } catch {} + context = { ...JSON.parse(el.dataset.vscodeContext), ...context }; + } catch (e) { + console.error(`Error parsing 'data-vscode-context' as json`, el, e) + } el = el.parentElement; } diff --git a/src/vs/workbench/contrib/webview/browser/pre/index.html b/src/vs/workbench/contrib/webview/browser/pre/index.html index 52276ac415c..6c00e8b5da2 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/index.html +++ b/src/vs/workbench/contrib/webview/browser/pre/index.html @@ -5,7 +5,7 @@ + content="default-src 'none'; script-src 'sha256-JpX/ganPoxpavjxWCz9DUZgwVZ59o2lwSYTQrziPsdU=' 'self'; frame-src 'self'; style-src 'unsafe-inline';"> Date: Wed, 27 Jul 2022 20:27:47 +0200 Subject: [PATCH 043/303] devcontainer schema: handle deprecated properties (#156425) --- .../devContainer.codespaces.schema.json | 7 ++++++ .../schemas/devContainer.vscode.schema.json | 23 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/extensions/configuration-editing/schemas/devContainer.codespaces.schema.json b/extensions/configuration-editing/schemas/devContainer.codespaces.schema.json index 6186ccd86ac..d224f919109 100644 --- a/extensions/configuration-editing/schemas/devContainer.codespaces.schema.json +++ b/extensions/configuration-editing/schemas/devContainer.codespaces.schema.json @@ -177,6 +177,13 @@ } } } + }, + "codespaces": { + "type": "object", + "additionalProperties": true, + "description": "Codespaces-specific configuration.", + "deprecated": true, + "deprecationMessage": "Use 'customizations/codespaces' instead" } } } diff --git a/extensions/configuration-editing/schemas/devContainer.vscode.schema.json b/extensions/configuration-editing/schemas/devContainer.vscode.schema.json index 4eb7a2f62dc..e0f2a8aa68f 100644 --- a/extensions/configuration-editing/schemas/devContainer.vscode.schema.json +++ b/extensions/configuration-editing/schemas/devContainer.vscode.schema.json @@ -28,6 +28,29 @@ } } } + }, + "extensions": { + "type": "array", + "description": "An array of extensions that should be installed into the container.", + "items": { + "type": "string", + "pattern": "^([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)((@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)|@prerelease)?$", + "errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'." + }, + "deprecated": true, + "deprecationMessage": "Use 'customizations/vscode/extensions' instead" + }, + "settings": { + "$ref": "vscode://schemas/settings/machine", + "description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time, rebuilding the container then triggers it again.", + "deprecated": true, + "deprecationMessage": "Use 'customizations/vscode/settings' instead" + }, + "devPort": { + "type": "integer", + "description": "The port VS Code can use to connect to its backend.", + "deprecated": true, + "deprecationMessage": "Use 'customizations/vscode/devPort' instead" } } } From 9b44eda62a9ea9c6b9aa70f14edd7e876200dffa Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Wed, 27 Jul 2022 11:31:44 -0700 Subject: [PATCH 044/303] still allow system context menu in some cases (#156488) fixes #156222 --- .../platform/windows/electron-main/window.ts | 29 +++++++++++++++---- .../parts/titlebar/titlebarPart.ts | 17 +---------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts index fce751e1f2d..938c6eb7300 100644 --- a/src/vs/platform/windows/electron-main/window.ts +++ b/src/vs/platform/windows/electron-main/window.ts @@ -305,14 +305,33 @@ export class CodeWindow extends Disposable implements ICodeWindow { this._win.hookWindowMessage(WM_INITMENU, () => { const [x, y] = this._win.getPosition(); const cursorPos = screen.getCursorScreenPoint(); + const cx = cursorPos.x - x; + const cy = cursorPos.y - y; - // This is necessary to make sure the native system context menu does not show up. - this._win.setEnabled(false); - this._win.setEnabled(true); + // In some cases, show the default system context menu + // 1) The mouse position is not within the title bar + // 2) The mouse position is within the title bar, but over the app icon + // We do not know the exact title bar height but we make an estimate based on window height + const shouldTriggerDefaultSystemContextMenu = () => { + // Use the custom context menu when over the title bar, but not over the app icon + // The app icon is estimated to be 30px wide + // The title bar is estimated to be the max of 35px and 15% of the window height + if (cx > 30 && cy >= 0 && cy <= Math.max(this._win.getBounds().height * 0.15, 35)) { + return false; + } - this._onDidTriggerSystemContextMenu.fire({ x: cursorPos.x - x, y: cursorPos.y - y }); + return true; + }; - return 0; // skip native menu + if (!shouldTriggerDefaultSystemContextMenu()) { + // This is necessary to make sure the native system context menu does not show up. + this._win.setEnabled(false); + this._win.setEnabled(true); + + this._onDidTriggerSystemContextMenu.fire({ x: cx, y: cy }); + } + + return 0; }); } diff --git a/src/vs/workbench/electron-sandbox/parts/titlebar/titlebarPart.ts b/src/vs/workbench/electron-sandbox/parts/titlebar/titlebarPart.ts index f6f5b60e313..4720f73a32a 100644 --- a/src/vs/workbench/electron-sandbox/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/electron-sandbox/parts/titlebar/titlebarPart.ts @@ -207,22 +207,7 @@ export class TitlebarPart extends BrowserTitleBarPart { } const zoomFactor = getZoomFactor(); - const boundingRect = this.rootContainer.getBoundingClientRect(); - const eventPosition = { x, y }; - const relativeCoordinates = { x, y }; - // When comparing the coordinates with the title bar, account for zoom level if not using counter zoom. - if (!this.useCounterZoom) { - relativeCoordinates.x /= zoomFactor; - relativeCoordinates.y /= zoomFactor; - } - - // Don't trigger the menu if the click is not over the title bar - if (relativeCoordinates.x < boundingRect.left || relativeCoordinates.x > boundingRect.right || - relativeCoordinates.y < boundingRect.top || relativeCoordinates.y > boundingRect.bottom) { - return; - } - - this.onContextMenu(new MouseEvent('mouseup', { clientX: eventPosition.x / zoomFactor, clientY: eventPosition.y / zoomFactor }), MenuId.TitleBarContext); + this.onContextMenu(new MouseEvent('mouseup', { clientX: x / zoomFactor, clientY: y / zoomFactor }), MenuId.TitleBarContext); })); } From 9db76b0b15ac879d6bf6de68fb94c8ebf6331bc8 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 27 Jul 2022 11:47:58 -0700 Subject: [PATCH 045/303] Fix #156477. Interactive Window Restore (#156480) * Fix #156477. Interactive Window Restore * Fix #156487. Update description --- .../contrib/interactive/browser/interactive.contribution.ts | 6 +++--- .../contrib/interactive/browser/interactiveCommon.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index c6442b9ce9c..3db0fd13064 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -283,7 +283,7 @@ export class InteractiveEditorSerializer implements IEditorSerializer { } canSerialize(): boolean { - return this.configurationService.getValue(InteractiveWindowSetting.interactiveWindowHotExit); + return this.configurationService.getValue(InteractiveWindowSetting.interactiveWindowRestore); } serialize(input: EditorInput): string { @@ -763,10 +763,10 @@ Registry.as(ConfigurationExtensions.Configuration).regis default: true, markdownDescription: localize('interactiveWindow.alwaysScrollOnNewCell', "Automatically scroll the interactive window to show the output of the last statement executed. If this value is false, the window will only scroll if the last cell was already the one scrolled to.") }, - [InteractiveWindowSetting.interactiveWindowHotExit]: { + [InteractiveWindowSetting.interactiveWindowRestore]: { type: 'boolean', default: false, - markdownDescription: localize('interactiveWindow.hotExit', "Controls whether the interactive window sessions should be restored when the workspace reloads.") + markdownDescription: localize('interactiveWindow.restore', "Controls whether the Interactive Window sessions/history should be restored across window reloads. Whether the state of controllers used in Interactive Windows is persisted across window reloads are controlled by extensions contributing controllers.") } } }); diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveCommon.ts b/src/vs/workbench/contrib/interactive/browser/interactiveCommon.ts index edda5c7f25f..c98f2e6a7e0 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveCommon.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveCommon.ts @@ -9,5 +9,5 @@ export const INTERACTIVE_INPUT_CURSOR_BOUNDARY = new RawContextKey<'none' | 'top export const InteractiveWindowSetting = { interactiveWindowAlwaysScrollOnNewCell: 'interactiveWindow.alwaysScrollOnNewCell', - interactiveWindowHotExit: 'interactiveWindow.hotExit' + interactiveWindowRestore: 'interactiveWindow.restore' }; From 59afa0a8ee51352e7d1a26bfe1d6abf17d22b1dd Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 27 Jul 2022 20:53:49 +0200 Subject: [PATCH 046/303] Create and remove manual folding range use the same shortcut. (#156490) Create and remove manual folding range use the same shortcut. Fixes #156489 --- src/vs/editor/contrib/folding/browser/folding.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/folding/browser/folding.ts b/src/vs/editor/contrib/folding/browser/folding.ts index 279ab870eb5..6744508970d 100644 --- a/src/vs/editor/contrib/folding/browser/folding.ts +++ b/src/vs/editor/contrib/folding/browser/folding.ts @@ -1076,7 +1076,7 @@ class FoldRangeFromSelectionAction extends FoldingAction { precondition: CONTEXT_FOLDING_ENABLED, kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, - primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Period), + primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Comma), weight: KeybindingWeight.EditorContrib } }); From 00bb9bdefcfef4cb0ec92399e52dedee4b223ff7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Jul 2022 11:54:24 -0700 Subject: [PATCH 047/303] Always log tsserver exit code, even for kill processes (#156378) We suspect that some exit code info is being dropped since 1.61. Changing this code to always log, even when the user manually restarts the server --- .../src/typescriptServiceClient.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index b09593f6c59..4eec03b0471 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -430,13 +430,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType }); handle.onExit((data: TypeScriptServerExitEvent) => { - if (this.token !== mytoken) { - // this is coming from an old process - return; - } - const { code, signal } = data; - if (code === null || typeof code === 'undefined') { this.info(`TSServer exited. Signal: ${signal}`); } else { @@ -456,6 +450,11 @@ export default class TypeScriptServiceClient extends Disposable implements IType this.logTelemetry('tsserver.exitWithCode', { code, signal: signal ?? undefined }); } + if (this.token !== mytoken) { + // this is coming from an old process + return; + } + if (handle.tsServerLogFile) { this.info(`TSServer log file: ${handle.tsServerLogFile}`); } From 4aa9759988b08626cf8a34ceaa9519c9af3e8676 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Jul 2022 12:02:01 -0700 Subject: [PATCH 048/303] Fix webview providerId not being restored on reload (#156492) Fixes #156491 --- .../customEditor/browser/customEditorInput.ts | 16 +++++++++----- .../browser/customEditorInputFactory.ts | 4 ++-- .../browser/webviewEditorInput.ts | 22 +++++++++++++++---- .../browser/webviewEditorInputSerializer.ts | 4 ++++ .../browser/webviewWorkbenchService.ts | 12 +++++----- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts index 116c74df092..a514a41b857 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts @@ -24,6 +24,12 @@ import { IWebviewService, IOverlayWebview } from 'vs/workbench/contrib/webview/b import { IWebviewWorkbenchService, LazilyResolvedWebviewEditorInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService'; import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; +export interface CustomEditorInputInitInfo { + readonly resource: URI; + readonly viewType: string; + readonly id: string; +} + export class CustomEditorInput extends LazilyResolvedWebviewEditorInput { static create( @@ -45,7 +51,7 @@ export class CustomEditorInput extends LazilyResolvedWebviewEditorInput { contentOptions: {}, extension: undefined, }); - const input = instantiationService.createInstance(CustomEditorInput, resource, viewType, id, webview, { untitledDocumentData: untitledDocumentData, oldResource: options?.oldResource }); + const input = instantiationService.createInstance(CustomEditorInput, { resource, viewType, id }, webview, { untitledDocumentData: untitledDocumentData, oldResource: options?.oldResource }); if (typeof group !== 'undefined') { input.updateGroup(group); } @@ -68,9 +74,7 @@ export class CustomEditorInput extends LazilyResolvedWebviewEditorInput { private _modelRef?: IReference; constructor( - resource: URI, - viewType: string, - id: string, + init: CustomEditorInputInitInfo, webview: IOverlayWebview, options: { startsDirty?: boolean; backupId?: string; untitledDocumentData?: VSBuffer; readonly oldResource?: URI }, @IWebviewWorkbenchService webviewWorkbenchService: IWebviewWorkbenchService, @@ -81,8 +85,8 @@ export class CustomEditorInput extends LazilyResolvedWebviewEditorInput { @IUndoRedoService private readonly undoRedoService: IUndoRedoService, @IFileService private readonly fileService: IFileService ) { - super(id, viewType, '', webview, webviewWorkbenchService); - this._editorResource = resource; + super({ id: init.id, providedId: init.viewType, viewType: init.viewType, name: '' }, webview, webviewWorkbenchService); + this._editorResource = init.resource; this.oldResource = options.oldResource; this._defaultDirtyState = options.startsDirty; this._backupId = options.backupId; diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditorInputFactory.ts b/src/vs/workbench/contrib/customEditor/browser/customEditorInputFactory.ts index 9bc10254662..4277c67ab6a 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditorInputFactory.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditorInputFactory.ts @@ -100,7 +100,7 @@ export class CustomEditorInputSerializer extends WebviewEditorInputSerializer { } const webview = reviveWebview(this._webviewService, data); - const customInput = this._instantiationService.createInstance(CustomEditorInput, data.editorResource, data.viewType, data.id, webview, { startsDirty: data.dirty, backupId: data.backupId }); + const customInput = this._instantiationService.createInstance(CustomEditorInput, { resource: data.editorResource, viewType: data.viewType, id: data.id }, webview, { startsDirty: data.dirty, backupId: data.backupId }); if (typeof data.group === 'number') { customInput.updateGroup(data.group); } @@ -196,7 +196,7 @@ export class ComplexCustomWorkingCopyEditorHandler extends Disposable implements extension, }); - const editor = this._instantiationService.createInstance(CustomEditorInput, URI.revive(backupData.editorResource), backupData.viewType, id, webview, { backupId: backupData.backupId }); + const editor = this._instantiationService.createInstance(CustomEditorInput, { resource: URI.revive(backupData.editorResource), viewType: backupData.viewType, id }, webview, { backupId: backupData.backupId }); editor.updateGroup(0); return editor; } diff --git a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInput.ts b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInput.ts index 63e3f1cc124..5a4ac6b904c 100644 --- a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInput.ts +++ b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInput.ts @@ -10,6 +10,13 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { IOverlayWebview } from 'vs/workbench/contrib/webview/browser/webview'; import { WebviewIconManager, WebviewIcons } from 'vs/workbench/contrib/webviewPanel/browser/webviewIconManager'; +export interface WebviewInputInitInfo { + readonly id: string; + readonly viewType: string; + readonly providedId: string | undefined; + readonly name: string; +} + export class WebviewInput extends EditorInput { public static typeId = 'workbench.editors.webviewInput'; @@ -41,15 +48,22 @@ export class WebviewInput extends EditorInput { }); } + public readonly id: string; + public readonly viewType: string; + public readonly providedId: string | undefined; + constructor( - public readonly id: string, - public readonly viewType: string, - name: string, + init: WebviewInputInitInfo, webview: IOverlayWebview, private readonly _iconManager: WebviewIconManager, ) { super(); - this._name = name; + + this.id = init.id; + this.viewType = init.viewType; + this.providedId = init.providedId; + + this._name = init.name; this._webview = webview; } diff --git a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInputSerializer.ts b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInputSerializer.ts index ec4f4c9ef91..483a6b37bc9 100644 --- a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInputSerializer.ts +++ b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInputSerializer.ts @@ -23,6 +23,7 @@ export interface SerializedWebview { readonly id: string; readonly origin: string | undefined; readonly viewType: string; + readonly providedId: string | undefined; readonly title: string; readonly options: SerializedWebviewOptions; readonly extensionLocation: UriComponents | undefined; @@ -36,6 +37,7 @@ export interface DeserializedWebview { readonly id: string; readonly origin: string | undefined; readonly viewType: string; + readonly providedId: string | undefined; readonly title: string; readonly webviewOptions: WebviewOptions; readonly contentOptions: WebviewContentOptions; @@ -78,6 +80,7 @@ export class WebviewEditorInputSerializer implements IEditorSerializer { return this._webviewWorkbenchService.reviveWebview({ webviewInitInfo: { id: data.id, + providedId: data.providedId, origin: data.origin, options: data.webviewOptions, contentOptions: data.contentOptions, @@ -107,6 +110,7 @@ export class WebviewEditorInputSerializer implements IEditorSerializer { id: input.id, origin: input.webview.origin, viewType: input.viewType, + providedId: input.providedId, title: input.getName(), options: { ...input.webview.options, ...input.webview.contentOptions }, extensionLocation: input.extension ? input.extension.location : undefined, diff --git a/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts b/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts index 9c8629d7e5f..00232b050e9 100644 --- a/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts +++ b/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts @@ -20,7 +20,7 @@ import { WebviewInitInfo } from 'vs/workbench/contrib/webview/browser/webviewEle import { WebviewIconManager, WebviewIcons } from 'vs/workbench/contrib/webviewPanel/browser/webviewIconManager'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import { ACTIVE_GROUP_TYPE, IEditorService, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService'; -import { WebviewInput } from './webviewEditorInput'; +import { WebviewInput, WebviewInputInitInfo } from './webviewEditorInput'; export const IWebviewWorkbenchService = createDecorator('webviewEditorService'); @@ -94,13 +94,11 @@ export class LazilyResolvedWebviewEditorInput extends WebviewInput { constructor( - id: string, - viewType: string, - name: string, + init: WebviewInputInitInfo, webview: IOverlayWebview, @IWebviewWorkbenchService private readonly _webviewWorkbenchService: IWebviewWorkbenchService, ) { - super(id, viewType, name, webview, _webviewWorkbenchService.iconManager); + super(init, webview, _webviewWorkbenchService.iconManager); } override dispose() { @@ -244,7 +242,7 @@ export class WebviewEditorService extends Disposable implements IWebviewWorkbenc showOptions: ICreateWebViewShowOptions, ): WebviewInput { const webview = this._webviewService.createWebviewOverlay(webviewInitInfo); - const webviewInput = this._instantiationService.createInstance(WebviewInput, webviewInitInfo.id, viewType, title, webview, this.iconManager); + const webviewInput = this._instantiationService.createInstance(WebviewInput, { id: webviewInitInfo.id, viewType, name: title, providedId: webviewInitInfo.providedId }, webview, this.iconManager); this._editorService.openEditor(webviewInput, { pinned: true, preserveFocus: showOptions.preserveFocus, @@ -295,7 +293,7 @@ export class WebviewEditorService extends Disposable implements IWebviewWorkbenc const webview = this._webviewService.createWebviewOverlay(options.webviewInitInfo); webview.state = options.state; - const webviewInput = this._instantiationService.createInstance(LazilyResolvedWebviewEditorInput, options.webviewInitInfo.id, options.viewType, options.title, webview); + const webviewInput = this._instantiationService.createInstance(LazilyResolvedWebviewEditorInput, { id: options.webviewInitInfo.id, viewType: options.viewType, providedId: options.webviewInitInfo.providedId, name: options.title }, webview); webviewInput.iconPath = options.iconPath; if (typeof options.group === 'number') { From 7b376e070407a0e73332138ae1c7266e9aedbe4a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 27 Jul 2022 21:02:35 +0200 Subject: [PATCH 049/303] Remove Manual Folding Range doesn't work (#156493) Remove Manual Folding Range doesn't work. Fixes #156277 --- src/vs/editor/contrib/folding/browser/folding.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/folding/browser/folding.ts b/src/vs/editor/contrib/folding/browser/folding.ts index 6744508970d..fec26e69c77 100644 --- a/src/vs/editor/contrib/folding/browser/folding.ts +++ b/src/vs/editor/contrib/folding/browser/folding.ts @@ -1140,12 +1140,8 @@ class RemoveFoldRangeFromSelectionAction extends FoldingAction { if (selections) { const ranges: ILineRange[] = []; for (const selection of selections) { - let endLineNumber = selection.endLineNumber; - if (selection.endColumn === 1) { - --endLineNumber; - } - const startLineNumber = selection.startLineNumber; - ranges.push(endLineNumber >= selection.startLineNumber ? { startLineNumber, endLineNumber } : { endLineNumber, startLineNumber }); + const { startLineNumber, endLineNumber } = selection; + ranges.push(endLineNumber >= startLineNumber ? { startLineNumber, endLineNumber } : { endLineNumber, startLineNumber }); } foldingModel.removeManualRanges(ranges); foldingController.triggerFoldingModelChanged(); From 06f8d52e37f3ba31764103dd51f7c06a7bee5676 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Jul 2022 12:58:52 -0700 Subject: [PATCH 050/303] Always log on tsserver exits (#156495) This ensures we also log if the TS Server exits with no code but a valid signal. Useful for figuring out how many users are hitting OOM errors --- .../src/typescriptServiceClient.ts | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index 4eec03b0471..0c740259823 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -431,24 +431,22 @@ export default class TypeScriptServiceClient extends Disposable implements IType handle.onExit((data: TypeScriptServerExitEvent) => { const { code, signal } = data; - if (code === null || typeof code === 'undefined') { - this.info(`TSServer exited. Signal: ${signal}`); - } else { - // In practice, the exit code is an integer with no ties to any identity, - // so it can be classified as SystemMetaData, rather than CallstackOrException. - this.error(`TSServer exited with code: ${code}. Signal: ${signal}`); - /* __GDPR__ - "tsserver.exitWithCode" : { - "owner": "mjbvz", - "code" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "signal" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, - "${include}": [ - "${TypeScriptCommonProperties}" - ] - } - */ - this.logTelemetry('tsserver.exitWithCode', { code, signal: signal ?? undefined }); - } + this.error(`TSServer exited. Code: ${code}. Signal: ${signal}`); + + // In practice, the exit code is an integer with no ties to any identity, + // so it can be classified as SystemMetaData, rather than CallstackOrException. + /* __GDPR__ + "tsserver.exitWithCode" : { + "owner": "mjbvz", + "code" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "signal" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "${include}": [ + "${TypeScriptCommonProperties}" + ] + } + */ + this.logTelemetry('tsserver.exitWithCode', { code: code ?? undefined, signal: signal ?? undefined }); + if (this.token !== mytoken) { // this is coming from an old process From d48349a494df57dca14f2478ceb3055188341d47 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 27 Jul 2022 13:17:22 -0700 Subject: [PATCH 051/303] Default edit sessions to hidden for 1.70 (#156494) --- .../contrib/editSessions/browser/editSessions.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts index 06a991fd12d..2853ab2d422 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -594,7 +594,7 @@ Registry.as(Extensions.Configuration).registerConfigurat 'workbench.experimental.editSessions.enabled': { 'type': 'boolean', 'tags': ['experimental', 'usesOnlineServices'], - 'default': true, + 'default': false, 'markdownDescription': localize('editSessionsEnabled', "Controls whether to display cloud-enabled actions to store and resume uncommitted changes when switching between web, desktop, or devices."), }, } From 89c30e1b86f941db095d9f52b128287e5039e004 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 27 Jul 2022 23:02:44 +0200 Subject: [PATCH 052/303] manual folding ranges: memento does not store all sources (#156273) use source: fix memento does not store all sources --- .../editor/contrib/folding/browser/folding.ts | 5 +- .../contrib/folding/browser/foldingModel.ts | 24 ++-- .../contrib/folding/browser/foldingRanges.ts | 69 +++++++---- .../test/browser/foldingRanges.test.ts | 108 ++++++++---------- 4 files changed, 109 insertions(+), 97 deletions(-) diff --git a/src/vs/editor/contrib/folding/browser/folding.ts b/src/vs/editor/contrib/folding/browser/folding.ts index fec26e69c77..c35cdb69a65 100644 --- a/src/vs/editor/contrib/folding/browser/folding.ts +++ b/src/vs/editor/contrib/folding/browser/folding.ts @@ -32,7 +32,7 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis import { editorSelectionBackground, iconForeground, registerColor, transparent } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { foldingCollapsedIcon, FoldingDecorationProvider, foldingExpandedIcon, foldingManualCollapsedIcon, foldingManualExpandedIcon } from './foldingDecorations'; -import { FoldingRegion, FoldingRegions, FoldRange, ILineRange } from './foldingRanges'; +import { FoldingRegion, FoldingRegions, FoldRange, FoldSource, ILineRange } from './foldingRanges'; import { SyntaxRangeProvider } from './syntaxRangeProvider'; import { INotificationService } from 'vs/platform/notification/common/notification'; import Severity from 'vs/base/common/severity'; @@ -1097,8 +1097,7 @@ class FoldRangeFromSelectionAction extends FoldingAction { endLineNumber: endLineNumber, type: undefined, isCollapsed: true, - isUserDefined: true, - isRecovered: false + source: FoldSource.userDefined }); editor.setSelection({ startLineNumber: selection.startLineNumber, diff --git a/src/vs/editor/contrib/folding/browser/foldingModel.ts b/src/vs/editor/contrib/folding/browser/foldingModel.ts index f3bc09b1ce3..936e83b605f 100644 --- a/src/vs/editor/contrib/folding/browser/foldingModel.ts +++ b/src/vs/editor/contrib/folding/browser/foldingModel.ts @@ -5,7 +5,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IModelDecorationOptions, IModelDecorationsChangeAccessor, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; -import { FoldingRegion, FoldingRegions, ILineRange, FoldRange } from './foldingRanges'; +import { FoldingRegion, FoldingRegions, ILineRange, FoldRange, FoldSource } from './foldingRanges'; import { hash } from 'vs/base/common/hash'; export interface IDecorationProvider { @@ -22,7 +22,7 @@ export interface FoldingModelChangeEvent { interface ILineMemento extends ILineRange { checksum?: number; isCollapsed?: boolean; - isUserDefined?: boolean; + source?: FoldSource; } export type CollapseMemento = ILineMemento[]; @@ -64,7 +64,7 @@ export class FoldingModel { const endLineNumber = this._regions.getEndLineNumber(k); const isCollapsed = this._regions.isCollapsed(k); if (endLineNumber <= dirtyRegionEndLine) { - const isManual = this.regions.isUserDefined(k) || this.regions.isRecovered(k); + const isManual = this.regions.getSource(k) !== FoldSource.provider; accessor.changeDecorationOptions(this._editorDecorationIds[k], this._decorationProvider.getDecorationOption(isCollapsed, endLineNumber <= lastHiddenLine, isManual)); } if (isCollapsed && endLineNumber > lastHiddenLine) { @@ -104,7 +104,7 @@ export class FoldingModel { }; for (let i = 0; i < this._regions.length; i++) { const foldRange = this._regions.toFoldRange(i); - if (!foldRange.isUserDefined && !foldRange.isRecovered || !intersects(foldRange)) { + if (foldRange.source === FoldSource.provider || !intersects(foldRange)) { newFoldingRanges.push(foldRange); } } @@ -124,7 +124,7 @@ export class FoldingModel { const startLineNumber = newRegions.getStartLineNumber(index); const endLineNumber = newRegions.getEndLineNumber(index); const isCollapsed = newRegions.isCollapsed(index); - const isManual = newRegions.isUserDefined(index) || newRegions.isRecovered(index); + const isManual = newRegions.getSource(index) !== FoldSource.provider; const decorationRange = { startLineNumber: startLineNumber, startColumn: this._textModel.getLineMaxColumn(startLineNumber), @@ -155,9 +155,8 @@ export class FoldingModel { const foldedRanges: FoldRange[] = []; for (let i = 0, limit = this._regions.length; i < limit; i++) { let isCollapsed = this.regions.isCollapsed(i); - const isUserDefined = this.regions.isUserDefined(i); - const isRecovered = this.regions.isRecovered(i); - if (isCollapsed || isUserDefined || isRecovered) { + const source = this.regions.getSource(i); + if (isCollapsed || source !== FoldSource.provider) { const foldRange = this._regions.toFoldRange(i); const decRange = this._textModel.getDecorationRange(this._editorDecorationIds[i]); if (decRange) { @@ -169,8 +168,7 @@ export class FoldingModel { endLineNumber: decRange.endLineNumber, type: foldRange.type, isCollapsed, - isUserDefined, - isRecovered + source }); } } @@ -192,7 +190,7 @@ export class FoldingModel { startLineNumber: range.startLineNumber, endLineNumber: range.endLineNumber, isCollapsed: range.isCollapsed, - isUserDefined: range.isRecovered, + source: range.source, checksum: checksum }); } @@ -214,14 +212,12 @@ export class FoldingModel { } const checksum = this._getLinesChecksum(range.startLineNumber + 1, range.endLineNumber); if (!range.checksum || checksum === range.checksum) { - const isUserDefined = range.isUserDefined === true; rangesToRestore.push({ startLineNumber: range.startLineNumber, endLineNumber: range.endLineNumber, type: undefined, isCollapsed: range.isCollapsed ?? true, - isUserDefined, - isRecovered: !isUserDefined + source: range.source ?? FoldSource.provider }); } } diff --git a/src/vs/editor/contrib/folding/browser/foldingRanges.ts b/src/vs/editor/contrib/folding/browser/foldingRanges.ts index 2dfb1e50003..8beb820778d 100644 --- a/src/vs/editor/contrib/folding/browser/foldingRanges.ts +++ b/src/vs/editor/contrib/folding/browser/foldingRanges.ts @@ -8,13 +8,18 @@ export interface ILineRange { endLineNumber: number; } +export const enum FoldSource { + provider = 0, + userDefined = 1, + recovered = 2 +} + export interface FoldRange { startLineNumber: number; endLineNumber: number; type: string | undefined; isCollapsed: boolean; - isUserDefined: boolean; - isRecovered: boolean; + source: FoldSource; } export const MAX_FOLDING_REGIONS = 0xFFFF; @@ -123,22 +128,44 @@ export class FoldingRegions { this._collapseStates.set(index, newState); } - public isUserDefined(index: number): boolean { + private isUserDefined(index: number): boolean { return this._userDefinedStates.get(index); } - public setUserDefined(index: number, newState: boolean) { + private setUserDefined(index: number, newState: boolean) { return this._userDefinedStates.set(index, newState); } - public isRecovered(index: number): boolean { + private isRecovered(index: number): boolean { return this._recoveredStates.get(index); } - public setRecovered(index: number, newState: boolean) { + private setRecovered(index: number, newState: boolean) { return this._recoveredStates.set(index, newState); } + public getSource(index: number): FoldSource { + if (this.isUserDefined(index)) { + return FoldSource.userDefined; + } else if (this.isRecovered(index)) { + return FoldSource.recovered; + } + return FoldSource.provider; + } + + public setSource(index: number, source: FoldSource): void { + if (source === FoldSource.userDefined) { + this.setUserDefined(index, true); + this.setRecovered(index, false); + } else if (source === FoldSource.recovered) { + this.setUserDefined(index, false); + this.setRecovered(index, true); + } else { + this.setUserDefined(index, false); + this.setRecovered(index, false); + } + } + public setCollapsedAllOfType(type: string, newState: boolean) { let hasChanged = false; if (this._types) { @@ -203,10 +230,16 @@ export class FoldingRegions { return -1; } + private readonly sourceAbbr = { + [FoldSource.provider]: ' ', + [FoldSource.userDefined]: 'u', + [FoldSource.recovered]: 'r', + }; + public toString() { const res: string[] = []; for (let i = 0; i < this.length; i++) { - res[i] = `[${this.isUserDefined(i) ? '*' : ' '}${this.isRecovered(i) ? 'r' : ' '}${this.isCollapsed(i) ? '+' : '-'}] ${this.getStartLineNumber(i)}/${this.getEndLineNumber(i)}`; + res[i] = `[${this.sourceAbbr[this.getSource(i)]}${this.isCollapsed(i) ? '+' : '-'}] ${this.getStartLineNumber(i)}/${this.getEndLineNumber(i)}`; } return res.join(', '); } @@ -217,8 +250,7 @@ export class FoldingRegions { endLineNumber: this._endIndexes[index] & MAX_LINE_NUMBER, type: this._types ? this._types[index] : undefined, isCollapsed: this.isCollapsed(index), - isUserDefined: this.isUserDefined(index), - isRecovered: this.isRecovered(index) + source: this.getSource(index) }; } @@ -245,12 +277,7 @@ export class FoldingRegions { if (ranges[i].isCollapsed) { regions.setCollapsed(i, true); } - if (ranges[i].isUserDefined) { - regions.setUserDefined(i, true); - } - if (ranges[i].isRecovered) { - regions.setRecovered(i, true); - } + regions.setSource(i, ranges[i].source); } return regions; } @@ -296,23 +323,21 @@ export class FoldingRegions { let useRange: FoldRange | undefined = undefined; if (nextB && (!nextA || nextA.startLineNumber >= nextB.startLineNumber)) { if (nextA && nextA.startLineNumber === nextB.startLineNumber) { - if (nextB.isUserDefined) { + if (nextB.source === FoldSource.userDefined) { // a user defined range (possibly unfolded) useRange = nextB; } else { // a previously folded range or a (possibly unfolded) recovered range useRange = nextA; useRange.isCollapsed = nextB.isCollapsed && nextA.endLineNumber === nextB.endLineNumber; - useRange.isUserDefined = false; - useRange.isRecovered = false; + useRange.source = FoldSource.provider; } nextA = getA(++indexA); // not necessary, just for speed } else { useRange = nextB; - if (nextB.isCollapsed && !nextB.isUserDefined && !nextB.isRecovered) { + if (nextB.isCollapsed && nextB.source === FoldSource.provider) { // a previously collapsed range - useRange.isRecovered = true; - useRange.isUserDefined = false; + useRange.source = FoldSource.recovered; } } nextB = getB(++indexB); @@ -326,7 +351,7 @@ export class FoldingRegions { useRange = nextA; break; // no conflict, use this nextA } - if (prescanB.isUserDefined && prescanB.endLineNumber > nextA!.endLineNumber) { + if (prescanB.source === FoldSource.userDefined && prescanB.endLineNumber > nextA!.endLineNumber) { // we found a user folded range, it wins break; // without setting nextResult, so this nextA gets skipped } diff --git a/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts b/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts index 671277579ee..9f6a381afbd 100644 --- a/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts +++ b/src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { FoldingMarkers } from 'vs/editor/common/languages/languageConfiguration'; -import { MAX_FOLDING_REGIONS, FoldRange, FoldingRegions } from 'vs/editor/contrib/folding/browser/foldingRanges'; +import { MAX_FOLDING_REGIONS, FoldRange, FoldingRegions, FoldSource } from 'vs/editor/contrib/folding/browser/foldingRanges'; import { computeRanges } from 'vs/editor/contrib/folding/browser/indentRangeProvider'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; @@ -14,30 +14,22 @@ const markers: FoldingMarkers = { end: /^\s*#endregion\b/ }; -enum State { - none = 0, - userDefined = 1, - recovered = 2 -} - suite('FoldingRanges', () => { - const foldRange = (from: number, to: number, collapsed: boolean | undefined = undefined, state: State = State.none, type: string | undefined = undefined) => + const foldRange = (from: number, to: number, collapsed: boolean | undefined = undefined, source: FoldSource = FoldSource.provider, type: string | undefined = undefined) => { startLineNumber: from, endLineNumber: to, type: type, isCollapsed: collapsed || false, - isUserDefined: state === State.userDefined, - isRecovered: state === State.recovered, + source }; const assertEqualRanges = (range1: FoldRange, range2: FoldRange, msg: string) => { assert.strictEqual(range1.startLineNumber, range2.startLineNumber, msg + ' start'); assert.strictEqual(range1.endLineNumber, range2.endLineNumber, msg + ' end'); assert.strictEqual(range1.type, range2.type, msg + ' type'); assert.strictEqual(range1.isCollapsed, range2.isCollapsed, msg + ' collapsed'); - assert.strictEqual(range1.isUserDefined, range2.isUserDefined, msg + ' userDefined'); - assert.strictEqual(range1.isRecovered, range2.isRecovered, msg + ' recovered'); + assert.strictEqual(range1.source, range2.source, msg + ' source'); }; test('test max folding regions', () => { @@ -130,88 +122,88 @@ suite('FoldingRanges', () => { test('sanitizeAndMerge1', () => { const regionSet1: FoldRange[] = [ foldRange(0, 100), // invalid, should be removed - foldRange(1, 100, false, State.none, 'A'), // valid - foldRange(1, 100, false, State.none, 'Z'), // invalid, duplicate start + foldRange(1, 100, false, FoldSource.provider, 'A'), // valid + foldRange(1, 100, false, FoldSource.provider, 'Z'), // invalid, duplicate start foldRange(10, 10, false), // invalid, should be removed - foldRange(20, 80, false, State.none, 'C1'), // valid inside 'B' - foldRange(22, 80, true, State.none, 'D1'), // valid inside 'C1' + foldRange(20, 80, false, FoldSource.provider, 'C1'), // valid inside 'B' + foldRange(22, 80, true, FoldSource.provider, 'D1'), // valid inside 'C1' foldRange(90, 101), // invalid, should be removed ]; const regionSet2: FoldRange[] = [ foldRange(20, 80, true), // should merge with C1 foldRange(18, 80, true), // invalid, out of order - foldRange(21, 81, true, State.none, 'Z'), // invalid, overlapping - foldRange(22, 80, true, State.none, 'D2'), // should merge with D1 + foldRange(21, 81, true, FoldSource.provider, 'Z'), // invalid, overlapping + foldRange(22, 80, true, FoldSource.provider, 'D2'), // should merge with D1 ]; const result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100); assert.strictEqual(result.length, 3, 'result length1'); - assertEqualRanges(result[0], foldRange(1, 100, false, State.none, 'A'), 'A1'); - assertEqualRanges(result[1], foldRange(20, 80, true, State.none, 'C1'), 'C1'); - assertEqualRanges(result[2], foldRange(22, 80, true, State.none, 'D1'), 'D1'); + assertEqualRanges(result[0], foldRange(1, 100, false, FoldSource.provider, 'A'), 'A1'); + assertEqualRanges(result[1], foldRange(20, 80, true, FoldSource.provider, 'C1'), 'C1'); + assertEqualRanges(result[2], foldRange(22, 80, true, FoldSource.provider, 'D1'), 'D1'); }); test('sanitizeAndMerge2', () => { const regionSet1: FoldRange[] = [ - foldRange(1, 100, false, State.none, 'a1'), // valid - foldRange(2, 100, false, State.none, 'a2'), // valid - foldRange(3, 19, false, State.none, 'a3'), // valid - foldRange(20, 71, false, State.none, 'a4'), // overlaps b3 - foldRange(21, 29, false, State.none, 'a5'), // valid - foldRange(81, 91, false, State.none, 'a6'), // overlaps b4 + foldRange(1, 100, false, FoldSource.provider, 'a1'), // valid + foldRange(2, 100, false, FoldSource.provider, 'a2'), // valid + foldRange(3, 19, false, FoldSource.provider, 'a3'), // valid + foldRange(20, 71, false, FoldSource.provider, 'a4'), // overlaps b3 + foldRange(21, 29, false, FoldSource.provider, 'a5'), // valid + foldRange(81, 91, false, FoldSource.provider, 'a6'), // overlaps b4 ]; const regionSet2: FoldRange[] = [ - foldRange(30, 39, true, State.none, 'b1'), // valid, will be recovered - foldRange(40, 49, true, State.userDefined, 'b2'), // valid - foldRange(50, 100, true, State.userDefined, 'b3'), // overlaps a4 - foldRange(80, 90, true, State.userDefined, 'b4'), // overlaps a6 - foldRange(92, 100, true, State.userDefined, 'b5'), // valid + foldRange(30, 39, true, FoldSource.provider, 'b1'), // valid, will be recovered + foldRange(40, 49, true, FoldSource.userDefined, 'b2'), // valid + foldRange(50, 100, true, FoldSource.userDefined, 'b3'), // overlaps a4 + foldRange(80, 90, true, FoldSource.userDefined, 'b4'), // overlaps a6 + foldRange(92, 100, true, FoldSource.userDefined, 'b5'), // valid ]; const result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100); assert.strictEqual(result.length, 9, 'result length1'); - assertEqualRanges(result[0], foldRange(1, 100, false, State.none, 'a1'), 'P1'); - assertEqualRanges(result[1], foldRange(2, 100, false, State.none, 'a2'), 'P2'); - assertEqualRanges(result[2], foldRange(3, 19, false, State.none, 'a3'), 'P3'); - assertEqualRanges(result[3], foldRange(21, 29, false, State.none, 'a5'), 'P4'); - assertEqualRanges(result[4], foldRange(30, 39, true, State.recovered, 'b1'), 'P5'); - assertEqualRanges(result[5], foldRange(40, 49, true, State.userDefined, 'b2'), 'P6'); - assertEqualRanges(result[6], foldRange(50, 100, true, State.userDefined, 'b3'), 'P7'); - assertEqualRanges(result[7], foldRange(80, 90, true, State.userDefined, 'b4'), 'P8'); - assertEqualRanges(result[8], foldRange(92, 100, true, State.userDefined, 'b5'), 'P9'); + assertEqualRanges(result[0], foldRange(1, 100, false, FoldSource.provider, 'a1'), 'P1'); + assertEqualRanges(result[1], foldRange(2, 100, false, FoldSource.provider, 'a2'), 'P2'); + assertEqualRanges(result[2], foldRange(3, 19, false, FoldSource.provider, 'a3'), 'P3'); + assertEqualRanges(result[3], foldRange(21, 29, false, FoldSource.provider, 'a5'), 'P4'); + assertEqualRanges(result[4], foldRange(30, 39, true, FoldSource.recovered, 'b1'), 'P5'); + assertEqualRanges(result[5], foldRange(40, 49, true, FoldSource.userDefined, 'b2'), 'P6'); + assertEqualRanges(result[6], foldRange(50, 100, true, FoldSource.userDefined, 'b3'), 'P7'); + assertEqualRanges(result[7], foldRange(80, 90, true, FoldSource.userDefined, 'b4'), 'P8'); + assertEqualRanges(result[8], foldRange(92, 100, true, FoldSource.userDefined, 'b5'), 'P9'); }); test('sanitizeAndMerge3', () => { const regionSet1: FoldRange[] = [ - foldRange(1, 100, false, State.none, 'a1'), // valid - foldRange(10, 29, false, State.none, 'a2'), // matches manual hidden - foldRange(35, 39, true, State.recovered, 'a3'), // valid + foldRange(1, 100, false, FoldSource.provider, 'a1'), // valid + foldRange(10, 29, false, FoldSource.provider, 'a2'), // matches manual hidden + foldRange(35, 39, true, FoldSource.recovered, 'a3'), // valid ]; const regionSet2: FoldRange[] = [ - foldRange(10, 29, true, State.recovered, 'b1'), // matches a - foldRange(20, 28, true, State.none, 'b2'), // should remain - foldRange(30, 39, true, State.recovered, 'b3'), // should remain + foldRange(10, 29, true, FoldSource.recovered, 'b1'), // matches a + foldRange(20, 28, true, FoldSource.provider, 'b2'), // should remain + foldRange(30, 39, true, FoldSource.recovered, 'b3'), // should remain ]; const result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100); assert.strictEqual(result.length, 5, 'result length3'); - assertEqualRanges(result[0], foldRange(1, 100, false, State.none, 'a1'), 'R1'); - assertEqualRanges(result[1], foldRange(10, 29, true, State.none, 'a2'), 'R2'); - assertEqualRanges(result[2], foldRange(20, 28, true, State.recovered, 'b2'), 'R3'); - assertEqualRanges(result[3], foldRange(30, 39, true, State.recovered, 'b3'), 'R3'); - assertEqualRanges(result[4], foldRange(35, 39, true, State.recovered, 'a3'), 'R4'); + assertEqualRanges(result[0], foldRange(1, 100, false, FoldSource.provider, 'a1'), 'R1'); + assertEqualRanges(result[1], foldRange(10, 29, true, FoldSource.provider, 'a2'), 'R2'); + assertEqualRanges(result[2], foldRange(20, 28, true, FoldSource.recovered, 'b2'), 'R3'); + assertEqualRanges(result[3], foldRange(30, 39, true, FoldSource.recovered, 'b3'), 'R3'); + assertEqualRanges(result[4], foldRange(35, 39, true, FoldSource.recovered, 'a3'), 'R4'); }); test('sanitizeAndMerge4', () => { const regionSet1: FoldRange[] = [ - foldRange(1, 100, false, State.none, 'a1'), // valid + foldRange(1, 100, false, FoldSource.provider, 'a1'), // valid ]; const regionSet2: FoldRange[] = [ - foldRange(20, 28, true, State.none, 'b1'), // hidden - foldRange(30, 38, true, State.none, 'b2'), // hidden + foldRange(20, 28, true, FoldSource.provider, 'b1'), // hidden + foldRange(30, 38, true, FoldSource.provider, 'b2'), // hidden ]; const result = FoldingRegions.sanitizeAndMerge(regionSet1, regionSet2, 100); assert.strictEqual(result.length, 3, 'result length4'); - assertEqualRanges(result[0], foldRange(1, 100, false, State.none, 'a1'), 'R1'); - assertEqualRanges(result[1], foldRange(20, 28, true, State.recovered, 'b1'), 'R2'); - assertEqualRanges(result[2], foldRange(30, 38, true, State.recovered, 'b2'), 'R3'); + assertEqualRanges(result[0], foldRange(1, 100, false, FoldSource.provider, 'a1'), 'R1'); + assertEqualRanges(result[1], foldRange(20, 28, true, FoldSource.recovered, 'b1'), 'R2'); + assertEqualRanges(result[2], foldRange(30, 38, true, FoldSource.recovered, 'b2'), 'R3'); }); }); From af67e60687f02256ded9f5d5cedb2a4a9a195dfc Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Wed, 27 Jul 2022 14:34:48 -0700 Subject: [PATCH 053/303] fix naming on hover --- src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts index dc1a9a5031b..d3a15fec005 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts @@ -141,7 +141,7 @@ class CodeMenuRenderer implements IListRenderer { const [accept, preview] = this.acceptKeybindings; - data.root.title = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Refactor, Shift+F2 to Preview"'] }, "{0} to Rename, {1} to Preview", this.keybindingService.lookupKeybinding(accept)?.getLabel(), this.keybindingService.lookupKeybinding(preview)?.getLabel()); + data.root.title = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Refactor, Shift+F2 to Preview"'] }, "{0} to Refactor, {1} to Preview", this.keybindingService.lookupKeybinding(accept)?.getLabel(), this.keybindingService.lookupKeybinding(preview)?.getLabel()); // data.root.title = this.keybindingService.lookupKeybinding(accept)?.getLabel() + ' to Refactor, ' + this.keybindingService.lookupKeybinding(preview)?.getLabel() + ' to Preview'; }; updateLabel(); From d949bdfb48025dd1b0e22b05501860b8f9fb6cb8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Jul 2022 14:52:17 -0700 Subject: [PATCH 054/303] Clarify wording in api (#156500) Clairify wording in api Fixes #156376 --- src/vscode-dts/vscode.d.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index 423ac8e7a4d..36aee9c2f76 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -5430,7 +5430,9 @@ declare module 'vscode' { /** * Provider which handles dropping of resources into a text editor. * - * The user can drop into a text editor by holding down `shift` while dragging. Requires `editor.dropIntoEditor.enabled` to be on. + * This allows users to drag and drop resources (including resources from external apps) into the editor. While dragging + * and dropping files, users can hold down `shift` to drop the file into the editor instead of opening it. + * Requires `editor.dropIntoEditor.enabled` to be on. */ export interface DocumentDropEditProvider { /** From 99cf19c04206beffd16dae6c824509d6d721b75b Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 27 Jul 2022 15:30:01 -0700 Subject: [PATCH 055/303] debug: bump js-debug and visualizer for 1.70 (#156508) --- product.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/product.json b/product.json index a50c00f6cf3..0e0d703e181 100644 --- a/product.json +++ b/product.json @@ -46,7 +46,7 @@ }, { "name": "ms-vscode.js-debug", - "version": "1.69.0", + "version": "1.70.0", "repo": "https://github.com/microsoft/vscode-js-debug", "metadata": { "id": "25629058-ddac-4e17-abba-74678e126c5d", @@ -61,7 +61,7 @@ }, { "name": "ms-vscode.vscode-js-profile-table", - "version": "1.0.2", + "version": "1.0.3", "repo": "https://github.com/microsoft/vscode-js-profile-visualizer", "metadata": { "id": "7e52b41b-71ad-457b-ab7e-0620f1fc4feb", From 083728eb874d5b1529db7b7ab29e3cce476c694b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Jul 2022 15:43:40 -0700 Subject: [PATCH 056/303] Fix drop indicator showing up even if you have disabled dropIntoEditor (#156506) This fixes a number of places where we were adding `dropIntoEditor` to the config override, which also overrides the user's configation. Instead we can check if the editor is readonly in `codeEditorWidget` --- src/vs/editor/browser/widget/codeEditorWidget.ts | 9 +++++++-- src/vs/workbench/browser/parts/editor/textDiffEditor.ts | 2 -- src/vs/workbench/browser/parts/editor/textEditor.ts | 7 +------ .../notebook/browser/view/cellParts/markdownCell.ts | 1 - .../notebook/browser/view/renderers/cellRenderer.ts | 1 - 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index bed9912d2d3..32b66fa6680 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -368,10 +368,15 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE this._actions[internalAction.id] = internalAction; }); + const isDropIntoEnabled = () => { + return !this._configuration.options.get(EditorOption.readOnly) + && this._configuration.options.get(EditorOption.dropIntoEditor).enabled; + }; + this._register(new dom.DragAndDropObserver(this._domElement, { onDragEnter: () => undefined, onDragOver: e => { - if (!this._configuration.options.get(EditorOption.dropIntoEditor).enabled) { + if (!isDropIntoEnabled()) { return; } @@ -381,7 +386,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE } }, onDrop: async e => { - if (!this._configuration.options.get(EditorOption.dropIntoEditor).enabled) { + if (!isDropIntoEnabled()) { return; } diff --git a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts index 2dcf135be7c..a638504849a 100644 --- a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts @@ -240,7 +240,6 @@ export class TextDiffEditor extends AbstractTextEditor imp return { ...super.getConfigurationOverrides(), readOnly, - dropIntoEditor: { enabled: !readOnly }, originalEditable: this.input instanceof DiffEditorInput && !this.input.original.hasCapability(EditorInputCapabilities.Readonly), lineDecorationsWidth: '2ch' }; @@ -251,7 +250,6 @@ export class TextDiffEditor extends AbstractTextEditor imp this.diffEditorControl?.updateOptions({ readOnly: input.hasCapability(EditorInputCapabilities.Readonly), originalEditable: !input.original.hasCapability(EditorInputCapabilities.Readonly), - dropIntoEditor: { enabled: !input.hasCapability(EditorInputCapabilities.Readonly) } }); } else { super.updateReadonly(input); diff --git a/src/vs/workbench/browser/parts/editor/textEditor.ts b/src/vs/workbench/browser/parts/editor/textEditor.ts index b43dd3baa8d..da518cdc0e7 100644 --- a/src/vs/workbench/browser/parts/editor/textEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textEditor.ts @@ -135,11 +135,7 @@ export abstract class AbstractTextEditor extends Abs protected updateReadonly(input: EditorInput): void { const readOnly = input.hasCapability(EditorInputCapabilities.Readonly); - - this.updateEditorControlOptions({ - readOnly, - dropIntoEditor: { enabled: !readOnly }, - }); + this.updateEditorControlOptions({ readOnly }); } protected getConfigurationOverrides(): ICodeEditorOptions { @@ -150,7 +146,6 @@ export abstract class AbstractTextEditor extends Abs lineNumbersMinChars: 3, fixedOverflowWidgets: true, readOnly, - dropIntoEditor: { enabled: !readOnly }, renderValidationDecorations: 'on' // render problems even in readonly editors (https://github.com/microsoft/vscode/issues/89057) }; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell.ts index 813a6ef4354..ac666a052eb 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell.ts @@ -329,7 +329,6 @@ export class StatefulMarkdownCell extends Disposable { width: width, height: editorHeight }, - dropIntoEditor: { enabled: true }, // overflowWidgetsDomNode: this.notebookEditor.getOverflowContainerDomNode() }, { contributions: this.notebookEditor.creationOptions.cellEditorContributions diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts index fff16d43316..8e3ab0b4640 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -275,7 +275,6 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende width: 0, height: 0 }, - dropIntoEditor: { enabled: true }, }, { contributions: this.notebookEditor.creationOptions.cellEditorContributions }); From 0e5245ccc780813981650fc7bb3fa854e423b5d1 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Jul 2022 20:22:19 -0700 Subject: [PATCH 057/303] Revert fix for #150995 (#156516) Fixes #156352 --- src/vs/workbench/browser/parts/editor/editorDropTarget.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts index 947f4475f3b..9e46f90b593 100644 --- a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts +++ b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts @@ -597,11 +597,6 @@ export class EditorDropTarget extends Themable { private registerListeners(): void { this._register(addDisposableListener(this.container, EventType.DRAG_ENTER, e => this.onDragEnter(e))); this._register(addDisposableListener(this.container, EventType.DRAG_LEAVE, () => this.onDragLeave())); - this._register(addDisposableListener(this.container, EventType.DRAG_OVER, e => { - if (!this.overlay) { - this.onDragEnter(e); - } - })); [this.container, window].forEach(node => this._register(addDisposableListener(node as HTMLElement, EventType.DRAG_END, () => this.onDragEnd()))); } From 3e26d50f995f4ed76adedff0138138b29b958625 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 28 Jul 2022 06:11:05 +0200 Subject: [PATCH 058/303] Revert "Warn user when they open a file within the install folder tree (#138815) (#155443)" (#156403) This reverts commit 688c30e498f16686cc0c681e9fdc65d770b2c69a. --- src/vs/workbench/electron-sandbox/window.ts | 57 +-------------------- 1 file changed, 2 insertions(+), 55 deletions(-) diff --git a/src/vs/workbench/electron-sandbox/window.ts b/src/vs/workbench/electron-sandbox/window.ts index 0d197e84c16..f044363676a 100644 --- a/src/vs/workbench/electron-sandbox/window.ts +++ b/src/vs/workbench/electron-sandbox/window.ts @@ -65,7 +65,6 @@ import { toErrorMessage } from 'vs/base/common/errorMessage'; import { registerWindowDriver } from 'vs/platform/driver/electron-sandbox/driver'; import { ILabelService } from 'vs/platform/label/common/label'; import { dirname } from 'vs/base/common/resources'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; export class NativeWindow extends Disposable { @@ -116,8 +115,7 @@ export class NativeWindow extends Disposable { @IInstantiationService private readonly instantiationService: IInstantiationService, @ISharedProcessService private readonly sharedProcessService: ISharedProcessService, @IProgressService private readonly progressService: IProgressService, - @ILabelService private readonly labelService: ILabelService, - @IUriIdentityService private readonly uriIdentityService: IUriIdentityService + @ILabelService private readonly labelService: ILabelService ) { super(); @@ -131,18 +129,7 @@ export class NativeWindow extends Disposable { this._register(addDisposableListener(window, EventType.RESIZE, e => this.onWindowResize(e, true))); // React to editor input changes - const appRootUri = URI.file(this.environmentService.appRoot); - this._register(this.editorService.onDidActiveEditorChange(() => { - - // Touchbar - this.updateTouchbarMenu(); - - // Potential data loss when editing files - // from within the installation app root - if (this.environmentService.isBuilt) { - this.notifyOnAppRootEditors(appRootUri); - } - })); + this._register(this.editorService.onDidActiveEditorChange(() => this.updateTouchbarMenu())); // prevent opening a real URL inside the window for (const event of [EventType.DRAG_OVER, EventType.DROP]) { @@ -808,46 +795,6 @@ export class NativeWindow extends Disposable { } } - private notifyOnAppRootEditors(appRootUri: URI): void { - const resourceUri = EditorResourceAccessor.getOriginalUri(this.editorService.activeEditor, { supportSideBySide: SideBySideEditor.BOTH }); - const isResourceAppRootedFn = (uri: URI): boolean => this.uriIdentityService.extUri.isEqualOrParent(uri, appRootUri); - let isResourceAppRooted = false; - if (URI.isUri(resourceUri)) { - if (isResourceAppRootedFn(resourceUri)) { - isResourceAppRooted = true; - } - } else if (resourceUri) { - if (resourceUri.primary && isResourceAppRootedFn(resourceUri.primary)) { - isResourceAppRooted = true; - } else if (resourceUri.secondary && isResourceAppRootedFn(resourceUri.secondary)) { - isResourceAppRooted = true; - } - } - - // It is dangerous to edit files in the installation directory of Code because - // an update will remove all files and replace them with the new version. - // As such, we notify the user whenever an editor opens that is located somewhere - // in the installation directory. - // https://github.com/microsoft/vscode/issues/138815 - - if (isResourceAppRooted) { - this.notificationService.prompt( - Severity.Warning, - localize('notifyOnAppRootEditors', "Files within the installation folder of '{0}' ({1}) will be OVERWRITTEN or DELETED IRREVERSIBLY without warning during a future update.", this.productService.nameShort, this.environmentService.appRoot), - [{ - label: localize('understood', 'Understood'), - run: async () => { - // Nothing to do - } - }], - { - neverShowAgain: { id: 'window.notifyOnAppRootEditors', isSecondary: true }, - sticky: true - } - ); - } - } - private onAddFoldersRequest(request: IAddFoldersRequest): void { // Buffer all pending requests From 916f7677fceedc80bfa3dbc037daddb78e949b01 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 28 Jul 2022 06:23:17 +0200 Subject: [PATCH 059/303] Fix #156321 (#156524) --- .../common/userDataProfileActions.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts index f1d27222b50..62e3de604fe 100644 --- a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts +++ b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts @@ -375,6 +375,7 @@ registerAction2(class ImportProfileAction extends Action2 { const userDataProfileImportExportService = accessor.get(IUserDataProfileImportExportService); const dialogService = accessor.get(IDialogService); const contextKeyService = accessor.get(IContextKeyService); + const notificationService = accessor.get(INotificationService); const isSettingProfilesEnabled = contextKeyService.contextMatchesRules(PROFILES_ENABLEMENT_CONTEXT); @@ -401,14 +402,18 @@ registerAction2(class ImportProfileAction extends Action2 { quickPick.matchOnLabel = false; quickPick.matchOnDescription = false; disposables.add(quickPick.onDidAccept(async () => { - quickPick.hide(); - const profile = quickPick.selectedItems[0].description ? await this.getProfileFromURL(quickPick.value, requestService) : await this.getProfileFromFileSystem(fileDialogService, fileService); - if (profile) { - if (isSettingProfilesEnabled) { - await userDataProfileImportExportService.importProfile(profile); - } else { - await userDataProfileImportExportService.setProfile(profile); + try { + quickPick.hide(); + const profile = quickPick.selectedItems[0].description ? await this.getProfileFromURL(quickPick.value, requestService) : await this.getProfileFromFileSystem(fileDialogService, fileService); + if (profile) { + if (isSettingProfilesEnabled) { + await userDataProfileImportExportService.importProfile(profile); + } else { + await userDataProfileImportExportService.setProfile(profile); + } } + } catch (error) { + notificationService.error(error); } })); disposables.add(quickPick.onDidHide(() => disposables.dispose())); From 4ee1d1a248dee5a5c5902bedadd094784366c8c6 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 28 Jul 2022 06:27:21 +0200 Subject: [PATCH 060/303] Fix #153942 (#156525) --- src/vs/workbench/contrib/extensions/browser/extensionsList.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts index 84eaa15be18..92938e503e5 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts @@ -119,8 +119,8 @@ export class Renderer implements IPagedRenderer { const actions = [ this.instantiationService.createInstance(ExtensionStatusLabelAction), this.instantiationService.createInstance(MigrateDeprecatedExtensionAction, true), - this.instantiationService.createInstance(UpdateAction), reloadAction, + this.instantiationService.createInstance(UpdateAction), this.instantiationService.createInstance(InstallDropdownAction), this.instantiationService.createInstance(InstallingLabelAction), this.instantiationService.createInstance(SetLanguageAction), From b4d5b4ed69af953901051b1f049851b9dca3563e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 28 Jul 2022 06:46:36 +0200 Subject: [PATCH 061/303] Fix #156468 (#156528) --- src/vs/workbench/contrib/extensions/browser/extensionsList.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts index 92938e503e5..c5a4a64a417 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts @@ -13,7 +13,7 @@ import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging'; import { Event } from 'vs/base/common/event'; import { IExtension, ExtensionContainers, ExtensionState, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions'; -import { UpdateAction, ManageExtensionAction, ReloadAction, ExtensionStatusLabelAction, RemoteInstallAction, ExtensionStatusAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, MigrateDeprecatedExtensionAction, SetLanguageAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; +import { UpdateAction, ManageExtensionAction, ReloadAction, ExtensionStatusLabelAction, RemoteInstallAction, ExtensionStatusAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, MigrateDeprecatedExtensionAction, SetLanguageAction, ClearLanguageAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, ExtensionPackCountWidget as ExtensionPackBadgeWidget, SyncIgnoredWidget, ExtensionHoverWidget, ExtensionActivationStatusWidget, PreReleaseBookmarkWidget, extensionVerifiedPublisherIconColor } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets'; import { IExtensionService, toExtension } from 'vs/workbench/services/extensions/common/extensions'; @@ -124,6 +124,7 @@ export class Renderer implements IPagedRenderer { this.instantiationService.createInstance(InstallDropdownAction), this.instantiationService.createInstance(InstallingLabelAction), this.instantiationService.createInstance(SetLanguageAction), + this.instantiationService.createInstance(ClearLanguageAction), this.instantiationService.createInstance(RemoteInstallAction, false), this.instantiationService.createInstance(LocalInstallAction), this.instantiationService.createInstance(WebInstallAction), From c4d99090fcfb199f12965594952c81fbdd6f5a7f Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Thu, 28 Jul 2022 09:50:51 +0300 Subject: [PATCH 062/303] Engineering - Code OSS pipeline to use generic node modules cache (#156537) Code OSS pipeline to use generic node modules cache --- .../linux/product-build-linux-client.yml | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/build/azure-pipelines/linux/product-build-linux-client.yml b/build/azure-pipelines/linux/product-build-linux-client.yml index 1f57307739a..97a9cf31d66 100644 --- a/build/azure-pipelines/linux/product-build-linux-client.yml +++ b/build/azure-pipelines/linux/product-build-linux-client.yml @@ -93,12 +93,21 @@ steps: node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash displayName: Prepare yarn cache flags - - task: Cache@2 - inputs: - key: "nodeModules | $(Agent.OS) | .build/yarnlockhash" - path: .build/node_modules_cache - cacheHitVar: NODE_MODULES_RESTORED - displayName: Restore node_modules cache + - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: + - task: Cache@2 + inputs: + key: "genericNodeModules | $(Agent.OS) | .build/yarnlockhash" + path: .build/node_modules_cache + cacheHitVar: NODE_MODULES_RESTORED + displayName: Restore node_modules cache + + - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: + - task: Cache@2 + inputs: + key: "nodeModules | $(Agent.OS) | .build/yarnlockhash" + path: .build/node_modules_cache + cacheHitVar: NODE_MODULES_RESTORED + displayName: Restore node_modules cache - script: | set -e From 3f502b2bcff29d983b67c5a145ad10524c080d49 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 28 Jul 2022 08:56:31 +0200 Subject: [PATCH 063/303] Fix #154485 (#156533) --- .../browser/userDataProfileManagement.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts index 5fab982a11c..7b124b207ca 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts @@ -87,7 +87,16 @@ export class UserDataProfileManagementService extends Disposable implements IUse } private async enterProfile(profile: IUserDataProfile, preserveData: boolean, reloadMessage?: string): Promise { - if (this.environmentService.remoteAuthority) { + const isRemoteWindow = !!this.environmentService.remoteAuthority; + + if (!isRemoteWindow) { + this.extensionService.stopExtensionHosts(); + } + + // In a remote window update current profile before reloading so that data is preserved from current profile if asked to preserve + await this.userDataProfileService.updateCurrentProfile(profile, preserveData); + + if (isRemoteWindow) { const result = await this.dialogService.confirm({ type: 'info', message: reloadMessage ?? localize('reload message', "Switching a settings profile requires reloading VS Code."), @@ -96,12 +105,9 @@ export class UserDataProfileManagementService extends Disposable implements IUse if (result.confirmed) { await this.hostService.reload(); } - return; + } else { + await this.extensionService.startExtensionHosts(); } - - this.extensionService.stopExtensionHosts(); - await this.userDataProfileService.updateCurrentProfile(profile, preserveData); - await this.extensionService.startExtensionHosts(); } } From 96c1ab3fa94e48dde6a6182769055d09380ea1c4 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Thu, 28 Jul 2022 10:25:22 +0300 Subject: [PATCH 064/303] Engineering - Add missing variable to cache maintenance job (#156540) Add missing variable to cache maintenance job --- build/azure-pipelines/product-build-pr.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/azure-pipelines/product-build-pr.yml b/build/azure-pipelines/product-build-pr.yml index 8f06bcfd09c..1a782b100ee 100644 --- a/build/azure-pipelines/product-build-pr.yml +++ b/build/azure-pipelines/product-build-pr.yml @@ -30,6 +30,8 @@ stages: - job: MaintainNodeModulesCache displayName: Maintain node_modules cache pool: vscode-1es-vscode-linux-20.04 + variables: + VSCODE_ARCH: x64 steps: - template: product-build-pr-cache.yml From 09935be99be55eb2374927030d3c4de9d5639d95 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 28 Jul 2022 12:33:14 +0200 Subject: [PATCH 065/303] Rename `getViewLineRenderingData` to `getViewportViewLineRenderingData` --- .../common/viewLayout/viewLinesViewportData.ts | 2 +- src/vs/editor/common/viewModel.ts | 2 +- src/vs/editor/common/viewModel/viewModelImpl.ts | 2 +- .../browser/viewModel/viewModelDecorations.test.ts | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/editor/common/viewLayout/viewLinesViewportData.ts b/src/vs/editor/common/viewLayout/viewLinesViewportData.ts index de06a61132e..8ddcfddb99d 100644 --- a/src/vs/editor/common/viewLayout/viewLinesViewportData.ts +++ b/src/vs/editor/common/viewLayout/viewLinesViewportData.ts @@ -70,7 +70,7 @@ export class ViewportData { } public getViewLineRenderingData(lineNumber: number): ViewLineRenderingData { - return this._model.getViewLineRenderingData(this.visibleRange, lineNumber); + return this._model.getViewportViewLineRenderingData(this.visibleRange, lineNumber); } public getDecorationsInViewport(): ViewModelDecoration[] { diff --git a/src/vs/editor/common/viewModel.ts b/src/vs/editor/common/viewModel.ts index e582f7dc719..06e3164ba07 100644 --- a/src/vs/editor/common/viewModel.ts +++ b/src/vs/editor/common/viewModel.ts @@ -41,7 +41,7 @@ export interface IViewModel extends ICursorSimpleModel { onCompositionEnd(): void; getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[]; - getViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData; + getViewportViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData; getViewLineData(lineNumber: number): ViewLineData; getMinimapLinesRenderingData(startLineNumber: number, endLineNumber: number, needed: boolean[]): MinimapLinesRenderingData; getCompletelyVisibleViewRange(): Range; diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index c55cf3d02d1..a990823ab9d 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -679,7 +679,7 @@ export class ViewModel extends Disposable implements IViewModel { return this._lines.getInjectedTextAt(viewPosition); } - public getViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData { + public getViewportViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData { const mightContainRTL = this.model.mightContainRTL(); const mightContainNonBasicASCII = this.model.mightContainNonBasicASCII(); const tabSize = this.getTabSize(); diff --git a/src/vs/editor/test/browser/viewModel/viewModelDecorations.test.ts b/src/vs/editor/test/browser/viewModel/viewModelDecorations.test.ts index 3c0942117e1..9a057ea0ec3 100644 --- a/src/vs/editor/test/browser/viewModel/viewModelDecorations.test.ts +++ b/src/vs/editor/test/browser/viewModel/viewModelDecorations.test.ts @@ -97,7 +97,7 @@ suite('ViewModelDecorations', () => { 'dec14', ]); - const inlineDecorations1 = viewModel.getViewLineRenderingData( + const inlineDecorations1 = viewModel.getViewportViewLineRenderingData( new Range(1, viewModel.getLineMinColumn(1), 2, viewModel.getLineMaxColumn(2)), 1 ).inlineDecorations; @@ -118,7 +118,7 @@ suite('ViewModelDecorations', () => { new InlineDecoration(new Range(1, 2, 1, 2), 'b-dec5', InlineDecorationType.Before), ]); - const inlineDecorations2 = viewModel.getViewLineRenderingData( + const inlineDecorations2 = viewModel.getViewportViewLineRenderingData( new Range(2, viewModel.getLineMinColumn(2), 3, viewModel.getLineMaxColumn(3)), 2 ).inlineDecorations; @@ -148,7 +148,7 @@ suite('ViewModelDecorations', () => { new InlineDecoration(new Range(2, 3, 2, 3), 'b-dec12', InlineDecorationType.Before), ]); - const inlineDecorations3 = viewModel.getViewLineRenderingData( + const inlineDecorations3 = viewModel.getViewportViewLineRenderingData( new Range(2, viewModel.getLineMinColumn(2), 3, viewModel.getLineMaxColumn(3)), 3 ).inlineDecorations; @@ -198,13 +198,13 @@ suite('ViewModelDecorations', () => { ).filter(x => Boolean(x.options.beforeContentClassName)); assert.deepStrictEqual(decorations, []); - const inlineDecorations1 = viewModel.getViewLineRenderingData( + const inlineDecorations1 = viewModel.getViewportViewLineRenderingData( new Range(2, viewModel.getLineMinColumn(2), 3, viewModel.getLineMaxColumn(3)), 2 ).inlineDecorations; assert.deepStrictEqual(inlineDecorations1, []); - const inlineDecorations2 = viewModel.getViewLineRenderingData( + const inlineDecorations2 = viewModel.getViewportViewLineRenderingData( new Range(2, viewModel.getLineMinColumn(2), 3, viewModel.getLineMaxColumn(3)), 3 ).inlineDecorations; @@ -229,7 +229,7 @@ suite('ViewModelDecorations', () => { ); }); - const inlineDecorations = viewModel.getViewLineRenderingData( + const inlineDecorations = viewModel.getViewportViewLineRenderingData( new Range(1, 1, 1, 1), 1 ).inlineDecorations; From 8ced34cb3172528b2c97c2993e7a358c501989bc Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Thu, 28 Jul 2022 13:38:45 +0300 Subject: [PATCH 066/303] Engineering - unify all Code OSS pipeline jobs (#156552) --- build/azure-pipelines/product-build-pr.yml | 328 ++++++++++----------- 1 file changed, 160 insertions(+), 168 deletions(-) diff --git a/build/azure-pipelines/product-build-pr.yml b/build/azure-pipelines/product-build-pr.yml index 1a782b100ee..8362da25ee5 100644 --- a/build/azure-pipelines/product-build-pr.yml +++ b/build/azure-pipelines/product-build-pr.yml @@ -22,176 +22,168 @@ variables: - name: VSCODE_STEP_ON_IT value: false -stages: - - ${{ if eq(variables['VSCODE_CIBUILD'], true) }}: - - stage: MaintainNodeModulesCache - displayName: Maintain node_modules cache - jobs: - - job: MaintainNodeModulesCache - displayName: Maintain node_modules cache - pool: vscode-1es-vscode-linux-20.04 - variables: - VSCODE_ARCH: x64 - steps: - - template: product-build-pr-cache.yml - +jobs: - ${{ if ne(variables['VSCODE_CIBUILD'], true) }}: - - stage: Compile + - job: Compile displayName: Compile & Hygiene - jobs: - - job: Compile - displayName: Compile & Hygiene - pool: vscode-1es-vscode-linux-20.04 - variables: - VSCODE_ARCH: x64 - steps: - - template: product-compile.yml - parameters: - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} + pool: vscode-1es-vscode-linux-20.04 + timeoutInMinutes: 30 + variables: + VSCODE_ARCH: x64 + steps: + - template: product-compile.yml + parameters: + VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - - stage: Test - dependsOn: [] - jobs: - - job: Linuxx64UnitTest - displayName: Linux (Unit Tests) - pool: vscode-1es-vscode-linux-20.04 - # container: vscode-bionic-x64 - timeoutInMinutes: 60 - variables: - VSCODE_ARCH: x64 - NPM_ARCH: x64 - DISPLAY: ":10" - steps: - - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: true - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: false - - job: Linuxx64IntegrationTest - displayName: Linux (Integration Tests) - pool: vscode-1es-vscode-linux-20.04 - # container: vscode-bionic-x64 - timeoutInMinutes: 60 - variables: - VSCODE_ARCH: x64 - NPM_ARCH: x64 - DISPLAY: ":10" - steps: - - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: true - VSCODE_RUN_SMOKE_TESTS: false - - job: Linuxx64SmokeTest - displayName: Linux (Smoke Tests) - pool: vscode-1es-vscode-linux-20.04 - # container: vscode-bionic-x64 - timeoutInMinutes: 60 - variables: - VSCODE_ARCH: x64 - NPM_ARCH: x64 - DISPLAY: ":10" - steps: - - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: true + - job: Linuxx64UnitTest + displayName: Linux (Unit Tests) + pool: vscode-1es-vscode-linux-20.04 + timeoutInMinutes: 30 + variables: + VSCODE_ARCH: x64 + NPM_ARCH: x64 + DISPLAY: ":10" + steps: + - template: linux/product-build-linux-client.yml + parameters: + VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} + VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} + VSCODE_RUN_UNIT_TESTS: true + VSCODE_RUN_INTEGRATION_TESTS: false + VSCODE_RUN_SMOKE_TESTS: false - # - job: macOSUnitTest - # displayName: macOS (Unit Tests) - # pool: - # vmImage: macOS-latest - # timeoutInMinutes: 60 - # variables: - # BUILDSECMON_OPT_IN: true - # VSCODE_ARCH: x64 - # steps: - # - template: darwin/product-build-darwin.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: true - # VSCODE_RUN_INTEGRATION_TESTS: false - # VSCODE_RUN_SMOKE_TESTS: false - # - job: macOSIntegrationTest - # displayName: macOS (Integration Tests) - # pool: - # vmImage: macOS-latest - # timeoutInMinutes: 60 - # variables: - # BUILDSECMON_OPT_IN: true - # VSCODE_ARCH: x64 - # steps: - # - template: darwin/product-build-darwin.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: false - # VSCODE_RUN_INTEGRATION_TESTS: true - # VSCODE_RUN_SMOKE_TESTS: false - # - job: macOSSmokeTest - # displayName: macOS (Smoke Tests) - # pool: - # vmImage: macOS-latest - # timeoutInMinutes: 60 - # variables: - # BUILDSECMON_OPT_IN: true - # VSCODE_ARCH: x64 - # steps: - # - template: darwin/product-build-darwin.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: false - # VSCODE_RUN_INTEGRATION_TESTS: false - # VSCODE_RUN_SMOKE_TESTS: true + - job: Linuxx64IntegrationTest + displayName: Linux (Integration Tests) + pool: vscode-1es-vscode-linux-20.04 + timeoutInMinutes: 30 + variables: + VSCODE_ARCH: x64 + NPM_ARCH: x64 + DISPLAY: ":10" + steps: + - template: linux/product-build-linux-client.yml + parameters: + VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} + VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} + VSCODE_RUN_UNIT_TESTS: false + VSCODE_RUN_INTEGRATION_TESTS: true + VSCODE_RUN_SMOKE_TESTS: false - # - job: WindowsUnitTests - # displayName: Windows (Unit Tests) - # pool: vscode-1es-vscode-windows-2019 - # timeoutInMinutes: 60 - # variables: - # VSCODE_ARCH: x64 - # steps: - # - template: win32/product-build-win32.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: true - # VSCODE_RUN_INTEGRATION_TESTS: false - # VSCODE_RUN_SMOKE_TESTS: false - # - job: WindowsIntegrationTests - # displayName: Windows (Integration Tests) - # pool: vscode-1es-vscode-windows-2019 - # timeoutInMinutes: 60 - # variables: - # VSCODE_ARCH: x64 - # steps: - # - template: win32/product-build-win32.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: false - # VSCODE_RUN_INTEGRATION_TESTS: true - # VSCODE_RUN_SMOKE_TESTS: false - # - job: WindowsSmokeTests - # displayName: Windows (Smoke Tests) - # pool: vscode-1es-vscode-windows-2019 - # timeoutInMinutes: 60 - # variables: - # VSCODE_ARCH: x64 - # steps: - # - template: win32/product-build-win32.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: false - # VSCODE_RUN_INTEGRATION_TESTS: false - # VSCODE_RUN_SMOKE_TESTS: true + - job: Linuxx64SmokeTest + displayName: Linux (Smoke Tests) + pool: vscode-1es-vscode-linux-20.04 + timeoutInMinutes: 30 + variables: + VSCODE_ARCH: x64 + NPM_ARCH: x64 + DISPLAY: ":10" + steps: + - template: linux/product-build-linux-client.yml + parameters: + VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} + VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} + VSCODE_RUN_UNIT_TESTS: false + VSCODE_RUN_INTEGRATION_TESTS: false + VSCODE_RUN_SMOKE_TESTS: true + + - ${{ if eq(variables['VSCODE_CIBUILD'], true) }}: + - job: Linuxx64MaintainNodeModulesCache + displayName: Linux (Maintain node_modules cache) + pool: vscode-1es-vscode-linux-20.04 + timeoutInMinutes: 30 + variables: + VSCODE_ARCH: x64 + steps: + - template: product-build-pr-cache.yml + + # - job: macOSUnitTest + # displayName: macOS (Unit Tests) + # pool: + # vmImage: macOS-latest + # timeoutInMinutes: 60 + # variables: + # BUILDSECMON_OPT_IN: true + # VSCODE_ARCH: x64 + # steps: + # - template: darwin/product-build-darwin.yml + # parameters: + # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} + # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} + # VSCODE_RUN_UNIT_TESTS: true + # VSCODE_RUN_INTEGRATION_TESTS: false + # VSCODE_RUN_SMOKE_TESTS: false + # - job: macOSIntegrationTest + # displayName: macOS (Integration Tests) + # pool: + # vmImage: macOS-latest + # timeoutInMinutes: 60 + # variables: + # BUILDSECMON_OPT_IN: true + # VSCODE_ARCH: x64 + # steps: + # - template: darwin/product-build-darwin.yml + # parameters: + # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} + # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} + # VSCODE_RUN_UNIT_TESTS: false + # VSCODE_RUN_INTEGRATION_TESTS: true + # VSCODE_RUN_SMOKE_TESTS: false + # - job: macOSSmokeTest + # displayName: macOS (Smoke Tests) + # pool: + # vmImage: macOS-latest + # timeoutInMinutes: 60 + # variables: + # BUILDSECMON_OPT_IN: true + # VSCODE_ARCH: x64 + # steps: + # - template: darwin/product-build-darwin.yml + # parameters: + # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} + # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} + # VSCODE_RUN_UNIT_TESTS: false + # VSCODE_RUN_INTEGRATION_TESTS: false + # VSCODE_RUN_SMOKE_TESTS: true + + # - job: WindowsUnitTests + # displayName: Windows (Unit Tests) + # pool: vscode-1es-vscode-windows-2019 + # timeoutInMinutes: 60 + # variables: + # VSCODE_ARCH: x64 + # steps: + # - template: win32/product-build-win32.yml + # parameters: + # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} + # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} + # VSCODE_RUN_UNIT_TESTS: true + # VSCODE_RUN_INTEGRATION_TESTS: false + # VSCODE_RUN_SMOKE_TESTS: false + # - job: WindowsIntegrationTests + # displayName: Windows (Integration Tests) + # pool: vscode-1es-vscode-windows-2019 + # timeoutInMinutes: 60 + # variables: + # VSCODE_ARCH: x64 + # steps: + # - template: win32/product-build-win32.yml + # parameters: + # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} + # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} + # VSCODE_RUN_UNIT_TESTS: false + # VSCODE_RUN_INTEGRATION_TESTS: true + # VSCODE_RUN_SMOKE_TESTS: false + # - job: WindowsSmokeTests + # displayName: Windows (Smoke Tests) + # pool: vscode-1es-vscode-windows-2019 + # timeoutInMinutes: 60 + # variables: + # VSCODE_ARCH: x64 + # steps: + # - template: win32/product-build-win32.yml + # parameters: + # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} + # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} + # VSCODE_RUN_UNIT_TESTS: false + # VSCODE_RUN_INTEGRATION_TESTS: false + # VSCODE_RUN_SMOKE_TESTS: true From 463d53f24eac85c81e57371135c3bc744157d5e1 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 28 Jul 2022 13:12:20 +0200 Subject: [PATCH 067/303] Fixes #156328: Use editor API to determine the top and bottom for line numbers Co-authored-by: aiday-mar --- src/vs/editor/browser/editorBrowser.ts | 7 +++- .../stickyScroll/browser/stickyScroll.ts | 40 +++++-------------- src/vs/monaco.d.ts | 6 ++- 3 files changed, 20 insertions(+), 33 deletions(-) diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index f91574dc4cb..25c2bbe8445 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -899,10 +899,15 @@ export interface ICodeEditor extends editorCommon.IEditor { getWhitespaces(): IEditorWhitespace[]; /** - * Get the vertical position (top offset) for the line w.r.t. to the first line. + * Get the vertical position (top offset) for the line's top w.r.t. to the first line. */ getTopForLineNumber(lineNumber: number): number; + /** + * Get the vertical position (top offset) for the line's bottom w.r.t. to the first line. + */ + getBottomForLineNumber(lineNumber: number): number; + /** * Get the vertical position (top offset) for the position w.r.t. to the first line. */ diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index 002828096d5..d7f669d3caa 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -19,12 +19,6 @@ import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations'; import { RunOnceScheduler } from 'vs/base/common/async'; import { IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; -const enum ScrollDirection { - Down = 0, - Up = 1, - None = 2 -} - class StickyScrollController extends Disposable implements IEditorContribution { static readonly ID = 'store.contrib.stickyScrollController'; @@ -36,7 +30,6 @@ class StickyScrollController extends Disposable implements IEditorContribution { private _ranges: [number, number, number][] = []; private _rangesVersionId: number = 0; private _cts: CancellationTokenSource | undefined; - private _lastScrollPosition: number = -1; private readonly _updateSoon: RunOnceScheduler; constructor( @@ -191,42 +184,27 @@ class StickyScrollController extends Disposable implements IEditorContribution { return; } const scrollTop = this._editor.getScrollTop(); - let scrollDirection: ScrollDirection; - if (this._lastScrollPosition < scrollTop) { - scrollDirection = ScrollDirection.Down; - } else { - scrollDirection = ScrollDirection.Up; - } - this._lastScrollPosition = scrollTop; - const scrollToBottomOfWidget = this._editor.getScrollTop() + this.stickyScrollWidget.codeLineCount * lineHeight; this.stickyScrollWidget.emptyRootNode(); const beginningLinesConsidered: Set = new Set(); - let topOfElementAtDepth: number; - let bottomOfElementAtDepth: number; - let bottomOfBeginningLine: number; - let topOfEndLine: number; - let bottomOfEndLine: number; for (const [index, arr] of this._ranges.entries()) { const [start, end, depth] = arr; if (end - start > 0 && model.getLineContent(start) !== '') { - topOfElementAtDepth = this._editor.getScrollTop() + (depth - 1) * lineHeight; - bottomOfElementAtDepth = this._editor.getScrollTop() + depth * lineHeight; - bottomOfBeginningLine = start * lineHeight; - topOfEndLine = (end - 1) * lineHeight; - bottomOfEndLine = end * lineHeight; + const topOfElementAtDepth = (depth - 1) * lineHeight; + const bottomOfElementAtDepth = depth * lineHeight; + + const bottomOfBeginningLine = this._editor.getBottomForLineNumber(start) - scrollTop; + const topOfEndLine = this._editor.getTopForLineNumber(end) - scrollTop; + const bottomOfEndLine = this._editor.getBottomForLineNumber(end) - scrollTop; + if (!beginningLinesConsidered.has(start)) { if (topOfElementAtDepth >= topOfEndLine - 1 && topOfElementAtDepth < bottomOfEndLine - 2) { beginningLinesConsidered.add(start); this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth)); break; } - else if (scrollDirection === ScrollDirection.Down && bottomOfElementAtDepth > bottomOfBeginningLine - 1 && bottomOfElementAtDepth < bottomOfEndLine - 1) { - beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, 0, 0)); - } else if (scrollDirection === ScrollDirection.Up && scrollToBottomOfWidget > bottomOfBeginningLine - 1 && scrollToBottomOfWidget < bottomOfEndLine || - scrollDirection === ScrollDirection.Up && bottomOfElementAtDepth > bottomOfBeginningLine && bottomOfElementAtDepth < topOfEndLine - 1) { + else if (bottomOfElementAtDepth > bottomOfBeginningLine - 1 && bottomOfElementAtDepth < bottomOfEndLine - 1) { beginningLinesConsidered.add(start); this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, 0, 0)); } @@ -262,7 +240,7 @@ class StickyScrollCodeLine { getDomNode() { const root: HTMLElement = document.createElement('div'); - const lineRenderingData = this._editor._getViewModel().getViewLineRenderingData(this._editor.getVisibleRangesPlusViewportAboveBelow()[0], this._lineNumber); + const lineRenderingData = this._editor._getViewModel().getViewportViewLineRenderingData(this._editor.getVisibleRangesPlusViewportAboveBelow()[0], this._lineNumber); let actualInlineDecorations: LineDecoration[]; try { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index db39c17f9c6..91b72dd4d11 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -5372,9 +5372,13 @@ declare namespace monaco.editor { */ getVisibleRanges(): Range[]; /** - * Get the vertical position (top offset) for the line w.r.t. to the first line. + * Get the vertical position (top offset) for the line's top w.r.t. to the first line. */ getTopForLineNumber(lineNumber: number): number; + /** + * Get the vertical position (top offset) for the line's bottom w.r.t. to the first line. + */ + getBottomForLineNumber(lineNumber: number): number; /** * Get the vertical position (top offset) for the position w.r.t. to the first line. */ From 469465b703e1594d62c65379b4189da0985a07a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 28 Jul 2022 12:28:43 +0100 Subject: [PATCH 068/303] fix issue with multiple tree filters related to #156127 --- src/vs/base/browser/ui/tree/abstractTree.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 7a75aa8070a..9f0b7aef2fc 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -593,11 +593,11 @@ class FindFilter implements ITreeFilter, IDi } filter(element: T, parentVisibility: TreeVisibility): TreeFilterResult { + let visibility = TreeVisibility.Visible; + if (this._filter) { const result = this._filter.filter(element, parentVisibility); - let visibility: TreeVisibility; - if (typeof result === 'boolean') { visibility = result ? TreeVisibility.Visible : TreeVisibility.Hidden; } else if (isFilterResult(result)) { @@ -615,7 +615,7 @@ class FindFilter implements ITreeFilter, IDi if (!this._pattern) { this._matchCount++; - return { data: FuzzyScore.Default, visibility: true }; + return { data: FuzzyScore.Default, visibility }; } const label = this.keyboardNavigationLabelProvider.getKeyboardNavigationLabel(element); @@ -624,22 +624,22 @@ class FindFilter implements ITreeFilter, IDi for (const l of labels) { const labelStr = l && l.toString(); if (typeof labelStr === 'undefined') { - return { data: FuzzyScore.Default, visibility: true }; + return { data: FuzzyScore.Default, visibility }; } const score = fuzzyScore(this._pattern, this._lowercasePattern, 0, labelStr, labelStr.toLowerCase(), 0, { firstMatchCanBeWeak: true, boostFullMatch: true }); if (score) { this._matchCount++; return labels.length === 1 ? - { data: score, visibility: true } : - { data: { label: labelStr, score: score }, visibility: true }; + { data: score, visibility } : + { data: { label: labelStr, score: score }, visibility }; } } if (this.tree.findMode === TreeFindMode.Filter) { return TreeVisibility.Recurse; } else { - return { data: FuzzyScore.Default, visibility: true }; + return { data: FuzzyScore.Default, visibility }; } } From baa2e394fb9b6bdde2ad40e60cd7ec382d5077e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 28 Jul 2022 12:37:10 +0100 Subject: [PATCH 069/303] disable find widget for testing view --- src/vs/base/browser/ui/tree/abstractTree.ts | 3 ++- .../workbench/contrib/testing/browser/testingExplorerView.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 9f0b7aef2fc..8b99d57080c 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1022,6 +1022,7 @@ export interface IAbstractTreeOptions extends IAbstractTr readonly filter?: ITreeFilter; readonly dnd?: ITreeDragAndDrop; readonly additionalScrollHeight?: number; + readonly findWidgetEnabled?: boolean; } function dfs(node: ITreeNode, fn: (node: ITreeNode) => void): void { @@ -1436,7 +1437,7 @@ export abstract class AbstractTree implements IDisposable onKeyDown.filter(e => e.keyCode === KeyCode.Space).on(this.onSpace, this, this.disposables); } - if (_options.keyboardNavigationLabelProvider && _options.contextViewProvider) { + if ((_options.findWidgetEnabled ?? true) && _options.keyboardNavigationLabelProvider && _options.contextViewProvider) { this.findController = new FindController(this, this.model, this.view, filter!, _options.contextViewProvider); this.focusNavigationFilter = node => this.findController!.shouldAllowFocus(node); this.onDidChangeFindOpenState = this.findController.onDidChangeOpenState; diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts index 2281441286a..a326f747bc5 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts @@ -491,6 +491,7 @@ export class TestingExplorerViewModel extends Disposable { keyboardNavigationLabelProvider: instantiationService.createInstance(TreeKeyboardNavigationLabelProvider), accessibilityProvider: instantiationService.createInstance(ListAccessibilityProvider), filter: this.filter, + findWidgetEnabled: false }) as WorkbenchObjectTree; this._register(this.tree.onDidChangeCollapseState(evt => { From 95fd5bf198bc9f0083421ce5a53c05ca0294a7fd Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Thu, 28 Jul 2022 15:10:19 +0200 Subject: [PATCH 070/303] Make sure to use view line numbers when fetching data from the view model (#156569) Fixes #156413: Make sure to use view line numbers when fetching data from the view model Co-authored-by: aiday-mar Co-authored-by: aiday-mar --- src/vs/editor/common/viewModel.ts | 1 + .../common/viewModel/viewModelDecorations.ts | 14 +++++++++----- src/vs/editor/common/viewModel/viewModelImpl.ts | 15 ++++++++++++--- .../contrib/stickyScroll/browser/stickyScroll.ts | 15 +++++++++------ 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/vs/editor/common/viewModel.ts b/src/vs/editor/common/viewModel.ts index 06e3164ba07..d4b67391d99 100644 --- a/src/vs/editor/common/viewModel.ts +++ b/src/vs/editor/common/viewModel.ts @@ -42,6 +42,7 @@ export interface IViewModel extends ICursorSimpleModel { getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[]; getViewportViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData; + getViewLineRenderingData(lineNumber: number): ViewLineRenderingData; getViewLineData(lineNumber: number): ViewLineData; getMinimapLinesRenderingData(startLineNumber: number, endLineNumber: number, needed: boolean[]): MinimapLinesRenderingData; getCompletelyVisibleViewRange(): Range; diff --git a/src/vs/editor/common/viewModel/viewModelDecorations.ts b/src/vs/editor/common/viewModel/viewModelDecorations.ts index 909d9f19bc3..25edc82d950 100644 --- a/src/vs/editor/common/viewModel/viewModelDecorations.ts +++ b/src/vs/editor/common/viewModel/viewModelDecorations.ts @@ -100,17 +100,21 @@ export class ViewModelDecorations implements IDisposable { let cacheIsValid = (this._cachedModelDecorationsResolver !== null); cacheIsValid = cacheIsValid && (viewRange.equalsRange(this._cachedModelDecorationsResolverViewRange)); if (!cacheIsValid) { - this._cachedModelDecorationsResolver = this._getDecorationsViewportData(viewRange); + this._cachedModelDecorationsResolver = this._getDecorationsInRange(viewRange); this._cachedModelDecorationsResolverViewRange = viewRange; } return this._cachedModelDecorationsResolver!; } - private _getDecorationsViewportData(viewportRange: Range): IDecorationsViewportData { - const modelDecorations = this._linesCollection.getDecorationsInRange(viewportRange, this.editorId, filterValidationDecorations(this.configuration.options)); + public getInlineDecorationsOnLine(lineNumber: number): InlineDecoration[] { + const range = new Range(lineNumber, this._linesCollection.getViewLineMinColumn(lineNumber), lineNumber, this._linesCollection.getViewLineMaxColumn(lineNumber)); + return this._getDecorationsInRange(range).inlineDecorations[0]; + } - const startLineNumber = viewportRange.startLineNumber; - const endLineNumber = viewportRange.endLineNumber; + private _getDecorationsInRange(viewRange: Range): IDecorationsViewportData { + const modelDecorations = this._linesCollection.getDecorationsInRange(viewRange, this.editorId, filterValidationDecorations(this.configuration.options)); + const startLineNumber = viewRange.startLineNumber; + const endLineNumber = viewRange.endLineNumber; const decorationsInViewport: ViewModelDecoration[] = []; let decorationsInViewportLen = 0; diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index a990823ab9d..160d63c8b33 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -34,7 +34,7 @@ import { ViewLayout } from 'vs/editor/common/viewLayout/viewLayout'; import { MinimapTokensColorTracker } from 'vs/editor/common/viewModel/minimapTokensColorTracker'; import { ILineBreaksComputer, ILineBreaksComputerFactory, InjectedText } from 'vs/editor/common/modelLineProjectionData'; import { ViewEventHandler } from 'vs/editor/common/viewEventHandler'; -import { ICoordinatesConverter, IViewModel, IWhitespaceChangeAccessor, MinimapLinesRenderingData, OverviewRulerDecorationsGroup, ViewLineData, ViewLineRenderingData, ViewModelDecoration } from 'vs/editor/common/viewModel'; +import { ICoordinatesConverter, InlineDecoration, IViewModel, IWhitespaceChangeAccessor, MinimapLinesRenderingData, OverviewRulerDecorationsGroup, ViewLineData, ViewLineRenderingData, ViewModelDecoration } from 'vs/editor/common/viewModel'; import { ViewModelDecorations } from 'vs/editor/common/viewModel/viewModelDecorations'; import { FocusChangedEvent, ModelContentChangedEvent, ModelDecorationsChangedEvent, ModelLanguageChangedEvent, ModelLanguageConfigurationChangedEvent, ModelOptionsChangedEvent, ModelTokensChangedEvent, OutgoingViewModelEvent, ReadOnlyEditAttemptEvent, ScrollChangedEvent, ViewModelEventDispatcher, ViewModelEventsCollector, ViewZonesChangedEvent } from 'vs/editor/common/viewModelEventDispatcher'; import { IViewModelLines, ViewModelLinesFromModelAsIs, ViewModelLinesFromProjectedModel } from 'vs/editor/common/viewModel/viewModelLines'; @@ -680,12 +680,21 @@ export class ViewModel extends Disposable implements IViewModel { } public getViewportViewLineRenderingData(visibleRange: Range, lineNumber: number): ViewLineRenderingData { + const allInlineDecorations = this._decorations.getDecorationsViewportData(visibleRange).inlineDecorations; + const inlineDecorations = allInlineDecorations[lineNumber - visibleRange.startLineNumber]; + return this._getViewLineRenderingData(lineNumber, inlineDecorations); + } + + public getViewLineRenderingData(lineNumber: number): ViewLineRenderingData { + const inlineDecorations = this._decorations.getInlineDecorationsOnLine(lineNumber); + return this._getViewLineRenderingData(lineNumber, inlineDecorations); + } + + private _getViewLineRenderingData(lineNumber: number, inlineDecorations: InlineDecoration[]): ViewLineRenderingData { const mightContainRTL = this.model.mightContainRTL(); const mightContainNonBasicASCII = this.model.mightContainNonBasicASCII(); const tabSize = this.getTabSize(); const lineData = this._lines.getViewLineData(lineNumber); - const allInlineDecorations = this._decorations.getDecorationsViewportData(visibleRange).inlineDecorations; - let inlineDecorations = allInlineDecorations[lineNumber - visibleRange.startLineNumber]; if (lineData.inlineDecorations) { inlineDecorations = [ diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index d7f669d3caa..899d3db5fc6 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -18,6 +18,7 @@ import { SymbolKind } from 'vs/editor/common/languages'; import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations'; import { RunOnceScheduler } from 'vs/base/common/async'; import { IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; +import { Position } from 'vs/editor/common/core/position'; class StickyScrollController extends Disposable implements IEditorContribution { @@ -201,12 +202,12 @@ class StickyScrollController extends Disposable implements IEditorContribution { if (!beginningLinesConsidered.has(start)) { if (topOfElementAtDepth >= topOfEndLine - 1 && topOfElementAtDepth < bottomOfEndLine - 2) { beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth)); + this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth)); break; } else if (bottomOfElementAtDepth > bottomOfBeginningLine - 1 && bottomOfElementAtDepth < bottomOfEndLine - 1) { beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(model.getLineContent(start), start, this._editor, 0, 0)); + this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, this._editor, 0, 0)); } } else { this._ranges.splice(index, 1); @@ -228,7 +229,7 @@ class StickyScrollCodeLine { public readonly effectiveLineHeight: number = 0; - constructor(private readonly _line: string, private readonly _lineNumber: number, private readonly _editor: IActiveCodeEditor, + constructor(private readonly _lineNumber: number, private readonly _editor: IActiveCodeEditor, private readonly _zIndex: number, private readonly _relativePosition: number) { this.effectiveLineHeight = this._editor.getOption(EditorOption.lineHeight) + this._relativePosition; } @@ -240,16 +241,18 @@ class StickyScrollCodeLine { getDomNode() { const root: HTMLElement = document.createElement('div'); - const lineRenderingData = this._editor._getViewModel().getViewportViewLineRenderingData(this._editor.getVisibleRangesPlusViewportAboveBelow()[0], this._lineNumber); + const viewModel = this._editor._getViewModel(); + const viewLineNumber = viewModel.coordinatesConverter.convertModelPositionToViewPosition(new Position(this._lineNumber, 1)).lineNumber; + const lineRenderingData = viewModel.getViewLineRenderingData(viewLineNumber); let actualInlineDecorations: LineDecoration[]; try { - actualInlineDecorations = LineDecoration.filter(lineRenderingData.inlineDecorations, this._lineNumber, lineRenderingData.minColumn, lineRenderingData.maxColumn); + actualInlineDecorations = LineDecoration.filter(lineRenderingData.inlineDecorations, viewLineNumber, lineRenderingData.minColumn, lineRenderingData.maxColumn); } catch (err) { actualInlineDecorations = []; } - const renderLineInput: RenderLineInput = new RenderLineInput(true, true, this._line, lineRenderingData.continuesWithWrappedLine, + const renderLineInput: RenderLineInput = new RenderLineInput(true, true, lineRenderingData.content, lineRenderingData.continuesWithWrappedLine, lineRenderingData.isBasicASCII, lineRenderingData.containsRTL, 0, lineRenderingData.tokens, actualInlineDecorations, lineRenderingData.tabSize, lineRenderingData.startVisibleColumn, 1, 1, 1, 100, 'none', true, true, null); From e65cf31952eb7d7a925b12da13726ea832c56b34 Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Thu, 28 Jul 2022 15:23:14 +0200 Subject: [PATCH 071/303] Fix view model event and expose a way to get hidden areas (#156571) * Fix emitting of wrong event in view model * Add `IViewModel.getHiddenAreas` --- src/vs/editor/common/viewModel.ts | 2 ++ src/vs/editor/common/viewModel/viewModelImpl.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/common/viewModel.ts b/src/vs/editor/common/viewModel.ts index d4b67391d99..55f613af360 100644 --- a/src/vs/editor/common/viewModel.ts +++ b/src/vs/editor/common/viewModel.ts @@ -48,6 +48,8 @@ export interface IViewModel extends ICursorSimpleModel { getCompletelyVisibleViewRange(): Range; getCompletelyVisibleViewRangeAtScrollTop(scrollTop: number): Range; + getHiddenAreas(): Range[]; + getLineCount(): number; getLineContent(lineNumber: number): string; getLineLength(lineNumber: number): number; diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index 160d63c8b33..a241643468e 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -36,7 +36,7 @@ import { ILineBreaksComputer, ILineBreaksComputerFactory, InjectedText } from 'v import { ViewEventHandler } from 'vs/editor/common/viewEventHandler'; import { ICoordinatesConverter, InlineDecoration, IViewModel, IWhitespaceChangeAccessor, MinimapLinesRenderingData, OverviewRulerDecorationsGroup, ViewLineData, ViewLineRenderingData, ViewModelDecoration } from 'vs/editor/common/viewModel'; import { ViewModelDecorations } from 'vs/editor/common/viewModel/viewModelDecorations'; -import { FocusChangedEvent, ModelContentChangedEvent, ModelDecorationsChangedEvent, ModelLanguageChangedEvent, ModelLanguageConfigurationChangedEvent, ModelOptionsChangedEvent, ModelTokensChangedEvent, OutgoingViewModelEvent, ReadOnlyEditAttemptEvent, ScrollChangedEvent, ViewModelEventDispatcher, ViewModelEventsCollector, ViewZonesChangedEvent } from 'vs/editor/common/viewModelEventDispatcher'; +import { FocusChangedEvent, HiddenAreasChangedEvent, ModelContentChangedEvent, ModelDecorationsChangedEvent, ModelLanguageChangedEvent, ModelLanguageConfigurationChangedEvent, ModelOptionsChangedEvent, ModelTokensChangedEvent, OutgoingViewModelEvent, ReadOnlyEditAttemptEvent, ScrollChangedEvent, ViewModelEventDispatcher, ViewModelEventsCollector, ViewZonesChangedEvent } from 'vs/editor/common/viewModelEventDispatcher'; import { IViewModelLines, ViewModelLinesFromModelAsIs, ViewModelLinesFromProjectedModel } from 'vs/editor/common/viewModel/viewModelLines'; import { IThemeService } from 'vs/platform/theme/common/themeService'; @@ -485,7 +485,7 @@ export class ViewModel extends Disposable implements IViewModel { this._updateConfigurationViewLineCount.schedule(); if (lineMappingChanged) { - this._eventDispatcher.emitOutgoingEvent(new ViewZonesChangedEvent()); + this._eventDispatcher.emitOutgoingEvent(new HiddenAreasChangedEvent()); } } @@ -508,6 +508,10 @@ export class ViewModel extends Disposable implements IViewModel { return this._toModelVisibleRanges(visibleViewRange); } + public getHiddenAreas(): Range[] { + return this._lines.getHiddenAreas(); + } + private _toModelVisibleRanges(visibleViewRange: Range): Range[] { const visibleRange = this.coordinatesConverter.convertViewRangeToModelRange(visibleViewRange); const hiddenAreas = this._lines.getHiddenAreas(); From 1fdade8d07d9c8b0aca3923fc7bb52df4c104264 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 28 Jul 2022 15:26:16 +0200 Subject: [PATCH 072/303] TreeView reveal fails to scroll to item when focusing and a different selection exists (#156572) Fixes #152803 --- src/vs/workbench/browser/parts/views/treeView.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index 4f8aa7d5b3a..3c9b24faefd 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -496,12 +496,12 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { protected abstract activate(): void; - focus(reveal: boolean = true): void { + focus(reveal: boolean = true, revealItem?: ITreeItem): void { if (this.tree && this.root.children && this.root.children.length > 0) { // Make sure the current selected element is revealed - const selectedElement = this.tree.getSelection()[0]; - if (selectedElement && reveal) { - this.tree.reveal(selectedElement, 0.5); + const element = revealItem ?? this.tree.getSelection()[0]; + if (element && reveal) { + this.tree.reveal(element, 0.5); } // Pass Focus to Viewer @@ -784,7 +784,7 @@ abstract class AbstractTreeView extends Disposable implements ITreeView { setFocus(item: ITreeItem): void { if (this.tree) { - this.focus(); + this.focus(true, item); this.tree.setFocus([item]); } } From cb7a75ea2d379ed103314ecd5887edddf4f08efb Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 28 Jul 2022 15:32:17 +0200 Subject: [PATCH 073/303] Consider using regular folding icons for manual or preserved folding ranges. Fixes #156279 (#156573) --- src/vs/editor/contrib/folding/browser/folding.css | 3 --- src/vs/editor/contrib/folding/browser/foldingDecorations.ts | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/contrib/folding/browser/folding.css b/src/vs/editor/contrib/folding/browser/folding.css index 232384ce3d5..4f70d1097fe 100644 --- a/src/vs/editor/contrib/folding/browser/folding.css +++ b/src/vs/editor/contrib/folding/browser/folding.css @@ -32,6 +32,3 @@ cursor: pointer; } -.monaco-editor .margin-view-overlays .codicon.codicon-folding-manual-expanded::before { - transform: rotate(90deg); -} diff --git a/src/vs/editor/contrib/folding/browser/foldingDecorations.ts b/src/vs/editor/contrib/folding/browser/foldingDecorations.ts index 9ad6cb77605..413d0ae9a74 100644 --- a/src/vs/editor/contrib/folding/browser/foldingDecorations.ts +++ b/src/vs/editor/contrib/folding/browser/foldingDecorations.ts @@ -14,8 +14,8 @@ import { ThemeIcon } from 'vs/platform/theme/common/themeService'; export const foldingExpandedIcon = registerIcon('folding-expanded', Codicon.chevronDown, localize('foldingExpandedIcon', 'Icon for expanded ranges in the editor glyph margin.')); export const foldingCollapsedIcon = registerIcon('folding-collapsed', Codicon.chevronRight, localize('foldingCollapsedIcon', 'Icon for collapsed ranges in the editor glyph margin.')); -export const foldingManualCollapsedIcon = registerIcon('folding-manual-collapsed', Codicon.ellipsis, localize('foldingManualCollapedIcon', 'Icon for manually collapsed ranges in the editor glyph margin.')); -export const foldingManualExpandedIcon = registerIcon('folding-manual-expanded', Codicon.ellipsis, localize('foldingManualExpandedIcon', 'Icon for manually expanded ranges in the editor glyph margin.')); +export const foldingManualCollapsedIcon = registerIcon('folding-manual-collapsed', foldingCollapsedIcon, localize('foldingManualCollapedIcon', 'Icon for manually collapsed ranges in the editor glyph margin.')); +export const foldingManualExpandedIcon = registerIcon('folding-manual-expanded', foldingExpandedIcon, localize('foldingManualExpandedIcon', 'Icon for manually expanded ranges in the editor glyph margin.')); export class FoldingDecorationProvider implements IDecorationProvider { From 589aba9097a564d85719a4c955a06e377aa96365 Mon Sep 17 00:00:00 2001 From: aiday-mar Date: Thu, 28 Jul 2022 16:09:08 +0200 Subject: [PATCH 074/303] Filtering the ranges with the hidden ranges from folding. Fixes #156268. --- .../editor/contrib/stickyScroll/browser/stickyScroll.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index 899d3db5fc6..637f7e4ab73 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -19,6 +19,7 @@ import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations'; import { RunOnceScheduler } from 'vs/base/common/async'; import { IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; import { Position } from 'vs/editor/common/core/position'; +import { Range } from 'vs/editor/common/core/range'; class StickyScrollController extends Disposable implements IEditorContribution { @@ -61,6 +62,7 @@ class StickyScrollController extends Disposable implements IEditorContribution { this._editor.addOverlayWidget(this.stickyScrollWidget); this._sessionStore.add(this._editor.onDidChangeModel(() => this._update(true))); this._sessionStore.add(this._editor.onDidScrollChange(() => this._update(false))); + this._sessionStore.add(this._editor.onDidChangeHiddenAreas(() => this._update(true))); this._sessionStore.add(this._editor.onDidChangeModelTokens((e) => this._onTokensChange(e))); this._sessionStore.add(this._editor.onDidChangeModelContent(() => this._updateSoon.schedule())); this._sessionStore.add(this._languageFeaturesService.documentSymbolProvider.onDidChange(() => this._update(true))); @@ -92,6 +94,12 @@ class StickyScrollController extends Disposable implements IEditorContribution { this._cts = new CancellationTokenSource(); await this._updateOutlineModel(this._cts.token); } + const hiddenRanges: Range[] | undefined = this._editor._getViewModel()?.getHiddenAreas(); + if (hiddenRanges) { + for (const hiddenRange of hiddenRanges) { + this._ranges = this._ranges.filter(range => { return !(range[0] >= hiddenRange.startLineNumber && range[1] <= hiddenRange.endLineNumber + 1); }); + } + } this._renderStickyScroll(); } From 3bf342b7c4d0cf504c78fe2731259b41af17c90a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 28 Jul 2022 16:19:32 +0200 Subject: [PATCH 075/303] Adjust tree find widget padding (#156577) fixes #156244 --- src/vs/base/browser/ui/tree/media/tree.css | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index f6dceb39e95..7f740a6ee1a 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -87,6 +87,7 @@ align-items: center; justify-content: center; cursor: grab; + margin-right: 2px; } .monaco-tree-type-filter-grab.grabbing { @@ -98,12 +99,16 @@ } .monaco-tree-type-filter-input .monaco-inputbox { - height: 26px; + height: 23px; } .monaco-tree-type-filter-input .monaco-inputbox > .ibwrapper > .input, .monaco-tree-type-filter-input .monaco-inputbox > .ibwrapper > .mirror { - padding: 2px; + padding: 2px 4px; +} + +.monaco-tree-type-filter-input .monaco-findInput > .controls { + top: 2px; } .monaco-tree-type-filter-actionbar { From fad1b7c7c2ca0097b4007027cfcc9b485d78b590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 28 Jul 2022 16:33:50 +0200 Subject: [PATCH 076/303] Fine tune tree find widget layout (#156579) fixes #156247 --- src/vs/base/browser/ui/tree/abstractTree.ts | 2 +- src/vs/base/browser/ui/tree/media/tree.css | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 7a75aa8070a..618efe8b08c 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -799,7 +799,7 @@ class FindWidget extends Disposable { layout(width: number = this.width): void { this.width = width; - this.right = Math.min(Math.max(20, this.right), Math.max(20, width - 170)); + this.right = clamp(this.right, 0, Math.max(0, width - 212)); this.elements.root.style.right = `${this.right}px`; } diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 7f740a6ee1a..1a2c0492ea7 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -74,8 +74,9 @@ display: flex; padding: 3px; transition: top 0.3s; - width: 160px; + max-width: 200px; z-index: 100; + margin: 0 6px; } .monaco-tree-type-filter.disabled { From f4d4971d75fe4ee2ee9b096f565141b9e61a2747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 28 Jul 2022 16:37:06 +0200 Subject: [PATCH 077/303] Existing trees should react to changes to `workbench.list.defaultFindMode` (#156581) fixes #156249 --- src/vs/base/browser/ui/tree/abstractTree.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 618efe8b08c..ca481ab1f31 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -876,7 +876,8 @@ class FindController implements IDisposable { return; } - this.widget = new FindWidget(this.view.getHTMLElement(), this.tree, this.contextViewProvider, this._mode, this.styles); + this.mode = this.tree.options.defaultFindMode ?? TreeFindMode.Highlight; + this.widget = new FindWidget(this.view.getHTMLElement(), this.tree, this.contextViewProvider, this.mode, this.styles); this.enabledDisposables.add(this.widget); this.widget.onDidChangeValue(this.onDidChangeValue, this, this.enabledDisposables); From 5d16a27d452dbbd1f6fc77ea2330a4f1139b06cc Mon Sep 17 00:00:00 2001 From: aiday-mar Date: Thu, 28 Jul 2022 17:10:33 +0200 Subject: [PATCH 078/303] Rendering the sticky line when one pixel into the line. Fixes #156566. --- .../contrib/stickyScroll/browser/stickyScroll.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index 637f7e4ab73..c42d96dff27 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -210,12 +210,12 @@ class StickyScrollController extends Disposable implements IEditorContribution { if (!beginningLinesConsidered.has(start)) { if (topOfElementAtDepth >= topOfEndLine - 1 && topOfElementAtDepth < bottomOfEndLine - 2) { beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth)); + this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, depth, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth)); break; } - else if (bottomOfElementAtDepth > bottomOfBeginningLine - 1 && bottomOfElementAtDepth < bottomOfEndLine - 1) { + else if (bottomOfElementAtDepth > bottomOfBeginningLine && bottomOfElementAtDepth < bottomOfEndLine - 1) { beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, this._editor, 0, 0)); + this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, depth, this._editor, 0, 0)); } } else { this._ranges.splice(index, 1); @@ -237,7 +237,7 @@ class StickyScrollCodeLine { public readonly effectiveLineHeight: number = 0; - constructor(private readonly _lineNumber: number, private readonly _editor: IActiveCodeEditor, + constructor(private readonly _lineNumber: number, private readonly _depth: number, private readonly _editor: IActiveCodeEditor, private readonly _zIndex: number, private readonly _relativePosition: number) { this.effectiveLineHeight = this._editor.getOption(EditorOption.lineHeight) + this._relativePosition; } @@ -302,8 +302,9 @@ class StickyScrollCodeLine { root.onclick = e => { e.stopPropagation(); e.preventDefault(); - this._editor.revealLine(this._lineNumber); + this._editor.revealPosition({ lineNumber: this._lineNumber - this._depth + 1, column: 1 }); }; + root.onmouseover = e => { innerLineNumberHTML.style.background = `var(--vscode-editorStickyScrollHover-background)`; lineHTMLNode.style.backgroundColor = `var(--vscode-editorStickyScrollHover-background)`; @@ -353,7 +354,7 @@ class StickyScrollWidget implements IOverlayWidget { constructor(public readonly _editor: ICodeEditor) { this.rootDomNode = document.createElement('div'); this.rootDomNode.style.width = '100%'; - this.rootDomNode.style.boxShadow = `var(--vscode-scrollbar-shadow) 0 6px 6px -6px`; // '0px 0px 8px 2px #000000'; + this.rootDomNode.style.boxShadow = `var(--vscode-scrollbar-shadow) 0 6px 6px -6px`; } get codeLineCount() { From 9c4a29cc58ce0e8f6eeb8a555a40e5d73435ea88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 28 Jul 2022 17:27:00 +0200 Subject: [PATCH 079/303] Make sure tree find widget can be moved using the keyboard (#156583) fixes #156251 --- src/vs/base/browser/dom.ts | 6 +++-- src/vs/base/browser/ui/tree/abstractTree.ts | 26 +++++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 4019ea90b61..06d13c90d93 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -1869,9 +1869,11 @@ export function h(tag: string, ...args: [] | [attributes: { $: string } & Partia typeof cssValue === 'number' ? cssValue + 'px' : '' + cssValue ); } - continue; + } else if (key === 'tabIndex') { + el.tabIndex = value; + } else { + el.setAttribute(camelCaseToHyphenCase(key), value.toString()); } - el.setAttribute(camelCaseToHyphenCase(key), value.toString()); } result['root'] = el; diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 45c7e9e98db..1032f3e48a9 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -685,7 +685,7 @@ export enum TreeFindMode { class FindWidget extends Disposable { private readonly elements = h('.monaco-tree-type-filter', [ - h('.monaco-tree-type-filter-grab.codicon.codicon-debug-gripper@grab'), + h('.monaco-tree-type-filter-grab.codicon.codicon-debug-gripper@grab', { tabIndex: 0 }), h('.monaco-tree-type-filter-input@findInput'), h('.monaco-tree-type-filter-actionbar@actionbar'), ]); @@ -699,7 +699,7 @@ class FindWidget extends Disposable { private readonly findInput: FindInput; private readonly actionbar: ActionBar; private width = 0; - private right = 4; + private right = 0; readonly _onDidDisable = new Emitter(); readonly onDidDisable = this._onDidDisable.event; @@ -772,6 +772,28 @@ class FindWidget extends Disposable { })); })); + const onGrabKeyDown = this._register(Event.chain(this._register(new DomEmitter(this.elements.grab, 'keydown')).event)) + .map(e => new StandardKeyboardEvent(e)) + .event; + + this._register(onGrabKeyDown((e): any => { + let right: number | undefined; + + if (e.keyCode === KeyCode.LeftArrow) { + right = Number.POSITIVE_INFINITY; + } else if (e.keyCode === KeyCode.RightArrow) { + right = 0; + } else if (e.keyCode === KeyCode.Space) { + right = this.right === 0 ? Number.POSITIVE_INFINITY : 0; + } + + if (right !== undefined) { + e.preventDefault(); + e.stopPropagation(); + this.right = right; + this.layout(); + } + })); this.onDidChangeValue = this.findInput.onDidChange; this.style(options ?? {}); From e45b7a5a426802fb475b3a0856b80b313f2c9411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 28 Jul 2022 17:27:25 +0200 Subject: [PATCH 080/303] Tree keyboard navigation should not steal keybindings (#156575) fixes #155571 --- src/vs/platform/list/browser/listService.ts | 28 +++++++++------------ 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 9716ea6dc75..2bd9c44b14d 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -189,7 +189,6 @@ class MultipleSelectionController extends Disposable implements IMultipleSele function toWorkbenchListOptions( accessor: ServicesAccessor, - container: HTMLElement, options: IListOptions, ): [IListOptions, IDisposable] { const configurationService = accessor.get(IConfigurationService); @@ -203,7 +202,7 @@ function toWorkbenchListOptions( mouseWheelScrollSensitivity: configurationService.getValue(mouseWheelScrollSensitivityKey), fastScrollSensitivity: configurationService.getValue(fastScrollSensitivityKey), multipleSelectionController: options.multipleSelectionController ?? disposables.add(new MultipleSelectionController(configurationService)), - keyboardNavigationEventFilter: createKeyboardNavigationEventFilter(container, keybindingService), + keyboardNavigationEventFilter: createKeyboardNavigationEventFilter(keybindingService), }; return [result, disposables]; @@ -244,7 +243,7 @@ export class WorkbenchList extends List { @IInstantiationService instantiationService: IInstantiationService ) { const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : Boolean(configurationService.getValue(horizontalScrollingKey)); - const [workbenchListOptions, workbenchListOptionsDisposable] = instantiationService.invokeFunction(toWorkbenchListOptions, container, options); + const [workbenchListOptions, workbenchListOptionsDisposable] = instantiationService.invokeFunction(toWorkbenchListOptions, options); super(user, container, delegate, renderers, { @@ -384,7 +383,7 @@ export class WorkbenchPagedList extends PagedList { @IInstantiationService instantiationService: IInstantiationService ) { const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : Boolean(configurationService.getValue(horizontalScrollingKey)); - const [workbenchListOptions, workbenchListOptionsDisposable] = instantiationService.invokeFunction(toWorkbenchListOptions, container, options); + const [workbenchListOptions, workbenchListOptionsDisposable] = instantiationService.invokeFunction(toWorkbenchListOptions, options); super(user, container, delegate, renderers, { keyboardSupport: false, @@ -517,7 +516,7 @@ export class WorkbenchTable extends Table { @IInstantiationService instantiationService: IInstantiationService ) { const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : Boolean(configurationService.getValue(horizontalScrollingKey)); - const [workbenchListOptions, workbenchListOptionsDisposable] = instantiationService.invokeFunction(toWorkbenchListOptions, container, options); + const [workbenchListOptions, workbenchListOptionsDisposable] = instantiationService.invokeFunction(toWorkbenchListOptions, options); super(user, container, delegate, columns, renderers, { @@ -812,7 +811,7 @@ class TreeResourceNavigator extends ResourceNavigator { } } -function createKeyboardNavigationEventFilter(container: HTMLElement, keybindingService: IKeybindingService): IKeyboardNavigationEventFilter { +function createKeyboardNavigationEventFilter(keybindingService: IKeybindingService): IKeyboardNavigationEventFilter { let inChord = false; return event => { @@ -825,7 +824,7 @@ function createKeyboardNavigationEventFilter(container: HTMLElement, keybindingS return false; } - const result = keybindingService.softDispatch(event, container); + const result = keybindingService.softDispatch(event, event.target); if (result?.enterChord) { inChord = true; @@ -862,7 +861,7 @@ export class WorkbenchObjectTree, TFilterData = void> @IThemeService themeService: IThemeService, @IConfigurationService configurationService: IConfigurationService ) { - const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, container, options as any); + const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, options as any); super(user, container, delegate, renderers, treeOptions); this.disposables.add(disposable); this.internals = new WorkbenchTreeInternals(this, options, getTypeNavigationMode, options.overrideStyles, contextKeyService, listService, themeService, configurationService); @@ -903,7 +902,7 @@ export class WorkbenchCompressibleObjectTree, TFilter @IThemeService themeService: IThemeService, @IConfigurationService configurationService: IConfigurationService ) { - const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, container, options as any); + const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, options as any); super(user, container, delegate, renderers, treeOptions); this.disposables.add(disposable); this.internals = new WorkbenchTreeInternals(this, options, getTypeNavigationMode, options.overrideStyles, contextKeyService, listService, themeService, configurationService); @@ -950,7 +949,7 @@ export class WorkbenchDataTree extends DataTree extends Async @IThemeService themeService: IThemeService, @IConfigurationService configurationService: IConfigurationService ) { - const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, container, options as any); + const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, options as any); super(user, container, delegate, renderers, dataSource, treeOptions); this.disposables.add(disposable); this.internals = new WorkbenchTreeInternals(this, options, getTypeNavigationMode, options.overrideStyles, contextKeyService, listService, themeService, configurationService); @@ -1042,7 +1041,7 @@ export class WorkbenchCompressibleAsyncDataTree e @IThemeService themeService: IThemeService, @IConfigurationService configurationService: IConfigurationService ) { - const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, container, options as any); + const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, options as any); super(user, container, virtualDelegate, compressionDelegate, renderers, dataSource, treeOptions); this.disposables.add(disposable); this.internals = new WorkbenchTreeInternals(this, options, getTypeNavigationMode, options.overrideStyles, contextKeyService, listService, themeService, configurationService); @@ -1077,11 +1076,9 @@ function getDefaultTreeFindMode(configurationService: IConfigurationService) { function workbenchTreeDataPreamble | IAsyncDataTreeOptions>( accessor: ServicesAccessor, - container: HTMLElement, options: TOptions, ): { options: TOptions; getTypeNavigationMode: () => TypeNavigationMode | undefined; disposable: IDisposable } { const configurationService = accessor.get(IConfigurationService); - const keybindingService = accessor.get(IKeybindingService); const contextViewService = accessor.get(IContextViewService); const contextKeyService = accessor.get(IContextKeyService); const instantiationService = accessor.get(IInstantiationService); @@ -1107,7 +1104,7 @@ function workbenchTreeDataPreamble(treeExpandMode) === 'doubleClick'), From 4017fd126ffb62def37c3bb380eb1a1866884ebe Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 28 Jul 2022 10:26:18 -0700 Subject: [PATCH 081/303] Show quick pick when redirect fails to complete redirect to be more robust (#156515) * show quick pick when redirect fails to complete redirect to be more robust * matt feedback --- .../microsoft-authentication/src/AADHelper.ts | 63 +++++++++++++------ .../microsoft-authentication/src/utils.ts | 33 ++++++++++ 2 files changed, 78 insertions(+), 18 deletions(-) diff --git a/extensions/microsoft-authentication/src/AADHelper.ts b/extensions/microsoft-authentication/src/AADHelper.ts index bb22142e584..4c3b9f2a38e 100644 --- a/extensions/microsoft-authentication/src/AADHelper.ts +++ b/extensions/microsoft-authentication/src/AADHelper.ts @@ -11,7 +11,7 @@ import * as nls from 'vscode-nls'; import { v4 as uuid } from 'uuid'; import fetch, { Response } from 'node-fetch'; import Logger from './logger'; -import { toBase64UrlEncoding } from './utils'; +import { isSupportedEnvironment, toBase64UrlEncoding } from './utils'; import { sha256 } from './env/node/sha256'; import { BetterTokenStorage, IDidChangeInOtherWindowEvent } from './betterSecretStorage'; import { LoopbackAuthServer } from './authServer'; @@ -319,13 +319,7 @@ export class AzureActiveDirectoryService { }, 5000); } - const token = await this.exchangeCodeForToken(codeToExchange, codeVerifier, scopeData); - if (token.expiresIn) { - this.setSessionTimeout(token.sessionId, token.refreshToken, scopeData, token.expiresIn * AzureActiveDirectoryService.REFRESH_TIMEOUT_MODIFIER); - } - await this.setToken(token, scopeData); - Logger.info(`Login successful for scopes: ${scopeData.scopeStr}`); - const session = await this.convertToSession(token); + const session = await this.exchangeCodeForSession(codeToExchange, codeVerifier, scopeData); return session; } @@ -355,9 +349,11 @@ export class AzureActiveDirectoryService { const uri = vscode.Uri.parse(`${signInUrl}?${oauthStartQuery.toString()}`); vscode.env.openExternal(uri); + let inputBox: vscode.InputBox | undefined; const timeoutPromise = new Promise((_: (value: vscode.AuthenticationSession) => void, reject) => { const wait = setTimeout(() => { clearTimeout(wait); + inputBox?.dispose(); reject('Login timed out.'); }, 1000 * 60 * 5); }); @@ -369,7 +365,12 @@ export class AzureActiveDirectoryService { // before completing it. let existingPromise = this._codeExchangePromises.get(scopeData.scopeStr); if (!existingPromise) { - existingPromise = this.handleCodeResponse(scopeData); + if (isSupportedEnvironment(callbackUri)) { + existingPromise = this.handleCodeResponse(scopeData); + } else { + inputBox = vscode.window.createInputBox(); + existingPromise = Promise.race([this.handleCodeInputBox(inputBox, codeVerifier, scopeData), this.handleCodeResponse(scopeData)]); + } this._codeExchangePromises.set(scopeData.scopeStr, existingPromise); } @@ -659,13 +660,7 @@ export class AzureActiveDirectoryService { throw new Error('No available code verifier'); } - const token = await this.exchangeCodeForToken(code, verifier, scopeData); - if (token.expiresIn) { - this.setSessionTimeout(token.sessionId, token.refreshToken, scopeData, token.expiresIn * AzureActiveDirectoryService.REFRESH_TIMEOUT_MODIFIER); - } - await this.setToken(token, scopeData); - - const session = await this.convertToSession(token); + const session = await this.exchangeCodeForSession(code, verifier, scopeData); resolve(session); } catch (err) { reject(err); @@ -680,8 +675,33 @@ export class AzureActiveDirectoryService { }); } - private async exchangeCodeForToken(code: string, codeVerifier: string, scopeData: IScopeData): Promise { + private async handleCodeInputBox(inputBox: vscode.InputBox, verifier: string, scopeData: IScopeData): Promise { + inputBox.ignoreFocusOut = true; + inputBox.title = localize('pasteCodeTitle', 'Microsoft Authentication'); + inputBox.prompt = localize('pasteCodePrompt', 'Provide the authorization code to complete the sign in flow.'); + inputBox.placeholder = localize('pasteCodePlaceholder', 'Paste authorization code here...'); + return new Promise((resolve: (value: vscode.AuthenticationSession) => void, reject) => { + inputBox.show(); + inputBox.onDidAccept(async () => { + const code = inputBox.value; + if (code) { + inputBox.dispose(); + const session = await this.exchangeCodeForSession(code, verifier, scopeData); + resolve(session); + } + }); + inputBox.onDidHide(() => { + if (!inputBox.value) { + inputBox.dispose(); + reject('Cancelled'); + } + }); + }); + } + + private async exchangeCodeForSession(code: string, codeVerifier: string, scopeData: IScopeData): Promise { Logger.info(`Exchanging login code for token for scopes: ${scopeData.scopeStr}`); + let token: IToken | undefined; try { const postData = querystring.stringify({ grant_type: 'authorization_code', @@ -698,11 +718,18 @@ export class AzureActiveDirectoryService { const json = await this.fetchTokenResponse(endpoint, postData, scopeData); Logger.info(`Exchanging login code for token (for scopes: ${scopeData.scopeStr}) succeeded!`); - return this.convertToTokenSync(json, scopeData); + token = this.convertToTokenSync(json, scopeData); } catch (e) { Logger.error(`Error exchanging code for token (for scopes ${scopeData.scopeStr}): ${e}`); throw e; } + + if (token.expiresIn) { + this.setSessionTimeout(token.sessionId, token.refreshToken, scopeData, token.expiresIn * AzureActiveDirectoryService.REFRESH_TIMEOUT_MODIFIER); + } + await this.setToken(token, scopeData); + Logger.info(`Login successful for scopes: ${scopeData.scopeStr}`); + return await this.convertToSession(token); } private async fetchTokenResponse(endpoint: string, postData: string, scopeData: IScopeData): Promise { diff --git a/extensions/microsoft-authentication/src/utils.ts b/extensions/microsoft-authentication/src/utils.ts index 164f2236221..443bb2dc048 100644 --- a/extensions/microsoft-authentication/src/utils.ts +++ b/extensions/microsoft-authentication/src/utils.ts @@ -2,7 +2,40 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { env, UIKind, Uri } from 'vscode'; export function toBase64UrlEncoding(base64string: string) { return base64string.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); // Need to use base64url encoding } + +const LOCALHOST_ADDRESSES = ['localhost', '127.0.0.1', '0:0:0:0:0:0:0:1', '::1']; +function isLocalhost(uri: Uri): boolean { + if (!/^https?$/i.test(uri.scheme)) { + return false; + } + const host = uri.authority.split(':')[0]; + return LOCALHOST_ADDRESSES.indexOf(host) >= 0; +} + +export function isSupportedEnvironment(uri: Uri): boolean { + if (env.uiKind === UIKind.Desktop) { + return true; + } + // local development (localhost:* or 127.0.0.1:*) + if (isLocalhost(uri)) { + return true; + } + // At this point we should only ever see https + if (uri.scheme !== 'https') { + return false; + } + + return ( + // vscode.dev & insiders.vscode.dev + /(?:^|\.)vscode\.dev$/.test(uri.authority) || + // github.dev & codespaces + /(?:^|\.)github\.dev$/.test(uri.authority) || + // github.dev/codespaces local setup (github.localhost) + /(?:^|\.)github\.localhost$/.test(uri.authority) + ); +} From fb66467d1e4f8c420803de5e0a10bc4467cebf5c Mon Sep 17 00:00:00 2001 From: Justin Chen <54879025+justschen@users.noreply.github.com> Date: Thu, 28 Jul 2022 11:35:10 -0700 Subject: [PATCH 082/303] Bugfix on enter/arrow/mouse interaction for code action widget (fixes #156587) * fix on hover vs key bindings interaction * removed allowClick boolean, modified current selected item for widget * modifed var types --- .../codeAction/browser/codeActionMenu.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts index d3a15fec005..aa51bc780af 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts @@ -161,7 +161,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { private _ctxMenuWidgetVisible: IContextKey; private viewItems: ICodeActionMenuItem[] = []; private focusedEnabledItem: number | undefined; - private currSelectedItem: number = 0; + private currSelectedItem: number | undefined; private hasSeperator: boolean = false; private block?: HTMLElement; @@ -213,21 +213,24 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { e.elements.forEach(element => { if (element.isEnabled) { element.action.run(); + this.hideCodeActionWidget(); } }); - this.hideCodeActionWidget(); } } - private _onListHover(e: IListMouseEvent): void { if (!e.element) { + this.currSelectedItem = undefined; this.codeActionList.value?.setFocus([]); } else { if (e.element?.isEnabled) { this.codeActionList.value?.setFocus([e.element.index]); this.focusedEnabledItem = this.viewItems.indexOf(e.element); this.currSelectedItem = e.element.index; + } else { + this.currSelectedItem = undefined; + this.codeActionList.value?.setFocus([e.element.index]); } } } @@ -318,7 +321,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { // List selection if (this.viewItems.length < 1 || this.viewItems.every(item => item.isDocumentation)) { - this.currSelectedItem = 0; + this.currSelectedItem = undefined; } else { this.focusedEnabledItem = 0; this.currSelectedItem = this.viewItems[0].index; @@ -391,7 +394,9 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { } public onEnterSet() { - this.codeActionList.value?.setSelection([this.currSelectedItem]); + if (typeof this.currSelectedItem === 'number') { + this.codeActionList.value?.setSelection([this.currSelectedItem]); + } } override dispose() { @@ -403,7 +408,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { this.options = []; this.viewItems = []; this.focusedEnabledItem = 0; - this.currSelectedItem = 0; + this.currSelectedItem = undefined; this.hasSeperator = false; this._contextViewService.hideContextView({ source: this }); } From 33a08dc6f4386aaa7067575dc8929183df080ae2 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Thu, 28 Jul 2022 11:40:11 -0700 Subject: [PATCH 083/303] use `task` instead of `taskName` (#156603) fix #155635 --- .../contrib/tasks/browser/abstractTaskService.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 3a0c564b42b..18a68093766 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -398,9 +398,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer type: 'string', description: nls.localize('runTask.type', "The contributed task type") }, - taskName: { + task: { type: 'string', - description: nls.localize('runTask.taskName', "The task's label or a term to filter by") + description: nls.localize('runTask.task', "The task's label or a term to filter by") } } } @@ -2700,7 +2700,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer })) === true; } - private async _runTaskCommand(filter?: { type?: string; taskName?: string } | string): Promise { + private async _runTaskCommand(filter?: any | { type?: string; task?: string }): Promise { if (!this._canRunCommand()) { return; } @@ -2708,8 +2708,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer let typeFilter: boolean = false; if (filter && typeof filter !== 'string') { // name takes precedence - typeFilter = !filter?.taskName && !!filter?.type; - filter = filter?.taskName || filter?.type; + typeFilter = !filter?.task && !!filter?.type; + filter = filter?.task || filter?.type; } const taskIdentifier: KeyedTaskIdentifier | undefined | string = this._getTaskIdentifier(filter); From 35a17f42e89ee15966dbe805d5faed63ec9b34c1 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 28 Jul 2022 11:48:33 -0700 Subject: [PATCH 084/303] fix another command to use ILocalizedString (#156615) --- src/vs/workbench/contrib/testing/browser/testExplorerActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts b/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts index 556f7f4e65d..53579678c41 100644 --- a/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts +++ b/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts @@ -249,7 +249,7 @@ export class ConfigureTestProfilesAction extends Action2 { constructor() { super({ id: TestCommandId.ConfigureTestProfilesAction, - title: localize('testing.configureProfile', 'Configure Test Profiles'), + title: { value: localize('testing.configureProfile', 'Configure Test Profiles'), original: 'Configure Test Profiles' }, icon: icons.testingUpdateProfiles, f1: true, category, From 0a65bea3573d503c3078eff3e4b7f26f138e967d Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Thu, 28 Jul 2022 11:52:52 -0700 Subject: [PATCH 085/303] allow context menu on command center (#156614) fixes #156512 --- .../workbench/browser/parts/titlebar/commandCenterControl.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts b/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts index 25e9213343e..3856e6439a2 100644 --- a/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts @@ -114,7 +114,8 @@ export class CommandCenterControl { } else { return createActionViewItem(instantiationService, action, { hoverDelegate }); } - } + }, + allowContextMenu: true }); const menu = this._disposables.add(menuService.createMenu(MenuId.CommandCenter, contextKeyService)); const menuDisposables = this._disposables.add(new DisposableStore()); From 6fbee10cc199f1d48f9d1b32f89021fbfba00a8d Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Thu, 28 Jul 2022 11:53:51 -0700 Subject: [PATCH 086/303] more checking for undefined objects, fixed bug casuing markdown renderer to entirely crash --- extensions/ipynb/src/cellAttachmentRenderer.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/extensions/ipynb/src/cellAttachmentRenderer.ts b/extensions/ipynb/src/cellAttachmentRenderer.ts index 7e05834dbcb..69e294d57b9 100644 --- a/extensions/ipynb/src/cellAttachmentRenderer.ts +++ b/extensions/ipynb/src/cellAttachmentRenderer.ts @@ -22,11 +22,19 @@ export async function activate(ctx: RendererContext) { md.renderer.rules.image = (tokens: MarkdownItToken[], idx: number, options, env, self) => { const token = tokens[idx]; const src = token.attrGet('src'); - const attachments: Record> = env.outputItem.metadata?.custom?.attachments; + const attachments: Record> = env.outputItem.metadata?.custom?.attachments; // this stores attachment entries for every image in the cell if (attachments && src) { - const [attachmentKey, attachmentVal] = Object.entries(attachments[src.replace('attachment:', '')])[0]; - const b64Markdown = 'data:' + attachmentKey + ';base64,' + attachmentVal; - token.attrSet('src', b64Markdown); + const imageAttachment = attachments[src.replace('attachment:', '')]; + if (imageAttachment) { + // objEntries will always be length 1, with objEntries[0] holding [0]=mime,[1]=b64 + // if length = 0, something is wrong with the attachment, mime/b64 weren't copied over + const objEntries = Object.entries(imageAttachment); + if (objEntries.length) { + const [attachmentKey, attachmentVal] = objEntries[0]; + const b64Markdown = 'data:' + attachmentKey + ';base64,' + attachmentVal; + token.attrSet('src', b64Markdown); + } + } } if (original) { From 0e2e0e2833b55469a585ccd4854748c5c7860971 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Thu, 28 Jul 2022 12:45:48 -0700 Subject: [PATCH 087/303] add tooltip tech to dropdown buttons (#156621) fixes #153429 --- .../browser/ui/dropdown/dropdownActionViewItem.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts b/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts index 0af76e3b6a0..00b21774ea0 100644 --- a/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts +++ b/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts @@ -126,9 +126,22 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem { }; } + this.updateTooltip(); this.updateEnabled(); } + override getTooltip(): string | undefined { + let title: string | null = null; + + if (this.getAction().tooltip) { + title = this.getAction().tooltip; + } else if (this.getAction().label) { + title = this.getAction().label; + } + + return title ?? undefined; + } + override setActionContext(newContext: unknown): void { super.setActionContext(newContext); From 743b016722db90df977feecde0a4b3b4f58c2a4c Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 28 Jul 2022 14:27:45 -0700 Subject: [PATCH 088/303] Have padding on qp list not the whole widget (#156624) --- src/vs/base/parts/quickinput/browser/media/quickInput.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/parts/quickinput/browser/media/quickInput.css b/src/vs/base/parts/quickinput/browser/media/quickInput.css index efab21e77bf..e3357d75fe8 100644 --- a/src/vs/base/parts/quickinput/browser/media/quickInput.css +++ b/src/vs/base/parts/quickinput/browser/media/quickInput.css @@ -7,7 +7,6 @@ position: absolute; width: 600px; z-index: 2550; - padding: 0 1px 1px 1px; left: 50%; margin-left: -300px; -webkit-app-region: no-drag; @@ -151,6 +150,7 @@ .quick-input-list { line-height: 22px; margin-top: 6px; + padding: 0px 1px 1px 1px; } .quick-input-widget.hidden-input .quick-input-list { From e8ee2cf78ffe38e878fc0faa652f9515502fe58c Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 29 Jul 2022 00:45:18 -0700 Subject: [PATCH 089/303] Avoid List View default find widget steal keybindings. (#156637) --- src/vs/platform/list/browser/listService.ts | 5 +++++ src/vs/workbench/browser/actions/listCommands.ts | 4 ++-- src/vs/workbench/contrib/preferences/browser/settingsTree.ts | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 2bd9c44b14d..5af76e7958e 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -125,6 +125,7 @@ export const WorkbenchTreeElementHasParent = new RawContextKey('treeEle export const WorkbenchTreeElementCanExpand = new RawContextKey('treeElementCanExpand', false); export const WorkbenchTreeElementHasChild = new RawContextKey('treeElementHasChild', false); export const WorkbenchTreeFindOpen = new RawContextKey('treeFindOpen', false); +export const WorkbenchTreeSupportsFind = new RawContextKey('treeSupportsFind', true); const WorkbenchListTypeNavigationModeKey = 'listTypeNavigationMode'; /** @@ -1143,6 +1144,7 @@ class WorkbenchTreeInternals { private treeElementCanExpand: IContextKey; private treeElementHasChild: IContextKey; private treeFindOpen: IContextKey; + private treeSupportFindWidget: IContextKey; private _useAltAsMultipleSelectionModifier: boolean; private disposables: IDisposable[] = []; private styler: IDisposable | undefined; @@ -1176,7 +1178,10 @@ class WorkbenchTreeInternals { this.treeElementHasParent = WorkbenchTreeElementHasParent.bindTo(this.contextKeyService); this.treeElementCanExpand = WorkbenchTreeElementCanExpand.bindTo(this.contextKeyService); this.treeElementHasChild = WorkbenchTreeElementHasChild.bindTo(this.contextKeyService); + this.treeFindOpen = WorkbenchTreeFindOpen.bindTo(this.contextKeyService); + this.treeSupportFindWidget = WorkbenchTreeSupportsFind.bindTo(this.contextKeyService); + this.treeSupportFindWidget.set(options.findWidgetEnabled ?? true); this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService); diff --git a/src/vs/workbench/browser/actions/listCommands.ts b/src/vs/workbench/browser/actions/listCommands.ts index ee4848ce1ae..f6d73f19284 100644 --- a/src/vs/workbench/browser/actions/listCommands.ts +++ b/src/vs/workbench/browser/actions/listCommands.ts @@ -7,7 +7,7 @@ import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { List } from 'vs/base/browser/ui/list/listWidget'; -import { WorkbenchListFocusContextKey, IListService, WorkbenchListSupportsMultiSelectContextKey, ListWidget, WorkbenchListHasSelectionOrFocus, getSelectionKeyboardEvent, WorkbenchListWidget, WorkbenchListSelectionNavigation, WorkbenchTreeElementCanCollapse, WorkbenchTreeElementHasParent, WorkbenchTreeElementHasChild, WorkbenchTreeElementCanExpand, RawWorkbenchListFocusContextKey, WorkbenchTreeFindOpen } from 'vs/platform/list/browser/listService'; +import { WorkbenchListFocusContextKey, IListService, WorkbenchListSupportsMultiSelectContextKey, ListWidget, WorkbenchListHasSelectionOrFocus, getSelectionKeyboardEvent, WorkbenchListWidget, WorkbenchListSelectionNavigation, WorkbenchTreeElementCanCollapse, WorkbenchTreeElementHasParent, WorkbenchTreeElementHasChild, WorkbenchTreeElementCanExpand, RawWorkbenchListFocusContextKey, WorkbenchTreeFindOpen, WorkbenchTreeSupportsFind } from 'vs/platform/list/browser/listService'; import { PagedList } from 'vs/base/browser/ui/list/listPaging'; import { equals, range } from 'vs/base/common/arrays'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; @@ -634,7 +634,7 @@ CommandsRegistry.registerCommandAlias('list.toggleFilterOnType', 'list.toggleFin KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'list.find', weight: KeybindingWeight.WorkbenchContrib, - when: RawWorkbenchListFocusContextKey, + when: ContextKeyExpr.and(RawWorkbenchListFocusContextKey, WorkbenchTreeSupportsFind), primary: KeyMod.CtrlCmd | KeyCode.KeyF, secondary: [KeyCode.F3], handler: (accessor) => { diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index 90a8b212b6c..2ad3516e3e9 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -2367,6 +2367,7 @@ export class SettingsTree extends WorkbenchObjectTree { filter: instantiationService.createInstance(SettingsTreeFilter, viewState), smoothScrolling: configurationService.getValue('workbench.list.smoothScrolling'), multipleSelectionSupport: false, + findWidgetEnabled: false }, instantiationService, contextKeyService, From d708be4ae49cc3144c50d52dc9dcb5e0807a6f2f Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 29 Jul 2022 10:47:17 +0200 Subject: [PATCH 090/303] Fixes #156645: Change the sticky scroll option to `editor.experimental.stickyScroll` --- src/vs/editor/common/config/editorOptions.ts | 55 +++--- .../common/standalone/standaloneEnums.ts | 146 +++++++-------- .../stickyScroll/browser/stickyScroll.ts | 6 +- src/vs/monaco.d.ts | 172 +++++++++--------- 4 files changed, 195 insertions(+), 184 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index b50d0d0e112..15b9d5cddd8 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -170,9 +170,9 @@ export interface IEditorOptions { */ scrollbar?: IEditorScrollbarOptions; /** - * Control the behavior of the sticky scroll + * Control the behavior of experimental options */ - stickyScroll?: IEditorStickyScrollOptions; + experimental?: IEditorExperimentalOptions; /** * Control the behavior and rendering of the minimap. */ @@ -2508,48 +2508,51 @@ class EditorLightbulb extends BaseEditorOption>; - -class EditorStickyScroll extends BaseEditorOption { +class EditorExperimental extends BaseEditorOption { constructor() { - const defaults: EditorStickyScrollOptions = { enabled: false }; + const defaults: EditorExperimentalOptions = { stickyScroll: { enabled: false } }; super( - EditorOption.stickyScroll, 'stickyScroll', defaults, + EditorOption.experimental, 'experimental', defaults, { - 'editor.stickyScroll.enabled': { + 'editor.experimental.stickyScroll.enabled': { type: 'boolean', - default: defaults.enabled, - description: nls.localize('editor.stickyScroll', "Shows the nested current scopes during the scroll at the top of the editor.") + default: defaults.stickyScroll.enabled, + description: nls.localize('editor.experimental.stickyScroll', "Shows the nested current scopes during the scroll at the top of the editor.") }, } ); } - public validate(_input: any): EditorStickyScrollOptions { + public validate(_input: any): EditorExperimentalOptions { if (!_input || typeof _input !== 'object') { return this.defaultValue; } - const input = _input as IEditorStickyScrollOptions; + const input = _input as IEditorExperimentalOptions; return { - enabled: boolean(input.enabled, this.defaultValue.enabled) + stickyScroll: { + enabled: boolean(input.stickyScroll?.enabled, this.defaultValue.stickyScroll.enabled) + } }; } } @@ -4550,6 +4553,7 @@ export const enum EditorOption { dragAndDrop, dropIntoEditor, emptySelectionClipboard, + experimental, extraEditorClassName, fastScrollSensitivity, find, @@ -4622,7 +4626,6 @@ export const enum EditorOption { smartSelect, smoothScrolling, stickyTabStops, - stickyScroll, stopRenderingLineAfter, suggest, suggestFontSize, @@ -4859,6 +4862,7 @@ export const EditorOptions = { )), emptySelectionClipboard: register(new EditorEmptySelectionClipboard()), dropIntoEditor: register(new EditorDropIntoEditor()), + experimental: register(new EditorExperimental()), extraEditorClassName: register(new EditorStringOption( EditorOption.extraEditorClassName, 'extraEditorClassName', '', )), @@ -5177,7 +5181,6 @@ export const EditorOptions = { EditorOption.smoothScrolling, 'smoothScrolling', false, { description: nls.localize('smoothScrolling', "Controls whether the editor will scroll using an animation.") } )), - stickyScroll: register(new EditorStickyScroll()), stopRenderingLineAfter: register(new EditorIntOption( EditorOption.stopRenderingLineAfter, 'stopRenderingLineAfter', 10000, -1, Constants.MAX_SAFE_SMALL_INTEGER, diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index c62e7fc404f..5b9c0195e7b 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -206,79 +206,79 @@ export enum EditorOption { dragAndDrop = 31, dropIntoEditor = 32, emptySelectionClipboard = 33, - extraEditorClassName = 34, - fastScrollSensitivity = 35, - find = 36, - fixedOverflowWidgets = 37, - folding = 38, - foldingStrategy = 39, - foldingHighlight = 40, - foldingImportsByDefault = 41, - foldingMaximumRegions = 42, - unfoldOnClickAfterEndOfLine = 43, - fontFamily = 44, - fontInfo = 45, - fontLigatures = 46, - fontSize = 47, - fontWeight = 48, - formatOnPaste = 49, - formatOnType = 50, - glyphMargin = 51, - gotoLocation = 52, - hideCursorInOverviewRuler = 53, - hover = 54, - inDiffEditor = 55, - inlineSuggest = 56, - letterSpacing = 57, - lightbulb = 58, - lineDecorationsWidth = 59, - lineHeight = 60, - lineNumbers = 61, - lineNumbersMinChars = 62, - linkedEditing = 63, - links = 64, - matchBrackets = 65, - minimap = 66, - mouseStyle = 67, - mouseWheelScrollSensitivity = 68, - mouseWheelZoom = 69, - multiCursorMergeOverlapping = 70, - multiCursorModifier = 71, - multiCursorPaste = 72, - occurrencesHighlight = 73, - overviewRulerBorder = 74, - overviewRulerLanes = 75, - padding = 76, - parameterHints = 77, - peekWidgetDefaultFocus = 78, - definitionLinkOpensInPeek = 79, - quickSuggestions = 80, - quickSuggestionsDelay = 81, - readOnly = 82, - renameOnType = 83, - renderControlCharacters = 84, - renderFinalNewline = 85, - renderLineHighlight = 86, - renderLineHighlightOnlyWhenFocus = 87, - renderValidationDecorations = 88, - renderWhitespace = 89, - revealHorizontalRightPadding = 90, - roundedSelection = 91, - rulers = 92, - scrollbar = 93, - scrollBeyondLastColumn = 94, - scrollBeyondLastLine = 95, - scrollPredominantAxis = 96, - selectionClipboard = 97, - selectionHighlight = 98, - selectOnLineNumbers = 99, - showFoldingControls = 100, - showUnused = 101, - snippetSuggestions = 102, - smartSelect = 103, - smoothScrolling = 104, - stickyTabStops = 105, - stickyScroll = 106, + experimental = 34, + extraEditorClassName = 35, + fastScrollSensitivity = 36, + find = 37, + fixedOverflowWidgets = 38, + folding = 39, + foldingStrategy = 40, + foldingHighlight = 41, + foldingImportsByDefault = 42, + foldingMaximumRegions = 43, + unfoldOnClickAfterEndOfLine = 44, + fontFamily = 45, + fontInfo = 46, + fontLigatures = 47, + fontSize = 48, + fontWeight = 49, + formatOnPaste = 50, + formatOnType = 51, + glyphMargin = 52, + gotoLocation = 53, + hideCursorInOverviewRuler = 54, + hover = 55, + inDiffEditor = 56, + inlineSuggest = 57, + letterSpacing = 58, + lightbulb = 59, + lineDecorationsWidth = 60, + lineHeight = 61, + lineNumbers = 62, + lineNumbersMinChars = 63, + linkedEditing = 64, + links = 65, + matchBrackets = 66, + minimap = 67, + mouseStyle = 68, + mouseWheelScrollSensitivity = 69, + mouseWheelZoom = 70, + multiCursorMergeOverlapping = 71, + multiCursorModifier = 72, + multiCursorPaste = 73, + occurrencesHighlight = 74, + overviewRulerBorder = 75, + overviewRulerLanes = 76, + padding = 77, + parameterHints = 78, + peekWidgetDefaultFocus = 79, + definitionLinkOpensInPeek = 80, + quickSuggestions = 81, + quickSuggestionsDelay = 82, + readOnly = 83, + renameOnType = 84, + renderControlCharacters = 85, + renderFinalNewline = 86, + renderLineHighlight = 87, + renderLineHighlightOnlyWhenFocus = 88, + renderValidationDecorations = 89, + renderWhitespace = 90, + revealHorizontalRightPadding = 91, + roundedSelection = 92, + rulers = 93, + scrollbar = 94, + scrollBeyondLastColumn = 95, + scrollBeyondLastLine = 96, + scrollPredominantAxis = 97, + selectionClipboard = 98, + selectionHighlight = 99, + selectOnLineNumbers = 100, + showFoldingControls = 101, + showUnused = 102, + snippetSuggestions = 103, + smartSelect = 104, + smoothScrolling = 105, + stickyTabStops = 106, stopRenderingLineAfter = 107, suggest = 108, suggestFontSize = 109, diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index c42d96dff27..d76b699dd54 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -43,7 +43,7 @@ class StickyScrollController extends Disposable implements IEditorContribution { this._languageFeaturesService = _languageFeaturesService; this.stickyScrollWidget = new StickyScrollWidget(this._editor); this._register(this._editor.onDidChangeConfiguration(e => { - if (e.hasChanged(EditorOption.stickyScroll)) { + if (e.hasChanged(EditorOption.experimental)) { this.onConfigurationChange(); } })); @@ -52,8 +52,8 @@ class StickyScrollController extends Disposable implements IEditorContribution { } private onConfigurationChange() { - const options = this._editor.getOption(EditorOption.stickyScroll); - if (options.enabled === false) { + const options = this._editor.getOption(EditorOption.experimental); + if (options.stickyScroll.enabled === false) { this.stickyScrollWidget.emptyRootNode(); this._editor.removeOverlayWidget(this.stickyScrollWidget); this._sessionStore.clear(); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 91b72dd4d11..8b0f9bbc295 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2947,9 +2947,9 @@ declare namespace monaco.editor { */ scrollbar?: IEditorScrollbarOptions; /** - * Control the behavior of the sticky scroll + * Control the behavior of experimental options */ - stickyScroll?: IEditorStickyScrollOptions; + experimental?: IEditorExperimentalOptions; /** * Control the behavior and rendering of the minimap. */ @@ -3808,14 +3808,22 @@ declare namespace monaco.editor { enabled?: boolean; } - /** - * Configuration options for editor sticky scroll - */ - export interface IEditorStickyScrollOptions { + export interface IEditorExperimentalOptions { /** - * Enable the sticky scroll + * Configuration options for editor sticky scroll */ - enabled?: boolean; + stickyScroll?: { + /** + * Enable the sticky scroll + */ + enabled?: boolean; + }; + } + + export interface EditorExperimentalOptions { + stickyScroll: { + enabled: boolean; + }; } /** @@ -4376,79 +4384,79 @@ declare namespace monaco.editor { dragAndDrop = 31, dropIntoEditor = 32, emptySelectionClipboard = 33, - extraEditorClassName = 34, - fastScrollSensitivity = 35, - find = 36, - fixedOverflowWidgets = 37, - folding = 38, - foldingStrategy = 39, - foldingHighlight = 40, - foldingImportsByDefault = 41, - foldingMaximumRegions = 42, - unfoldOnClickAfterEndOfLine = 43, - fontFamily = 44, - fontInfo = 45, - fontLigatures = 46, - fontSize = 47, - fontWeight = 48, - formatOnPaste = 49, - formatOnType = 50, - glyphMargin = 51, - gotoLocation = 52, - hideCursorInOverviewRuler = 53, - hover = 54, - inDiffEditor = 55, - inlineSuggest = 56, - letterSpacing = 57, - lightbulb = 58, - lineDecorationsWidth = 59, - lineHeight = 60, - lineNumbers = 61, - lineNumbersMinChars = 62, - linkedEditing = 63, - links = 64, - matchBrackets = 65, - minimap = 66, - mouseStyle = 67, - mouseWheelScrollSensitivity = 68, - mouseWheelZoom = 69, - multiCursorMergeOverlapping = 70, - multiCursorModifier = 71, - multiCursorPaste = 72, - occurrencesHighlight = 73, - overviewRulerBorder = 74, - overviewRulerLanes = 75, - padding = 76, - parameterHints = 77, - peekWidgetDefaultFocus = 78, - definitionLinkOpensInPeek = 79, - quickSuggestions = 80, - quickSuggestionsDelay = 81, - readOnly = 82, - renameOnType = 83, - renderControlCharacters = 84, - renderFinalNewline = 85, - renderLineHighlight = 86, - renderLineHighlightOnlyWhenFocus = 87, - renderValidationDecorations = 88, - renderWhitespace = 89, - revealHorizontalRightPadding = 90, - roundedSelection = 91, - rulers = 92, - scrollbar = 93, - scrollBeyondLastColumn = 94, - scrollBeyondLastLine = 95, - scrollPredominantAxis = 96, - selectionClipboard = 97, - selectionHighlight = 98, - selectOnLineNumbers = 99, - showFoldingControls = 100, - showUnused = 101, - snippetSuggestions = 102, - smartSelect = 103, - smoothScrolling = 104, - stickyTabStops = 105, - stickyScroll = 106, + experimental = 34, + extraEditorClassName = 35, + fastScrollSensitivity = 36, + find = 37, + fixedOverflowWidgets = 38, + folding = 39, + foldingStrategy = 40, + foldingHighlight = 41, + foldingImportsByDefault = 42, + foldingMaximumRegions = 43, + unfoldOnClickAfterEndOfLine = 44, + fontFamily = 45, + fontInfo = 46, + fontLigatures = 47, + fontSize = 48, + fontWeight = 49, + formatOnPaste = 50, + formatOnType = 51, + glyphMargin = 52, + gotoLocation = 53, + hideCursorInOverviewRuler = 54, + hover = 55, + inDiffEditor = 56, + inlineSuggest = 57, + letterSpacing = 58, + lightbulb = 59, + lineDecorationsWidth = 60, + lineHeight = 61, + lineNumbers = 62, + lineNumbersMinChars = 63, + linkedEditing = 64, + links = 65, + matchBrackets = 66, + minimap = 67, + mouseStyle = 68, + mouseWheelScrollSensitivity = 69, + mouseWheelZoom = 70, + multiCursorMergeOverlapping = 71, + multiCursorModifier = 72, + multiCursorPaste = 73, + occurrencesHighlight = 74, + overviewRulerBorder = 75, + overviewRulerLanes = 76, + padding = 77, + parameterHints = 78, + peekWidgetDefaultFocus = 79, + definitionLinkOpensInPeek = 80, + quickSuggestions = 81, + quickSuggestionsDelay = 82, + readOnly = 83, + renameOnType = 84, + renderControlCharacters = 85, + renderFinalNewline = 86, + renderLineHighlight = 87, + renderLineHighlightOnlyWhenFocus = 88, + renderValidationDecorations = 89, + renderWhitespace = 90, + revealHorizontalRightPadding = 91, + roundedSelection = 92, + rulers = 93, + scrollbar = 94, + scrollBeyondLastColumn = 95, + scrollBeyondLastLine = 96, + scrollPredominantAxis = 97, + selectionClipboard = 98, + selectionHighlight = 99, + selectOnLineNumbers = 100, + showFoldingControls = 101, + showUnused = 102, + snippetSuggestions = 103, + smartSelect = 104, + smoothScrolling = 105, + stickyTabStops = 106, stopRenderingLineAfter = 107, suggest = 108, suggestFontSize = 109, @@ -4515,6 +4523,7 @@ declare namespace monaco.editor { dragAndDrop: IEditorOption; emptySelectionClipboard: IEditorOption; dropIntoEditor: IEditorOption>>; + experimental: IEditorOption; extraEditorClassName: IEditorOption; fastScrollSensitivity: IEditorOption; find: IEditorOption>>; @@ -4587,7 +4596,6 @@ declare namespace monaco.editor { snippetSuggestions: IEditorOption; smartSelect: IEditorOption>>; smoothScrolling: IEditorOption; - stickyScroll: IEditorOption>>; stopRenderingLineAfter: IEditorOption; suggest: IEditorOption>>; inlineSuggest: IEditorOption>>; From 84dc769b20d232daa03472cb29d3ccc67b91e3e7 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 29 Jul 2022 11:11:12 +0200 Subject: [PATCH 091/303] Include namespace in the sticky scroll. Fixes https://github.com/microsoft/vscode/issues/156611. (#156649) Sticks namespace {} to the sticky scroll widget too. Fixes https://github.com/microsoft/vscode/issues/156611. --- src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index d76b699dd54..b394b835466 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -108,7 +108,7 @@ class StickyScrollController extends Disposable implements IEditorContribution { let didRecursion: boolean = false; for (const outline of outlineElement?.children.values()) { const kind: SymbolKind = outline.symbol.kind; - if (kind === SymbolKind.Class || kind === SymbolKind.Constructor || kind === SymbolKind.Function || kind === SymbolKind.Interface || kind === SymbolKind.Method) { + if (kind === SymbolKind.Class || kind === SymbolKind.Constructor || kind === SymbolKind.Function || kind === SymbolKind.Interface || kind === SymbolKind.Method || kind === SymbolKind.Module) { didRecursion = true; this._findLineRanges(outline, depth + 1); } @@ -127,7 +127,7 @@ class StickyScrollController extends Disposable implements IEditorContribution { while (outlineElement) { const kind: SymbolKind = outlineElement.symbol.kind; - if (kind === SymbolKind.Class || kind === SymbolKind.Constructor || kind === SymbolKind.Function || kind === SymbolKind.Interface || kind === SymbolKind.Method) { + if (kind === SymbolKind.Class || kind === SymbolKind.Constructor || kind === SymbolKind.Function || kind === SymbolKind.Interface || kind === SymbolKind.Method || kind === SymbolKind.Module) { currentStartLine = outlineElement?.symbol.range.startLineNumber as number; currentEndLine = outlineElement?.symbol.range.endLineNumber as number; this._ranges.push([currentStartLine, currentEndLine, depth]); @@ -154,7 +154,7 @@ class StickyScrollController extends Disposable implements IEditorContribution { for (const outline of outlineModel.children.values()) { if (outline instanceof OutlineElement) { const kind: SymbolKind = outline.symbol.kind; - if (kind === SymbolKind.Class || kind === SymbolKind.Constructor || kind === SymbolKind.Function || kind === SymbolKind.Interface || kind === SymbolKind.Method) { + if (kind === SymbolKind.Class || kind === SymbolKind.Constructor || kind === SymbolKind.Function || kind === SymbolKind.Interface || kind === SymbolKind.Method || kind === SymbolKind.Module) { this._findLineRanges(outline, 1); } else { this._findLineRanges(outline, 0); From 12b08be500f8a307f30e92cbc3ee39ba115eab69 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 29 Jul 2022 12:30:05 +0200 Subject: [PATCH 092/303] Only use the commit in share link when upstream (#156658) Fixes #156627 --- extensions/github/src/links.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/github/src/links.ts b/extensions/github/src/links.ts index 22ede57ccbd..66f5b071ecd 100644 --- a/extensions/github/src/links.ts +++ b/extensions/github/src/links.ts @@ -125,11 +125,11 @@ export function getPermalink(gitAPI: GitAPI, useSelection: boolean, hostPrefix?: return; } - const commitHash = gitRepo.state.HEAD?.commit; + const commitHash = (gitRepo.state.HEAD?.ahead === 0) ? `/blob/${gitRepo.state.HEAD?.commit}` : ''; const fileSegments = fileAndPosition.type === LinkType.File ? (useSelection ? `${uri.path.substring(gitRepo.rootUri.path.length)}${rangeString(fileAndPosition.range)}` : '') : (useSelection ? `${uri.path.substring(gitRepo.rootUri.path.length)}${notebookCellRangeString(fileAndPosition.cellIndex, fileAndPosition.range)}` : ''); - return `${hostPrefix}/${repo.owner}/${repo.repo}/blob/${commitHash + return `${hostPrefix}/${repo.owner}/${repo.repo}${commitHash }${fileSegments}`; } From 03214ee7b9b94d9498450b86f633b1a77b9ad6a9 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Fri, 29 Jul 2022 12:09:35 -0700 Subject: [PATCH 093/303] delay title bar adjustments until after menu bar is updated (#156688) fixes #156483 --- src/vs/workbench/browser/parts/titlebar/titlebarPart.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 31f4d9b6e27..34edabed458 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -461,12 +461,12 @@ export class TitlebarPart extends Part implements ITitleService { this.element.style.setProperty('--zoom-factor', zoomFactor.toString()); this.rootContainer.classList.toggle('counter-zoom', this.useCounterZoom); - runAtThisOrScheduleAtNextAnimationFrame(() => this.adjustTitleMarginToCenter()); - if (this.customMenubar) { const menubarDimension = new Dimension(0, dimension.height); this.customMenubar.layout(menubarDimension); } + + runAtThisOrScheduleAtNextAnimationFrame(() => this.adjustTitleMarginToCenter()); } } From b96204a2406f895e04f466da7a3107090afa6715 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Fri, 29 Jul 2022 13:12:51 -0700 Subject: [PATCH 094/303] Show Edit Sessions should focus view, not container (#156678) Show Edit Sessions should focus view not container --- .../contrib/editSessions/browser/editSessions.contribution.ts | 4 ++-- .../contrib/editSessions/browser/editSessionsViews.ts | 4 ++-- src/vs/workbench/contrib/editSessions/common/editSessions.ts | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts index 2853ab2d422..3d96c44b96f 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -10,7 +10,7 @@ import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle import { Action2, IAction2Options, registerAction2 } from 'vs/platform/actions/common/actions'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { localize } from 'vs/nls'; -import { IEditSessionsWorkbenchService, Change, ChangeType, Folder, EditSession, FileType, EDIT_SESSION_SYNC_CATEGORY, EDIT_SESSIONS_CONTAINER_ID, EditSessionSchemaVersion, IEditSessionsLogService, EDIT_SESSIONS_VIEW_ICON, EDIT_SESSIONS_TITLE, EDIT_SESSIONS_SCHEME, EDIT_SESSIONS_SHOW_VIEW, EDIT_SESSIONS_SIGNED_IN } from 'vs/workbench/contrib/editSessions/common/editSessions'; +import { IEditSessionsWorkbenchService, Change, ChangeType, Folder, EditSession, FileType, EDIT_SESSION_SYNC_CATEGORY, EDIT_SESSIONS_CONTAINER_ID, EditSessionSchemaVersion, IEditSessionsLogService, EDIT_SESSIONS_VIEW_ICON, EDIT_SESSIONS_TITLE, EDIT_SESSIONS_SCHEME, EDIT_SESSIONS_SHOW_VIEW, EDIT_SESSIONS_SIGNED_IN, EDIT_SESSIONS_DATA_VIEW_ID } from 'vs/workbench/contrib/editSessions/common/editSessions'; import { ISCMRepository, ISCMService } from 'vs/workbench/contrib/scm/common/scm'; import { IFileService } from 'vs/platform/files/common/files'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -199,7 +199,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo async run(accessor: ServicesAccessor) { that.shouldShowViewsContext.set(true); const viewsService = accessor.get(IViewsService); - await viewsService.openViewContainer(EDIT_SESSIONS_CONTAINER_ID); + await viewsService.openView(EDIT_SESSIONS_DATA_VIEW_ID); } })); } diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts index 36b0c497939..28dfa2257e4 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts @@ -10,7 +10,7 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati import { Registry } from 'vs/platform/registry/common/platform'; import { TreeView, TreeViewPane } from 'vs/workbench/browser/parts/views/treeView'; import { Extensions, ITreeItem, ITreeViewDataProvider, ITreeViewDescriptor, IViewsRegistry, TreeItemCollapsibleState, TreeViewItemHandleArg, ViewContainer } from 'vs/workbench/common/views'; -import { EDIT_SESSIONS_SCHEME, EDIT_SESSIONS_SHOW_VIEW, EDIT_SESSIONS_SIGNED_IN, EDIT_SESSIONS_TITLE, IEditSessionsWorkbenchService } from 'vs/workbench/contrib/editSessions/common/editSessions'; +import { EDIT_SESSIONS_DATA_VIEW_ID, EDIT_SESSIONS_SCHEME, EDIT_SESSIONS_SHOW_VIEW, EDIT_SESSIONS_SIGNED_IN, EDIT_SESSIONS_TITLE, IEditSessionsWorkbenchService } from 'vs/workbench/contrib/editSessions/common/editSessions'; import { URI } from 'vs/base/common/uri'; import { fromNow } from 'vs/base/common/date'; import { Codicon } from 'vs/base/common/codicons'; @@ -30,7 +30,7 @@ export class EditSessionsDataViews extends Disposable { } private registerViews(container: ViewContainer): void { - const viewId = 'workbench.views.editSessions.data'; + const viewId = EDIT_SESSIONS_DATA_VIEW_ID; const name = localize('edit sessions data', 'All Sessions'); const treeView = this.instantiationService.createInstance(TreeView, viewId, name); treeView.showCollapseAllAction = true; diff --git a/src/vs/workbench/contrib/editSessions/common/editSessions.ts b/src/vs/workbench/contrib/editSessions/common/editSessions.ts index da791afa9df..c4a2801d9ff 100644 --- a/src/vs/workbench/contrib/editSessions/common/editSessions.ts +++ b/src/vs/workbench/contrib/editSessions/common/editSessions.ts @@ -71,6 +71,7 @@ export const EDIT_SESSIONS_SIGNED_IN_KEY = 'editSessionsSignedIn'; export const EDIT_SESSIONS_SIGNED_IN = new RawContextKey(EDIT_SESSIONS_SIGNED_IN_KEY, false); export const EDIT_SESSIONS_CONTAINER_ID = 'workbench.view.editSessions'; +export const EDIT_SESSIONS_DATA_VIEW_ID = 'workbench.views.editSessions.data'; export const EDIT_SESSIONS_TITLE = localize('edit sessions', 'Edit Sessions'); export const EDIT_SESSIONS_VIEW_ICON = registerIcon('edit-sessions-view-icon', Codicon.cloudDownload, localize('editSessionViewIcon', 'View icon of the edit sessions view.')); From dbae720630e5996cc4d05c14649480a19b077d78 Mon Sep 17 00:00:00 2001 From: Evpok Date: Sat, 30 Jul 2022 03:59:55 +0200 Subject: [PATCH 095/303] Enable Wayland build for snaps (#156551) Enable Wayland build --- resources/linux/snap/snapcraft.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/linux/snap/snapcraft.yaml b/resources/linux/snap/snapcraft.yaml index 8bbad497ace..fc775b6554f 100644 --- a/resources/linux/snap/snapcraft.yaml +++ b/resources/linux/snap/snapcraft.yaml @@ -58,11 +58,9 @@ apps: command: electron-launch $SNAP/usr/share/@@NAME@@/bin/@@NAME@@ --no-sandbox common-id: @@NAME@@.desktop environment: - DISABLE_WAYLAND: 1 GSETTINGS_SCHEMA_DIR: $SNAP/usr/share/glib-2.0/schemas url-handler: command: electron-launch $SNAP/usr/share/@@NAME@@/bin/@@NAME@@ --open-url --no-sandbox environment: - DISABLE_WAYLAND: 1 GSETTINGS_SCHEMA_DIR: $SNAP/usr/share/glib-2.0/schemas From 07feb2bbd328d7b71d0576c6a0313b4b047c71bd Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Sat, 30 Jul 2022 11:37:25 +0900 Subject: [PATCH 096/303] chore: bump electron@19.0.10 --- .yarnrc | 2 +- cgmanifest.json | 8 ++++---- package.json | 2 +- yarn.lock | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.yarnrc b/.yarnrc index dc429531e37..7b6a179b254 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,4 +1,4 @@ disturl "https://electronjs.org/headers" -target "19.0.8" +target "19.0.10" runtime "electron" build_from_source "true" diff --git a/cgmanifest.json b/cgmanifest.json index e552709b2fb..78d331b3612 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "chromium", "repositoryUrl": "https://chromium.googlesource.com/chromium/src", - "commitHash": "c53c15c92c076f8d7593518ba99a9f8a6fc5ead6" + "commitHash": "16e28102fdf876ce6d136674ba66343ede07441f" } }, "licenseDetail": [ @@ -40,7 +40,7 @@ "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ], "isOnlyProductionDependency": true, - "version": "102.0.5005.148" + "version": "102.0.5005.167" }, { "component": { @@ -60,12 +60,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "c67ca40ed6054aadcdfb901aa1abaee2ccc690f3" + "commitHash": "7e1099a8e4b04709e3d5068403c77eb0feb7371f" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "19.0.8" + "version": "19.0.10" }, { "component": { diff --git a/package.json b/package.json index 0e570c2c0ae..bbf58446263 100644 --- a/package.json +++ b/package.json @@ -136,7 +136,7 @@ "cssnano": "^4.1.11", "debounce": "^1.0.0", "deemon": "^1.4.0", - "electron": "19.0.8", + "electron": "19.0.10", "eslint": "8.7.0", "eslint-plugin-header": "3.1.1", "eslint-plugin-jsdoc": "^39.3.2", diff --git a/yarn.lock b/yarn.lock index b11b23e316f..1c62c69ff0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4176,10 +4176,10 @@ electron-to-chromium@^1.4.17: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.45.tgz#cf1144091d6683cbd45a231954a745f02fb24598" integrity sha512-czF9eYVuOmlY/vxyMQz2rGlNSjZpxNQYBe1gmQv7al171qOIhgyO9k7D5AKlgeTCSPKk+LHhj5ZyIdmEub9oNg== -electron@19.0.8: - version "19.0.8" - resolved "https://registry.yarnpkg.com/electron/-/electron-19.0.8.tgz#c4d4ba915de554f2926261eb37d3527d2b092d4c" - integrity sha512-OWK3P/NbDFfBUv+wbYv1/OV4jehY5DQPT7n1maQJfN9hsnrWTMktXS/bmS05eSUAjNAzHmKPKfiKH2c1Yr7nGw== +electron@19.0.10: + version "19.0.10" + resolved "https://registry.yarnpkg.com/electron/-/electron-19.0.10.tgz#4d2f03f307fbb70a295ff419112130b75661eda9" + integrity sha512-EiWtPWdD7CzkRkp1cw7t0N9W2qhI5XZOudHX7daOh5wI076nsdV2dtlAf/XyTHhPNoKR5qhTWrSnYL9PY6D1vg== dependencies: "@electron/get" "^1.14.1" "@types/node" "^16.11.26" From 6fcdbd0eeb7b358fba196dfbbde95a11357bf051 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 31 Jul 2022 12:34:32 +0000 Subject: [PATCH 097/303] =?UTF-8?q?=F0=9F=94=A8=20Extract=20sanitizeFishHi?= =?UTF-8?q?storyCmd=20function=20for=20testability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Babak K. Shandiz --- .../contrib/terminal/common/history.ts | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/history.ts b/src/vs/workbench/contrib/terminal/common/history.ts index e84408622c6..dc9495580af 100644 --- a/src/vs/workbench/contrib/terminal/common/history.ts +++ b/src/vs/workbench/contrib/terminal/common/history.ts @@ -412,20 +412,7 @@ export async function fetchFishHistory(accessor: ServicesAccessor) { .filter(x => x.startsWith('- cmd:')) .map(x => x.substring(6).trimStart()); for (let i = 0; i < cmds.length; i++) { - /** - * NOTE - * This repeatedReplace() call can be eliminated by using look-ahead - * caluses in the original RegExp pattern: - * - * >>> ```ts - * >>> cmds[i].replace(/(?<=^|[^\\])((?:\\\\)*)(\\n)/g, '$1\n') - * >>> ``` - * - * But since not all browsers support look aheads we opted to a simple - * pattern and repeatedly calling replace method. - */ - const sanitized = repeatedReplace(/(^|[^\\])((?:\\\\)*)(\\n)/g, cmds[i], '$1$2\n') - .replace(/\\/g, '\\').trim(); + const sanitized = sanitizeFishHistoryCmd(cmds[i]).trim(); if (sanitized.length > 0) { result.add(sanitized); } @@ -433,6 +420,23 @@ export async function fetchFishHistory(accessor: ServicesAccessor) { return result.values(); } +export function sanitizeFishHistoryCmd(cmd: string): string { + /** + * NOTE + * This repeatedReplace() call can be eliminated by using look-ahead + * caluses in the original RegExp pattern: + * + * >>> ```ts + * >>> cmds[i].replace(/(?<=^|[^\\])((?:\\\\)*)(\\n)/g, '$1\n') + * >>> ``` + * + * But since not all browsers support look aheads we opted to a simple + * pattern and repeatedly calling replace method. + */ + return repeatedReplace(/(^|[^\\])((?:\\\\)*)(\\n)/g, cmd, '$1$2\n') + .replace(/\\/g, '\\'); +} + function repeatedReplace(pattern: RegExp, value: string, replaceValue: string): string { let last; let current = value; From 0f48e3145a7ccd8af3dea3e458e017eaf5c5ba38 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 31 Jul 2022 12:35:11 +0000 Subject: [PATCH 098/303] =?UTF-8?q?=E2=9A=97=EF=B8=8F=20Add=20unit=20tests?= =?UTF-8?q?=20for=20sanitizeFishHistoryCmd=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Babak K. Shandiz --- .../terminal/test/common/history.test.ts | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/test/common/history.test.ts b/src/vs/workbench/contrib/terminal/test/common/history.test.ts index 860f5f075f9..a43742452fc 100644 --- a/src/vs/workbench/contrib/terminal/test/common/history.test.ts +++ b/src/vs/workbench/contrib/terminal/test/common/history.test.ts @@ -16,7 +16,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; import { IStorageService } from 'vs/platform/storage/common/storage'; -import { fetchBashHistory, fetchFishHistory, fetchPwshHistory, fetchZshHistory, ITerminalPersistedHistory, TerminalPersistedHistory } from 'vs/workbench/contrib/terminal/common/history'; +import { fetchBashHistory, fetchFishHistory, fetchPwshHistory, fetchZshHistory, ITerminalPersistedHistory, sanitizeFishHistoryCmd, TerminalPersistedHistory } from 'vs/workbench/contrib/terminal/common/history'; import { IRemoteAgentConnection, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; @@ -537,5 +537,51 @@ suite('Terminal history', () => { deepStrictEqual(Array.from((await instantiationService.invokeFunction(fetchFishHistory))!), expectedCommands); }); }); + + suite('sanitizeFishHistoryCmd', () => { + test('valid new lines', () => { + const cases = [ + '\\n at start', + 'some \\n in the middle', + 'at the end \\n', + '\\\\\\n valid at start', + 'valid \\\\\\n in the middle', + 'valid in the end \\\\\\n', + '\\\\\\\\\\n valid at start', + 'valid \\\\\\\\\\n in the middle', + 'valid in the end \\\\\\\\\\n', + 'mixed valid \\r\\n', + 'mixed valid \\\\\\r\\n', + 'mixed valid \\r\\\\\\n', + ]; + + for (const x of cases) { + if (!sanitizeFishHistoryCmd(x).includes('\n')) { + fail(x); + } + } + }); + + test('invalid new lines', () => { + const cases = [ + '\\\\n invalid at start', + 'invalid \\\\n in the middle', + 'invalid in the end \\\\n', + '\\\\\\\\n invalid at start', + 'invalid \\\\\\\\n in the middle', + 'invalid in the end \\\\\\\\n', + 'mixed invalid \\r\\\\n', + 'mixed invalid \\r\\\\\\\\n', + 'echo "\\\\n"', + ]; + + for (const x of cases) { + if (sanitizeFishHistoryCmd(x).includes('\n')) { + fail(x); + } + } + }); + + }); }); }); From 33d6bed13b8fce7c2a647c3423f8e9c5ed444eeb Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Sun, 31 Jul 2022 12:49:01 +0000 Subject: [PATCH 099/303] =?UTF-8?q?=E2=9A=97=EF=B8=8F=20Update=20`sanitize?= =?UTF-8?q?FishHistoryCmd`=20unit=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Babak K. Shandiz --- .../terminal/test/common/history.test.ts | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/test/common/history.test.ts b/src/vs/workbench/contrib/terminal/test/common/history.test.ts index a43742452fc..c5d90edc5e2 100644 --- a/src/vs/workbench/contrib/terminal/test/common/history.test.ts +++ b/src/vs/workbench/contrib/terminal/test/common/history.test.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { deepStrictEqual, fail, strictEqual } from 'assert'; +import { deepStrictEqual, fail, strictEqual, ok } from 'assert'; import { VSBuffer } from 'vs/base/common/buffer'; import { Schemas } from 'vs/base/common/network'; import { join } from 'vs/base/common/path'; @@ -539,14 +539,20 @@ suite('Terminal history', () => { }); suite('sanitizeFishHistoryCmd', () => { - test('valid new lines', () => { + test('valid new-lines', () => { + /** + * Valid new-lines have odd number of leading backslashes: \n, \\\n, \\\\\n + */ const cases = [ + '\\n', '\\n at start', 'some \\n in the middle', 'at the end \\n', + '\\\\\\n', '\\\\\\n valid at start', 'valid \\\\\\n in the middle', 'valid in the end \\\\\\n', + '\\\\\\\\\\n', '\\\\\\\\\\n valid at start', 'valid \\\\\\\\\\n in the middle', 'valid in the end \\\\\\\\\\n', @@ -556,17 +562,20 @@ suite('Terminal history', () => { ]; for (const x of cases) { - if (!sanitizeFishHistoryCmd(x).includes('\n')) { - fail(x); - } + ok(sanitizeFishHistoryCmd(x).includes('\n')); } }); - test('invalid new lines', () => { + test('invalid new-lines', () => { + /** + * Invalid new-lines have even number of leading backslashes: \\n, \\\\n, \\\\\\n + */ const cases = [ + '\\\\n', '\\\\n invalid at start', 'invalid \\\\n in the middle', 'invalid in the end \\\\n', + '\\\\\\\\n', '\\\\\\\\n invalid at start', 'invalid \\\\\\\\n in the middle', 'invalid in the end \\\\\\\\n', @@ -576,9 +585,7 @@ suite('Terminal history', () => { ]; for (const x of cases) { - if (sanitizeFishHistoryCmd(x).includes('\n')) { - fail(x); - } + ok(!sanitizeFishHistoryCmd(x).includes('\n')); } }); From cdf6e9902074dc26c611ffa87a9a58e0a0d0ed05 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 1 Aug 2022 20:25:29 +0900 Subject: [PATCH 100/303] ci: don't restore stale cache --- .github/workflows/basic.yml | 9 +++------ .github/workflows/ci.yml | 9 +++------ build/.cachesalt | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml index 341a6d2c420..8a0a39315bb 100644 --- a/.github/workflows/basic.yml +++ b/.github/workflows/basic.yml @@ -39,8 +39,7 @@ jobs: uses: actions/cache@v3 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules23- + key: ${{ runner.os }}-cacheNodeModulesLinux-${{ steps.nodeModulesCacheKey.outputs.value }} - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} @@ -92,8 +91,7 @@ jobs: uses: actions/cache@v3 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules23- + key: ${{ runner.os }}-cacheNodeModulesLinux-${{ steps.nodeModulesCacheKey.outputs.value }} - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} @@ -155,8 +153,7 @@ jobs: uses: actions/cache@v3 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules23- + key: ${{ runner.os }}-cacheNodeModulesLinux-${{ steps.nodeModulesCacheKey.outputs.value }} - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f2d290664b..d505e2b9129 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -125,8 +125,7 @@ jobs: uses: actions/cache@v2 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules23- + key: ${{ runner.os }}-cacheNodeModulesLinux-${{ steps.nodeModulesCacheKey.outputs.value }} - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} @@ -197,8 +196,7 @@ jobs: uses: actions/cache@v2 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules23- + key: ${{ runner.os }}-cacheNodeModulesMacOS-${{ steps.nodeModulesCacheKey.outputs.value }} - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} @@ -271,8 +269,7 @@ jobs: uses: actions/cache@v2 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules23- + key: ${{ runner.os }}-cacheNodeModulesLinux-${{ steps.nodeModulesCacheKey.outputs.value }} - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} diff --git a/build/.cachesalt b/build/.cachesalt index c0d4fa40fce..4f9c24c0470 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2022-07-19T07:55:26.168Z +2022-08-01T11:24:47.411Z From 689bef2197675541007d88fc1d40366105e226d5 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 1 Aug 2022 13:35:10 +0200 Subject: [PATCH 101/303] use the profile from current or last active window --- .../userDataProfile/common/userDataProfile.ts | 39 +++++++--- .../electron-sandbox/userDataProfile.ts | 11 ++- .../platform/windows/electron-main/window.ts | 5 +- .../electron-main/windowsMainService.ts | 2 +- src/vs/workbench/browser/web.main.ts | 2 +- .../common/userDataProfileActions.ts | 72 ++++++++++++------- .../browser/userDataProfileManagement.ts | 8 +++ 7 files changed, 98 insertions(+), 41 deletions(-) diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 1d7ad908f95..b2064a7698f 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -91,11 +91,14 @@ export interface IUserDataProfilesService { readonly onDidChangeProfiles: Event; readonly profiles: IUserDataProfile[]; + readonly onDidResetWorkspaces: Event; + createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: WorkspaceIdentifier): Promise; updateProfile(profile: IUserDataProfile, name: string, useDefaultFlags?: UseDefaultProfileFlags): Promise; setProfileForWorkspace(profile: IUserDataProfile, workspaceIdentifier: WorkspaceIdentifier): Promise; - getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile; + getProfile(workspaceIdentifier: WorkspaceIdentifier, profileToUseIfNotSet: IUserDataProfile): IUserDataProfile; removeProfile(profile: IUserDataProfile): Promise; + resetWorkspaces(): Promise; } export function reviveProfile(profile: UriDto, scheme: string): IUserDataProfile { @@ -171,6 +174,9 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf protected readonly _onWillRemoveProfile = this._register(new Emitter()); readonly onWillRemoveProfile = this._onWillRemoveProfile.event; + private readonly _onDidResetWorkspaces = this._register(new Emitter()); + readonly onDidResetWorkspaces = this._onDidResetWorkspaces.event; + constructor( @IEnvironmentService protected readonly environmentService: IEnvironmentService, @IFileService protected readonly fileService: IFileService, @@ -194,6 +200,8 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf const profiles = this.enabled ? this.getStoredProfiles().map(storedProfile => toUserDataProfile(storedProfile.name, storedProfile.location, storedProfile.useDefaultFlags)) : []; let emptyWindow: IUserDataProfile | undefined; const workspaces = new ResourceMap(); + const defaultProfile = toUserDataProfile(localize('defaultProfile', "Default"), this.environmentService.userRoamingDataHome); + profiles.unshift({ ...defaultProfile, isDefault: true, extensionsResource: this.defaultProfileShouldIncludeExtensionsResourceAlways || profiles.length > 0 ? defaultProfile.extensionsResource : undefined }); if (profiles.length) { const profileAssicaitions = this.getStoredProfileAssociations(); if (profileAssicaitions.workspaces) { @@ -211,17 +219,23 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf emptyWindow = profiles.find(p => this.uriIdentityService.extUri.isEqual(p.location, emptyWindowProfileLocation)); } } - const profile = toUserDataProfile(localize('defaultProfile', "Default"), this.environmentService.userRoamingDataHome); - profiles.unshift({ ...profile, isDefault: true, extensionsResource: this.defaultProfileShouldIncludeExtensionsResourceAlways || profiles.length > 0 ? profile.extensionsResource : undefined }); this._profilesObject = { profiles, workspaces, emptyWindow }; } return this._profilesObject; } - getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { + getProfile(workspaceIdentifier: WorkspaceIdentifier, profileToUseIfNotSet: IUserDataProfile): IUserDataProfile { const workspace = this.getWorkspace(workspaceIdentifier); - const profile = URI.isUri(workspace) ? this.profilesObject.workspaces.get(workspace) : this.profilesObject.emptyWindow; - return profile ?? this.defaultProfile; + let profile = URI.isUri(workspace) ? this.profilesObject.workspaces.get(workspace) : this.profilesObject.emptyWindow; + if (!profile) { + profile = profileToUseIfNotSet; + // Associate the profile to workspace only if there are user profiles + // If there are no profiles, workspaces are associated to default profile by default + if (this.profiles.length > 1) { + this.updateWorkspaceAssociation(workspaceIdentifier, profile); + } + } + return profile; } protected getWorkspace(workspaceIdentifier: WorkspaceIdentifier): URI | EmptyWindowWorkspaceIdentifier { @@ -299,6 +313,13 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf this.updateWorkspaceAssociation(workspaceIdentifier); } + async resetWorkspaces(): Promise { + this.profilesObject.workspaces.clear(); + this.profilesObject.emptyWindow = undefined; + this.updateStoredProfileAssociations(); + this._onDidResetWorkspaces.fire(); + } + async removeProfile(profileToRemove: IUserDataProfile): Promise { if (!this.enabled) { throw new Error(`Settings Profiles are disabled. Enable them via the '${PROFILES_ENABLEMENT_CONFIG}' setting.`); @@ -364,19 +385,19 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf this._onDidChangeProfiles.fire({ added, removed, updated, all: this.profiles }); } - private updateWorkspaceAssociation(workspaceIdentifier: WorkspaceIdentifier, newProfile?: IUserDataProfile) { + private updateWorkspaceAssociation(workspaceIdentifier: WorkspaceIdentifier, newProfile?: IUserDataProfile): void { const workspace = this.getWorkspace(workspaceIdentifier); // Folder or Multiroot workspace if (URI.isUri(workspace)) { this.profilesObject.workspaces.delete(workspace); - if (newProfile && !newProfile.isDefault) { + if (newProfile) { this.profilesObject.workspaces.set(workspace, newProfile); } } // Empty Window else { - this.profilesObject.emptyWindow = !newProfile?.isDefault ? newProfile : undefined; + this.profilesObject.emptyWindow = newProfile; } this.updateStoredProfileAssociations(); diff --git a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts index eb662f36339..113012688aa 100644 --- a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Emitter } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { joinPath } from 'vs/base/common/resources'; import { UriDto } from 'vs/base/common/types'; @@ -29,6 +29,8 @@ export class UserDataProfilesNativeService extends Disposable implements IUserDa private readonly _onDidChangeProfiles = this._register(new Emitter()); readonly onDidChangeProfiles = this._onDidChangeProfiles.event; + readonly onDidResetWorkspaces: Event; + constructor( profiles: UriDto[], @IMainProcessService mainProcessService: IMainProcessService, @@ -45,6 +47,7 @@ export class UserDataProfilesNativeService extends Disposable implements IUserDa this._profiles = e.all.map(profile => reviveProfile(profile, this.profilesHome.scheme)); this._onDidChangeProfiles.fire({ added, removed, updated, all: this.profiles }); })); + this.onDidResetWorkspaces = this.channel.listen('onDidResetWorkspaces'); } async createProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, workspaceIdentifier?: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): Promise { @@ -65,6 +68,10 @@ export class UserDataProfilesNativeService extends Disposable implements IUserDa return reviveProfile(result, this.profilesHome.scheme); } - getProfile(workspaceIdentifier: WorkspaceIdentifier): IUserDataProfile { throw new Error('Not implemented'); } + resetWorkspaces(): Promise { + return this.channel.call('resetWorkspaces'); + } + + getProfile(workspaceIdentifier: WorkspaceIdentifier, profileToUseIfNotSet: IUserDataProfile): IUserDataProfile { throw new Error('Not implemented'); } } diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts index 938c6eb7300..b19da2206be 100644 --- a/src/vs/platform/windows/electron-main/window.ts +++ b/src/vs/platform/windows/electron-main/window.ts @@ -117,8 +117,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { get openedWorkspace(): IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined { return this._config?.workspace; } - private _profile: IUserDataProfile | undefined; - get profile(): IUserDataProfile | undefined { if (!this._profile) { this._profile = revive(this._config?.profiles.current); } return this._profile; } + get profile(): IUserDataProfile | undefined { return this.config ? this.userDataProfilesService.getProfile(this.config.workspace ?? 'empty-window', revive(this.config.profiles.current)) : undefined; } get remoteAuthority(): string | undefined { return this._config?.remoteAuthority; } @@ -948,7 +947,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { configuration.editSessionId = this.environmentMainService.editSessionId; // set latest edit session id configuration.profiles = { all: this.userDataProfilesService.profiles, - current: this.userDataProfilesService.getProfile(configuration.workspace ?? 'empty-window'), + current: this.profile || this.userDataProfilesService.defaultProfile, }; // Load config diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index 8452c1c5fc4..b287f30732d 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -1326,7 +1326,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic profiles: { all: this.userDataProfilesService.profiles, - current: this.userDataProfilesService.getProfile(options.workspace ?? 'empty-window'), + current: this.userDataProfilesService.getProfile(options.workspace ?? 'empty-window', (options.windowToUse ?? this.getLastActiveWindow())?.profile ?? this.userDataProfilesService.defaultProfile), }, homeDir: this.environmentMainService.userHome.fsPath, diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 02ea6a2b6cb..b36b008adce 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -269,7 +269,7 @@ export class BrowserMain extends Disposable { // User Data Profiles const userDataProfilesService = new BrowserUserDataProfilesService(environmentService, fileService, uriIdentityService, logService); serviceCollection.set(IUserDataProfilesService, userDataProfilesService); - const userDataProfileService = new UserDataProfileService(userDataProfilesService.getProfile(isWorkspaceIdentifier(payload) || isSingleFolderWorkspaceIdentifier(payload) ? payload : 'empty-window'), userDataProfilesService); + const userDataProfileService = new UserDataProfileService(userDataProfilesService.getProfile(isWorkspaceIdentifier(payload) || isSingleFolderWorkspaceIdentifier(payload) ? payload : 'empty-window', userDataProfilesService.defaultProfile), userDataProfilesService); serviceCollection.set(IUserDataProfileService, userDataProfileService); // Long running services (workspace, config, storage) diff --git a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts index 62e3de604fe..a5961b7c3c8 100644 --- a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts +++ b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts @@ -275,31 +275,6 @@ registerAction2(class SwitchProfileAction extends Action2 { } }); -registerAction2(class CleanupProfilesAction extends Action2 { - constructor() { - super({ - id: 'workbench.profiles.actions.cleanupProfiles', - title: { - value: localize('cleanup profile', "Cleanup Settings Profiles"), - original: 'Cleanup Profiles' - }, - category: CATEGORIES.Developer, - f1: true, - precondition: PROFILES_ENABLEMENT_CONTEXT, - }); - } - - async run(accessor: ServicesAccessor) { - const userDataProfilesService = accessor.get(IUserDataProfilesService); - const fileService = accessor.get(IFileService); - const uriIdentityService = accessor.get(IUriIdentityService); - - const stat = await fileService.resolve(userDataProfilesService.profilesHome); - await Promise.all((stat.children || [])?.filter(child => child.isDirectory && userDataProfilesService.profiles.every(p => !uriIdentityService.extUri.isEqual(p.location, child.resource))) - .map(child => fileService.del(child.resource, { recursive: true }))); - } -}); - registerAction2(class ExportProfileAction extends Action2 { constructor() { super({ @@ -449,3 +424,50 @@ registerAction2(class ImportProfileAction extends Action2 { } }); + +// Developer Actions + +registerAction2(class CleanupProfilesAction extends Action2 { + constructor() { + super({ + id: 'workbench.profiles.actions.cleanupProfiles', + title: { + value: localize('cleanup profile', "Cleanup Settings Profiles"), + original: 'Cleanup Profiles' + }, + category: CATEGORIES.Developer, + f1: true, + precondition: PROFILES_ENABLEMENT_CONTEXT, + }); + } + + async run(accessor: ServicesAccessor) { + const userDataProfilesService = accessor.get(IUserDataProfilesService); + const fileService = accessor.get(IFileService); + const uriIdentityService = accessor.get(IUriIdentityService); + + const stat = await fileService.resolve(userDataProfilesService.profilesHome); + await Promise.all((stat.children || [])?.filter(child => child.isDirectory && userDataProfilesService.profiles.every(p => !uriIdentityService.extUri.isEqual(p.location, child.resource))) + .map(child => fileService.del(child.resource, { recursive: true }))); + } +}); + +registerAction2(class ResetWorkspacesAction extends Action2 { + constructor() { + super({ + id: 'workbench.profiles.actions.resetWorkspaces', + title: { + value: localize('reset workspaces', "Reset Workspace Settings Profiles Associations"), + original: 'Reset Workspace Settings Profiles Associations' + }, + category: CATEGORIES.Developer, + f1: true, + precondition: PROFILES_ENABLEMENT_CONTEXT, + }); + } + + async run(accessor: ServicesAccessor) { + const userDataProfilesService = accessor.get(IUserDataProfilesService); + return userDataProfilesService.resetWorkspaces(); + } +}); diff --git a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts index 7b124b207ca..719b6951865 100644 --- a/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts +++ b/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts @@ -28,6 +28,7 @@ export class UserDataProfileManagementService extends Disposable implements IUse ) { super(); this._register(userDataProfilesService.onDidChangeProfiles(e => this.onDidChangeProfiles(e))); + this._register(userDataProfilesService.onDidResetWorkspaces(() => this.onDidResetWorkspaces())); } private onDidChangeProfiles(e: DidChangeProfilesEvent): void { @@ -37,6 +38,13 @@ export class UserDataProfileManagementService extends Disposable implements IUse } } + private onDidResetWorkspaces(): void { + if (!this.userDataProfileService.currentProfile.isDefault) { + this.enterProfile(this.userDataProfilesService.defaultProfile, false, localize('reload message when removed', "The current settings profile has been removed. Please reload to switch back to default settings profile")); + return; + } + } + async createAndEnterProfile(name: string, useDefaultFlags?: UseDefaultProfileFlags, fromExisting?: boolean): Promise { const profile = await this.userDataProfilesService.createProfile(name, useDefaultFlags, this.getWorkspaceIdentifier()); await this.enterProfile(profile, !!fromExisting); From 852b4ae5f8b2aadedfa03648f9fbb1c99b608372 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 1 Aug 2022 04:57:27 -0700 Subject: [PATCH 102/303] Update to xterm 5 Mainly just canvas renderer not yet hooked up --- package.json | 6 +-- remote/package.json | 6 +-- remote/web/package.json | 4 +- remote/web/yarn.lock | 16 +++--- remote/yarn.lock | 24 ++++----- src/vs/platform/terminal/node/ptyService.ts | 9 +++- .../terminal/browser/terminalInstance.ts | 2 +- .../terminal/browser/xterm/xtermTerminal.ts | 49 ++++++++++--------- .../test/browser/xterm/xtermTerminal.test.ts | 31 ++++++------ yarn.lock | 24 ++++----- 10 files changed, 91 insertions(+), 80 deletions(-) diff --git a/package.json b/package.json index 838defde1cb..5d91cf0a232 100644 --- a/package.json +++ b/package.json @@ -86,12 +86,12 @@ "vscode-proxy-agent": "^0.12.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "7.0.1", - "xterm": "4.20.0-beta.20", + "xterm": "5.0.0-beta.32", "xterm-addon-search": "0.10.0-beta.3", "xterm-addon-serialize": "0.8.0-beta.3", "xterm-addon-unicode11": "0.4.0-beta.3", - "xterm-addon-webgl": "0.13.0-beta.9", - "xterm-headless": "4.20.0-beta.20", + "xterm-addon-webgl": "0.13.0-beta.32", + "xterm-headless": "5.0.0-beta.5", "yauzl": "^2.9.2", "yazl": "^2.4.3" }, diff --git a/remote/package.json b/remote/package.json index 6b5622069ed..b8da1151d24 100644 --- a/remote/package.json +++ b/remote/package.json @@ -24,12 +24,12 @@ "vscode-proxy-agent": "^0.12.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "7.0.1", - "xterm": "4.20.0-beta.20", + "xterm": "5.0.0-beta.32", "xterm-addon-search": "0.10.0-beta.3", "xterm-addon-serialize": "0.8.0-beta.3", "xterm-addon-unicode11": "0.4.0-beta.3", - "xterm-addon-webgl": "0.13.0-beta.9", - "xterm-headless": "4.20.0-beta.20", + "xterm-addon-webgl": "0.13.0-beta.32", + "xterm-headless": "5.0.0-beta.5", "yauzl": "^2.9.2", "yazl": "^2.4.3" }, diff --git a/remote/web/package.json b/remote/web/package.json index 9e4dc583566..7a230e76868 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -11,9 +11,9 @@ "tas-client-umd": "0.1.6", "vscode-oniguruma": "1.6.1", "vscode-textmate": "7.0.1", - "xterm": "4.20.0-beta.20", + "xterm": "5.0.0-beta.32", "xterm-addon-search": "0.10.0-beta.3", "xterm-addon-unicode11": "0.4.0-beta.3", - "xterm-addon-webgl": "0.13.0-beta.9" + "xterm-addon-webgl": "0.13.0-beta.32" } } diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index a2ae83d5fce..87c4c4d35ff 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -78,12 +78,12 @@ xterm-addon-unicode11@0.4.0-beta.3: resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.4.0-beta.3.tgz#f350184155fafd5ad0d6fbf31d13e6ca7dea1efa" integrity sha512-FryZAVwbUjKTmwXnm1trch/2XO60F5JsDvOkZhzobV1hm10sFLVuZpFyHXiUx7TFeeFsvNP+S77LAtWoeT5z+Q== -xterm-addon-webgl@0.13.0-beta.9: - version "0.13.0-beta.9" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.9.tgz#66a9ac142ae347d0548abbf4e66bb2f35f415adb" - integrity sha512-x1o1tpCqIsICvhcRsZs+BLcwUIdizYS2G4TIH0KBnUDiSN+oSqpVBQNG8qKg56xbK8WtpdbQ9dLB7JR2W5cX0g== +xterm-addon-webgl@0.13.0-beta.32: + version "0.13.0-beta.32" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.32.tgz#ae7335f788ae611733e03f6ca38280ab7b86d212" + integrity sha512-xOudNzYXaRh9QZ+IigXM5EB3bM8l3/F8F35EpJRYvvsylVxiB6Km8X8l7+nxlWt+uYdnHZs0ka2rvtL8kOP/uw== -xterm@4.20.0-beta.20: - version "4.20.0-beta.20" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.20.0-beta.20.tgz#2979a31839f7b8ee3ffe4f063b40c02facdb0fed" - integrity sha512-ltDtTquH+33tXQPFSDqenbgz6LkvIob6l6Rac85L4aX5Ve7P3ubVLrq+lTFJGQn3iiwGqNmnE1t1EUuGhxsXcQ== +xterm@5.0.0-beta.32: + version "5.0.0-beta.32" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0-beta.32.tgz#62bb9902429c0055fd2fd85c9eecfbf1756ed31c" + integrity sha512-OAM1GaBs/chK63Cr86XbVhfVCLLXLpNxxFrv3RK9xoyb9dwiY3gaMxK9jeGzTnrbGLWJb+k5nxaC0rx2YsHvUA== diff --git a/remote/yarn.lock b/remote/yarn.lock index 762745d5927..c729673b610 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -803,20 +803,20 @@ xterm-addon-unicode11@0.4.0-beta.3: resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.4.0-beta.3.tgz#f350184155fafd5ad0d6fbf31d13e6ca7dea1efa" integrity sha512-FryZAVwbUjKTmwXnm1trch/2XO60F5JsDvOkZhzobV1hm10sFLVuZpFyHXiUx7TFeeFsvNP+S77LAtWoeT5z+Q== -xterm-addon-webgl@0.13.0-beta.9: - version "0.13.0-beta.9" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.9.tgz#66a9ac142ae347d0548abbf4e66bb2f35f415adb" - integrity sha512-x1o1tpCqIsICvhcRsZs+BLcwUIdizYS2G4TIH0KBnUDiSN+oSqpVBQNG8qKg56xbK8WtpdbQ9dLB7JR2W5cX0g== +xterm-addon-webgl@0.13.0-beta.32: + version "0.13.0-beta.32" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.32.tgz#ae7335f788ae611733e03f6ca38280ab7b86d212" + integrity sha512-xOudNzYXaRh9QZ+IigXM5EB3bM8l3/F8F35EpJRYvvsylVxiB6Km8X8l7+nxlWt+uYdnHZs0ka2rvtL8kOP/uw== -xterm-headless@4.20.0-beta.20: - version "4.20.0-beta.20" - resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-4.20.0-beta.20.tgz#da2d8131b02d6f1e37f47cc17e578f2c2980fbb6" - integrity sha512-JK4jUIiUH7TdzvMrpfDnbGxTuC4s7byjqnMHR8+gIpY8qCFjz0xcMFSbp+ZshxGwVyziI4jtJqTHZjFToT2/kw== +xterm-headless@5.0.0-beta.5: + version "5.0.0-beta.5" + resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.0.0-beta.5.tgz#e29b6c5081f31f887122b7263ba996b0c46b3c22" + integrity sha512-CMQ1+prBNF92oBMeZzc2rfTcmOaCGfwwSaoPYNTjyziZT6mZsEg7amajYkb0YAnqJ29MFm4kPGZbU78/dX4k2A== -xterm@4.20.0-beta.20: - version "4.20.0-beta.20" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.20.0-beta.20.tgz#2979a31839f7b8ee3ffe4f063b40c02facdb0fed" - integrity sha512-ltDtTquH+33tXQPFSDqenbgz6LkvIob6l6Rac85L4aX5Ve7P3ubVLrq+lTFJGQn3iiwGqNmnE1t1EUuGhxsXcQ== +xterm@5.0.0-beta.32: + version "5.0.0-beta.32" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0-beta.32.tgz#62bb9902429c0055fd2fd85c9eecfbf1756ed31c" + integrity sha512-OAM1GaBs/chK63Cr86XbVhfVCLLXLpNxxFrv3RK9xoyb9dwiY3gaMxK9jeGzTnrbGLWJb+k5nxaC0rx2YsHvUA== yallist@^4.0.0: version "4.0.0" diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 5e1feff3086..cb23737373f 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -789,7 +789,12 @@ class XtermSerializer implements ITerminalSerializer { private _rawReviveBuffer: string | undefined, logService: ILogService ) { - this._xterm = new XtermTerminal({ cols, rows, scrollback }); + this._xterm = new XtermTerminal({ + cols, + rows, + scrollback, + allowProposedApi: true + }); if (reviveBufferWithRestoreMessage) { this._xterm.writeln(reviveBufferWithRestoreMessage); } @@ -815,7 +820,7 @@ class XtermSerializer implements ITerminalSerializer { const serialize = new (await this._getSerializeConstructor()); this._xterm.loadAddon(serialize); const options: ISerializeOptions = { - scrollback: this._xterm.getOption('scrollback') + scrollback: this._xterm.options.scrollback }; if (normalBufferOnly) { options.excludeAltBuffer = true; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index fde509c864f..1ba61b1d3d7 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1249,7 +1249,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // If IShellLaunchConfig.waitOnExit was true and the process finished before the terminal // panel was initialized. - if (xterm.raw.getOption('disableStdin')) { + if (xterm.raw.options.disableStdin) { this._attachPressAnyKeyToCloseListener(xterm.raw); } } diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index 88a89cb7a6c..3c60805a553 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { IBuffer, IMarker, ITheme, RendererType, Terminal as RawXtermTerminal } from 'xterm'; +import type { IBuffer, IMarker, ITheme, Terminal as RawXtermTerminal } from 'xterm'; import type { ISearchOptions, SearchAddon as SearchAddonType } from 'xterm-addon-search'; import type { Unicode11Addon as Unicode11AddonType } from 'xterm-addon-unicode11'; import type { WebglAddon as WebglAddonType } from 'xterm-addon-webgl'; @@ -117,6 +117,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II const editorOptions = this._configurationService.getValue('editor'); this.raw = this.add(new xtermCtor({ + allowProposedApi: true, cols, rows, altClickMovesCursor: config.altClickMovesCursor && editorOptions.multiCursorModifier === 'alt', @@ -133,14 +134,13 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II cursorBlink: config.cursorBlinking, cursorStyle: config.cursorStyle === 'line' ? 'bar' : config.cursorStyle, cursorWidth: config.cursorWidth, - bellStyle: 'none', macOptionIsMeta: config.macOptionIsMeta, macOptionClickForcesSelection: config.macOptionClickForcesSelection, rightClickSelectsWord: config.rightClickBehavior === 'selectWord', fastScrollModifier: 'alt', fastScrollSensitivity: config.fastScrollSensitivity, scrollSensitivity: config.mouseWheelScrollSensitivity, - rendererType: this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType), + // rendererType: this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType), wordSeparator: config.wordSeparators, overviewRulerWidth: 10 })); @@ -241,7 +241,8 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II this._enableWebglRenderer(); } else { this._disposeOfWebglRenderer(); - this.raw.options.rendererType = this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType); + // TODO: Fix renderer + // this.raw.options.rendererType = this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType); } } @@ -267,12 +268,13 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II // This is to fix an issue where dragging the windpow to the top of the screen to // maximize on Windows/Linux would fire an event saying that the terminal was not // visible. - if (this.raw.getOption('rendererType') === 'canvas') { - this._core._renderService?._onIntersectionChange({ intersectionRatio: 1 }); - // HACK: Force a refresh of the screen to ensure links are refresh corrected. - // This can probably be removed when the above hack is fixed in Chromium. - this.raw.refresh(0, this.raw.rows - 1); - } + // TODO: Fix renderer + // if (this.raw.getOption('rendererType') === 'canvas') { + // this._core._renderService?._onIntersectionChange({ intersectionRatio: 1 }); + // // HACK: Force a refresh of the screen to ensure links are refresh corrected. + // // This can probably be removed when the above hack is fixed in Chromium. + // this.raw.refresh(0, this.raw.rows - 1); + // } } async findNext(term: string, searchOptions: ISearchOptions): Promise { @@ -419,13 +421,14 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II } } - private _getBuiltInXtermRenderer(gpuAcceleration: string, suggestedRendererType?: string): RendererType { - let rendererType: RendererType = 'canvas'; - if (gpuAcceleration === 'off' || (gpuAcceleration === 'auto' && suggestedRendererType === 'dom')) { - rendererType = 'dom'; - } - return rendererType; - } + // TODO: Fix renderer + // private _getBuiltInXtermRenderer(gpuAcceleration: string, suggestedRendererType?: string): RendererType { + // let rendererType: RendererType = 'canvas'; + // if (gpuAcceleration === 'off' || (gpuAcceleration === 'auto' && suggestedRendererType === 'dom')) { + // rendererType = 'dom'; + // } + // return rendererType; + // } private async _enableWebglRenderer(): Promise { if (!this.raw.element || this._webglAddon) { @@ -439,7 +442,8 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II this._webglAddon.onContextLoss(() => { this._logService.info(`Webgl lost context, disposing of webgl renderer`); this._disposeOfWebglRenderer(); - this.raw.options.rendererType = 'dom'; + // TODO: Fix renderer + // this.raw.options.rendererType = 'dom'; }); // Uncomment to add the texture atlas to the DOM // setTimeout(() => { @@ -454,8 +458,9 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II if (!neverMeasureRenderTime && this._configHelper.config.gpuAcceleration !== 'off') { this._measureRenderTime(); } - this.raw.options.rendererType = 'canvas'; - XtermTerminal._suggestedRendererType = 'canvas'; + // TODO: Fix renderer + // this.raw.options.rendererType = 'canvas'; + // XtermTerminal._suggestedRendererType = 'canvas'; this._disposeOfWebglRenderer(); } } @@ -573,7 +578,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II foreground: foregroundColor?.toString(), cursor: cursorColor?.toString(), cursorAccent: cursorAccentColor?.toString(), - selection: selectionBackgroundColor?.toString(), + selectionBackground: selectionBackgroundColor?.toString(), selectionForeground: selectionForegroundColor?.toString(), black: theme.getColor(ansiColorIdentifiers[0])?.toString(), red: theme.getColor(ansiColorIdentifiers[1])?.toString(), @@ -595,7 +600,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II } private _updateTheme(theme?: IColorTheme): void { - this.raw.setOption('theme', this._getXtermTheme(theme)); + this.raw.options.theme = this._getXtermTheme(theme); } private async _updateUnicodeVersion(): Promise { diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts index 99bc8e0b095..57ec65285bd 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts @@ -31,6 +31,7 @@ import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuS class TestWebglAddon { static shouldThrow = false; static isEnabled = false; + readonly onChangeTextureAtlas = new Emitter().event as IEvent; readonly onContextLoss = new Emitter().event as IEvent; activate() { TestWebglAddon.isEnabled = !TestWebglAddon.shouldThrow; @@ -120,8 +121,8 @@ suite('XtermTerminal', () => { }); test('should use fallback dimensions of 80x30', () => { - strictEqual(xterm.raw.options.cols, 80); - strictEqual(xterm.raw.options.rows, 30); + strictEqual(xterm.raw.cols, 80); + strictEqual(xterm.raw.rows, 30); }); suite('theme', () => { @@ -243,7 +244,6 @@ suite('XtermTerminal', () => { suite('renderers', () => { test('should re-evaluate gpu acceleration auto when the setting is changed', async () => { // Check initial state - strictEqual(xterm.raw.options.rendererType, 'dom'); strictEqual(TestWebglAddon.isEnabled, false); // Open xterm as otherwise the webgl addon won't activate @@ -261,19 +261,20 @@ suite('XtermTerminal', () => { } // Turn off to reset state - await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'off' } }); - configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); - await xterm.webglAddonPromise; // await addon activate - strictEqual(xterm.raw.options.rendererType, 'dom'); - strictEqual(TestWebglAddon.isEnabled, false); + // TODO: Fix renderer + // await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'off' } }); + // configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); + // await xterm.webglAddonPromise; // await addon activate + // strictEqual(xterm.raw.options.rendererType, 'dom'); + // strictEqual(TestWebglAddon.isEnabled, false); - // Set to auto again but throw when activating the webgl addon - TestWebglAddon.shouldThrow = true; - await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'auto' } }); - configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); - await xterm.webglAddonPromise; // await addon activate - strictEqual(xterm.raw.options.rendererType, 'canvas'); - strictEqual(TestWebglAddon.isEnabled, false); + // // Set to auto again but throw when activating the webgl addon + // TestWebglAddon.shouldThrow = true; + // await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'auto' } }); + // configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); + // await xterm.webglAddonPromise; // await addon activate + // strictEqual(xterm.raw.options.rendererType, 'canvas'); + // strictEqual(TestWebglAddon.isEnabled, false); }); }); }); diff --git a/yarn.lock b/yarn.lock index 9121ca37524..c3f1dcc3ba1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12087,20 +12087,20 @@ xterm-addon-unicode11@0.4.0-beta.3: resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.4.0-beta.3.tgz#f350184155fafd5ad0d6fbf31d13e6ca7dea1efa" integrity sha512-FryZAVwbUjKTmwXnm1trch/2XO60F5JsDvOkZhzobV1hm10sFLVuZpFyHXiUx7TFeeFsvNP+S77LAtWoeT5z+Q== -xterm-addon-webgl@0.13.0-beta.9: - version "0.13.0-beta.9" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.9.tgz#66a9ac142ae347d0548abbf4e66bb2f35f415adb" - integrity sha512-x1o1tpCqIsICvhcRsZs+BLcwUIdizYS2G4TIH0KBnUDiSN+oSqpVBQNG8qKg56xbK8WtpdbQ9dLB7JR2W5cX0g== +xterm-addon-webgl@0.13.0-beta.32: + version "0.13.0-beta.32" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.32.tgz#ae7335f788ae611733e03f6ca38280ab7b86d212" + integrity sha512-xOudNzYXaRh9QZ+IigXM5EB3bM8l3/F8F35EpJRYvvsylVxiB6Km8X8l7+nxlWt+uYdnHZs0ka2rvtL8kOP/uw== -xterm-headless@4.20.0-beta.20: - version "4.20.0-beta.20" - resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-4.20.0-beta.20.tgz#da2d8131b02d6f1e37f47cc17e578f2c2980fbb6" - integrity sha512-JK4jUIiUH7TdzvMrpfDnbGxTuC4s7byjqnMHR8+gIpY8qCFjz0xcMFSbp+ZshxGwVyziI4jtJqTHZjFToT2/kw== +xterm-headless@5.0.0-beta.5: + version "5.0.0-beta.5" + resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.0.0-beta.5.tgz#e29b6c5081f31f887122b7263ba996b0c46b3c22" + integrity sha512-CMQ1+prBNF92oBMeZzc2rfTcmOaCGfwwSaoPYNTjyziZT6mZsEg7amajYkb0YAnqJ29MFm4kPGZbU78/dX4k2A== -xterm@4.20.0-beta.20: - version "4.20.0-beta.20" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.20.0-beta.20.tgz#2979a31839f7b8ee3ffe4f063b40c02facdb0fed" - integrity sha512-ltDtTquH+33tXQPFSDqenbgz6LkvIob6l6Rac85L4aX5Ve7P3ubVLrq+lTFJGQn3iiwGqNmnE1t1EUuGhxsXcQ== +xterm@5.0.0-beta.32: + version "5.0.0-beta.32" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0-beta.32.tgz#62bb9902429c0055fd2fd85c9eecfbf1756ed31c" + integrity sha512-OAM1GaBs/chK63Cr86XbVhfVCLLXLpNxxFrv3RK9xoyb9dwiY3gaMxK9jeGzTnrbGLWJb+k5nxaC0rx2YsHvUA== y18n@^3.2.1: version "3.2.2" From b7e713947e09c9f2625cc7904f5ebd8b7b5f97a3 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 1 Aug 2022 21:53:12 +0900 Subject: [PATCH 103/303] ci: remove hardcoded chromium version and sysroot file --- build/linux/debian/dependencies-generator.js | 6 ++++- build/linux/debian/dependencies-generator.ts | 6 ++++- build/linux/debian/install-sysroot.js | 11 +++++++-- build/linux/debian/install-sysroot.ts | 11 +++++++-- build/linux/debian/sysroots.js | 26 -------------------- build/linux/debian/sysroots.ts | 24 ------------------ 6 files changed, 28 insertions(+), 56 deletions(-) delete mode 100644 build/linux/debian/sysroots.js delete mode 100644 build/linux/debian/sysroots.ts diff --git a/build/linux/debian/dependencies-generator.js b/build/linux/debian/dependencies-generator.js index 235ca268531..db39a908535 100644 --- a/build/linux/debian/dependencies-generator.js +++ b/build/linux/debian/dependencies-generator.js @@ -10,6 +10,7 @@ const fs_1 = require("fs"); const os_1 = require("os"); const path = require("path"); const dep_lists_1 = require("./dep-lists"); +const manifests = require("../../../cgmanifest.json"); // A flag that can easily be toggled. // Make sure to compile the build directory after toggling the value. // If false, we warn about new dependencies if they show up @@ -76,7 +77,10 @@ function calculatePackageDeps(binaryPath, arch, sysroot) { console.error('Tried to stat ' + binaryPath + ' but failed.'); } // Get the Chromium dpkg-shlibdeps file. - const dpkgShlibdepsUrl = 'https://raw.githubusercontent.com/chromium/chromium/100.0.4896.160/third_party/dpkg-shlibdeps/dpkg-shlibdeps.pl'; + const chromiumManifest = manifests.registrations.filter(registration => { + return registration.component.type === 'git' && registration.component.git.name === 'chromium'; + }); + const dpkgShlibdepsUrl = `https://raw.githubusercontent.com/chromium/chromium/${chromiumManifest[0].version}/third_party/dpkg-shlibdeps/dpkg-shlibdeps.pl`; const dpkgShlibdepsScriptLocation = `${(0, os_1.tmpdir)()}/dpkg-shlibdeps.pl`; const result = (0, child_process_1.spawnSync)('curl', [dpkgShlibdepsUrl, '-o', dpkgShlibdepsScriptLocation]); if (result.status !== 0) { diff --git a/build/linux/debian/dependencies-generator.ts b/build/linux/debian/dependencies-generator.ts index 9e3d466cfe0..12e2048f2a9 100644 --- a/build/linux/debian/dependencies-generator.ts +++ b/build/linux/debian/dependencies-generator.ts @@ -11,6 +11,7 @@ import { tmpdir } from 'os'; import path = require('path'); import { additionalDeps, bundledDeps, referenceGeneratedDepsByArch } from './dep-lists'; import { ArchString } from './types'; +import * as manifests from '../../../cgmanifest.json'; // A flag that can easily be toggled. // Make sure to compile the build directory after toggling the value. @@ -86,7 +87,10 @@ function calculatePackageDeps(binaryPath: string, arch: ArchString, sysroot: str } // Get the Chromium dpkg-shlibdeps file. - const dpkgShlibdepsUrl = 'https://raw.githubusercontent.com/chromium/chromium/100.0.4896.160/third_party/dpkg-shlibdeps/dpkg-shlibdeps.pl'; + const chromiumManifest = manifests.registrations.filter(registration => { + return registration.component.type === 'git' && registration.component.git!.name === 'chromium'; + }); + const dpkgShlibdepsUrl = `https://raw.githubusercontent.com/chromium/chromium/${chromiumManifest[0].version}/third_party/dpkg-shlibdeps/dpkg-shlibdeps.pl`; const dpkgShlibdepsScriptLocation = `${tmpdir()}/dpkg-shlibdeps.pl`; const result = spawnSync('curl', [dpkgShlibdepsUrl, '-o', dpkgShlibdepsScriptLocation]); if (result.status !== 0) { diff --git a/build/linux/debian/install-sysroot.js b/build/linux/debian/install-sysroot.js index c6b57a7b8a3..9608b6356d3 100644 --- a/build/linux/debian/install-sysroot.js +++ b/build/linux/debian/install-sysroot.js @@ -11,7 +11,7 @@ const os_1 = require("os"); const fs = require("fs"); const https = require("https"); const path = require("path"); -const sysroots_1 = require("./sysroots"); +const util = require("../../lib/util"); // Based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/install-sysroot.py. const URL_PREFIX = 'https://msftelectron.blob.core.windows.net'; const URL_PATH = 'sysroots/toolchain'; @@ -30,7 +30,14 @@ function getSha(filename) { return hash.digest('hex'); } async function getSysroot(arch) { - const sysrootDict = sysroots_1.sysrootInfo[arch]; + const sysrootJSONUrl = `https://raw.githubusercontent.com/electron/electron/v${util.getElectronVersion()}/script/sysroots.json`; + const sysrootDictLocation = `${(0, os_1.tmpdir)()}/sysroots.json`; + const result = (0, child_process_1.spawnSync)('curl', [sysrootJSONUrl, '-o', sysrootDictLocation]); + if (result.status !== 0) { + throw new Error('Cannot retrieve sysroots.json. Stderr:\n' + result.stderr); + } + const sysrootInfo = require(sysrootDictLocation); + const sysrootDict = sysrootInfo[`bullseye_${arch}`]; const tarballFilename = sysrootDict['Tarball']; const tarballSha = sysrootDict['Sha1Sum']; const sysroot = path.join((0, os_1.tmpdir)(), sysrootDict['SysrootDir']); diff --git a/build/linux/debian/install-sysroot.ts b/build/linux/debian/install-sysroot.ts index 7c04c44f730..acc71ce5ce7 100644 --- a/build/linux/debian/install-sysroot.ts +++ b/build/linux/debian/install-sysroot.ts @@ -9,8 +9,8 @@ import { tmpdir } from 'os'; import * as fs from 'fs'; import * as https from 'https'; import * as path from 'path'; -import { sysrootInfo } from './sysroots'; import { ArchString } from './types'; +import * as util from '../../lib/util'; // Based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/install-sysroot.py. const URL_PREFIX = 'https://msftelectron.blob.core.windows.net'; @@ -38,7 +38,14 @@ type SysrootDictEntry = { }; export async function getSysroot(arch: ArchString): Promise { - const sysrootDict: SysrootDictEntry = sysrootInfo[arch]; + const sysrootJSONUrl = `https://raw.githubusercontent.com/electron/electron/v${util.getElectronVersion()}/script/sysroots.json`; + const sysrootDictLocation = `${tmpdir()}/sysroots.json`; + const result = spawnSync('curl', [sysrootJSONUrl, '-o', sysrootDictLocation]); + if (result.status !== 0) { + throw new Error('Cannot retrieve sysroots.json. Stderr:\n' + result.stderr); + } + const sysrootInfo = require(sysrootDictLocation); + const sysrootDict: SysrootDictEntry = sysrootInfo[`bullseye_${arch}`]; const tarballFilename = sysrootDict['Tarball']; const tarballSha = sysrootDict['Sha1Sum']; const sysroot = path.join(tmpdir(), sysrootDict['SysrootDir']); diff --git a/build/linux/debian/sysroots.js b/build/linux/debian/sysroots.js deleted file mode 100644 index 3825de44028..00000000000 --- a/build/linux/debian/sysroots.js +++ /dev/null @@ -1,26 +0,0 @@ -"use strict"; -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -Object.defineProperty(exports, "__esModule", { value: true }); -exports.sysrootInfo = void 0; -// Based on https://github.com/electron/electron/blob/main/script/sysroots.json, -// which itself is based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/sysroots.json. -exports.sysrootInfo = { - 'amd64': { - 'Sha1Sum': '7e008cea9eae822d80d55c67fbb5ef4204678e74', - 'SysrootDir': 'debian_sid_amd64-sysroot', - 'Tarball': 'debian_sid_amd64_sysroot.tar.xz' - }, - 'armhf': { - 'Sha1Sum': 'b6f4bb07817bea91b06514a9c1e3832df5a90dbf', - 'SysrootDir': 'debian_sid_arm-sysroot', - 'Tarball': 'debian_sid_arm_sysroot.tar.xz' - }, - 'arm64': { - 'Sha1Sum': '5a56c1ef714154ea5003bcafb16f21b0f8dde023', - 'SysrootDir': 'debian_sid_arm64-sysroot', - 'Tarball': 'debian_sid_arm64_sysroot.tar.xz' - } -}; diff --git a/build/linux/debian/sysroots.ts b/build/linux/debian/sysroots.ts deleted file mode 100644 index 5fda6e6c7bb..00000000000 --- a/build/linux/debian/sysroots.ts +++ /dev/null @@ -1,24 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -// Based on https://github.com/electron/electron/blob/main/script/sysroots.json, -// which itself is based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/sysroots.json. -export const sysrootInfo = { - 'amd64': { - 'Sha1Sum': '7e008cea9eae822d80d55c67fbb5ef4204678e74', - 'SysrootDir': 'debian_sid_amd64-sysroot', - 'Tarball': 'debian_sid_amd64_sysroot.tar.xz' - }, - 'armhf': { - 'Sha1Sum': 'b6f4bb07817bea91b06514a9c1e3832df5a90dbf', - 'SysrootDir': 'debian_sid_arm-sysroot', - 'Tarball': 'debian_sid_arm_sysroot.tar.xz' - }, - 'arm64': { - 'Sha1Sum': '5a56c1ef714154ea5003bcafb16f21b0f8dde023', - 'SysrootDir': 'debian_sid_arm64-sysroot', - 'Tarball': 'debian_sid_arm64_sysroot.tar.xz' - } -}; From 519f9b51f33c457b0dce854c3b43f81b548b097a Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 1 Aug 2022 09:35:32 -0400 Subject: [PATCH 104/303] Bump distro + update labels (#156685) --- .github/commands.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/commands.json b/.github/commands.json index f67ee72c873..bd319fe1148 100644 --- a/.github/commands.json +++ b/.github/commands.json @@ -197,10 +197,10 @@ }, { "type": "label", - "name": "~needs version info", + "name": "~version-info-needed", "action": "updateLabels", "addLabel": "info-needed", - "removeLabel": "~needs version info", + "removeLabel": "~version-info-needed", "comment": "Thanks for creating this issue! We figured it's missing some basic information, such as a version number, or in some other way doesn't follow our [issue reporting guidelines](https://aka.ms/vscodeissuereporting). Please take the time to review these and update the issue.\n\nHappy Coding!" }, { diff --git a/package.json b/package.json index 838defde1cb..7b9d7fd9bc7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.70.0", - "distro": "25c5a766dec5d762c3205176fec650c6964c7763", + "distro": "81cca34eb9bc1d2c0a7d0124ce64b62c994ca9b7", "author": { "name": "Microsoft Corporation" }, From 25fd5e204e1f165cd1b25e1508b590ffaf3a2a06 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 1 Aug 2022 15:37:55 +0200 Subject: [PATCH 105/303] Fix #156698 (#156799) --- .../common/userDataProfileActions.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts index 62e3de604fe..99090a700f0 100644 --- a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts +++ b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts @@ -42,9 +42,16 @@ class CreateFromCurrentProfileAction extends Action2 { const quickInputService = accessor.get(IQuickInputService); const notificationService = accessor.get(INotificationService); const userDataProfileManagementService = accessor.get(IUserDataProfileManagementService); + const userDataProfilesService = accessor.get(IUserDataProfilesService); const name = await quickInputService.input({ placeHolder: localize('name', "Profile name"), title: localize('save profile as', "Create from Current Settings Profile..."), + validateInput: async (value: string) => { + if (userDataProfilesService.profiles.some(p => p.name === value)) { + return localize('profileExists', "Settings Profile with name {0} already exists.", value); + } + return undefined; + } }); if (name) { try { @@ -77,9 +84,16 @@ class CreateEmptyProfileAction extends Action2 { const quickInputService = accessor.get(IQuickInputService); const userDataProfileManagementService = accessor.get(IUserDataProfileManagementService); const notificationService = accessor.get(INotificationService); + const userDataProfilesService = accessor.get(IUserDataProfilesService); const name = await quickInputService.input({ placeHolder: localize('name', "Profile name"), title: localize('create and enter empty profile', "Create an Empty Profile..."), + validateInput: async (value: string) => { + if (userDataProfilesService.profiles.some(p => p.name === value)) { + return localize('profileExists', "Settings Profile with name {0} already exists.", value); + } + return undefined; + } }); if (name) { try { @@ -175,6 +189,12 @@ registerAction2(class RenameProfileAction extends Action2 { const name = await quickInputService.input({ value: pick.profile.name, title: localize('edit settings profile', "Rename Settings Profile..."), + validateInput: async (value: string) => { + if (pick.profile.name !== value && profiles.some(p => p.name === value)) { + return localize('profileExists', "Settings Profile with name {0} already exists.", value); + } + return undefined; + } }); if (name && name !== pick.profile.name) { try { From ef65649326cff17aae488a4fe953f0f4a6d70260 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 1 Aug 2022 16:29:23 +0200 Subject: [PATCH 106/303] do not report builtin extensions (#156793) --- .../contrib/extensions/browser/extensionsWorkbenchService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 1282bccb531..807d327879c 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -786,7 +786,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension } private _reportTelemetry() { const extensionIds = this.installed.filter(extension => - extension.type === ExtensionType.User && + !extension.isBuiltin && (extension.enablementState === EnablementState.EnabledWorkspace || extension.enablementState === EnablementState.EnabledGlobally)) .map(extension => ExtensionIdentifier.toKey(extension.identifier.id)); From ca1c8c70e3ab4fab498f26bfddd56f729368d690 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 1 Aug 2022 08:37:56 -0700 Subject: [PATCH 107/303] Support default icon/color in folder scope Fixes #156806 --- .../terminal/browser/terminalProfileResolverService.ts | 9 +++++---- .../contrib/terminal/common/terminalConfiguration.ts | 4 +++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts index f920f87442f..a3a05c3ffd8 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts @@ -116,8 +116,8 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro } } - getDefaultIcon(): TerminalIcon & ThemeIcon { - return this._iconRegistry.getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon)) || Codicon.terminal; + getDefaultIcon(resource?: URI): TerminalIcon & ThemeIcon { + return this._iconRegistry.getIcon(this._configurationService.getValue(TerminalSettingId.TabsDefaultIcon, { resource })) || Codicon.terminal; } async resolveShellLaunchConfig(shellLaunchConfig: IShellLaunchConfig, options: IShellLaunchConfigResolveOptions): Promise { @@ -145,9 +145,10 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro // Verify the icon is valid, and fallback correctly to the generic terminal id if there is // an issue + const resource = shellLaunchConfig === undefined || typeof shellLaunchConfig.cwd === 'string' ? undefined : shellLaunchConfig.cwd; shellLaunchConfig.icon = this._getCustomIcon(shellLaunchConfig.icon) || this._getCustomIcon(resolvedProfile.icon) - || this.getDefaultIcon(); + || this.getDefaultIcon(resource); // Override the name if specified if (resolvedProfile.overrideName) { @@ -157,7 +158,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro // Apply the color shellLaunchConfig.color = shellLaunchConfig.color || resolvedProfile.color - || this._configurationService.getValue(TerminalSettingId.TabsDefaultColor); + || this._configurationService.getValue(TerminalSettingId.TabsDefaultColor, { resource }); // Resolve useShellEnvironment based on the setting if it's not set if (shellLaunchConfig.useShellEnvironment === undefined) { diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index c5b6caee4af..4b52e0191f4 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -42,12 +42,14 @@ const terminalConfiguration: IConfigurationNode = { }, [TerminalSettingId.TabsDefaultColor]: { description: localize('terminal.integrated.tabs.defaultColor', "A theme color ID to associate with terminal icons by default."), - ...terminalColorSchema + ...terminalColorSchema, + scope: ConfigurationScope.RESOURCE }, [TerminalSettingId.TabsDefaultIcon]: { description: localize('terminal.integrated.tabs.defaultIcon', "A codicon ID to associate with terminal icons by default."), ...terminalIconSchema, default: Codicon.terminal.id, + scope: ConfigurationScope.RESOURCE }, [TerminalSettingId.TabsEnabled]: { description: localize('terminal.integrated.tabs.enabled', 'Controls whether terminal tabs display as a list to the side of the terminal. When this is disabled a dropdown will display instead.'), From 2f72682e5d0b9e2115b3062f55f47c90f134db7c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 1 Aug 2022 09:29:26 -0700 Subject: [PATCH 108/303] Add canvas renderer addon --- .eslintrc.json | 1 + build/.webignore | 3 + package.json | 1 + remote/package.json | 1 + remote/web/package.json | 1 + remote/web/yarn.lock | 5 ++ remote/yarn.lock | 5 ++ scripts/update-xterm.js | 1 + src/bootstrap-window.js | 3 +- .../terminal/browser/xterm/xtermTerminal.ts | 66 ++++++++++++++++--- yarn.lock | 5 ++ 11 files changed, 83 insertions(+), 9 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index af34ee181a9..d86f6103a7d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -259,6 +259,7 @@ "windows-process-tree", "worker_threads", "xterm", + "xterm-addon-canvas", "xterm-addon-search", "xterm-addon-serialize", "xterm-addon-unicode11", diff --git a/build/.webignore b/build/.webignore index 563dfb0000c..1a5b3ee2c10 100644 --- a/build/.webignore +++ b/build/.webignore @@ -20,6 +20,9 @@ vscode-textmate/webpack.config.js xterm/src/** +xterm-addon-canvas/src/** +xterm-addon-canvas/out/** + xterm-addon-search/src/** xterm-addon-search/out/** xterm-addon-search/fixtures/** diff --git a/package.json b/package.json index 5d91cf0a232..23a4ea7b32b 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "vscode-regexpp": "^3.1.0", "vscode-textmate": "7.0.1", "xterm": "5.0.0-beta.32", + "xterm-addon-canvas": "0.2.0-beta.15", "xterm-addon-search": "0.10.0-beta.3", "xterm-addon-serialize": "0.8.0-beta.3", "xterm-addon-unicode11": "0.4.0-beta.3", diff --git a/remote/package.json b/remote/package.json index b8da1151d24..68e36b12bc9 100644 --- a/remote/package.json +++ b/remote/package.json @@ -25,6 +25,7 @@ "vscode-regexpp": "^3.1.0", "vscode-textmate": "7.0.1", "xterm": "5.0.0-beta.32", + "xterm-addon-canvas": "0.2.0-beta.15", "xterm-addon-search": "0.10.0-beta.3", "xterm-addon-serialize": "0.8.0-beta.3", "xterm-addon-unicode11": "0.4.0-beta.3", diff --git a/remote/web/package.json b/remote/web/package.json index 7a230e76868..17c98d4f00b 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -12,6 +12,7 @@ "vscode-oniguruma": "1.6.1", "vscode-textmate": "7.0.1", "xterm": "5.0.0-beta.32", + "xterm-addon-canvas": "0.2.0-beta.15", "xterm-addon-search": "0.10.0-beta.3", "xterm-addon-unicode11": "0.4.0-beta.3", "xterm-addon-webgl": "0.13.0-beta.32" diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index 87c4c4d35ff..352fc68499b 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -68,6 +68,11 @@ vscode-textmate@7.0.1: resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-7.0.1.tgz#8118a32b02735dccd14f893b495fa5389ad7de79" integrity sha512-zQ5U/nuXAAMsh691FtV0wPz89nSkHbs+IQV8FDk+wew9BlSDhf4UmWGlWJfTR2Ti6xZv87Tj5fENzKf6Qk7aLw== +xterm-addon-canvas@0.2.0-beta.15: + version "0.2.0-beta.15" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.2.0-beta.15.tgz#de863e46410b1de357b153abf1984227777760e4" + integrity sha512-E1pNCDSVTINchwWLysZ9ZD/BPv1WLGV52xRHB00US1PHHELbhtvms+6dZ44WZEDXhtfpptRZ1VBx+QpvfJIuvw== + xterm-addon-search@0.10.0-beta.3: version "0.10.0-beta.3" resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.10.0-beta.3.tgz#5194434d86105637c71f6f20139a9d0b5c1a956a" diff --git a/remote/yarn.lock b/remote/yarn.lock index c729673b610..5e5938f14a9 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -788,6 +788,11 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +xterm-addon-canvas@0.2.0-beta.15: + version "0.2.0-beta.15" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.2.0-beta.15.tgz#de863e46410b1de357b153abf1984227777760e4" + integrity sha512-E1pNCDSVTINchwWLysZ9ZD/BPv1WLGV52xRHB00US1PHHELbhtvms+6dZ44WZEDXhtfpptRZ1VBx+QpvfJIuvw== + xterm-addon-search@0.10.0-beta.3: version "0.10.0-beta.3" resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.10.0-beta.3.tgz#5194434d86105637c71f6f20139a9d0b5c1a956a" diff --git a/scripts/update-xterm.js b/scripts/update-xterm.js index 70637a8493c..ac11b9e3217 100644 --- a/scripts/update-xterm.js +++ b/scripts/update-xterm.js @@ -8,6 +8,7 @@ const path = require('path'); const moduleNames = [ 'xterm', + 'xterm-addon-canvas', 'xterm-addon-search', 'xterm-addon-unicode11', 'xterm-addon-webgl' diff --git a/src/bootstrap-window.js b/src/bootstrap-window.js index 79381017f50..61ca6dd8477 100644 --- a/src/bootstrap-window.js +++ b/src/bootstrap-window.js @@ -136,6 +136,7 @@ 'vscode-textmate': `${baseNodeModulesPath}/vscode-textmate/release/main.js`, 'vscode-oniguruma': `${baseNodeModulesPath}/vscode-oniguruma/release/main.js`, 'xterm': `${baseNodeModulesPath}/xterm/lib/xterm.js`, + 'xterm-addon-canvas': `${baseNodeModulesPath}/xterm-addon-canvas/lib/xterm-addon-canvas.js`, 'xterm-addon-search': `${baseNodeModulesPath}/xterm-addon-search/lib/xterm-addon-search.js`, 'xterm-addon-unicode11': `${baseNodeModulesPath}/xterm-addon-unicode11/lib/xterm-addon-unicode11.js`, 'xterm-addon-webgl': `${baseNodeModulesPath}/xterm-addon-webgl/lib/xterm-addon-webgl.js`, @@ -150,7 +151,7 @@ // which has a fallback to using node.js `require` // (node.js enabled renderers only) if (!safeProcess.sandboxed) { - loaderConfig.amdModulesPattern = /(^vs\/)|(^vscode-textmate$)|(^vscode-oniguruma$)|(^xterm$)|(^xterm-addon-search$)|(^xterm-addon-unicode11$)|(^xterm-addon-webgl$)|(^@vscode\/iconv-lite-umd$)|(^jschardet$)|(^@vscode\/vscode-languagedetection$)|(^vscode-regexp-languagedetection$)|(^tas-client-umd$)/; + loaderConfig.amdModulesPattern = /(^vs\/)|(^vscode-textmate$)|(^vscode-oniguruma$)|(^xterm$)|(^xterm-addon-canvas$)|(^xterm-addon-search$)|(^xterm-addon-unicode11$)|(^xterm-addon-webgl$)|(^@vscode\/iconv-lite-umd$)|(^jschardet$)|(^@vscode\/vscode-languagedetection$)|(^vscode-regexp-languagedetection$)|(^tas-client-umd$)/; } // Signal before require.config() diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index 3c60805a553..f4cc3403c1a 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -4,10 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import type { IBuffer, IMarker, ITheme, Terminal as RawXtermTerminal } from 'xterm'; +import type { CanvasAddon as CanvasAddonType } from 'xterm-addon-canvas'; import type { ISearchOptions, SearchAddon as SearchAddonType } from 'xterm-addon-search'; import type { Unicode11Addon as Unicode11AddonType } from 'xterm-addon-unicode11'; import type { WebglAddon as WebglAddonType } from 'xterm-addon-webgl'; -import { SerializeAddon as SerializeAddonType } from 'xterm-addon-serialize'; +import type { SerializeAddon as SerializeAddonType } from 'xterm-addon-serialize'; import { IXtermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; @@ -42,10 +43,11 @@ import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProc const SLOW_CANVAS_RENDER_THRESHOLD = 50; const NUMBER_OF_FRAMES_TO_MEASURE = 20; +let CanvasAddon: typeof CanvasAddonType; let SearchAddon: typeof SearchAddonType; +let SerializeAddon: typeof SerializeAddonType; let Unicode11Addon: typeof Unicode11AddonType; let WebglAddon: typeof WebglAddonType; -let SerializeAddon: typeof SerializeAddonType; /** * Wraps the xterm object with additional functionality. Interaction with the backing process is out @@ -65,6 +67,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II private _decorationAddon: DecorationAddon; // Optional addons + private _canvasAddon?: CanvasAddonType; private _searchAddon?: SearchAddonType; private _unicode11Addon?: Unicode11AddonType; private _webglAddon?: WebglAddonType; @@ -140,7 +143,6 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II fastScrollModifier: 'alt', fastScrollSensitivity: config.fastScrollSensitivity, scrollSensitivity: config.mouseWheelScrollSensitivity, - // rendererType: this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType), wordSeparator: config.wordSeparators, overviewRulerWidth: 10 })); @@ -214,6 +216,9 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II this._container = container; if (this._shouldLoadWebgl()) { this._enableWebglRenderer(); + } else if (this._shouldLoadCanvas()) { + this._enableCanvasRenderer(); + // rendererType: this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType), } // Screen must be created at this point as xterm.open is called return this._container.querySelector('.xterm-screen')!; @@ -241,8 +246,11 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II this._enableWebglRenderer(); } else { this._disposeOfWebglRenderer(); - // TODO: Fix renderer - // this.raw.options.rendererType = this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType); + if (this._shouldLoadCanvas()) { + this._enableCanvasRenderer(); + } else { + this._disposeOfCanvasRenderer(); + } } } @@ -250,6 +258,10 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II return !isSafari && (this._configHelper.config.gpuAcceleration === 'auto' && XtermTerminal._suggestedRendererType === undefined) || this._configHelper.config.gpuAcceleration === 'on'; } + private _shouldLoadCanvas(): boolean { + return (this._configHelper.config.gpuAcceleration === 'auto' && (XtermTerminal._suggestedRendererType === undefined || XtermTerminal._suggestedRendererType === 'canvas')) || this._configHelper.config.gpuAcceleration === 'canvas'; + } + forceRedraw() { this._webglAddon?.clearTextureAtlas(); this.raw.clearTextureAtlas(); @@ -436,6 +448,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II } const Addon = await this._getWebglAddonConstructor(); this._webglAddon = new Addon(); + this._disposeOfCanvasRenderer(); try { this.raw.loadAddon(this._webglAddon); this._logService.trace('Webgl was loaded'); @@ -458,13 +471,41 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II if (!neverMeasureRenderTime && this._configHelper.config.gpuAcceleration !== 'off') { this._measureRenderTime(); } - // TODO: Fix renderer - // this.raw.options.rendererType = 'canvas'; - // XtermTerminal._suggestedRendererType = 'canvas'; + XtermTerminal._suggestedRendererType = 'canvas'; this._disposeOfWebglRenderer(); + this._enableCanvasRenderer(); } } + private async _enableCanvasRenderer(): Promise { + if (!this.raw.element || this._canvasAddon) { + return; + } + const Addon = await this._getCanvasAddonConstructor(); + this._canvasAddon = new Addon(); + this._disposeOfWebglRenderer(); + try { + this.raw.loadAddon(this._canvasAddon); + this._logService.trace('Canvas was loaded'); + } catch (e) { + this._logService.warn(`Canvas could not be loaded. Falling back to the dom renderer type.`, e); + const neverMeasureRenderTime = this._storageService.getBoolean(TerminalStorageKeys.NeverMeasureRenderTime, StorageScope.APPLICATION, false); + // if it's already set to dom, no need to measure render time + if (!neverMeasureRenderTime && this._configHelper.config.gpuAcceleration !== 'off') { + this._measureRenderTime(); + } + XtermTerminal._suggestedRendererType = 'dom'; + this._disposeOfCanvasRenderer(); + } + } + + protected async _getCanvasAddonConstructor(): Promise { + if (!CanvasAddon) { + CanvasAddon = (await import('xterm-addon-canvas')).CanvasAddon; + } + return CanvasAddon; + } + protected async _getSearchAddonConstructor(): Promise { if (!SearchAddon) { SearchAddon = (await import('xterm-addon-search')).SearchAddon; @@ -493,6 +534,15 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II return SerializeAddon; } + private _disposeOfCanvasRenderer(): void { + try { + this._canvasAddon?.dispose(); + } catch { + // ignore + } + this._canvasAddon = undefined; + } + private _disposeOfWebglRenderer(): void { try { this._webglAddon?.dispose(); diff --git a/yarn.lock b/yarn.lock index c3f1dcc3ba1..11b0d85665c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12072,6 +12072,11 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" +xterm-addon-canvas@0.2.0-beta.15: + version "0.2.0-beta.15" + resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.2.0-beta.15.tgz#de863e46410b1de357b153abf1984227777760e4" + integrity sha512-E1pNCDSVTINchwWLysZ9ZD/BPv1WLGV52xRHB00US1PHHELbhtvms+6dZ44WZEDXhtfpptRZ1VBx+QpvfJIuvw== + xterm-addon-search@0.10.0-beta.3: version "0.10.0-beta.3" resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.10.0-beta.3.tgz#5194434d86105637c71f6f20139a9d0b5c1a956a" From 21504708043941c1e9e45b7d0892a9a8a03470d7 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Mon, 1 Aug 2022 21:13:31 +0430 Subject: [PATCH 109/303] =?UTF-8?q?=F0=9F=8E=81=20Add=20option=20to=20disa?= =?UTF-8?q?ble=20script=20hovers=20in=20`package.json`=20files=20(#156752)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ⚙️ Define `npm.scriptHover` configuration parameter Signed-off-by: Babak K. Shandiz * 🌐 Add localized description for `npm.scriptHover` config parameter Signed-off-by: Babak K. Shandiz * 🎁 Respect `npm.scriptHover` config parameter in `NpmScriptHoverProvider` Signed-off-by: Babak K. Shandiz --- extensions/npm/package.json | 6 ++++++ extensions/npm/package.nls.json | 1 + extensions/npm/src/scriptHover.ts | 13 +++++++++++++ 3 files changed, 20 insertions(+) diff --git a/extensions/npm/package.json b/extensions/npm/package.json index 6df1a4835e7..0a0cd05411f 100644 --- a/extensions/npm/package.json +++ b/extensions/npm/package.json @@ -298,6 +298,12 @@ "tags": [ "usesOnlineServices" ] + }, + "npm.scriptHover": { + "type": "boolean", + "description": "%config.npm.scriptHover%", + "default": true, + "scope": "window" } } }, diff --git a/extensions/npm/package.nls.json b/extensions/npm/package.nls.json index b0a4f06c01f..44f1d00f0f4 100644 --- a/extensions/npm/package.nls.json +++ b/extensions/npm/package.nls.json @@ -15,6 +15,7 @@ "config.npm.scriptExplorerExclude": "An array of regular expressions that indicate which scripts should be excluded from the NPM Scripts view.", "config.npm.enableRunFromFolder": "Enable running npm scripts contained in a folder from the Explorer context menu.", "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.scriptHover": "Display hover with 'Run' and 'Debug' commands for scripts.", "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/npm/src/scriptHover.ts b/extensions/npm/src/scriptHover.ts index b8924bb25df..c96f3330d39 100644 --- a/extensions/npm/src/scriptHover.ts +++ b/extensions/npm/src/scriptHover.ts @@ -33,6 +33,7 @@ export function invalidateHoverScriptsCache(document?: TextDocument) { } export class NpmScriptHoverProvider implements HoverProvider { + private enabled: boolean; constructor(private context: ExtensionContext) { context.subscriptions.push(commands.registerCommand('npm.runScriptFromHover', this.runScriptFromHover, this)); @@ -40,9 +41,21 @@ export class NpmScriptHoverProvider implements HoverProvider { context.subscriptions.push(workspace.onDidChangeTextDocument((e) => { invalidateHoverScriptsCache(e.document); })); + + const isEnabled = () => workspace.getConfiguration('npm').get('scriptHover', true); + this.enabled = isEnabled(); + context.subscriptions.push(workspace.onDidChangeConfiguration((e) => { + if (e.affectsConfiguration('npm.scriptHover')) { + this.enabled = isEnabled(); + } + })); } public provideHover(document: TextDocument, position: Position, _token: CancellationToken): ProviderResult { + if (!this.enabled) { + return; + } + let hover: Hover | undefined = undefined; if (!cachedDocument || cachedDocument.fsPath !== document.uri.fsPath) { From d5de9523edb09c7e1ba090e8d5bae50b13cb6188 Mon Sep 17 00:00:00 2001 From: Svante Boberg Date: Mon, 1 Aug 2022 19:04:45 +0200 Subject: [PATCH 110/303] Cleanup disposed terminals (#156326) Terminals spawned in extensions are added to a map, but no cleanup was being done. This causes memory leaks when js cannot garbage collect the disposed terminals. --- src/vs/workbench/api/browser/mainThreadTerminalService.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 23802f649dc..ff0365ecff8 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -151,7 +151,10 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape r(terminal); }); this._extHostTerminals.set(extHostTerminalId, terminal); - await terminal; + const terminalInstance = await terminal; + this._toDispose.add(terminalInstance.onDisposed(() => { + this._extHostTerminals.delete(extHostTerminalId); + })); } private async _deserializeParentTerminal(location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminalIdentifier } | { splitActiveTerminal: boolean; location?: TerminalLocation }): Promise { From b511de5fa31fd47653d9b5dcf1ba654365625d88 Mon Sep 17 00:00:00 2001 From: Semesse Date: Tue, 2 Aug 2022 01:32:03 +0800 Subject: [PATCH 111/303] Skip collapsed state check for nested children when dropping files in explorer (#156759) fixes #156746 --- .../contrib/files/browser/views/explorerViewer.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 33dd4174024..5e61f1b4aff 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -1176,20 +1176,22 @@ export class FileDragAndDrop implements ITreeDragAndDrop { private async handleExplorerDrop(data: ElementsDragAndDropData, target: ExplorerItem, originalEvent: DragEvent): Promise { const elementsData = FileDragAndDrop.getStatsFromDragAndDropData(data); - const distinctItems = new Set(elementsData); + const distinctItems = new Map(elementsData.map(element => [element, this.isCollapsed(element)])); - for (const item of distinctItems) { - if (this.isCollapsed(item)) { + for (const [item, collapsed] of distinctItems) { + if (collapsed) { const nestedChildren = item.nestedChildren; if (nestedChildren) { for (const child of nestedChildren) { - distinctItems.add(child); + // if parent is collapsed, then the nested children is considered collapsed to operate as a group + // and skip collapsed state check since they're not in the tree + distinctItems.set(child, true); } } } } - const items = distinctParents([...distinctItems], s => s.resource); + const items = distinctParents([...distinctItems.keys()], s => s.resource); const isCopy = (originalEvent.ctrlKey && !isMacintosh) || (originalEvent.altKey && isMacintosh); // Handle confirm setting From 4eef7a94e1239f92cc5530e60d27aa53fe8266a9 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 1 Aug 2022 10:44:33 -0700 Subject: [PATCH 112/303] Tell users about enabled TS plugins on crash (#156514) We've been seeing a fair number of reported issues about TS Server crashes that are caused by plugins contributed by extension. This change adds info to the error message about enabled global plugins so users can try disabling them Other changes: - Use `JS/TS` instead of Typescript since the server is used for javascript too (a common source of confusion) - Fix some missing checks to `_isPromptingAfterCrash` and some extra guards that were causing some crashes to now show this message - Use `crashed` instead of `died unexpectedly` --- .../src/typescriptServiceClient.ts | 28 +++++++++++++------ .../src/utils/plugins.ts | 2 ++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index 0c740259823..db540f2e887 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -584,6 +584,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType this.numberRestarts++; let startService = true; + const pluginExtensionList = this.pluginManager.plugins.map(plugin => plugin.extension.id).join(', '); const reportIssueItem: vscode.MessageItem = { title: localize('serverDiedReportIssue', 'Report Issue'), }; @@ -596,7 +597,9 @@ export default class TypeScriptServiceClient extends Disposable implements IType startService = false; this.hasServerFatallyCrashedTooManyTimes = true; prompt = vscode.window.showErrorMessage( - localize('serverDiedAfterStart', 'The TypeScript language service died 5 times right after it got started. The service will not be restarted.'), + this.pluginManager.plugins.length + ? localize('serverDiedImmediatelyWithPlugins', "The JS/TS language service immediately crashed 5 times. The service will not be restarted.\nThis may be caused by a plugin contributed by one of these extensions: {0}", pluginExtensionList) + : localize('serverDiedImmediately', "The JS/TS language service immediately crashed 5 times. The service will not be restarted."), reportIssueItem); /* __GDPR__ @@ -610,21 +613,30 @@ export default class TypeScriptServiceClient extends Disposable implements IType this.logTelemetry('serviceExited'); } else if (diff < 60 * 1000 * 5 /* 5 Minutes */) { this.lastStart = Date.now(); - prompt = vscode.window.showWarningMessage( - localize('serverDied', 'The TypeScript language service died unexpectedly 5 times in the last 5 Minutes.'), - reportIssueItem); + if (!this._isPromptingAfterCrash) { + prompt = vscode.window.showWarningMessage( + this.pluginManager.plugins.length + ? localize('serverDiedFiveTimesWithPlugins', "The JS/TS language service crashed 5 times in the last 5 Minutes.\nThis may be caused by a plugin contributed by one of these extensions: {0}", pluginExtensionList) + : localize('serverDiedFiveTimes', "The JS/TS language service crashed 5 times in the last 5 Minutes."), + reportIssueItem); + } } } else if (['vscode-insiders', 'code-oss'].includes(vscode.env.uriScheme)) { // Prompt after a single restart - if (!this._isPromptingAfterCrash && previousState.type === ServerState.Type.Errored && previousState.error instanceof TypeScriptServerError) { - this.numberRestarts = 0; - this._isPromptingAfterCrash = true; + this.numberRestarts = 0; + if (!this._isPromptingAfterCrash) { prompt = vscode.window.showWarningMessage( - localize('serverDiedOnce', 'The TypeScript language service died unexpectedly.'), + this.pluginManager.plugins.length + ? localize('serverDiedOnceWithPlugins', "The JS/TS language service crashed.\nThis may be caused by a plugin contributed by one of these extensions: {0}", pluginExtensionList) + : localize('serverDiedOnce', "The JS/TS language service crashed."), reportIssueItem); } } + if (prompt) { + this._isPromptingAfterCrash = true; + } + prompt?.then(item => { this._isPromptingAfterCrash = false; diff --git a/extensions/typescript-language-features/src/utils/plugins.ts b/extensions/typescript-language-features/src/utils/plugins.ts index 92d61e3e235..697e5422445 100644 --- a/extensions/typescript-language-features/src/utils/plugins.ts +++ b/extensions/typescript-language-features/src/utils/plugins.ts @@ -8,6 +8,7 @@ import * as arrays from './arrays'; import { Disposable } from './dispose'; export interface TypeScriptServerPlugin { + readonly extension: vscode.Extension; readonly uri: vscode.Uri; readonly name: string; readonly enableForWorkspaceTypeScriptVersions: boolean; @@ -74,6 +75,7 @@ export class PluginManager extends Disposable { const plugins: TypeScriptServerPlugin[] = []; for (const plugin of pack.contributes.typescriptServerPlugins) { plugins.push({ + extension, name: plugin.name, enableForWorkspaceTypeScriptVersions: !!plugin.enableForWorkspaceTypeScriptVersions, uri: extension.extensionUri, From 97c8a97261377a11dc5d6b547e275f4cb4e9399a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 1 Aug 2022 10:44:46 -0700 Subject: [PATCH 113/303] Include globally enabled TS Server plugins when reporting issues (#156510) We're seeing a lot of crashes caused by TS Server plugins (usually those that come from extension). This will be easier to track down if we also include the enabled plugins when reporting issues --- .../src/typescriptServiceClient.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index db540f2e887..a42f5c29f06 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -25,7 +25,7 @@ import * as fileSchemes from './utils/fileSchemes'; import { Logger } from './utils/logger'; import { isWeb } from './utils/platform'; import { TypeScriptPluginPathsProvider } from './utils/pluginPathsProvider'; -import { PluginManager } from './utils/plugins'; +import { PluginManager, TypeScriptServerPlugin } from './utils/plugins'; import { TelemetryProperties, TelemetryReporter, VSCodeTelemetryReporter } from './utils/telemetry'; import Tracer from './utils/tracer'; import { inferredProjectCompilerOptions, ProjectType } from './utils/tsconfig'; @@ -656,7 +656,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType }); } else { const args = previousState.type === ServerState.Type.Errored && previousState.error instanceof TypeScriptServerError - ? getReportIssueArgsForError(previousState.error, previousState.tsServerLogFile) + ? getReportIssueArgsForError(previousState.error, previousState.tsServerLogFile, this.pluginManager.plugins) : undefined; vscode.commands.executeCommand('workbench.action.openIssueReporter', args); } @@ -1014,6 +1014,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType function getReportIssueArgsForError( error: TypeScriptServerError, logPath: string | undefined, + globalPlugins: readonly TypeScriptServerPlugin[], ): { extensionId: string; issueTitle: string; issueBody: string } | undefined { if (!error.serverStack || !error.serverMessage) { return undefined; @@ -1032,6 +1033,10 @@ function getReportIssueArgsForError( 3.`, ]; + if (globalPlugins.length) { + sections.push(`**Global TS Server Plugins**\n\n` + globalPlugins.map(plugin => `- \`${plugin.name}\``).join('\n')); + } + if (logPath) { sections.push(`**TS Server Log** @@ -1045,7 +1050,7 @@ The log file may contain personal data, including full paths and source code fro sections.push(`**TS Server Log** -❗️Server logging disabled. To help us fix crashes like this, please enable logging by setting: +❗️ Server logging disabled. To help us fix crashes like this, please enable logging by setting: \`\`\`json "typescript.tsserver.log": "verbose" From cf4922392cb2d657b3be7542626d1f5d54cce286 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 1 Aug 2022 11:25:38 -0700 Subject: [PATCH 114/303] Use flat and coalesce (#156817) --- .../contrib/gotoSymbol/browser/goToSymbol.ts | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/contrib/gotoSymbol/browser/goToSymbol.ts b/src/vs/editor/contrib/gotoSymbol/browser/goToSymbol.ts index 03d2b232bd8..02cc3acebab 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/goToSymbol.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/goToSymbol.ts @@ -3,17 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { coalesce } from 'vs/base/common/arrays'; import { CancellationToken } from 'vs/base/common/cancellation'; import { onUnexpectedExternalError } from 'vs/base/common/errors'; import { registerModelAndPositionCommand } from 'vs/editor/browser/editorExtensions'; import { Position } from 'vs/editor/common/core/position'; -import { ITextModel } from 'vs/editor/common/model'; -import { DeclarationProvider, DefinitionProvider, ImplementationProvider, LocationLink, ProviderResult, ReferenceProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; -import { ReferencesModel } from 'vs/editor/contrib/gotoSymbol/browser/referencesModel'; +import { DeclarationProvider, DefinitionProvider, ImplementationProvider, LocationLink, ProviderResult, ReferenceProvider, TypeDefinitionProvider } from 'vs/editor/common/languages'; +import { ITextModel } from 'vs/editor/common/model'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; +import { ReferencesModel } from 'vs/editor/contrib/gotoSymbol/browser/referencesModel'; -function getLocationLinks( +async function getLocationLinks( model: ITextModel, position: Position, registry: LanguageFeatureRegistry, @@ -29,17 +30,8 @@ function getLocationLinks( }); }); - return Promise.all(promises).then(values => { - const result: LocationLink[] = []; - for (const value of values) { - if (Array.isArray(value)) { - result.push(...value); - } else if (value) { - result.push(value); - } - } - return result; - }); + const values = await Promise.all(promises); + return coalesce(values.flat()); } export function getDefinitionsAtPosition(registry: LanguageFeatureRegistry, model: ITextModel, position: Position, token: CancellationToken): Promise { From f4433141c78a6310e4ba95758b64aab1ad6c0e3b Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 1 Aug 2022 12:09:41 -0700 Subject: [PATCH 115/303] Move off asPromise (#155920) * Troubleshoot asPromise * Update batch edit api * Update workspace edit * fix #156663 * :lipstick: --- .../src/singlefolder-tests/notebook.test.ts | 100 +++++++----------- extensions/vscode-api-tests/src/utils.ts | 3 +- 2 files changed, 40 insertions(+), 63 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts index 5ffcebf945c..5b77eab65bf 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts @@ -258,25 +258,23 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { // }); }); - test.skip('edit API batch edits', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/155808 + test('edit API batch edits', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/155808 const notebook = await openRandomNotebookDocument(); const editor = await vscode.window.showNotebookDocument(notebook); - const notebookChangeEvent = asPromise(vscode.workspace.onDidChangeNotebookDocument); const version = editor.notebook.version; const edit = new vscode.WorkspaceEdit(); const cellEdit = vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(1, 0), [{ kind: vscode.NotebookCellKind.Code, languageId: 'javascript', value: 'test 2', outputs: [], metadata: undefined }]); const metdataEdit = vscode.NotebookEdit.updateNotebookMetadata({ ...notebook.metadata, custom: { ...(notebook.metadata.custom || {}), extraNotebookMetadata: true } }); edit.set(notebook.uri, [cellEdit, metdataEdit]); - await vscode.workspace.applyEdit(edit); - await notebookChangeEvent; + let success = await vscode.workspace.applyEdit(edit); + assert.equal(success, true); - const notebookChangeEvent2 = asPromise(vscode.workspace.onDidChangeNotebookDocument); const edit2 = new vscode.WorkspaceEdit(); const cellMetadataEdit = vscode.NotebookEdit.updateCellMetadata(0, { extraCellMetadata: true }); edit2.set(notebook.uri, [cellMetadataEdit]); - await vscode.workspace.applyEdit(edit2); - await notebookChangeEvent2; + success = await vscode.workspace.applyEdit(edit2); + assert.equal(success, true); assert.strictEqual(version + 2, editor.notebook.version); const cell = editor.notebook.cellAt(0); @@ -284,18 +282,18 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { assert.ok(cell.metadata.extraCellMetadata, `Test cell metdata not found`); }); - test.skip('edit API batch edits undo/redo', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/155825 + test('edit API batch edits undo/redo', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/155825 const notebook = await openRandomNotebookDocument(); const editor = await vscode.window.showNotebookDocument(notebook); - const notebookChangeEvent = asPromise(vscode.workspace.onDidChangeNotebookDocument); const version = editor.notebook.version; - await editor.edit(editBuilder => { - editBuilder.replaceCells(1, 0, [{ kind: vscode.NotebookCellKind.Code, languageId: 'javascript', value: 'test 2', outputs: [], metadata: undefined }]); - editBuilder.replaceCellMetadata(0, { inputCollapsed: false }); - }); + const edit = new vscode.WorkspaceEdit(); + const cellEdit = vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(1, 1), [{ kind: vscode.NotebookCellKind.Code, languageId: 'javascript', value: 'test 2', outputs: [], metadata: undefined }]); + const metadataEdit = vscode.NotebookEdit.updateCellMetadata(0, { inputCollapsed: false }); + edit.set(notebook.uri, [cellEdit, metadataEdit]); + const success = await vscode.workspace.applyEdit(edit); + assert.equal(success, true); - await notebookChangeEvent; assert.strictEqual(editor.notebook.cellCount, 3); assert.strictEqual(editor.notebook.cellAt(0)?.metadata.inputCollapsed, false); assert.strictEqual(version + 1, editor.notebook.version); @@ -448,8 +446,8 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { // TODO@rebornix this is wrong, `await vscode.commands.executeCommand('notebook.execute');` doesn't wait until the workspace edit is applied test.skip('cell execute command takes arguments', async () => { - const resource = await createRandomNotebookFile(); - await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest'); + const notebook = await openRandomNotebookDocument(); + await vscode.window.showNotebookDocument(notebook); assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first'); const editor = vscode.window.activeNotebookEditor!; const cell = editor.notebook.cellAt(0); @@ -459,8 +457,8 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { }); test('cell execute command takes arguments 2', async () => { - const resource = await createRandomNotebookFile(); - await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest'); + const notebook = await openRandomNotebookDocument(); + await vscode.window.showNotebookDocument(notebook); assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first'); const editor = vscode.window.activeNotebookEditor!; const cell = editor.notebook.cellAt(0); @@ -481,7 +479,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { await vscode.commands.executeCommand('vscode.openWith', secondResource, 'notebookCoreTest'); await withEvent(vscode.workspace.onDidChangeNotebookDocument, async (event) => { - await vscode.commands.executeCommand('notebook.cell.execute', { start: 0, end: 1 }, resource); + await vscode.commands.executeCommand('notebook.cell.execute', { start: 0, end: 1 }, notebook.uri); await event; assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked assert.strictEqual(vscode.window.activeNotebookEditor?.notebook.uri.fsPath, secondResource.fsPath); @@ -490,8 +488,8 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { // #126371 test.skip('cell execute command takes arguments ICellRange[]', async () => { - const resource = await createRandomNotebookFile(); - await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest'); + const notebook = await openRandomNotebookDocument(); + await vscode.window.showNotebookDocument(notebook); vscode.commands.executeCommand('notebook.cell.execute', { ranges: [{ start: 0, end: 1 }, { start: 1, end: 2 }] }); let firstCellExecuted = false; @@ -520,32 +518,17 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { }); test('document execute command takes arguments', async () => { - const resource = await createRandomNotebookFile(); - await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest'); + const notebook = await openRandomNotebookDocument(); + await vscode.window.showNotebookDocument(notebook); assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first'); const editor = vscode.window.activeNotebookEditor!; const cell = editor.notebook.cellAt(0); await withEvent(vscode.workspace.onDidChangeNotebookDocument, async (event) => { - await vscode.commands.executeCommand('notebook.execute'); + await vscode.commands.executeCommand('notebook.execute', notebook.uri); await event; assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked }); - - const clearChangeEvent = asPromise(vscode.workspace.onDidChangeNotebookDocument); - await vscode.commands.executeCommand('notebook.cell.clearOutputs'); - await clearChangeEvent; - assert.strictEqual(cell.outputs.length, 0, 'should clear'); - - const secondResource = await createRandomNotebookFile(); - await vscode.commands.executeCommand('vscode.openWith', secondResource, 'notebookCoreTest'); - - await withEvent(vscode.workspace.onDidChangeNotebookDocument, async (event) => { - await vscode.commands.executeCommand('notebook.execute', resource); - await event; - assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked - assert.strictEqual(vscode.window.activeNotebookEditor?.notebook.uri.fsPath, secondResource.fsPath); - }); }); test('cell execute and select kernel', async function () { @@ -594,9 +577,8 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { }); test.skip('onDidChangeCellExecutionState is fired', async () => { // TODO@rebornix https://github.com/microsoft/vscode/issues/139350 - const resource = await createRandomNotebookFile(); - await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest'); - const editor = vscode.window.activeNotebookEditor!; + const notebook = await openRandomNotebookDocument(); + const editor = await vscode.window.showNotebookDocument(notebook); const cell = editor.notebook.cellAt(0); vscode.commands.executeCommand('notebook.cell.execute'); @@ -796,8 +778,8 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { }); test('#102423 - copy/paste shares the same text buffer', async function () { - const resource = await createRandomNotebookFile(); - await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest'); + const notebook = await openRandomNotebookDocument(); + await vscode.window.showNotebookDocument(notebook); let activeCell = getFocusedCell(vscode.window.activeNotebookEditor); assert.strictEqual(activeCell?.document.getText(), 'test'); @@ -821,22 +803,17 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { test('#115855 onDidSaveNotebookDocument', async function () { const resource = await createRandomNotebookFile(); const notebook = await vscode.workspace.openNotebookDocument(resource); - const editor = await vscode.window.showNotebookDocument(notebook); - const cellsChangeEvent = asPromise(vscode.workspace.onDidChangeNotebookDocument); - await editor.edit(editBuilder => { - editBuilder.replaceCells(1, 0, [{ kind: vscode.NotebookCellKind.Code, languageId: 'javascript', value: 'test 2', outputs: [], metadata: undefined }]); - }); - - const cellChangeEventRet = await cellsChangeEvent; - assert.strictEqual(cellChangeEventRet.notebook === notebook, true); - assert.strictEqual(cellChangeEventRet.notebook.isDirty, true); + const notebookEdit = new vscode.NotebookEdit(new vscode.NotebookRange(1, 1), [new vscode.NotebookCellData(vscode.NotebookCellKind.Code, 'test 2', 'javascript')]); + const edit = new vscode.WorkspaceEdit(); + edit.set(notebook.uri, [notebookEdit]); + await vscode.workspace.applyEdit(edit); + assert.strictEqual(notebook.isDirty, true); const saveEvent = asPromise(vscode.workspace.onDidSaveNotebookDocument); - await notebook.save(); - await saveEvent; + assert.strictEqual(notebook.isDirty, false); }); @@ -873,9 +850,8 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { }); test('executionSummary', async () => { - const resource = await createRandomNotebookFile(); - await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest'); - const editor = vscode.window.activeNotebookEditor!; + const notebook = await openRandomNotebookDocument(); + const editor = await vscode.window.showNotebookDocument(notebook); const cell = editor.notebook.cellAt(0); assert.strictEqual(cell.executionSummary?.success, undefined); @@ -1028,14 +1004,14 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { suiteDisposables.push(vscode.workspace.registerNotebookContentProvider('notebookCoreTest', apiTestContentProvider)); }); - test.skip('provideCellStatusBarItems called on metadata change', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/139324 + test.skip('provideCellStatusBarItems called on metadata change', async function () { // TODO@roblourens https://github.com/microsoft/vscode/issues/139324 const provideCalled = asPromise(onDidCallProvide); - const resource = await createRandomNotebookFile(); - await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest'); + const notebook = await openRandomNotebookDocument(); + await vscode.window.showNotebookDocument(notebook); await provideCalled; const edit = new vscode.WorkspaceEdit(); - edit.replaceNotebookCellMetadata(resource, 0, { inputCollapsed: true }); + edit.replaceNotebookCellMetadata(notebook.uri, 0, { inputCollapsed: true }); vscode.workspace.applyEdit(edit); await provideCalled; }); diff --git a/extensions/vscode-api-tests/src/utils.ts b/extensions/vscode-api-tests/src/utils.ts index c5a8e58483f..cd2a653bee8 100644 --- a/extensions/vscode-api-tests/src/utils.ts +++ b/extensions/vscode-api-tests/src/utils.ts @@ -125,11 +125,12 @@ export function assertNoRpcFromEntry(entry: [obj: any, name: string]) { } export async function asPromise(event: vscode.Event, timeout = vscode.env.uiKind === vscode.UIKind.Desktop ? 5000 : 15000): Promise { + const error = new Error('asPromise TIMEOUT reached'); return new Promise((resolve, reject) => { const handle = setTimeout(() => { sub.dispose(); - reject(new Error('asPromise TIMEOUT reached')); + reject(error); }, timeout); const sub = event(e => { From d32b92bd7a49ce8667b954d86320cc29545fc505 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 1 Aug 2022 16:05:57 -0400 Subject: [PATCH 116/303] Make comment and owner required by default (#156822) --- src/vs/base/common/actions.ts | 1 + .../standalone/browser/standaloneServices.ts | 6 +- .../platform/telemetry/common/gdprTypings.ts | 19 +++--- .../common/serverTelemetryService.ts | 6 +- src/vs/platform/telemetry/common/telemetry.ts | 6 +- .../telemetry/common/telemetryService.ts | 6 +- .../telemetry/common/telemetryUtils.ts | 6 +- .../test/browser/telemetryService.test.ts | 4 +- .../platform/windows/electron-main/window.ts | 2 +- .../api/browser/mainThreadTelemetry.ts | 4 +- .../workbench/api/common/extHost.protocol.ts | 4 +- .../browser/parts/editor/editorStatus.ts | 8 ++- .../browser/extensionsWorkbenchService.ts | 5 +- .../format/browser/formatActionsMultiple.ts | 2 +- .../preferences/browser/settingsEditor2.ts | 2 + .../textsearch.perf.integrationTest.ts | 6 +- .../browser/searchEditorActions.ts | 4 +- .../searchEditor/browser/searchEditorInput.ts | 2 +- .../browser/telemetry.contribution.ts | 3 +- .../browser/gettingStartedService.ts | 2 + .../electron-sandbox/accessibilityService.ts | 3 +- .../extensions/browser/extensionUrlHandler.ts | 5 +- .../services/search/common/searchService.ts | 61 ++++++++++--------- .../telemetry/browser/telemetryService.ts | 6 +- .../electron-sandbox/telemetryService.ts | 6 +- .../services/timer/browser/timerService.ts | 2 +- 26 files changed, 95 insertions(+), 86 deletions(-) diff --git a/src/vs/base/common/actions.ts b/src/vs/base/common/actions.ts index cfaa9389600..4043cf741a6 100644 --- a/src/vs/base/common/actions.ts +++ b/src/vs/base/common/actions.ts @@ -15,6 +15,7 @@ export interface ITelemetryData { export type WorkbenchActionExecutedClassification = { owner: 'bpasero'; + comment: 'TODO @bpasero'; id: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The identifier of the action that was run.' }; from: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The name of the component the action was run from.' }; }; diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index be6633e6582..44c106cb931 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -46,7 +46,7 @@ import { ITelemetryInfo, ITelemetryService, TelemetryLevel } from 'vs/platform/t import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier, IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, IWorkspaceFoldersWillChangeEvent, WorkbenchState, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { StandaloneServicesNLS } from 'vs/editor/common/standaloneStrings'; -import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; +import { ClassifiedEvent, StrictPropertyCheck, OmitMetadata, IGDPRProperty } from 'vs/platform/telemetry/common/gdprTypings'; import { basename } from 'vs/base/common/resources'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { ConsoleLogger, ILogService, LogService } from 'vs/platform/log/common/log'; @@ -670,7 +670,7 @@ class StandaloneTelemetryService implements ITelemetryService { return Promise.resolve(undefined); } - publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + publicLog2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck) { return this.publicLog(eventName, data as any); } @@ -678,7 +678,7 @@ class StandaloneTelemetryService implements ITelemetryService { return Promise.resolve(undefined); } - publicLogError2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + publicLogError2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck) { return this.publicLogError(eventName, data as any); } diff --git a/src/vs/platform/telemetry/common/gdprTypings.ts b/src/vs/platform/telemetry/common/gdprTypings.ts index e14d6fb900d..903c0e698f7 100644 --- a/src/vs/platform/telemetry/common/gdprTypings.ts +++ b/src/vs/platform/telemetry/common/gdprTypings.ts @@ -5,29 +5,28 @@ export interface IPropertyData { classification: 'SystemMetaData' | 'CallstackOrException' | 'CustomerContent' | 'PublicNonPersonalData' | 'EndUserPseudonymizedInformation'; purpose: 'PerformanceAndHealth' | 'FeatureInsight' | 'BusinessInsight'; - comment?: string; + comment: string; expiration?: string; endpoint?: string; isMeasurement?: boolean; } export interface IGDPRProperty { - owner?: string; - comment?: string; + owner: string; + comment: string; expiration?: string; readonly [name: string]: IPropertyData | undefined | IGDPRProperty | string; } -type IGDPRPropertyWithoutMetadata = Omit; +type IGDPRPropertyWithoutMetadata = Omit; +export type OmitMetadata = Omit; -export type ClassifiedEvent = { - [k in keyof IGDPRPropertyWithoutMetadata]: any +export type ClassifiedEvent = { + [k in keyof T]: any }; -export type StrictPropertyChecker = keyof TEvent extends keyof TClassifiedEvent ? keyof TClassifiedEvent extends keyof TEvent ? TEvent : TError : TError; +export type StrictPropertyChecker = keyof TEvent extends keyof OmitMetadata ? keyof OmitMetadata extends keyof TEvent ? TEvent : TError : TError; export type StrictPropertyCheckError = { error: 'Type of classified event does not match event properties' }; -export type StrictPropertyCheck = StrictPropertyChecker, StrictPropertyCheckError>; - -export type GDPRClassification = { [_ in keyof T]: IPropertyData | IGDPRProperty | undefined | string }; +export type StrictPropertyCheck = StrictPropertyChecker>, StrictPropertyCheckError>; diff --git a/src/vs/platform/telemetry/common/serverTelemetryService.ts b/src/vs/platform/telemetry/common/serverTelemetryService.ts index 74d12ea8086..a034f4d81c0 100644 --- a/src/vs/platform/telemetry/common/serverTelemetryService.ts +++ b/src/vs/platform/telemetry/common/serverTelemetryService.ts @@ -6,7 +6,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IProductService } from 'vs/platform/product/common/productService'; -import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; +import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { ITelemetryData, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { NullTelemetryServiceShape } from 'vs/platform/telemetry/common/telemetryUtils'; @@ -37,7 +37,7 @@ export class ServerTelemetryService extends TelemetryService implements IServerT return super.publicLog(eventName, data, anonymizeFilePaths); } - override publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean): Promise { + override publicLog2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean): Promise { return this.publicLog(eventName, data as ITelemetryData | undefined, anonymizeFilePaths); } @@ -48,7 +48,7 @@ export class ServerTelemetryService extends TelemetryService implements IServerT return super.publicLogError(errorEventName, data); } - override publicLogError2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck): Promise { + override publicLogError2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck): Promise { return this.publicLogError(eventName, data as ITelemetryData | undefined); } diff --git a/src/vs/platform/telemetry/common/telemetry.ts b/src/vs/platform/telemetry/common/telemetry.ts index 6e107b6714e..f465690a677 100644 --- a/src/vs/platform/telemetry/common/telemetry.ts +++ b/src/vs/platform/telemetry/common/telemetry.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; +import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { IObservableValue } from 'vs/base/common/observableValue'; export const ITelemetryService = createDecorator('telemetryService'); @@ -40,14 +40,14 @@ export interface ITelemetryService { * Sends a telemetry event that has been privacy approved. * Do not call this unless you have been given approval. */ - publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean): Promise; + publicLog2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean): Promise; /** * @deprecated Use publicLogError2 and the typescript GDPR annotation where possible */ publicLogError(errorEventName: string, data?: ITelemetryData): Promise; - publicLogError2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck): Promise; + publicLogError2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck): Promise; getTelemetryInfo(): Promise; diff --git a/src/vs/platform/telemetry/common/telemetryService.ts b/src/vs/platform/telemetry/common/telemetryService.ts index 37feaf8b488..bfe90f7fed7 100644 --- a/src/vs/platform/telemetry/common/telemetryService.ts +++ b/src/vs/platform/telemetry/common/telemetryService.ts @@ -14,7 +14,7 @@ import { ConfigurationScope, Extensions, IConfigurationRegistry } from 'vs/platf import product from 'vs/platform/product/common/product'; import { IProductService } from 'vs/platform/product/common/productService'; import { Registry } from 'vs/platform/registry/common/platform'; -import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; +import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { ITelemetryData, ITelemetryInfo, ITelemetryService, TelemetryConfiguration, TelemetryLevel, TELEMETRY_OLD_SETTING_ID, TELEMETRY_SECTION_ID, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry'; import { getTelemetryLevel, ITelemetryAppender } from 'vs/platform/telemetry/common/telemetryUtils'; @@ -137,7 +137,7 @@ export class TelemetryService implements ITelemetryService { return this._log(eventName, TelemetryLevel.USAGE, data, anonymizeFilePaths); } - publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean): Promise { + publicLog2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean): Promise { return this.publicLog(eventName, data as ITelemetryData, anonymizeFilePaths); } @@ -150,7 +150,7 @@ export class TelemetryService implements ITelemetryService { return this._log(errorEventName, TelemetryLevel.ERROR, data, true); } - publicLogError2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck): Promise { + publicLogError2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck): Promise { return this.publicLogError(eventName, data as ITelemetryData); } diff --git a/src/vs/platform/telemetry/common/telemetryUtils.ts b/src/vs/platform/telemetry/common/telemetryUtils.ts index ded0380e412..fd8e1a4f972 100644 --- a/src/vs/platform/telemetry/common/telemetryUtils.ts +++ b/src/vs/platform/telemetry/common/telemetryUtils.ts @@ -12,7 +12,7 @@ import { ConfigurationTarget, ConfigurationTargetToString, IConfigurationService import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IProductService } from 'vs/platform/product/common/productService'; import { verifyMicrosoftInternalDomain } from 'vs/platform/telemetry/common/commonProperties'; -import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; +import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { ICustomEndpointTelemetryService, ITelemetryData, ITelemetryEndpoint, ITelemetryInfo, ITelemetryService, TelemetryConfiguration, TelemetryLevel, TELEMETRY_OLD_SETTING_ID, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry'; export class NullTelemetryServiceShape implements ITelemetryService { @@ -22,13 +22,13 @@ export class NullTelemetryServiceShape implements ITelemetryService { publicLog(eventName: string, data?: ITelemetryData) { return Promise.resolve(undefined); } - publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + publicLog2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck) { return this.publicLog(eventName, data as ITelemetryData); } publicLogError(eventName: string, data?: ITelemetryData) { return Promise.resolve(undefined); } - publicLogError2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + publicLogError2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck) { return this.publicLogError(eventName, data as ITelemetryData); } diff --git a/src/vs/platform/telemetry/test/browser/telemetryService.test.ts b/src/vs/platform/telemetry/test/browser/telemetryService.test.ts index 1d3afae1d4b..501ea625958 100644 --- a/src/vs/platform/telemetry/test/browser/telemetryService.test.ts +++ b/src/vs/platform/telemetry/test/browser/telemetryService.test.ts @@ -11,7 +11,7 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/ import product from 'vs/platform/product/common/product'; import { IProductService } from 'vs/platform/product/common/productService'; import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry'; -import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; +import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { ITelemetryData, TelemetryConfiguration, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { ITelemetryAppender, NullAppender } from 'vs/platform/telemetry/common/telemetryUtils'; @@ -240,7 +240,7 @@ suite('TelemetryService', () => { return p; } - override publicLogError2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck): Promise { + override publicLogError2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck): Promise { return this.publicLogError(eventName, data as ITelemetryData); } } diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts index 938c6eb7300..c577f16bcee 100644 --- a/src/vs/platform/windows/electron-main/window.ts +++ b/src/vs/platform/windows/electron-main/window.ts @@ -610,7 +610,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { type WindowErrorClassification = { type: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The type of window crash to understand the nature of the crash better.' }; reason: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The reason of the window crash to understand the nature of the crash better.' }; - code: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; omment: 'The exit code of the window process to understand the nature of the crash better' }; + code: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The exit code of the window process to understand the nature of the crash better' }; owner: 'bpasero'; comment: 'Provides insight into reasons the vscode window crashes.'; }; diff --git a/src/vs/workbench/api/browser/mainThreadTelemetry.ts b/src/vs/workbench/api/browser/mainThreadTelemetry.ts index ac89aca9280..ca99ca23109 100644 --- a/src/vs/workbench/api/browser/mainThreadTelemetry.ts +++ b/src/vs/workbench/api/browser/mainThreadTelemetry.ts @@ -6,7 +6,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IProductService } from 'vs/platform/product/common/productService'; -import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; +import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; @@ -51,7 +51,7 @@ export class MainThreadTelemetry extends Disposable implements MainThreadTelemet this._telemetryService.publicLog(eventName, data); } - $publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck): void { + $publicLog2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck): void { this.$publicLog(eventName, data as any); } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 8766b160f4d..ed17dcc5b4c 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -38,7 +38,7 @@ import { IMarkerData } from 'vs/platform/markers/common/markers'; import { IProgressOptions, IProgressStep } from 'vs/platform/progress/common/progress'; import * as quickInput from 'vs/platform/quickinput/common/quickInput'; import { IRemoteConnectionData, TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver'; -import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; +import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { ICreateContributedTerminalProfileOptions, IProcessProperty, IShellLaunchConfigDto, ITerminalEnvironment, ITerminalLaunchError, ITerminalProfile, TerminalExitReason, TerminalLocation } from 'vs/platform/terminal/common/terminal'; import { ThemeColor, ThemeIcon } from 'vs/platform/theme/common/themeService'; @@ -598,7 +598,7 @@ export interface MainThreadStorageShape extends IDisposable { export interface MainThreadTelemetryShape extends IDisposable { $publicLog(eventName: string, data?: any): void; - $publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck): void; + $publicLog2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck): void; } export interface MainThreadEditorInsetsShape extends IDisposable { diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 48245d942a3..9e3f74f3bd9 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -1242,22 +1242,24 @@ export class ChangeLanguageAction extends Action { if (resource?.scheme === Schemas.untitled) { type SetUntitledDocumentLanguageEvent = { to: string; from: string; modelPreference: string }; type SetUntitledDocumentLanguageClassification = { + owner: 'TylerLeonhardt'; + comment: 'Helps understand what the automatic language detection does for untitled files'; to: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; - owner: 'JacksonKearl'; + owner: 'TylerLeonhardt'; comment: 'Help understand effectiveness of automatic language detection'; }; from: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; - owner: 'JacksonKearl'; + owner: 'TylerLeonhardt'; comment: 'Help understand effectiveness of automatic language detection'; }; modelPreference: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; - owner: 'JacksonKearl'; + owner: 'TylerLeonhardt'; comment: 'Help understand effectiveness of automatic language detection'; }; }; diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 807d327879c..81bf4b28d5b 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -46,7 +46,6 @@ import { IExtensionManifestPropertiesService } from 'vs/workbench/services/exten import { IExtensionService, IExtensionsStatus } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionEditor } from 'vs/workbench/contrib/extensions/browser/extensionEditor'; import { isWeb, language } from 'vs/base/common/platform'; -import { GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks'; import { ILocaleService } from 'vs/workbench/contrib/localization/common/locale'; @@ -58,12 +57,12 @@ interface InstalledExtensionsEvent { readonly extensionIds: string; readonly count: number; } -interface ExtensionsLoadClassification extends GDPRClassification { +type ExtensionsLoadClassification = { owner: 'digitarald'; comment: 'Helps to understand which extensions are the most actively used.'; readonly extensionIds: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; comment: 'The list of extension ids that are installed.' }; readonly count: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; comment: 'The number of extensions that are installed.' }; -} +}; export class Extension implements IExtension { diff --git a/src/vs/workbench/contrib/format/browser/formatActionsMultiple.ts b/src/vs/workbench/contrib/format/browser/formatActionsMultiple.ts index 5a3e059af9e..635bfd39597 100644 --- a/src/vs/workbench/contrib/format/browser/formatActionsMultiple.ts +++ b/src/vs/workbench/contrib/format/browser/formatActionsMultiple.ts @@ -272,7 +272,7 @@ function logFormatterTelemetry( comment: 'Information about resolving formatter conflicts'; mode: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Formatting mode: whole document or a range/selection' }; extensions: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The extension that got picked' }; - pick: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comments: 'The possible extensions to pick' }; + pick: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The possible extensions to pick' }; }; function extKey(obj: T): string { return obj.extensionId ? ExtensionIdentifier.toKey(obj.extensionId) : 'unknown'; diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index 20b0969540c..a506b12de3d 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -1615,6 +1615,8 @@ export class SettingsEditor2 extends EditorPane { 'message': string; }; type SettingsSearchErrorClassification = { + owner: 'rzhao271'; + comment: 'Helps understand when settings search errors out'; 'message': { 'classification': 'CallstackOrException'; 'purpose': 'FeatureInsight'; 'owner': 'rzhao271'; 'comment': 'The error message of the search error.' }; }; diff --git a/src/vs/workbench/contrib/search/test/electron-browser/textsearch.perf.integrationTest.ts b/src/vs/workbench/contrib/search/test/electron-browser/textsearch.perf.integrationTest.ts index cfcbec62d50..3b73a35ecb3 100644 --- a/src/vs/workbench/contrib/search/test/electron-browser/textsearch.perf.integrationTest.ts +++ b/src/vs/workbench/contrib/search/test/electron-browser/textsearch.perf.integrationTest.ts @@ -25,7 +25,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; -import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; +import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { ITelemetryInfo, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; @@ -207,7 +207,7 @@ class TestTelemetryService implements ITelemetryService { return Promise.resolve(); } - public publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + public publicLog2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck) { return this.publicLog(eventName, data as any); } @@ -215,7 +215,7 @@ class TestTelemetryService implements ITelemetryService { return this.publicLog(eventName, data); } - public publicLogError2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + public publicLogError2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck) { return this.publicLogError(eventName, data as any); } diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts index 8878b684466..f854d0c75a0 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts @@ -139,7 +139,7 @@ export const openNewSearchEditor = } } - telemetryService.publicLog2<{}, { owner: 'roblourens' }>('searchEditor/openNewSearchEditor'); + telemetryService.publicLog2<{}, { owner: 'roblourens'; comment: 'TODO @roblourens' }>('searchEditor/openNewSearchEditor'); const seedSearchStringFromSelection = _args.location === 'new' || configurationService.getValue('editor').find!.seedSearchStringFromSelection; const args: OpenSearchEditorArgs = { query: seedSearchStringFromSelection ? selected : undefined }; @@ -189,7 +189,7 @@ export const createEditorFromSearchResult = const sortOrder = configurationService.getValue('search').sortOrder; - telemetryService.publicLog2<{}, { owner: 'roblourens' }>('searchEditor/createEditorFromSearchResult'); + telemetryService.publicLog2<{}, { owner: 'roblourens'; comment: 'TODO @roblourens' }>('searchEditor/createEditorFromSearchResult'); const labelFormatter = (uri: URI): string => labelService.getUriLabel(uri, { relative: true }); diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts index 56f822657f5..3481a3c4978 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts @@ -184,7 +184,7 @@ export class SearchEditorInput extends EditorInput { override async saveAs(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise { const path = await this.fileDialogService.pickFileToSave(await this.suggestFileName(), options?.availableFileSystems); if (path) { - this.telemetryService.publicLog2<{}, { owner: 'roblourens' }>('searchEditor/saveSearchResults'); + this.telemetryService.publicLog2<{}, { owner: 'roblourens'; comment: 'TODO @roblourens' }>('searchEditor/saveSearchResults'); const toWrite = await this.serializeForDisk(); if (await this.textFileService.create([{ resource: path, value: toWrite, options: { overwrite: true } }])) { this.setDirty(false); diff --git a/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts b/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts index 40346309f5e..ad17e2c08ac 100644 --- a/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts +++ b/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts @@ -71,6 +71,7 @@ export class TelemetryContribution extends Disposable implements IWorkbenchContr innerWidth: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The width of the current window.' }; outerHeight: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The height of the current window with all decoration removed.' }; outerWidth: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The width of the current window with all decoration removed.' }; + owner: 'bpasero'; comment: 'The size of the window.'; }; @@ -82,7 +83,7 @@ export class TelemetryContribution extends Disposable implements IWorkbenchContr 'workbench.filesToOpenOrCreate': { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of files that should open or be created.' }; 'workbench.filesToDiff': { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of files that should be compared.' }; 'workbench.filesToMerge': { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of files that should be merged.' }; - customKeybindingsCount: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true }; + customKeybindingsCount: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of custom keybindings' }; theme: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The current theme of the window.' }; language: { classification: 'SystemMetaData'; purpose: 'BusinessInsight'; comment: 'The display language of the window.' }; pinnedViewlets: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The identifiers of views that are pinned.' }; diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts index 1cdd953a342..4a3f8edcec1 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts @@ -415,6 +415,8 @@ export class WalkthroughsService extends Disposable implements IWalkthroughsServ if (sectionToOpen && this.configurationService.getValue('workbench.welcomePage.walkthroughs.openOnInstall')) { type GettingStartedAutoOpenClassification = { + owner: 'lramos15'; + comment: 'When a walkthrthrough is opened upon extension installation'; id: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; owner: 'lramos15'; diff --git a/src/vs/workbench/services/accessibility/electron-sandbox/accessibilityService.ts b/src/vs/workbench/services/accessibility/electron-sandbox/accessibilityService.ts index eb818e7fc16..a7d574ca562 100644 --- a/src/vs/workbench/services/accessibility/electron-sandbox/accessibilityService.ts +++ b/src/vs/workbench/services/accessibility/electron-sandbox/accessibilityService.ts @@ -23,7 +23,8 @@ interface AccessibilityMetrics { } type AccessibilityMetricsClassification = { owner: 'isidorn'; - enabled: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; + comment: 'Helps gain an understanding of when accessibility features are being used'; + enabled: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Whether or not accessibility features are enabled' }; }; export class NativeAccessibilityService extends AccessibilityService implements IAccessibilityService { diff --git a/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts b/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts index fa54d7d9ecd..56cc51c6dfb 100644 --- a/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts +++ b/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts @@ -30,7 +30,6 @@ import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/commo import { CancellationToken } from 'vs/base/common/cancellation'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; const FIVE_MINUTES = 5 * 60 * 1000; const THIRTY_SECONDS = 30 * 1000; @@ -81,11 +80,11 @@ export interface ExtensionUrlHandlerEvent { readonly extensionId: string; } -export interface ExtensionUrlHandlerClassification extends GDPRClassification { +type ExtensionUrlHandlerClassification = { owner: 'joaomoreno'; readonly extensionId: { classification: 'PublicNonPersonalData'; purpose: 'FeatureInsight'; comment: 'The ID of the extension that should handle the URI' }; comment: 'This is used to understand the drop funnel of extension URI handling by the OS & VS Code.'; -} +}; /** * This class handles URLs which are directed towards extensions. diff --git a/src/vs/workbench/services/search/common/searchService.ts b/src/vs/workbench/services/search/common/searchService.ts index f5127405714..4d6a8cc305f 100644 --- a/src/vs/workbench/services/search/common/searchService.ts +++ b/src/vs/workbench/services/search/common/searchService.ts @@ -283,17 +283,18 @@ export class SearchService extends Disposable implements ISearchService { type CachedSearchCompleteClassifcation = { owner: 'roblourens'; - reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' }; - resultCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - type: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' }; - endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - sortingTime?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - cacheWasResolved: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' }; - cacheLookupTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - cacheFilterTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - cacheEntryCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' }; + comment: 'TODO @roblourens'; + reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; + resultCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + type: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; + endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + sortingTime?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + cacheWasResolved: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; + cacheLookupTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + cacheFilterTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + cacheEntryCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; }; type CachedSearchCompleteEvent = { reason?: string; @@ -326,18 +327,19 @@ export class SearchService extends Disposable implements ISearchService { type SearchCompleteClassification = { owner: 'roblourens'; - reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' }; - resultCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - type: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' }; - endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - sortingTime?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - fileWalkTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - directoriesWalked: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - filesWalked: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - cmdTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - cmdResultCount?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' }; + comment: 'TODO @roblourens'; + reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; + resultCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + type: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; + endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + sortingTime?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + fileWalkTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + directoriesWalked: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + filesWalked: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + cmdTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + cmdResultCount?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; }; type SearchCompleteEvent = { reason?: string; @@ -384,12 +386,13 @@ export class SearchService extends Disposable implements ISearchService { type TextSearchCompleteClassification = { owner: 'roblourens'; - reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' }; - workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true }; - scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' }; - error?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' }; - usePCRE2: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth' }; + comment: 'TODO @roblourens'; + reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; + workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; + scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; + error?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; + usePCRE2: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; }; type TextSearchCompleteEvent = { reason?: string; diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index f181154fe05..2c12f5a3305 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -11,7 +11,7 @@ import { ILoggerService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { OneDataSystemWebAppender } from 'vs/platform/telemetry/browser/1dsAppender'; -import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; +import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { ITelemetryData, ITelemetryInfo, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender'; import { ITelemetryServiceConfig, TelemetryService as BaseTelemetryService } from 'vs/platform/telemetry/common/telemetryService'; @@ -68,7 +68,7 @@ export class TelemetryService extends Disposable implements ITelemetryService { return this.impl.publicLog(eventName, data, anonymizeFilePaths); } - publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean) { + publicLog2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean) { return this.publicLog(eventName, data as ITelemetryData, anonymizeFilePaths); } @@ -76,7 +76,7 @@ export class TelemetryService extends Disposable implements ITelemetryService { return this.impl.publicLog(errorEventName, data); } - publicLogError2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + publicLogError2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck) { return this.publicLogError(eventName, data as ITelemetryData); } diff --git a/src/vs/workbench/services/telemetry/electron-sandbox/telemetryService.ts b/src/vs/workbench/services/telemetry/electron-sandbox/telemetryService.ts index 0645973a7bb..026d7294125 100644 --- a/src/vs/workbench/services/telemetry/electron-sandbox/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/electron-sandbox/telemetryService.ts @@ -15,7 +15,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { resolveWorkbenchCommonProperties } from 'vs/workbench/services/telemetry/electron-sandbox/workbenchCommonProperties'; import { TelemetryService as BaseTelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; +import { ClassifiedEvent, StrictPropertyCheck, OmitMetadata, IGDPRProperty } from 'vs/platform/telemetry/common/gdprTypings'; import { IFileService } from 'vs/platform/files/common/files'; import { IObservableValue } from 'vs/base/common/observableValue'; @@ -66,7 +66,7 @@ export class TelemetryService extends Disposable implements ITelemetryService { return this.impl.publicLog(eventName, data, anonymizeFilePaths); } - publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean) { + publicLog2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean) { return this.publicLog(eventName, data as ITelemetryData, anonymizeFilePaths); } @@ -74,7 +74,7 @@ export class TelemetryService extends Disposable implements ITelemetryService { return this.impl.publicLogError(errorEventName, data); } - publicLogError2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + publicLogError2> = never, T extends IGDPRProperty = never>(eventName: string, data?: StrictPropertyCheck) { return this.publicLog(eventName, data as ITelemetryData); } diff --git a/src/vs/workbench/services/timer/browser/timerService.ts b/src/vs/workbench/services/timer/browser/timerService.ts index c4fd56aa771..4c025af5946 100644 --- a/src/vs/workbench/services/timer/browser/timerService.ts +++ b/src/vs/workbench/services/timer/browser/timerService.ts @@ -534,7 +534,7 @@ export abstract class AbstractTimerService implements ITimerService { source: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Where this marker was generated, e.g main, renderer, extension host' }; name: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The name of this marker (as defined in source code)' }; relativeStartTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The duration between the previous and this marker' }; - startTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comments: 'The absolute timestamp (unix time)' }; + startTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The absolute timestamp (unix time)' }; }; let lastMark: perf.PerformanceMark = marks[0]; From f9bee281e0f250d4cf073f0e5ed469256e6f8135 Mon Sep 17 00:00:00 2001 From: John Murray Date: Mon, 1 Aug 2022 21:37:27 +0100 Subject: [PATCH 117/303] Show Issue Reporter window in taskbar (#130497) (#156141) --- src/vs/platform/issue/electron-main/issueMainService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/issue/electron-main/issueMainService.ts b/src/vs/platform/issue/electron-main/issueMainService.ts index 24cc5db2fab..e283eb85e95 100644 --- a/src/vs/platform/issue/electron-main/issueMainService.ts +++ b/src/vs/platform/issue/electron-main/issueMainService.ts @@ -317,7 +317,7 @@ export class IssueMainService implements ICommonIssueService { private createBrowserWindow(position: IWindowState, ipcObjectUrl: IIPCObjectUrl, options: IBrowserWindowOptions, windowKind: string): BrowserWindow { const window = new BrowserWindow({ fullscreen: false, - skipTaskbar: true, + skipTaskbar: false, resizable: true, width: position.width, height: position.height, From f31a88e1611ccba3139770b6f6444820e783819b Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 1 Aug 2022 13:54:49 -0700 Subject: [PATCH 118/303] Remove move cell integration test (#156825) * Remove move cell integration test * :lipstick: * test didn't really run locally --- .../src/singlefolder-tests/notebook.test.ts | 53 ++----------------- .../test/browser/cellOperations.test.ts | 5 +- 2 files changed, 7 insertions(+), 51 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts index 5b77eab65bf..a5c21988214 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts @@ -212,9 +212,9 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { addedCells: [editor.notebook.cellAt(1)] }); - const moveCellEvent = asPromise(vscode.workspace.onDidChangeNotebookDocument); - await vscode.commands.executeCommand('notebook.cell.moveUp'); - await moveCellEvent; + // const moveCellEvent = asPromise(vscode.workspace.onDidChangeNotebookDocument); + // await vscode.commands.executeCommand('notebook.cell.moveUp'); + // await moveCellEvent; const cellOutputChange = asPromise(vscode.workspace.onDidChangeNotebookDocument); await vscode.commands.executeCommand('notebook.cell.execute'); @@ -393,57 +393,10 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { activeCell = getFocusedCell(editor); assert.strictEqual(editor.notebook.getCells().indexOf(activeCell!), 0); - - // ---- move up and down ---- // - - await vscode.commands.executeCommand('notebook.cell.moveDown'); - assert.strictEqual(editor.notebook.getCells().indexOf(getFocusedCell(editor)!), 1, - `first move down, active cell ${getFocusedCell(editor)!.document.uri.toString()}, ${getFocusedCell(editor)!.document.getText()}`); - await vscode.commands.executeCommand('workbench.action.files.save'); await vscode.commands.executeCommand('workbench.action.closeActiveEditor'); }); - test('editor move command - event and move cells will not recreate cells in ExtHost (#98126)', async function () { - const notebook = await openRandomNotebookDocument(); - const editor = await vscode.window.showNotebookDocument(notebook); - - const activeCell = getFocusedCell(editor); - assert.strictEqual(activeCell?.index, 0); - const notebookChangeEvent = asPromise(vscode.workspace.onDidChangeNotebookDocument); - await vscode.commands.executeCommand('notebook.cell.moveDown'); - assert.ok(await notebookChangeEvent); - - const newActiveCell = getFocusedCell(editor); - assert.strictEqual(newActiveCell?.index, 1); - assert.deepStrictEqual(activeCell, newActiveCell); - }); - - // test('document runnable based on kernel count', async () => { - // const resource = await createRandomNotebookFile(); - // await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest'); - // assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first'); - // const editor = vscode.window.activeNotebookEditor!; - - // const cell = editor.notebook.cellAt(0); - // assert.strictEqual(cell.outputs.length, 0); - - // currentKernelProvider.setHasKernels(false); - // await vscode.commands.executeCommand('notebook.execute'); - // assert.strictEqual(cell.outputs.length, 0, 'should not execute'); // not runnable, didn't work - - // currentKernelProvider.setHasKernels(true); - - // await withEvent(vscode.notebooks.onDidChangeCellOutputs, async (event) => { - // await vscode.commands.executeCommand('notebook.execute'); - // await event; - // assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked - // }); - - // await saveAllFilesAndCloseAll(undefined); - // }); - - // TODO@rebornix this is wrong, `await vscode.commands.executeCommand('notebook.execute');` doesn't wait until the workspace edit is applied test.skip('cell execute command takes arguments', async () => { const notebook = await openRandomNotebookDocument(); diff --git a/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts b/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts index 08fd7b6e023..51c9d9a4798 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts @@ -24,8 +24,11 @@ suite('CellOperations', () => { ], async (editor, viewModel) => { viewModel.updateSelectionsState({ kind: SelectionStateType.Index, focus: { start: 1, end: 2 }, selections: [{ start: 1, end: 2 }] }); - await moveCellRange({ notebookEditor: editor, cell: viewModel.cellAt(1)! }, 'down'); + const cell = viewModel.cellAt(1); + assert.ok(cell); + await moveCellRange({ notebookEditor: editor, cell: cell }, 'down'); assert.strictEqual(viewModel.cellAt(2)?.getText(), 'var b = 1;'); + assert.strictEqual(cell, viewModel.cellAt(2)); }); }); From f0434c0960d5486f021ce3e9b5791646f7b063f1 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 1 Aug 2022 13:59:07 -0700 Subject: [PATCH 119/303] Pick up TS 4.8 for JS/TS extension (#156828) --- extensions/package.json | 2 +- .../src/languageFeatures/fileConfigurationManager.ts | 1 - extensions/yarn.lock | 8 ++++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/extensions/package.json b/extensions/package.json index 2c89538c8a2..5419d4e4291 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -4,7 +4,7 @@ "license": "MIT", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "4.7.3" + "typescript": "^4.8.0-dev.20220801" }, "scripts": { "postinstall": "node ./postinstall.mjs" diff --git a/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts b/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts index caeb91d1dc3..fd3f84963e6 100644 --- a/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts +++ b/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts @@ -190,7 +190,6 @@ export default class FileConfigurationManager extends Disposable { includeCompletionsWithSnippetText: config.get('suggest.includeCompletionsWithSnippetText', true), includeCompletionsWithClassMemberSnippets: config.get('suggest.classMemberSnippets.enabled', true), includeCompletionsWithObjectLiteralMethodSnippets: config.get('suggest.objectLiteralMethodSnippets.enabled', true), - // @ts-expect-error until TS 4.8 autoImportFileExcludePatterns: this.getAutoImportFileExcludePatternsPreference(preferencesConfig, vscode.workspace.getWorkspaceFolder(document.uri)?.uri), useLabelDetailsInCompletionEntries: true, allowIncompleteCompletions: true, diff --git a/extensions/yarn.lock b/extensions/yarn.lock index da2bcfbff02..10a2696374a 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -42,10 +42,10 @@ node-gyp-build@^4.3.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== -typescript@4.7.3: - version "4.7.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.3.tgz#8364b502d5257b540f9de4c40be84c98e23a129d" - integrity sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA== +typescript@^4.8.0-dev.20220801: + version "4.8.0-dev.20220801" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.0-dev.20220801.tgz#547ae7fea513fde4058f6715afa673b388e73129" + integrity sha512-idPY4geCSbS6npeHcr4m4nITkxz0/w4LmLSAao0UGvaWoHGFfkThJZhCXWFAx9TxQV1zZUWgXmngJBjfTm3otw== vscode-grammar-updater@^1.1.0: version "1.1.0" From 6f8b946d70f4d2eda7b10978dd59903103800bf3 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Mon, 1 Aug 2022 14:41:08 -0700 Subject: [PATCH 120/303] Remove locale and include download count (#156823) --- .../languagePacks/common/languagePacks.ts | 38 ++++++++++++++----- .../languagePacks/node/languagePacks.ts | 5 ++- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/vs/platform/languagePacks/common/languagePacks.ts b/src/vs/platform/languagePacks/common/languagePacks.ts index 098cbe3a471..d316ba89c3e 100644 --- a/src/vs/platform/languagePacks/common/languagePacks.ts +++ b/src/vs/platform/languagePacks/common/languagePacks.ts @@ -53,7 +53,7 @@ export abstract class LanguagePackBaseService extends Disposable implements ILan const allFromMarketplace: ILanguagePackItem[] = languagePackExtensions.map(lp => { const languageName = lp.properties.localizedLanguages?.[0]; const locale = this.getLocale(lp)!; - const baseQuickPick = this.createQuickPickItem({ locale, label: languageName }); + const baseQuickPick = this.createQuickPickItem(locale, languageName, lp); return { ...baseQuickPick, extensionId: lp.identifier.id, @@ -62,7 +62,7 @@ export abstract class LanguagePackBaseService extends Disposable implements ILan }); allFromMarketplace.push({ - ...this.createQuickPickItem({ locale: 'en', label: 'English' }), + ...this.createQuickPickItem('en', 'English'), extensionId: 'default', }); @@ -73,17 +73,35 @@ export abstract class LanguagePackBaseService extends Disposable implements ILan return extension.tags.find(t => t.startsWith('lp-'))?.split('lp-')[1]; } - protected createQuickPickItem(languageItem: { locale: string; label?: string | undefined }): IQuickPickItem { - const label = languageItem.label ?? languageItem.locale; - let description: string | undefined = languageItem.locale !== languageItem.label ? languageItem.locale : undefined; - if (languageItem.locale.toLowerCase() === language.toLowerCase()) { - if (!description) { - description = ''; - } + protected createQuickPickItem(locale: string, languageName?: string, languagePack?: IGalleryExtension): IQuickPickItem { + const label = languageName ?? locale; + let description: string | undefined; + if (label !== locale) { + description = `(${locale})`; + } + + if (locale.toLowerCase() === language.toLowerCase()) { + description ??= ''; description += localize('currentDisplayLanguage', " (Current)"); } + + if (languagePack?.installCount) { + description ??= ''; + + const count = languagePack.installCount; + let countLabel: string; + if (count > 1000000) { + countLabel = `${Math.floor(count / 100000) / 10}M`; + } else if (count > 1000) { + countLabel = `${Math.floor(count / 1000)}K`; + } else { + countLabel = String(count); + } + description += ` $(cloud-download) ${countLabel}`; + } + return { - id: languageItem.locale, + id: locale, label, description }; diff --git a/src/vs/platform/languagePacks/node/languagePacks.ts b/src/vs/platform/languagePacks/node/languagePacks.ts index 8129163e88f..defe0957b17 100644 --- a/src/vs/platform/languagePacks/node/languagePacks.ts +++ b/src/vs/platform/languagePacks/node/languagePacks.ts @@ -52,16 +52,17 @@ export class NativeLanguagePackService extends LanguagePackBaseService { const languagePacks = await this.cache.getLanguagePacks(); const languages = Object.keys(languagePacks).map(locale => { const languagePack = languagePacks[locale]; - const baseQuickPick = this.createQuickPickItem({ locale, label: languagePack.label }); + const baseQuickPick = this.createQuickPickItem(locale, languagePack.label); return { ...baseQuickPick, extensionId: languagePack.extensions[0].extensionIdentifier.id, }; }); languages.push({ - ...this.createQuickPickItem({ locale: 'en', label: 'English' }), + ...this.createQuickPickItem('en', 'English'), extensionId: 'default', }); + languages.sort((a, b) => a.label.localeCompare(b.label)); return languages; } From a7cd732b7f05c035580104d2f9f96089aa27df7d Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Mon, 1 Aug 2022 16:45:44 -0700 Subject: [PATCH 121/303] ignore query and fragment of trustedDomains (#156841) --- .../externalUriOpener/common/externalUriOpenerService.ts | 2 +- .../contrib/url/browser/trustedDomainsValidator.ts | 2 +- src/vs/workbench/contrib/url/common/urlGlob.ts | 7 ++++++- .../contrib/url/test/browser/trustedDomains.test.ts | 5 +++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/externalUriOpener/common/externalUriOpenerService.ts b/src/vs/workbench/contrib/externalUriOpener/common/externalUriOpenerService.ts index 63b4e36e63e..2c600f3c3a0 100644 --- a/src/vs/workbench/contrib/externalUriOpener/common/externalUriOpenerService.ts +++ b/src/vs/workbench/contrib/externalUriOpener/common/externalUriOpenerService.ts @@ -177,7 +177,7 @@ export class ExternalUriOpenerService extends Disposable implements IExternalUri private getConfiguredOpenerForUri(openers: Map, targetUri: URI): IExternalUriOpener | 'default' | undefined { const config = this.configurationService.getValue(externalUriOpenersSettingId) || {}; for (const [uriGlob, id] of Object.entries(config)) { - if (testUrlMatchesGlob(targetUri.toString(), uriGlob)) { + if (testUrlMatchesGlob(targetUri, uriGlob)) { if (id === defaultExternalUriOpenerId) { return 'default'; } diff --git a/src/vs/workbench/contrib/url/browser/trustedDomainsValidator.ts b/src/vs/workbench/contrib/url/browser/trustedDomainsValidator.ts index 46cea815e4c..95f8e6964b0 100644 --- a/src/vs/workbench/contrib/url/browser/trustedDomainsValidator.ts +++ b/src/vs/workbench/contrib/url/browser/trustedDomainsValidator.ts @@ -200,7 +200,7 @@ export function isURLDomainTrusted(url: URI, trustedDomains: string[]) { return true; } - if (testUrlMatchesGlob(url.toString(), trustedDomains[i])) { + if (testUrlMatchesGlob(url, trustedDomains[i])) { return true; } } diff --git a/src/vs/workbench/contrib/url/common/urlGlob.ts b/src/vs/workbench/contrib/url/common/urlGlob.ts index 8893796290c..012eb52ed2c 100644 --- a/src/vs/workbench/contrib/url/common/urlGlob.ts +++ b/src/vs/workbench/contrib/url/common/urlGlob.ts @@ -3,7 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -export const testUrlMatchesGlob = (url: string, globUrl: string): boolean => { +import { URI } from 'vs/base/common/uri'; + +// TODO: rewrite this to use URIs directly and validate each part individually +// instead of relying on memoization of the stringified URI. +export const testUrlMatchesGlob = (uri: URI, globUrl: string): boolean => { + let url = uri.with({ query: null, fragment: null }).toString(); const normalize = (url: string) => url.replace(/\/+$/, ''); globUrl = normalize(globUrl); url = normalize(url); diff --git a/src/vs/workbench/contrib/url/test/browser/trustedDomains.test.ts b/src/vs/workbench/contrib/url/test/browser/trustedDomains.test.ts index 9ff8c657b18..898f6af547d 100644 --- a/src/vs/workbench/contrib/url/test/browser/trustedDomains.test.ts +++ b/src/vs/workbench/contrib/url/test/browser/trustedDomains.test.ts @@ -129,4 +129,9 @@ suite('Link protection domain matching', () => { linkAllowedByRules('https://github.com/microsoft/vscode/issues/new', ['https://github.com/microsoft']); linkAllowedByRules('https://github.com/microsoft/vscode/issues/new', ['https://github.com/microsoft']); }); + + test('ignore query & fragment - https://github.com/microsoft/vscode/issues/156839', () => { + linkAllowedByRules('https://github.com/login/oauth/authorize?foo=4', ['https://github.com/login/oauth/authorize']); + linkAllowedByRules('https://github.com/login/oauth/authorize#foo', ['https://github.com/login/oauth/authorize']); + }); }); From cf43717e18bbf1be6bd49a26e2cdadd61435fb8a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 1 Aug 2022 17:13:55 -0700 Subject: [PATCH 122/303] Pick up new md grammar (#156844) Also updates themes to better handle https://github.com/microsoft/vscode-markdown-tm-grammar/issues/4 --- extensions/markdown-basics/cgmanifest.json | 2 +- .../syntaxes/markdown.tmLanguage.json | 42 +++++++++++++++++-- .../theme-abyss/themes/abyss-color-theme.json | 6 ++- extensions/theme-defaults/themes/dark_vs.json | 3 +- .../theme-defaults/themes/hc_black.json | 3 +- .../theme-defaults/themes/light_vs.json | 3 +- .../themes/kimbie-dark-color-theme.json | 6 ++- .../themes/monokai-color-theme.json | 3 +- .../themes/quietlight-color-theme.json | 3 +- .../theme-red/themes/Red-color-theme.json | 3 +- .../themes/solarized-dark-color-theme.json | 3 +- .../themes/solarized-light-color-theme.json | 3 +- .../tomorrow-night-blue-color-theme.json | 11 +++-- 13 files changed, 73 insertions(+), 18 deletions(-) diff --git a/extensions/markdown-basics/cgmanifest.json b/extensions/markdown-basics/cgmanifest.json index 46b4bae2286..899a3b2422b 100644 --- a/extensions/markdown-basics/cgmanifest.json +++ b/extensions/markdown-basics/cgmanifest.json @@ -33,7 +33,7 @@ "git": { "name": "microsoft/vscode-markdown-tm-grammar", "repositoryUrl": "https://github.com/microsoft/vscode-markdown-tm-grammar", - "commitHash": "69d3321b4923ca2d5e8e900018887cc38b5fe04a" + "commitHash": "97f2f8d38f10d3febd77d85b745945dc60fe334e" } }, "license": "MIT", diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index 895836a188f..7ba6ebe393e 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/69d3321b4923ca2d5e8e900018887cc38b5fe04a", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/97f2f8d38f10d3febd77d85b745945dc60fe334e", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -2766,7 +2766,24 @@ "name": "punctuation.definition.link.title.begin.markdown" }, "2": { - "name": "string.other.link.title.markdown" + "name": "string.other.link.title.markdown", + "patterns": [ + { + "include": "#raw" + }, + { + "include": "#bold" + }, + { + "include": "#italic" + }, + { + "include": "#strikethrough" + }, + { + "include": "#image-inline" + } + ] }, "4": { "name": "punctuation.definition.link.title.end.markdown" @@ -2826,7 +2843,24 @@ "name": "punctuation.definition.link.title.begin.markdown" }, "2": { - "name": "string.other.link.title.markdown" + "name": "string.other.link.title.markdown", + "patterns": [ + { + "include": "#raw" + }, + { + "include": "#bold" + }, + { + "include": "#italic" + }, + { + "include": "#strikethrough" + }, + { + "include": "#image-inline" + } + ] }, "4": { "name": "punctuation.definition.link.title.end.markdown" @@ -2957,7 +2991,7 @@ "name": "punctuation.definition.strikethrough.markdown" } }, - "match": "(~{2,})((?:[^~]|(?!(? Date: Mon, 1 Aug 2022 17:15:52 -0700 Subject: [PATCH 123/303] up timeout to 5min (#156846) --- extensions/github-authentication/src/githubServer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/github-authentication/src/githubServer.ts b/extensions/github-authentication/src/githubServer.ts index 6816d9d992e..1614794fcb0 100644 --- a/extensions/github-authentication/src/githubServer.ts +++ b/extensions/github-authentication/src/githubServer.ts @@ -243,7 +243,7 @@ export class GitHubServer implements IGitHubServer { try { return await Promise.race([ codeExchangePromise.promise, - new Promise((_, reject) => setTimeout(() => reject('Cancelled'), 60000)), + new Promise((_, reject) => setTimeout(() => reject('Timed out'), 300_000)), // 5min timeout promiseFromEvent(token.onCancellationRequested, (_, __, reject) => { reject('User Cancelled'); }).promise ]); } finally { @@ -276,7 +276,7 @@ export class GitHubServer implements IGitHubServer { vscode.env.openExternal(vscode.Uri.parse(`http://127.0.0.1:${port}/signin?nonce=${encodeURIComponent(server.nonce)}`)); const { code } = await Promise.race([ server.waitForOAuthResponse(), - new Promise((_, reject) => setTimeout(() => reject('Cancelled'), 60000)), + new Promise((_, reject) => setTimeout(() => reject('Timed out'), 300_000)), // 5min timeout promiseFromEvent(token.onCancellationRequested, (_, __, reject) => { reject('User Cancelled'); }).promise ]); codeToExchange = code; From 96dac9e2aea51b63b073786656c48231a5381594 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Mon, 1 Aug 2022 17:35:13 -0700 Subject: [PATCH 124/303] Adjust margin in getting started (#156845) Adjust margin --- .../browser/gettingStartedDetailsRenderer.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer.ts index b4d6e89f34a..8d066d8c49e 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer.ts @@ -72,9 +72,11 @@ export class GettingStartedDetailsRenderer { margin: 5px; cursor: pointer; } + checkbox > img { + margin-bottom: 4px; + } checkbox.checked > img { box-sizing: border-box; - margin-bottom: 4px; } checkbox.checked > img { outline: 2px solid var(--vscode-focusBorder); From 887536f50099f2a4f500f35dfa7f912a616110b9 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 1 Aug 2022 18:57:02 -0700 Subject: [PATCH 125/303] Include directory of notebook in local resources roots (#156852) Fixes #156815 This is also how the markdown preview operates: https://github.com/microsoft/vscode/blob/3b549009fe133f5b98f1fd9c8d3116dbd033dbe9/extensions/markdown-language-features/src/preview/preview.ts#L442 --- .../contrib/notebook/browser/view/renderers/backLayerWebView.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index faa5dabcc3f..eed6f5eb480 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -884,11 +884,13 @@ var requirejs = (function() { private _createInset(webviewService: IWebviewService, content: string) { const workspaceFolders = this.contextService.getWorkspace().folders.map(x => x.uri); + const notebookDir = dirname(this.documentUri); this.localResourceRootsCache = [ ...this.notebookService.getNotebookProviderResourceRoots(), ...this.notebookService.getRenderers().map(x => dirname(x.entrypoint)), ...workspaceFolders, + notebookDir, ...this.getBuiltinLocalResourceRoots(), ]; const webview = webviewService.createWebviewElement({ From 820306c5243e6779c9a1dd72c8726ac66df63466 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 2 Aug 2022 13:20:41 +0900 Subject: [PATCH 126/303] ci: fix arm arch config for sysroot --- build/linux/debian/install-sysroot.js | 3 ++- build/linux/debian/install-sysroot.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/build/linux/debian/install-sysroot.js b/build/linux/debian/install-sysroot.js index 9608b6356d3..a599912b892 100644 --- a/build/linux/debian/install-sysroot.js +++ b/build/linux/debian/install-sysroot.js @@ -37,7 +37,8 @@ async function getSysroot(arch) { throw new Error('Cannot retrieve sysroots.json. Stderr:\n' + result.stderr); } const sysrootInfo = require(sysrootDictLocation); - const sysrootDict = sysrootInfo[`bullseye_${arch}`]; + const sysrootArch = arch === 'armhf' ? 'bullseye_arm' : `bullseye_${arch}`; + const sysrootDict = sysrootInfo[sysrootArch]; const tarballFilename = sysrootDict['Tarball']; const tarballSha = sysrootDict['Sha1Sum']; const sysroot = path.join((0, os_1.tmpdir)(), sysrootDict['SysrootDir']); diff --git a/build/linux/debian/install-sysroot.ts b/build/linux/debian/install-sysroot.ts index acc71ce5ce7..943790eefcf 100644 --- a/build/linux/debian/install-sysroot.ts +++ b/build/linux/debian/install-sysroot.ts @@ -45,7 +45,8 @@ export async function getSysroot(arch: ArchString): Promise { throw new Error('Cannot retrieve sysroots.json. Stderr:\n' + result.stderr); } const sysrootInfo = require(sysrootDictLocation); - const sysrootDict: SysrootDictEntry = sysrootInfo[`bullseye_${arch}`]; + const sysrootArch = arch === 'armhf' ? 'bullseye_arm' : `bullseye_${arch}`; + const sysrootDict: SysrootDictEntry = sysrootInfo[sysrootArch]; const tarballFilename = sysrootDict['Tarball']; const tarballSha = sysrootDict['Sha1Sum']; const sysroot = path.join(tmpdir(), sysrootDict['SysrootDir']); From 82f6cbd6b5755f856951f4f011e41c0ed95990f0 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 2 Aug 2022 13:37:02 +0900 Subject: [PATCH 127/303] ci: update amd64 debian dependencies list --- build/linux/debian/dep-lists.js | 2 +- build/linux/debian/dep-lists.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/linux/debian/dep-lists.js b/build/linux/debian/dep-lists.js index 3db2ef1abff..6c304b07643 100644 --- a/build/linux/debian/dep-lists.js +++ b/build/linux/debian/dep-lists.js @@ -48,7 +48,7 @@ exports.referenceGeneratedDepsByArch = { 'libdrm2 (>= 2.4.38)', 'libexpat1 (>= 2.0.1)', 'libgbm1 (>= 8.1~0)', - 'libgcc1 (>= 1:3.0)', + 'libgcc-s1 (>= 3.0)', 'libglib2.0-0 (>= 2.16.0)', 'libglib2.0-0 (>= 2.39.4)', 'libgtk-3-0 (>= 3.9.10)', diff --git a/build/linux/debian/dep-lists.ts b/build/linux/debian/dep-lists.ts index 1e1b0e5b63f..85cd5e37a76 100644 --- a/build/linux/debian/dep-lists.ts +++ b/build/linux/debian/dep-lists.ts @@ -49,7 +49,7 @@ export const referenceGeneratedDepsByArch = { 'libdrm2 (>= 2.4.38)', 'libexpat1 (>= 2.0.1)', 'libgbm1 (>= 8.1~0)', - 'libgcc1 (>= 1:3.0)', + 'libgcc-s1 (>= 3.0)', 'libglib2.0-0 (>= 2.16.0)', 'libglib2.0-0 (>= 2.39.4)', 'libgtk-3-0 (>= 3.9.10)', From 0fffd354d3a5071aa68db59610e1d19f3f63c6ea Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 2 Aug 2022 07:18:44 +0200 Subject: [PATCH 128/303] Sandbox: Enable on Insiders by default (fix #156440) (#156733) * Sandbox: Enable on Insiders by default (fix #156440) * fix tests --- .../code/electron-sandbox/issue/issueReporterModel.ts | 2 ++ .../electron-sandbox/issue/testReporterModel.test.ts | 7 +++++++ src/vs/platform/issue/common/issue.ts | 1 + src/vs/platform/windows/electron-main/window.ts | 10 +++++++++- .../workbench/electron-sandbox/desktop.contribution.ts | 5 +++-- .../electron-sandbox/parts/dialogs/dialogHandler.ts | 5 +++-- .../services/issue/electron-sandbox/issueService.ts | 2 ++ 7 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/vs/code/electron-sandbox/issue/issueReporterModel.ts b/src/vs/code/electron-sandbox/issue/issueReporterModel.ts index b0cc736e46e..a58acca2f5a 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterModel.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterModel.ts @@ -34,6 +34,7 @@ export interface IssueReporterData { experimentInfo?: string; restrictedMode?: boolean; isUnsupported?: boolean; + isSandboxed?: boolean; } export class IssueReporterModel { @@ -77,6 +78,7 @@ ${this.getExtensionVersion()} VS Code version: ${this._data.versionInfo && this._data.versionInfo.vscodeVersion} OS version: ${this._data.versionInfo && this._data.versionInfo.os} Modes:${modes.length ? ' ' + modes.join(', ') : ''} +Sandboxed: ${this._data.isSandboxed ? 'Yes' : 'No'} ${this.getRemoteOSes()} ${this.getInfos()} `; diff --git a/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts b/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts index e2280b2338e..aa0fac7bf0d 100644 --- a/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts +++ b/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts @@ -34,6 +34,7 @@ undefined VS Code version: undefined OS version: undefined Modes: +Sandboxed: No Extensions: none `); @@ -65,6 +66,7 @@ undefined VS Code version: undefined OS version: undefined Modes: +Sandboxed: No
System Info @@ -109,6 +111,7 @@ undefined VS Code version: undefined OS version: undefined Modes: +Sandboxed: No
System Info @@ -164,6 +167,7 @@ undefined VS Code version: undefined OS version: undefined Modes: +Sandboxed: No
System Info @@ -221,6 +225,7 @@ undefined VS Code version: undefined OS version: undefined Modes: +Sandboxed: No Remote OS version: Linux x64 4.18.0
@@ -270,6 +275,7 @@ undefined VS Code version: undefined OS version: undefined Modes: +Sandboxed: No
System Info @@ -301,6 +307,7 @@ undefined VS Code version: undefined OS version: undefined Modes: Restricted, Unsupported +Sandboxed: No Extensions: none `); diff --git a/src/vs/platform/issue/common/issue.ts b/src/vs/platform/issue/common/issue.ts index cbc4d251934..1b28a7f7d09 100644 --- a/src/vs/platform/issue/common/issue.ts +++ b/src/vs/platform/issue/common/issue.ts @@ -60,6 +60,7 @@ export interface IssueReporterData extends WindowData { experiments?: string; restrictedMode: boolean; isUnsupported: boolean; + isSandboxed: boolean; // TODO@bpasero remove me once sandbox is final githubAccessToken: string; readonly issueTitle?: string; readonly issueBody?: string; diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts index c577f16bcee..61220857b74 100644 --- a/src/vs/platform/windows/electron-main/window.ts +++ b/src/vs/platform/windows/electron-main/window.ts @@ -42,6 +42,7 @@ import { Color } from 'vs/base/common/color'; import { IPolicyService } from 'vs/platform/policy/common/policy'; import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { revive } from 'vs/base/common/marshalling'; +import product from 'vs/platform/product/common/product'; export interface IWindowCreationOptions { state: IWindowState; @@ -189,6 +190,13 @@ export class CodeWindow extends Disposable implements ICodeWindow { const windowSettings = this.configurationService.getValue('window'); + let useSandbox = false; + if (typeof windowSettings?.experimental?.useSandbox === 'boolean') { + useSandbox = windowSettings.experimental.useSandbox; + } else { + useSandbox = typeof product.quality === 'string' && product.quality !== 'stable'; + } + const options: BrowserWindowConstructorOptions & { experimentalDarkMode: boolean } = { width: this.windowState.width, height: this.windowState.height, @@ -209,7 +217,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { // Enable experimental css highlight api https://chromestatus.com/feature/5436441440026624 // Refs https://github.com/microsoft/vscode/issues/140098 enableBlinkFeatures: 'HighlightAPI', - ...windowSettings?.experimental?.useSandbox ? + ...useSandbox ? // Sandbox { diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts index 6559a5f52b7..95e31623896 100644 --- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts +++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts @@ -26,6 +26,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { ShutdownReason } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { NativeWindow } from 'vs/workbench/electron-sandbox/window'; import { ModifierKeyEmitter } from 'vs/base/browser/dom'; +import product from 'vs/platform/product/common/product'; // Actions (function registerActions(): void { @@ -238,10 +239,10 @@ import { ModifierKeyEmitter } from 'vs/base/browser/dom'; 'description': localize('window.clickThroughInactive', "If enabled, clicking on an inactive window will both activate the window and trigger the element under the mouse if it is clickable. If disabled, clicking anywhere on an inactive window will activate it only and a second click is required on the element."), 'included': isMacintosh }, - 'window.experimental.useSandbox': { + 'window.experimental.useSandbox': { // TODO@bpasero remove me once sandbox is final type: 'boolean', description: localize('experimentalUseSandbox', "Experimental: When enabled, the window will have sandbox mode enabled via Electron API."), - default: false, + default: typeof product.quality === 'string' && product.quality !== 'stable', // disabled by default in stable for now 'scope': ConfigurationScope.APPLICATION, ignoreSync: true }, diff --git a/src/vs/workbench/electron-sandbox/parts/dialogs/dialogHandler.ts b/src/vs/workbench/electron-sandbox/parts/dialogs/dialogHandler.ts index a4728e73b7d..f63b75f2e8f 100644 --- a/src/vs/workbench/electron-sandbox/parts/dialogs/dialogHandler.ts +++ b/src/vs/workbench/electron-sandbox/parts/dialogs/dialogHandler.ts @@ -167,7 +167,7 @@ export class NativeDialogHandler implements IDialogHandler { const detailString = (useAgo: boolean): string => { return localize({ key: 'aboutDetail', comment: ['Electron, Chromium, Node.js and V8 are product names that need no translation'] }, - "Version: {0}\nCommit: {1}\nDate: {2}\nElectron: {3}\nChromium: {4}\nNode.js: {5}\nV8: {6}\nOS: {7}", + "Version: {0}\nCommit: {1}\nDate: {2}\nElectron: {3}\nChromium: {4}\nNode.js: {5}\nV8: {6}\nOS: {7}\nSandboxed: {8}", version, this.productService.commit || 'Unknown', this.productService.date ? `${this.productService.date}${useAgo ? ' (' + fromNow(new Date(this.productService.date), true) + ')' : ''}` : 'Unknown', @@ -175,7 +175,8 @@ export class NativeDialogHandler implements IDialogHandler { process.versions['chrome'], process.versions['node'], process.versions['v8'], - `${osProps.type} ${osProps.arch} ${osProps.release}${isLinuxSnap ? ' snap' : ''}` + `${osProps.type} ${osProps.arch} ${osProps.release}${isLinuxSnap ? ' snap' : ''}`, + process.sandboxed ? 'Yes' : 'No' // TODO@bpasero remove me once sandbox is final ); }; diff --git a/src/vs/workbench/services/issue/electron-sandbox/issueService.ts b/src/vs/workbench/services/issue/electron-sandbox/issueService.ts index a72466b917a..044560a8bac 100644 --- a/src/vs/workbench/services/issue/electron-sandbox/issueService.ts +++ b/src/vs/workbench/services/issue/electron-sandbox/issueService.ts @@ -21,6 +21,7 @@ import { IAuthenticationService } from 'vs/workbench/services/authentication/com import { registerMainProcessRemoteService } from 'vs/platform/ipc/electron-sandbox/services'; import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust'; import { IIntegrityService } from 'vs/workbench/services/integrity/common/integrity'; +import { process } from 'vs/base/parts/sandbox/electron-sandbox/globals'; export class WorkbenchIssueService implements IWorkbenchIssueService { declare readonly _serviceBrand: undefined; @@ -101,6 +102,7 @@ export class WorkbenchIssueService implements IWorkbenchIssueService { restrictedMode: !this.workspaceTrustManagementService.isWorkspaceTrusted(), isUnsupported, githubAccessToken, + isSandboxed: process.sandboxed }, dataOverrides); return this.issueService.openReporter(issueReporterData); } From 8bd41544eeff415daa09e404bf89b61cbc262a44 Mon Sep 17 00:00:00 2001 From: Ping <5123601+pingren@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:20:42 +0800 Subject: [PATCH 129/303] Fix isStandalone when PWA entering fullscreen (#156424) Fixes https://github.com/microsoft/vscode/issues/156347 --- src/vs/base/browser/browser.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/vs/base/browser/browser.ts b/src/vs/base/browser/browser.ts index 8191f523595..01db9eebc27 100644 --- a/src/vs/base/browser/browser.ts +++ b/src/vs/base/browser/browser.ts @@ -194,9 +194,16 @@ export const isAndroid = (userAgent.indexOf('Android') >= 0); let standalone = false; if (window.matchMedia) { - const matchMedia = window.matchMedia('(display-mode: standalone)'); - standalone = matchMedia.matches; - addMatchMediaChangeListener(matchMedia, ({ matches }) => { + const standaloneMatchMedia = window.matchMedia('(display-mode: standalone)'); + const fullScreenMatchMedia = window.matchMedia('(display-mode: fullscreen)'); + standalone = standaloneMatchMedia.matches; + addMatchMediaChangeListener(standaloneMatchMedia, ({ matches }) => { + // entering fullscreen would change standaloneMatchMedia.matches to false + // if standalone is true (running as PWA) and entering fullscreen, skip this change + if (standalone && fullScreenMatchMedia.matches) { + return; + } + // otherwise update standalone (browser to PWA or PWA to browser) standalone = matches; }); } From 2cf9834d650b356c4a314df22f7d07c4808e4353 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 2 Aug 2022 14:27:20 +0900 Subject: [PATCH 130/303] ci: update armhf debian dependencies list --- build/linux/debian/dep-lists.js | 3 ++- build/linux/debian/dep-lists.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/build/linux/debian/dep-lists.js b/build/linux/debian/dep-lists.js index 6c304b07643..c27672feda0 100644 --- a/build/linux/debian/dep-lists.js +++ b/build/linux/debian/dep-lists.js @@ -85,7 +85,8 @@ exports.referenceGeneratedDepsByArch = { 'libdrm2 (>= 2.4.38)', 'libexpat1 (>= 2.0.1)', 'libgbm1 (>= 8.1~0)', - 'libgcc1 (>= 1:3.0)', + 'libgcc-s1 (>= 3.0)', + 'libgcc-s1 (>= 3.5)', 'libgcc1 (>= 1:3.5)', 'libglib2.0-0 (>= 2.16.0)', 'libglib2.0-0 (>= 2.39.4)', diff --git a/build/linux/debian/dep-lists.ts b/build/linux/debian/dep-lists.ts index 85cd5e37a76..7d5e853063f 100644 --- a/build/linux/debian/dep-lists.ts +++ b/build/linux/debian/dep-lists.ts @@ -86,7 +86,8 @@ export const referenceGeneratedDepsByArch = { 'libdrm2 (>= 2.4.38)', 'libexpat1 (>= 2.0.1)', 'libgbm1 (>= 8.1~0)', - 'libgcc1 (>= 1:3.0)', + 'libgcc-s1 (>= 3.0)', + 'libgcc-s1 (>= 3.5)', 'libgcc1 (>= 1:3.5)', 'libglib2.0-0 (>= 2.16.0)', 'libglib2.0-0 (>= 2.39.4)', From 359d3d47428bc5df30e2f4503859ccdf381d6430 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 2 Aug 2022 07:54:38 +0200 Subject: [PATCH 131/303] :up: `playwright@1.24.2` (#156715) * :up: pw * distro --- package.json | 4 +- yarn.lock | 898 ++------------------------------------------------- 2 files changed, 32 insertions(+), 870 deletions(-) diff --git a/package.json b/package.json index 7b9d7fd9bc7..00194ba2031 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.70.0", - "distro": "81cca34eb9bc1d2c0a7d0124ce64b62c994ca9b7", + "distro": "ed2b6a548e515c964cfc30c99203906e96a1b92a", "author": { "name": "Microsoft Corporation" }, @@ -97,7 +97,7 @@ }, "devDependencies": { "7zip": "0.0.6", - "@playwright/test": "1.21.0", + "@playwright/test": "1.24.2", "@types/cookie": "^0.3.3", "@types/copy-webpack-plugin": "^6.0.3", "@types/cssnano": "^4.0.0", diff --git a/yarn.lock b/yarn.lock index 9121ca37524..fd16bf3002c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -95,13 +95,6 @@ events "^3.0.0" tslib "^2.2.0" -"@babel/code-frame@7.16.7", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== - dependencies: - "@babel/highlight" "^7.16.7" - "@babel/code-frame@^7.0.0": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -116,32 +109,6 @@ dependencies: "@babel/highlight" "^7.8.3" -"@babel/compat-data@^7.16.4": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" - integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== - -"@babel/core@7.16.12": - version "7.16.12" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.12.tgz#5edc53c1b71e54881315923ae2aedea2522bb784" - integrity sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.16.8" - "@babel/helper-compilation-targets" "^7.16.7" - "@babel/helper-module-transforms" "^7.16.7" - "@babel/helpers" "^7.16.7" - "@babel/parser" "^7.16.12" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.10" - "@babel/types" "^7.16.8" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.1.2" - semver "^6.3.0" - source-map "^0.5.0" - "@babel/core@^7.7.5": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.3.tgz#30b0ebb4dd1585de6923a0b4d179e0b9f5d82941" @@ -163,24 +130,6 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" - integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw== - dependencies: - "@babel/types" "^7.16.8" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/generator@^7.17.3": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.7.tgz#8da2599beb4a86194a3b24df6c085931d9ee45ad" - integrity sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w== - dependencies: - "@babel/types" "^7.17.0" - jsesc "^2.5.1" - source-map "^0.5.0" - "@babel/generator@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.3.tgz#0e22c005b0a94c1c74eafe19ef78ce53a4d45c03" @@ -191,65 +140,6 @@ lodash "^4.17.13" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" - integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-compilation-targets@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" - integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA== - dependencies: - "@babel/compat-data" "^7.16.4" - "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.17.5" - semver "^6.3.0" - -"@babel/helper-create-class-features-plugin@^7.16.10": - version "7.17.6" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz#3778c1ed09a7f3e65e6d6e0f6fbfcc53809d92c9" - integrity sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-member-expression-to-functions" "^7.16.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - -"@babel/helper-create-class-features-plugin@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.7.tgz#9c5b34b53a01f2097daf10678d65135c1b9f84ba" - integrity sha512-kIFozAvVfK05DM4EVQYKK+zteWvY85BFdGBRQBytRyY3y+6PX0DkDOn/CZ3lEuczCfrCxEzwt0YtP/87YPTWSw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-member-expression-to-functions" "^7.16.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - -"@babel/helper-environment-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" - integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-function-name@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" - integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== - dependencies: - "@babel/helper-get-function-arity" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/types" "^7.16.7" - "@babel/helper-function-name@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" @@ -259,13 +149,6 @@ "@babel/template" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-get-function-arity@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" - integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== - dependencies: - "@babel/types" "^7.16.7" - "@babel/helper-get-function-arity@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" @@ -273,85 +156,6 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-hoist-variables@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" - integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-member-expression-to-functions@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" - integrity sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-module-imports@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" - integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-module-transforms@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" - integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng== - dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-simple-access" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/helper-optimise-call-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" - integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-plugin-utils@7.16.7", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" - integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== - -"@babel/helper-replace-supers@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" - integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw== - dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-member-expression-to-functions" "^7.16.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/traverse" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/helper-simple-access@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" - integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" - integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-split-export-declaration@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" - integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== - dependencies: - "@babel/types" "^7.16.7" - "@babel/helper-split-export-declaration@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" @@ -364,25 +168,6 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== -"@babel/helper-validator-identifier@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" - integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== - -"@babel/helper-validator-option@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" - integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== - -"@babel/helpers@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc" - integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw== - dependencies: - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.7" - "@babel/types" "^7.16.7" - "@babel/helpers@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.3.tgz#382fbb0382ce7c4ce905945ab9641d688336ce85" @@ -401,15 +186,6 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/highlight@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.7.tgz#81a01d7d675046f0d96f82450d9d9578bdfd6b0b" - integrity sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - chalk "^2.0.0" - js-tokens "^4.0.0" - "@babel/highlight@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" @@ -419,217 +195,11 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.16.12", "@babel/parser@^7.17.3": - version "7.17.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.8.tgz#2817fb9d885dd8132ea0f8eb615a6388cca1c240" - integrity sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ== - -"@babel/parser@^7.16.7", "@babel/parser@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.8.tgz#61c243a3875f7d0b0962b0543a33ece6ff2f1f17" - integrity sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw== - "@babel/parser@^7.7.5", "@babel/parser@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.3.tgz#790874091d2001c9be6ec426c2eed47bc7679081" integrity sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ== -"@babel/plugin-proposal-class-properties@7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" - integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-proposal-dynamic-import@7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" - integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" - integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" - integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" - integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-proposal-numeric-separator@7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" - integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-optional-chaining@7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" - integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-proposal-private-methods@7.16.11": - version "7.16.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" - integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.10" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-proposal-private-property-in-object@7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz#b0b8cef543c2c3d57e59e2c611994861d46a3fce" - integrity sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-create-class-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-syntax-async-generators@7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-json-strings@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" - integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" - integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-modules-commonjs@7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe" - integrity sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA== - dependencies: - "@babel/helper-module-transforms" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-simple-access" "^7.16.7" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-typescript@^7.16.7": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz#591ce9b6b83504903fa9dd3652c357c2ba7a1ee0" - integrity sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-typescript" "^7.16.7" - -"@babel/preset-typescript@7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz#ab114d68bb2020afc069cd51b37ff98a046a70b9" - integrity sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-transform-typescript" "^7.16.7" - -"@babel/template@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" - integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/parser" "^7.16.7" - "@babel/types" "^7.16.7" - "@babel/template@^7.7.4", "@babel/template@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8" @@ -639,38 +209,6 @@ "@babel/parser" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/traverse@^7.16.10": - version "7.17.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" - integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.3" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.17.3" - "@babel/types" "^7.17.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.16.7": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.8.tgz#bab2f2b09a5fe8a8d9cad22cbfe3ba1d126fef9c" - integrity sha512-xe+H7JlvKsDQwXRsBhSnq1/+9c+LlQcCK3Tn/l5sbx02HYns/cn7ibp9+RV1sIUqu7hKg91NWsgHurO9dowITQ== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.16.8" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.16.8" - "@babel/types" "^7.16.8" - debug "^4.1.0" - globals "^11.1.0" - "@babel/traverse@^7.7.4", "@babel/traverse@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.3.tgz#a826215b011c9b4f73f3a893afbc05151358bf9a" @@ -686,22 +224,6 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" - integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - to-fast-properties "^2.0.0" - -"@babel/types@^7.17.0": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" - integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - to-fast-properties "^2.0.0" - "@babel/types@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" @@ -810,17 +332,6 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== -"@jest/types@^27.2.5", "@jest/types@^27.4.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.4.2.tgz#96536ebd34da6392c2b7c7737d693885b5dd44a5" - integrity sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - "@koa/cors@^3.3.0": version "3.3.0" resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.3.0.tgz#b4c1c7ee303b7c968c8727f2a638a74675b50bb2" @@ -1017,45 +528,13 @@ node-addon-api "^3.2.1" node-gyp-build "^4.3.0" -"@playwright/test@1.21.0": - version "1.21.0" - resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.21.0.tgz#611dd3f469c539e5be3a764395effa40735742a6" - integrity sha512-jvgN3ZeAG6rw85z4u9Rc4uyj6qIaYlq2xrOtS7J2+CDYhzKOttab9ix9ELcvBOCHuQ6wgTfxfJYdh6DRZmQ9hg== +"@playwright/test@1.24.2": + version "1.24.2" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.24.2.tgz#283ea8cc497f9742037458659bf235f4776cf1f0" + integrity sha512-Q4X224pRHw4Dtkk5PoNJplZCokLNvVbXD9wDQEMrHcEuvWpJWEQDeJ9gEwkZ3iCWSFSWBshIX177B231XW4wOQ== dependencies: - "@babel/code-frame" "7.16.7" - "@babel/core" "7.16.12" - "@babel/helper-plugin-utils" "7.16.7" - "@babel/plugin-proposal-class-properties" "7.16.7" - "@babel/plugin-proposal-dynamic-import" "7.16.7" - "@babel/plugin-proposal-export-namespace-from" "7.16.7" - "@babel/plugin-proposal-logical-assignment-operators" "7.16.7" - "@babel/plugin-proposal-nullish-coalescing-operator" "7.16.7" - "@babel/plugin-proposal-numeric-separator" "7.16.7" - "@babel/plugin-proposal-optional-chaining" "7.16.7" - "@babel/plugin-proposal-private-methods" "7.16.11" - "@babel/plugin-proposal-private-property-in-object" "7.16.7" - "@babel/plugin-syntax-async-generators" "7.8.4" - "@babel/plugin-syntax-json-strings" "7.8.3" - "@babel/plugin-syntax-object-rest-spread" "7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "7.8.3" - "@babel/plugin-transform-modules-commonjs" "7.16.8" - "@babel/preset-typescript" "7.16.7" - colors "1.4.0" - commander "8.3.0" - debug "4.3.3" - expect "27.2.5" - jest-matcher-utils "27.2.5" - json5 "2.2.1" - mime "3.0.0" - minimatch "3.0.4" - ms "2.1.3" - open "8.4.0" - pirates "4.0.4" - playwright-core "1.21.0" - rimraf "3.0.2" - source-map-support "0.4.18" - stack-utils "2.0.5" - yazl "2.5.1" + "@types/node" "*" + playwright-core "1.24.2" "@sindresorhus/is@^0.14.0": version "0.14.0" @@ -1233,25 +712,6 @@ dependencies: "@types/node" "*" -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== - -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== - dependencies: - "@types/istanbul-lib-report" "*" - "@types/json-schema@*": version "7.0.7" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" @@ -1349,11 +809,6 @@ resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== -"@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== - "@types/svgo@^1": version "1.3.6" resolved "https://registry.yarnpkg.com/@types/svgo/-/svgo-1.3.6.tgz#9db00a7ddf9b26ad2feb6b834bef1818677845e1" @@ -1442,18 +897,6 @@ resolved "https://registry.yarnpkg.com/@types/winreg/-/winreg-1.2.30.tgz#91d6710e536d345b9c9b017c574cf6a8da64c518" integrity sha1-kdZxDlNtNFucmwF8V0z2qNpkxRg= -"@types/yargs-parser@*": - version "20.2.1" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" - integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw== - -"@types/yargs@^16.0.0": - version "16.0.4" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" - integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== - dependencies: - "@types/yargs-parser" "*" - "@types/yauzl@^2.9.1": version "2.9.1" resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.1.tgz#d10f69f9f522eef3cf98e30afb684a1e1ec923af" @@ -2102,11 +1545,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - ansi-wrap@0.1.0, ansi-wrap@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" @@ -2395,13 +1833,6 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - bach@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" @@ -2653,17 +2084,6 @@ browserslist@^4.0.0, browserslist@^4.14.5: escalade "^3.1.1" node-releases "^1.1.71" -browserslist@^4.17.5: - version "4.19.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" - integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== - dependencies: - caniuse-lite "^1.0.30001286" - electron-to-chromium "^1.4.17" - escalade "^3.1.1" - node-releases "^2.0.1" - picocolors "^1.0.0" - buffer-alloc-unsafe@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" @@ -2879,11 +2299,6 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001219: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== -caniuse-lite@^1.0.30001286: - version "1.0.30001299" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001299.tgz#d753bf6444ed401eb503cbbe17aa3e1451b5a68c" - integrity sha512-iujN4+x7QzqA2NCSrS5VUy+4gLmRd4xv6vbBBsmfVqTx8bLAD8097euLqQgKxSVLvxjSDcvF1T/i9ocgnUFexw== - caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -3230,11 +2645,6 @@ colorette@^1.2.1, colorette@^1.2.2: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== -colors@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -3252,7 +2662,7 @@ command-line-args@^5.2.1: lodash.camelcase "^4.3.0" typical "^4.0.0" -commander@*, commander@8.3.0: +commander@*: version "8.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== @@ -3914,11 +3324,6 @@ defer-to-connect@^1.0.1: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -4016,11 +3421,6 @@ detect-node@^2.0.4: resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== -diff-sequences@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" - integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww== - diff@5.0.0, diff@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" @@ -4187,11 +3587,6 @@ electron-to-chromium@^1.3.723: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.737.tgz#196f2e9656f4f3c31930750e1899c091b72d36b5" integrity sha512-P/B84AgUSQXaum7a8m11HUsYL8tj9h/Pt5f7Hg7Ty6bm5DxlFq+e5+ouHUoNQMsKDJ7u4yGfI8mOErCmSH9wyg== -electron-to-chromium@^1.4.17: - version "1.4.45" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.45.tgz#cf1144091d6683cbd45a231954a745f02fb24598" - integrity sha512-czF9eYVuOmlY/vxyMQz2rGlNSjZpxNQYBe1gmQv7al171qOIhgyO9k7D5AKlgeTCSPKk+LHhj5ZyIdmEub9oNg== - electron@18.3.5: version "18.3.5" resolved "https://registry.yarnpkg.com/electron/-/electron-18.3.5.tgz#a589c2bfa3fe807914a055f54f665999329b739b" @@ -4431,11 +3826,6 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - eslint-plugin-header@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz#6ce512432d57675265fac47292b50d1eff11acd6" @@ -4754,18 +4144,6 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" -expect@27.2.5: - version "27.2.5" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.2.5.tgz#16154aaa60b4d9a5b0adacfea3e4d6178f4b93fd" - integrity sha512-ZrO0w7bo8BgGoP/bLz+HDCI+0Hfei9jUSZs5yI/Wyn9VkG9w8oJ7rHRgYj+MA7yqqFa0IwHA3flJzZtYugShJA== - dependencies: - "@jest/types" "^27.2.5" - ansi-styles "^5.0.0" - jest-get-type "^27.0.6" - jest-matcher-utils "^27.2.5" - jest-message-util "^27.2.5" - jest-regex-util "^27.0.6" - ext@^1.1.2: version "1.4.0" resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" @@ -4823,17 +4201,6 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extract-zip@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" - integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== - dependencies: - debug "^4.1.1" - get-stream "^5.1.0" - yauzl "^2.10.0" - optionalDependencies: - "@types/yauzl" "^2.9.1" - extract-zip@^1.0.3: version "1.7.0" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927" @@ -5332,11 +4699,6 @@ gensync@^1.0.0-beta.1: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" @@ -6137,14 +5499,6 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -https-proxy-agent@5.0.0, https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - https-proxy-agent@^2.2.3: version "2.2.4" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" @@ -6153,6 +5507,14 @@ https-proxy-agent@^2.2.3: agent-base "^4.3.0" debug "^3.1.0" +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -6515,11 +5877,6 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -6753,13 +6110,6 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - is@^3.1.0, is@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" @@ -6849,61 +6199,6 @@ istextorbinary@1.0.2: binaryextensions "~1.0.0" textextensions "~1.0.0" -jest-diff@^27.2.5, jest-diff@^27.4.6: - version "27.4.6" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.4.6.tgz#93815774d2012a2cbb6cf23f84d48c7a2618f98d" - integrity sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w== - dependencies: - chalk "^4.0.0" - diff-sequences "^27.4.0" - jest-get-type "^27.4.0" - pretty-format "^27.4.6" - -jest-get-type@^27.0.6, jest-get-type@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" - integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ== - -jest-matcher-utils@27.2.5: - version "27.2.5" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.2.5.tgz#4684faaa8eb32bf15e6edaead6834031897e2980" - integrity sha512-qNR/kh6bz0Dyv3m68Ck2g1fLW5KlSOUNcFQh87VXHZwWc/gY6XwnKofx76Qytz3x5LDWT09/2+yXndTkaG4aWg== - dependencies: - chalk "^4.0.0" - jest-diff "^27.2.5" - jest-get-type "^27.0.6" - pretty-format "^27.2.5" - -jest-matcher-utils@^27.2.5: - version "27.4.6" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz#53ca7f7b58170638590e946f5363b988775509b8" - integrity sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA== - dependencies: - chalk "^4.0.0" - jest-diff "^27.4.6" - jest-get-type "^27.4.0" - pretty-format "^27.4.6" - -jest-message-util@^27.2.5: - version "27.4.6" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.4.6.tgz#9fdde41a33820ded3127465e1a5896061524da31" - integrity sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.4.2" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.4" - micromatch "^4.0.4" - pretty-format "^27.4.6" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-regex-util@^27.0.6: - version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.4.0.tgz#e4c45b52653128843d07ad94aec34393ea14fbca" - integrity sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg== - jest-worker@^27.0.2: version "27.0.6" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.6.tgz#a5fdb1e14ad34eb228cfe162d9f729cdbfa28aed" @@ -6913,11 +6208,6 @@ jest-worker@^27.0.2: merge-stream "^2.0.0" supports-color "^8.0.0" -jpeg-js@0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b" - integrity sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q== - js-beautify@^1.8.9: version "1.8.9" resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.8.9.tgz#08e3c05ead3ecfbd4f512c3895b1cda76c87d523" @@ -6999,11 +6289,6 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== - json5@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" @@ -7679,11 +6964,6 @@ mime-types@^2.1.27: dependencies: mime-db "1.48.0" -mime@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" - integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== - mime@^1.3.4: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" @@ -7724,7 +7004,7 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.3, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -8105,11 +7385,6 @@ node-releases@^1.1.71: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== -node-releases@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" - integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== - node.extend@~1.1.2: version "1.1.8" resolved "https://registry.yarnpkg.com/node.extend/-/node.extend-1.1.8.tgz#0aab3e63789f4e6d68b42bc00073ad1881243cf0" @@ -8387,15 +7662,6 @@ only@~0.0.2: resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= -open@8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - opn@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/opn/-/opn-6.0.0.tgz#3c5b0db676d5f97da1233d1ed42d182bc5a27d2d" @@ -8817,18 +8083,6 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= -pirates@4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.4.tgz#07df81e61028e402735cdd49db701e4885b4e6e6" - integrity sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw== - -pixelmatch@5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-5.2.1.tgz#9e4e4f4aa59648208a31310306a5bed5522b0d65" - integrity sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ== - dependencies: - pngjs "^4.0.1" - pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" @@ -8843,35 +8097,16 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -playwright-core@1.21.0: - version "1.21.0" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.21.0.tgz#1b68e87f4fd2fc5653def1e61ccdef6845c604a6" - integrity sha512-yDGVs9qaaW6WiefgR7wH1CGt9D6D/X4U3jNpIzH0FjjrrWLCOYQo78Tu3SkW8X+/kWlBpj49iWf3QNSxhYc12Q== - dependencies: - colors "1.4.0" - commander "8.3.0" - debug "4.3.3" - extract-zip "2.0.1" - https-proxy-agent "5.0.0" - jpeg-js "0.4.3" - mime "3.0.0" - pixelmatch "5.2.1" - pngjs "6.0.0" - progress "2.0.3" - proper-lockfile "4.1.2" - proxy-from-env "1.1.0" - rimraf "3.0.2" - socks-proxy-agent "6.1.1" - stack-utils "2.0.5" - ws "8.4.2" - yauzl "2.10.0" - yazl "2.5.1" - playwright-core@1.23.4: version "1.23.4" resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.23.4.tgz#e8a45e549faf6bfad24a0e9998e451979514d41e" integrity sha512-h5V2yw7d8xIwotjyNrkLF13nV9RiiZLHdXeHo+nVJIYGVlZ8U2qV0pMxNJKNTvfQVT0N8/A4CW6/4EW2cOcTiA== +playwright-core@1.24.2: + version "1.24.2" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.24.2.tgz#47bc5adf3dcfcc297a5a7a332449c9009987db26" + integrity sha512-zfAoDoPY/0sDLsgSgLZwWmSCevIg1ym7CppBwllguVBNiHeixZkc1AdMuYUPZC6AdEYc4CxWEyLMBTw2YcmRrA== + playwright@^1.23.1: version "1.23.4" resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.23.4.tgz#a9641a8d523fafdc58a5a2b59efe3496dec49c8d" @@ -8908,16 +8143,6 @@ plugin-error@^1.0.0, plugin-error@^1.0.1: arr-union "^3.1.0" extend-shallow "^3.0.2" -pngjs@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-6.0.0.tgz#ca9e5d2aa48db0228a52c419c3308e87720da821" - integrity sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg== - -pngjs@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-4.0.1.tgz#f803869bb2fc1bfe1bf99aa4ec21c108117cfdbe" - integrity sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg== - posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -9290,15 +8515,6 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -pretty-format@^27.2.5, pretty-format@^27.4.6: - version "27.4.6" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.4.6.tgz#1b784d2f53c68db31797b2348fa39b49e31846b7" - integrity sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g== - dependencies: - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^17.0.1" - pretty-hrtime@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" @@ -9314,36 +8530,27 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -progress@2.0.3, progress@^2.0.0, progress@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74= +progress@^2.0.0, progress@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= -proper-lockfile@4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" - integrity sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA== - dependencies: - graceful-fs "^4.2.4" - retry "^0.12.0" - signal-exit "^3.0.2" - proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= -proxy-from-env@1.1.0, proxy-from-env@^1.1.0: +proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== @@ -9499,11 +8706,6 @@ rcedit@^1.1.0: resolved "https://registry.yarnpkg.com/rcedit/-/rcedit-1.1.0.tgz#ae21c28d4efdd78e95fcab7309a5dd084920b16a" integrity sha512-JkXJ0IrUcdupLoIx6gE4YcFaMVSGtu7kQf4NJoDJUnfBZGuATmJ2Yal2v55KTltp+WV8dGr7A0RtOzx6jmtM6Q== -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -9828,11 +9030,6 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -9862,7 +9059,7 @@ rimraf@2.6.3, rimraf@~2.6.2: dependencies: glob "^7.1.3" -rimraf@3.0.2, rimraf@^3.0.2: +rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -10224,15 +9421,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -socks-proxy-agent@6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz#e664e8f1aaf4e1fb3df945f09e3d94f911137f87" - integrity sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew== - dependencies: - agent-base "^6.0.2" - debug "^4.3.1" - socks "^2.6.1" - socks-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" @@ -10242,7 +9430,7 @@ socks-proxy-agent@^5.0.0: debug "4" socks "^2.3.3" -socks@^2.3.3, socks@^2.6.1: +socks@^2.3.3: version "2.6.1" resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== @@ -10274,13 +9462,6 @@ source-map-resolve@^0.6.0: atob "^2.1.2" decode-uri-component "^0.2.0" -source-map-support@0.4.18: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== - dependencies: - source-map "^0.5.6" - source-map-support@^0.3.2: version "0.3.3" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.3.3.tgz#34900977d5ba3f07c7757ee72e73bb1a9b53754f" @@ -10441,13 +9622,6 @@ stack-trace@0.0.10: resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= -stack-utils@2.0.5, stack-utils@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" - integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== - dependencies: - escape-string-regexp "^2.0.0" - static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -12014,11 +11188,6 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" -ws@8.4.2: - version "8.4.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.2.tgz#18e749868d8439f2268368829042894b6907aa0b" - integrity sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA== - ws@^7.2.0: version "7.4.6" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" @@ -12247,7 +11416,7 @@ yaserver@^0.2.0: resolved "https://registry.yarnpkg.com/yaserver/-/yaserver-0.2.0.tgz#56393027dc13f3c1bb89d20e0bd17269aa927802" integrity sha512-onsELrl7Y42M4P3T9R0N/ZJNJRu4cGwzhDyOWIFRMJvPUIrGKInYGh+DJBefrbr1qoyDu7DSCLl9BL5hSSVfDA== -yauzl@2.10.0, yauzl@^2.10.0, yauzl@^2.4.2, yauzl@^2.9.2: +yauzl@^2.10.0, yauzl@^2.4.2, yauzl@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= @@ -12263,13 +11432,6 @@ yauzl@^2.2.1: buffer-crc32 "~0.2.3" fd-slicer "~1.0.1" -yazl@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" - integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== - dependencies: - buffer-crc32 "~0.2.3" - yazl@^2.2.1, yazl@^2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.4.3.tgz#ec26e5cc87d5601b9df8432dbdd3cd2e5173a071" From df9ecf06cdc2e6b3ec104a1c95454d8cc1fe7052 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 1 Aug 2022 22:57:14 -0700 Subject: [PATCH 132/303] Build VS Code using latest TS version (#156819) Pick up latest TS for building VS Code --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 00194ba2031..8e639c8576c 100644 --- a/package.json +++ b/package.json @@ -200,7 +200,7 @@ "style-loader": "^1.3.0", "ts-loader": "^9.2.7", "tsec": "0.1.4", - "typescript": "^4.8.0-dev.20220719", + "typescript": "^4.8.0-dev.20220801", "typescript-formatter": "7.1.0", "underscore": "^1.12.1", "util": "^0.12.4", diff --git a/yarn.lock b/yarn.lock index fd16bf3002c..22cc8f649b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10443,10 +10443,10 @@ typescript@^2.6.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4" integrity sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q= -typescript@^4.8.0-dev.20220719: - version "4.8.0-dev.20220719" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.0-dev.20220719.tgz#5481fe69ef18473d0da5ed23512d5754a2f998ef" - integrity sha512-IAZp6IDszN9iZi7R5LOqR5j0Ffy737RVQF7IefH1hNtFE+HiTjfsEYtWD2M0X/2feOCESZEKaa+GmuOVFuFhUQ== +typescript@^4.8.0-dev.20220801: + version "4.8.0-dev.20220801" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.0-dev.20220801.tgz#547ae7fea513fde4058f6715afa673b388e73129" + integrity sha512-idPY4geCSbS6npeHcr4m4nITkxz0/w4LmLSAao0UGvaWoHGFfkThJZhCXWFAx9TxQV1zZUWgXmngJBjfTm3otw== typical@^4.0.0: version "4.0.0" From 0ea1cfd5d252245aef711b552966eb567f4a5653 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 2 Aug 2022 08:45:25 +0200 Subject: [PATCH 133/303] :up: distro (#156863) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8e639c8576c..eb739d87531 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.70.0", - "distro": "ed2b6a548e515c964cfc30c99203906e96a1b92a", + "distro": "7dc7a14b0f0031128c799f96c856bd3290c3ebee", "author": { "name": "Microsoft Corporation" }, From 6e935e3f3693a559f102ef4be19f13a2ec27532b Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Tue, 2 Aug 2022 00:27:53 -0700 Subject: [PATCH 134/303] Present Continue Edit Session options in sorted order (#156860) --- .../contrib/editSessions/browser/editSessions.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts index 3d96c44b96f..abcadc9ca07 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -539,7 +539,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo )); } - return items; + return items.sort((item1, item2) => item1.label.localeCompare(item2.label)); } } From fded5726068f893417695e2836acd0b6a0e12aa8 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 2 Aug 2022 00:28:37 -0700 Subject: [PATCH 135/303] Re #155587. Move undo/redo to unit tests. (#156849) --- .../src/singlefolder-tests/notebook.test.ts | 54 ------------- .../browser/contrib/notebookUndoRedo.test.ts | 78 ++++++++++++++++++- 2 files changed, 76 insertions(+), 56 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts index a5c21988214..126eabe5661 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts @@ -178,25 +178,6 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { await saveAllFilesAndCloseAll(); }); - test.skip('correct cell selection on undo/redo of cell creation', async function () { - const notebook = await openRandomNotebookDocument(); - await vscode.window.showNotebookDocument(notebook); - await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow'); - await vscode.commands.executeCommand('undo'); - const selectionUndo = [...vscode.window.activeNotebookEditor!.selections]; - await vscode.commands.executeCommand('redo'); - const selectionRedo = vscode.window.activeNotebookEditor!.selections; - - // On undo, the selected cell must be the upper cell, ie the first one - assert.strictEqual(selectionUndo.length, 1); - assert.strictEqual(selectionUndo[0].start, 0); - assert.strictEqual(selectionUndo[0].end, 1); - // On redo, the selected cell must be the new cell, ie the second one - assert.strictEqual(selectionRedo.length, 1); - assert.strictEqual(selectionRedo[0].start, 1); - assert.strictEqual(selectionRedo[0].end, 2); - }); - test.skip('editor editing event', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/152145 const notebook = await openRandomNotebookDocument(); const editor = await vscode.window.showNotebookDocument(notebook); @@ -282,41 +263,6 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { assert.ok(cell.metadata.extraCellMetadata, `Test cell metdata not found`); }); - test('edit API batch edits undo/redo', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/155825 - const notebook = await openRandomNotebookDocument(); - const editor = await vscode.window.showNotebookDocument(notebook); - - const version = editor.notebook.version; - const edit = new vscode.WorkspaceEdit(); - const cellEdit = vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(1, 1), [{ kind: vscode.NotebookCellKind.Code, languageId: 'javascript', value: 'test 2', outputs: [], metadata: undefined }]); - const metadataEdit = vscode.NotebookEdit.updateCellMetadata(0, { inputCollapsed: false }); - edit.set(notebook.uri, [cellEdit, metadataEdit]); - const success = await vscode.workspace.applyEdit(edit); - assert.equal(success, true); - - assert.strictEqual(editor.notebook.cellCount, 3); - assert.strictEqual(editor.notebook.cellAt(0)?.metadata.inputCollapsed, false); - assert.strictEqual(version + 1, editor.notebook.version); - - await vscode.commands.executeCommand('undo'); - assert.strictEqual(version + 2, editor.notebook.version); - assert.strictEqual(editor.notebook.cellAt(0)?.metadata.inputCollapsed, undefined); - assert.strictEqual(editor.notebook.cellCount, 2); - }); - - // #126371 - test.skip('#98841, initialzation should not emit cell change events.', async function () { - let count = 0; - - testDisposables.push(vscode.workspace.onDidChangeNotebookDocument(() => { - count++; - })); - - const notebook = await openRandomNotebookDocument(); - await vscode.window.showNotebookDocument(notebook); - assert.strictEqual(count, 0); - }); - test('notebook open', async function () { const notebook = await openRandomNotebookDocument(); const editor = await vscode.window.showNotebookDocument(notebook); diff --git a/src/vs/workbench/contrib/notebook/test/browser/contrib/notebookUndoRedo.test.ts b/src/vs/workbench/contrib/notebook/test/browser/contrib/notebookUndoRedo.test.ts index 00397f1f1e3..b40b1e63633 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/contrib/notebookUndoRedo.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/contrib/notebookUndoRedo.test.ts @@ -5,8 +5,8 @@ import * as assert from 'assert'; import { ILanguageService } from 'vs/editor/common/languages/language'; -import { CellEditType, CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon'; -import { TestCell, withTestNotebook } from 'vs/workbench/contrib/notebook/test/browser/testNotebookEditor'; +import { CellEditType, CellKind, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { createNotebookCellList, TestCell, withTestNotebook } from 'vs/workbench/contrib/notebook/test/browser/testNotebookEditor'; suite('Notebook Undo/Redo', () => { test('Basics', async function () { @@ -125,4 +125,78 @@ suite('Notebook Undo/Redo', () => { } ); }); + + test('Focus/selection update', async function () { + await withTestNotebook( + [ + ['# header 1', 'markdown', CellKind.Markup, [], {}], + ['body', 'markdown', CellKind.Markup, [], {}], + ], + async (editor, viewModel, accessor) => { + const languageService = accessor.get(ILanguageService); + const cellList = createNotebookCellList(accessor); + cellList.attachViewModel(viewModel); + cellList.setFocus([1]); + + editor.textModel.applyEdits([{ + editType: CellEditType.Replace, index: 2, count: 0, cells: [ + new TestCell(viewModel.viewType, 3, '# header 2', 'markdown', CellKind.Code, [], languageService) + ] + }], true, { focus: { start: 1, end: 2 }, selections: [{ start: 1, end: 2 }], kind: SelectionStateType.Index }, () => { + return { + focus: { start: 2, end: 3 }, selections: [{ start: 2, end: 3 }], kind: SelectionStateType.Index + }; + }, undefined, true); + assert.strictEqual(viewModel.length, 3); + assert.strictEqual(viewModel.getVersionId(), 1); + assert.deepStrictEqual(cellList.getFocus(), [2]); + assert.deepStrictEqual(cellList.getSelection(), [2]); + + await viewModel.undo(); + assert.strictEqual(viewModel.length, 2); + assert.strictEqual(viewModel.getVersionId(), 2); + assert.deepStrictEqual(cellList.getFocus(), [1]); + assert.deepStrictEqual(cellList.getSelection(), [1]); + + await viewModel.redo(); + assert.strictEqual(viewModel.length, 3); + assert.strictEqual(viewModel.getVersionId(), 3); + assert.deepStrictEqual(cellList.getFocus(), [2]); + assert.deepStrictEqual(cellList.getSelection(), [2]); + } + ); + }); + + test('Batch edits', async function () { + await withTestNotebook( + [ + ['# header 1', 'markdown', CellKind.Markup, [], {}], + ['body', 'markdown', CellKind.Markup, [], {}], + ], + async (editor, viewModel, accessor) => { + const languageService = accessor.get(ILanguageService); + + editor.textModel.applyEdits([{ + editType: CellEditType.Replace, index: 2, count: 0, cells: [ + new TestCell(viewModel.viewType, 3, '# header 2', 'markdown', CellKind.Code, [], languageService) + ] + }, { + editType: CellEditType.Metadata, index: 0, metadata: { inputCollapsed: false } + }], true, undefined, () => undefined, undefined, true); + assert.strictEqual(viewModel.getVersionId(), 1); + assert.deepStrictEqual(viewModel.cellAt(0)?.metadata, { inputCollapsed: false }); + + await viewModel.undo(); + assert.strictEqual(viewModel.length, 2); + assert.strictEqual(viewModel.getVersionId(), 2); + assert.deepStrictEqual(viewModel.cellAt(0)?.metadata, {}); + + await viewModel.redo(); + assert.strictEqual(viewModel.length, 3); + assert.strictEqual(viewModel.getVersionId(), 3); + assert.deepStrictEqual(viewModel.cellAt(0)?.metadata, { inputCollapsed: false }); + + } + ); + }); }); From 35ab68698ae4cdb37ed9eeef2e16d78d0aab88c0 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 2 Aug 2022 10:46:55 +0200 Subject: [PATCH 136/303] Sticky scroll should not cover scrollbar and minimap (fixes #156570) (#156869) * Sticks namespace {} to the sticky scroll widget too. Fixes https://github.com/microsoft/vscode/issues/156611. * No longer need the verification model.getLineContent(start) !== '' with the latest changes. Fixes https://github.com/microsoft/vscode/issues/156616. * Set the width of the sticky scroll so the widget is not over the minimap. Works on resize too. Only for minimap placed on the right. * Sticky scroll should not take into account the vertical scrollbar (takes into account the minimap side as well). Fixes https://github.com/microsoft/vscode/issues/156570. --- .../stickyScroll/browser/stickyScroll.ts | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index b394b835466..5100c6fac2c 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -64,12 +64,18 @@ class StickyScrollController extends Disposable implements IEditorContribution { this._sessionStore.add(this._editor.onDidScrollChange(() => this._update(false))); this._sessionStore.add(this._editor.onDidChangeHiddenAreas(() => this._update(true))); this._sessionStore.add(this._editor.onDidChangeModelTokens((e) => this._onTokensChange(e))); + this._sessionStore.add(this._editor.onDidLayoutChange(() => this._onDidResize())); this._sessionStore.add(this._editor.onDidChangeModelContent(() => this._updateSoon.schedule())); this._sessionStore.add(this._languageFeaturesService.documentSymbolProvider.onDidChange(() => this._update(true))); this._update(true); } } + private _onDidResize() { + const width = this._editor.getLayoutInfo().width - this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth - this._editor.getLayoutInfo().verticalScrollbarWidth; + this.stickyScrollWidget.getDomNode().style.width = width + 'px'; + } + private _needsUpdate(event: IModelTokensChangedEvent) { const stickyLineNumbers = this.stickyScrollWidget.getCurrentLines(); for (const stickyLineNumber of stickyLineNumbers) { @@ -199,7 +205,7 @@ class StickyScrollController extends Disposable implements IEditorContribution { for (const [index, arr] of this._ranges.entries()) { const [start, end, depth] = arr; - if (end - start > 0 && model.getLineContent(start) !== '') { + if (end - start > 0) { const topOfElementAtDepth = (depth - 1) * lineHeight; const bottomOfElementAtDepth = depth * lineHeight; @@ -252,6 +258,8 @@ class StickyScrollCodeLine { const viewModel = this._editor._getViewModel(); const viewLineNumber = viewModel.coordinatesConverter.convertModelPositionToViewPosition(new Position(this._lineNumber, 1)).lineNumber; const lineRenderingData = viewModel.getViewLineRenderingData(viewLineNumber); + const width = this._editor.getLayoutInfo().width - this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth - this._editor.getLayoutInfo().verticalScrollbarWidth; + const minimapSide = this._editor.getOption(EditorOption.minimap).side; let actualInlineDecorations: LineDecoration[]; try { @@ -283,7 +291,11 @@ class StickyScrollCodeLine { lineHTMLNode.innerHTML = newLine as string; const lineNumberHTMLNode = document.createElement('span'); - lineNumberHTMLNode.style.width = this._editor.getLayoutInfo().contentLeft.toString() + 'px'; + if (minimapSide === 'left') { + lineNumberHTMLNode.style.width = this._editor.getLayoutInfo().contentLeft - this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth + 'px'; + } else if (minimapSide === 'right') { + lineNumberHTMLNode.style.width = this._editor.getLayoutInfo().contentLeft.toString() + 'px'; + } lineNumberHTMLNode.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; lineNumberHTMLNode.style.color = 'var(--vscode-editorLineNumber-foreground)'; lineNumberHTMLNode.style.display = 'inline-block'; @@ -291,7 +303,11 @@ class StickyScrollCodeLine { const innerLineNumberHTML = document.createElement('span'); innerLineNumberHTML.innerText = this._lineNumber.toString(); - innerLineNumberHTML.style.paddingLeft = this._editor.getLayoutInfo().lineNumbersLeft.toString() + 'px'; + if (minimapSide === 'left') { + innerLineNumberHTML.style.paddingLeft = this._editor.getLayoutInfo().lineNumbersLeft - this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth + 'px'; + } else if (minimapSide === 'right') { + innerLineNumberHTML.style.paddingLeft = this._editor.getLayoutInfo().lineNumbersLeft.toString() + 'px'; + } innerLineNumberHTML.style.width = this._editor.getLayoutInfo().lineNumbersWidth.toString() + 'px'; innerLineNumberHTML.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; innerLineNumberHTML.style.textAlign = 'right'; @@ -332,7 +348,7 @@ class StickyScrollCodeLine { root.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; root.style.overflow = 'hidden'; root.style.whiteSpace = 'nowrap'; - root.style.width = '100%'; + root.style.width = width + 'px'; root.style.lineHeight = this._editor.getOption(EditorOption.lineHeight).toString() + 'px'; root.style.height = this._editor.getOption(EditorOption.lineHeight).toString() + 'px'; @@ -340,7 +356,7 @@ class StickyScrollCodeLine { if (this._relativePosition) { root.style.position = 'relative'; root.style.top = this._relativePosition + 'px'; - root.style.width = '100%'; + root.style.width = width + 'px'; } return root; } @@ -353,8 +369,10 @@ class StickyScrollWidget implements IOverlayWidget { constructor(public readonly _editor: ICodeEditor) { this.rootDomNode = document.createElement('div'); - this.rootDomNode.style.width = '100%'; + const width = this._editor.getLayoutInfo().width - this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth - this._editor.getLayoutInfo().verticalScrollbarWidth; + this.rootDomNode.style.width = width + 'px'; this.rootDomNode.style.boxShadow = `var(--vscode-scrollbar-shadow) 0 6px 6px -6px`; + this.rootDomNode.style.overflow = 'hidden'; } get codeLineCount() { @@ -394,6 +412,12 @@ class StickyScrollWidget implements IOverlayWidget { getDomNode(): HTMLElement { this.rootDomNode.style.zIndex = '2'; this.rootDomNode.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; + const minimapSide = this._editor.getOption(EditorOption.minimap).side; + if (minimapSide === 'left') { + this.rootDomNode.style.marginLeft = this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth + 'px'; + } else if (minimapSide === 'right') { + this.rootDomNode.style.marginLeft = '0px'; + } return this.rootDomNode; } From dac86fc1978d67afe461e2b6b4be47048ce14569 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 2 Aug 2022 12:39:20 +0200 Subject: [PATCH 137/303] Fix #156696 (#156866) --- .../node/extensionDownloader.ts | 2 +- .../node/extensionManagementService.ts | 50 +++++++++++++------ 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/vs/platform/extensionManagement/node/extensionDownloader.ts b/src/vs/platform/extensionManagement/node/extensionDownloader.ts index c37857b3dce..3077d4586f8 100644 --- a/src/vs/platform/extensionManagement/node/extensionDownloader.ts +++ b/src/vs/platform/extensionManagement/node/extensionDownloader.ts @@ -20,7 +20,7 @@ import { ILogService } from 'vs/platform/log/common/log'; export class ExtensionsDownloader extends Disposable { - private readonly extensionsDownloadDir: URI; + readonly extensionsDownloadDir: URI; private readonly cache: number; private readonly cleanUpPromise: Promise; diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index a5f367b4124..ece1564b77f 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -71,7 +71,7 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi @IExtensionGalleryService galleryService: IExtensionGalleryService, @ITelemetryService telemetryService: ITelemetryService, @ILogService logService: ILogService, - @INativeEnvironmentService private readonly environmentService: INativeEnvironmentService, + @INativeEnvironmentService environmentService: INativeEnvironmentService, @IExtensionsScannerService private readonly extensionsScannerService: IExtensionsScannerService, @IExtensionsProfileScannerService private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, @IDownloadService private downloadService: IDownloadService, @@ -107,7 +107,7 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi async zip(extension: ILocalExtension): Promise { this.logService.trace('ExtensionManagementService#zip', extension.identifier.id); const files = await this.collectFiles(extension); - const location = await zip(joinPath(this.environmentService.tmpDir, generateUuid()).fsPath, files); + const location = await zip(joinPath(this.extensionsDownloader.extensionsDownloadDir, generateUuid()).fsPath, files); return URI.file(location); } @@ -118,9 +118,13 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi } async getManifest(vsix: URI): Promise { - const downloadLocation = await this.downloadVsix(vsix); - const zipPath = path.resolve(downloadLocation.fsPath); - return getManifest(zipPath); + const { location, cleanup } = await this.downloadVsix(vsix); + const zipPath = path.resolve(location.fsPath); + try { + return await getManifest(zipPath); + } finally { + await cleanup(); + } } getInstalled(type?: ExtensionType, profileLocation?: URI): Promise { @@ -134,13 +138,18 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi async install(vsix: URI, options: ServerInstallVSIXOptions = {}): Promise { this.logService.trace('ExtensionManagementService#install', vsix.toString()); - const downloadLocation = await this.downloadVsix(vsix); - const manifest = await getManifest(path.resolve(downloadLocation.fsPath)); - if (manifest.engines && manifest.engines.vscode && !isEngineValid(manifest.engines.vscode, this.productService.version, this.productService.date)) { - throw new Error(nls.localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", getGalleryExtensionId(manifest.publisher, manifest.name), this.productService.version)); - } + const { location, cleanup } = await this.downloadVsix(vsix); - return this.installExtension(manifest, downloadLocation, options); + try { + const manifest = await getManifest(path.resolve(location.fsPath)); + if (manifest.engines && manifest.engines.vscode && !isEngineValid(manifest.engines.vscode, this.productService.version, this.productService.date)) { + throw new Error(nls.localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", getGalleryExtensionId(manifest.publisher, manifest.name), this.productService.version)); + } + + return await this.installExtension(manifest, location, options); + } finally { + await cleanup(); + } } getMetadata(extension: ILocalExtension): Promise { @@ -169,13 +178,22 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi return this.extensionsScanner.cleanUp(removeOutdated); } - private async downloadVsix(vsix: URI): Promise { + private async downloadVsix(vsix: URI): Promise<{ location: URI; cleanup: () => Promise }> { if (vsix.scheme === Schemas.file) { - return vsix; + return { location: vsix, async cleanup() { } }; } - const downloadedLocation = joinPath(this.environmentService.tmpDir, generateUuid()); - await this.downloadService.download(vsix, downloadedLocation); - return downloadedLocation; + this.logService.trace('Downloading extension from', vsix.toString()); + const location = joinPath(this.extensionsDownloader.extensionsDownloadDir, generateUuid()); + await this.downloadService.download(vsix, location); + this.logService.info('Downloaded extension to', location.toString()); + const cleanup = async () => { + try { + await this.fileService.del(location); + } catch (error) { + this.logService.error(error); + } + }; + return { location, cleanup }; } protected doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask { From f7aa4b1596317be6e5b40bb574b88b96fb917401 Mon Sep 17 00:00:00 2001 From: John Murray Date: Tue, 2 Aug 2022 12:09:37 +0100 Subject: [PATCH 138/303] Correct initial window size on Windows secondary display with different scaling factor (#146499) (#155589) * Correct initial window size on Windows secondary display with different scaling factor (#146499) * :lipstick: Co-authored-by: Benjamin Pasero Co-authored-by: Benjamin Pasero --- src/vs/platform/windows/electron-main/window.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts index cce402a89ba..c1e6bb0b70b 100644 --- a/src/vs/platform/windows/electron-main/window.ts +++ b/src/vs/platform/windows/electron-main/window.ts @@ -346,17 +346,18 @@ export class CodeWindow extends Disposable implements ICodeWindow { // to open the window has a larger resolution than the primary display, the window will not size // correctly unless we set the bounds again (https://github.com/microsoft/vscode/issues/74872) // + // Extended to cover Windows as well as Mac (https://github.com/microsoft/vscode/issues/146499) + // // However, when running with native tabs with multiple windows we cannot use this workaround // because there is a potential that the new window will be added as native tab instead of being // a window on its own. In that case calling setBounds() would cause https://github.com/microsoft/vscode/issues/75830 - if (isMacintosh && hasMultipleDisplays && (!useNativeTabs || BrowserWindow.getAllWindows().length === 1)) { + if ((isMacintosh || isWindows) && hasMultipleDisplays && (!useNativeTabs || BrowserWindow.getAllWindows().length === 1)) { if ([this.windowState.width, this.windowState.height, this.windowState.x, this.windowState.y].every(value => typeof value === 'number')) { - const ensuredWindowState = this.windowState as Required; this._win.setBounds({ - width: ensuredWindowState.width, - height: ensuredWindowState.height, - x: ensuredWindowState.x, - y: ensuredWindowState.y + width: this.windowState.width, + height: this.windowState.height, + x: this.windowState.x, + y: this.windowState.y }); } } From b4cc8ddac26b24aa2d9c60a85ae741a490d02e16 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 2 Aug 2022 15:14:08 +0200 Subject: [PATCH 139/303] debt - do not run long running ops in web on shutdown (#156735) * debt - do not run long running ops in web on shutdown * fix tests --- .../common/storedFileWorkingCopyManager.ts | 21 ++++++++++--------- .../storedFileWorkingCopyManager.test.ts | 3 ++- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts index d0bc02b3e64..7b3ffb8c368 100644 --- a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts +++ b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts @@ -207,23 +207,24 @@ export class StoredFileWorkingCopyManager this._register(this.workingCopyFileService.onDidRunWorkingCopyFileOperation(e => this.onDidRunWorkingCopyFileOperation(e))); // Lifecycle - this.lifecycleService.onBeforeShutdown(event => event.veto(this.onBeforeShutdown(), 'veto.fileWorkingCopyManager')); - this.lifecycleService.onWillShutdown(event => event.join(this.onWillShutdown(), { id: 'join.fileWorkingCopyManager', label: localize('join.fileWorkingCopyManager', "Saving working copies") })); + if (isWeb) { + this.lifecycleService.onBeforeShutdown(event => event.veto(this.onBeforeShutdownWeb(), 'veto.fileWorkingCopyManager')); + } else { + this.lifecycleService.onWillShutdown(event => event.join(this.onWillShutdownDesktop(), { id: 'join.fileWorkingCopyManager', label: localize('join.fileWorkingCopyManager', "Saving working copies") })); + } } - private onBeforeShutdown(): boolean { - if (isWeb) { - if (this.workingCopies.some(workingCopy => workingCopy.hasState(StoredFileWorkingCopyState.PENDING_SAVE))) { - // stored file working copies are pending to be saved: - // veto because web does not support long running shutdown - return true; - } + private onBeforeShutdownWeb(): boolean { + if (this.workingCopies.some(workingCopy => workingCopy.hasState(StoredFileWorkingCopyState.PENDING_SAVE))) { + // stored file working copies are pending to be saved: + // veto because web does not support long running shutdown + return true; } return false; } - private async onWillShutdown(): Promise { + private async onWillShutdownDesktop(): Promise { let pendingSavedWorkingCopies: IStoredFileWorkingCopy[]; // As long as stored file working copies are pending to be saved, we prolong the shutdown diff --git a/src/vs/workbench/services/workingCopy/test/browser/storedFileWorkingCopyManager.test.ts b/src/vs/workbench/services/workingCopy/test/browser/storedFileWorkingCopyManager.test.ts index 7b157378feb..cfb69f33e2e 100644 --- a/src/vs/workbench/services/workingCopy/test/browser/storedFileWorkingCopyManager.test.ts +++ b/src/vs/workbench/services/workingCopy/test/browser/storedFileWorkingCopyManager.test.ts @@ -16,6 +16,7 @@ import { TestStoredFileWorkingCopyModel, TestStoredFileWorkingCopyModelFactory } import { CancellationToken } from 'vs/base/common/cancellation'; import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; import { DisposableStore } from 'vs/base/common/lifecycle'; +import { isWeb } from 'vs/base/common/platform'; suite('StoredFileWorkingCopyManager', () => { @@ -617,7 +618,7 @@ suite('StoredFileWorkingCopyManager', () => { assert.strictEqual(canDispose2, true); }); - test('pending saves join on shutdown', async () => { + (isWeb ? test.skip : test)('pending saves join on shutdown', async () => { const resource1 = URI.file('/path/index_something1.txt'); const resource2 = URI.file('/path/index_something2.txt'); From 58f0a069f92b198a29799c5c46df2b1b38aae4ff Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 2 Aug 2022 08:14:46 -0500 Subject: [PATCH 140/303] Add telemetry comments (#156827) * Add telemetry comments. Fix microsoft/vscode-internalbacklog#2762 * Remove unused usePcre2 attribute Co-authored-by: Logan Ramos --- .../browser/searchEditorActions.ts | 16 ++++- .../searchEditor/browser/searchEditorInput.ts | 8 ++- .../services/search/common/searchService.ts | 67 ++++++++----------- 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts index f854d0c75a0..88175988d9a 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorActions.ts @@ -139,7 +139,12 @@ export const openNewSearchEditor = } } - telemetryService.publicLog2<{}, { owner: 'roblourens'; comment: 'TODO @roblourens' }>('searchEditor/openNewSearchEditor'); + telemetryService.publicLog2<{}, + { + owner: 'roblourens'; + comment: 'Fired when a search editor is opened'; + }> + ('searchEditor/openNewSearchEditor'); const seedSearchStringFromSelection = _args.location === 'new' || configurationService.getValue('editor').find!.seedSearchStringFromSelection; const args: OpenSearchEditorArgs = { query: seedSearchStringFromSelection ? selected : undefined }; @@ -188,8 +193,13 @@ export const createEditorFromSearchResult = const configurationService = accessor.get(IConfigurationService); const sortOrder = configurationService.getValue('search').sortOrder; - - telemetryService.publicLog2<{}, { owner: 'roblourens'; comment: 'TODO @roblourens' }>('searchEditor/createEditorFromSearchResult'); + telemetryService.publicLog2< + {}, + { + owner: 'roblourens'; + comment: 'Fired when a search editor is opened from the search view'; + }> + ('searchEditor/createEditorFromSearchResult'); const labelFormatter = (uri: URI): string => labelService.getUriLabel(uri, { relative: true }); diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts index 3481a3c4978..cb9c0e342b5 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts @@ -184,7 +184,13 @@ export class SearchEditorInput extends EditorInput { override async saveAs(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise { const path = await this.fileDialogService.pickFileToSave(await this.suggestFileName(), options?.availableFileSystems); if (path) { - this.telemetryService.publicLog2<{}, { owner: 'roblourens'; comment: 'TODO @roblourens' }>('searchEditor/saveSearchResults'); + this.telemetryService.publicLog2< + {}, + { + owner: 'roblourens'; + comment: 'Fired when a search editor is saved'; + }> + ('searchEditor/saveSearchResults'); const toWrite = await this.serializeForDisk(); if (await this.textFileService.create([{ resource: path, value: toWrite, options: { overwrite: true } }])) { this.setDirty(false); diff --git a/src/vs/workbench/services/search/common/searchService.ts b/src/vs/workbench/services/search/common/searchService.ts index 4d6a8cc305f..874de93dad5 100644 --- a/src/vs/workbench/services/search/common/searchService.ts +++ b/src/vs/workbench/services/search/common/searchService.ts @@ -283,24 +283,22 @@ export class SearchService extends Disposable implements ISearchService { type CachedSearchCompleteClassifcation = { owner: 'roblourens'; - comment: 'TODO @roblourens'; - reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; - resultCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - type: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; - endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - sortingTime?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - cacheWasResolved: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; - cacheLookupTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - cacheFilterTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - cacheEntryCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; + comment: 'Fired when a file search is completed from previously cached results'; + reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Indicates which extension or UI feature triggered this search' }; + resultCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The number of search results' }; + workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The number of folders in the workspace' }; + endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The total search time' }; + sortingTime?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The amount of time spent sorting results' }; + cacheWasResolved: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Whether the cache was already resolved when the search began' }; + cacheLookupTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The amount of time spent looking up the cache to use for the search' }; + cacheFilterTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The amount of time spent searching within the cache' }; + cacheEntryCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The number of entries in the searched-in cache' }; + scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The uri scheme of the folder searched in' }; }; type CachedSearchCompleteEvent = { reason?: string; resultCount: number; workspaceFolderCount: number; - type: 'fileSearchProvider' | 'searchProcess'; endToEndTime: number; sortingTime?: number; cacheWasResolved: boolean; @@ -313,7 +311,6 @@ export class SearchService extends Disposable implements ISearchService { reason: query._reason, resultCount: fileSearchStats.resultCount, workspaceFolderCount: query.folderQueries.length, - type: fileSearchStats.type, endToEndTime: endToEndTime, sortingTime: fileSearchStats.sortingTime, cacheWasResolved: cacheStats.cacheWasResolved, @@ -327,25 +324,23 @@ export class SearchService extends Disposable implements ISearchService { type SearchCompleteClassification = { owner: 'roblourens'; - comment: 'TODO @roblourens'; - reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; - resultCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - type: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; - endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - sortingTime?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - fileWalkTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - directoriesWalked: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - filesWalked: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - cmdTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - cmdResultCount?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; + comment: 'Fired when a file search is completed'; + reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Indicates which extension or UI feature triggered this search' }; + resultCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The number of search results' }; + workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The number of folders in the workspace' }; + endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The total search time' }; + sortingTime?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The amount of time spent sorting results' }; + fileWalkTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The amount of time spent walking file system' }; + directoriesWalked: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The number of directories walked' }; + filesWalked: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The number of files walked' }; + cmdTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The amount of time spent running the search command' }; + cmdResultCount?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The number of results returned from the search command' }; + scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The uri scheme of the folder searched in' }; }; type SearchCompleteEvent = { reason?: string; resultCount: number; workspaceFolderCount: number; - type: 'fileSearchProvider' | 'searchProcess'; endToEndTime: number; sortingTime?: number; fileWalkTime: number; @@ -361,7 +356,6 @@ export class SearchService extends Disposable implements ISearchService { reason: query._reason, resultCount: fileSearchStats.resultCount, workspaceFolderCount: query.folderQueries.length, - type: fileSearchStats.type, endToEndTime: endToEndTime, sortingTime: fileSearchStats.sortingTime, fileWalkTime: searchEngineStats.fileWalkTime, @@ -386,13 +380,12 @@ export class SearchService extends Disposable implements ISearchService { type TextSearchCompleteClassification = { owner: 'roblourens'; - comment: 'TODO @roblourens'; - reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; - workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'TODO @roblourens' }; - scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; - error?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; - usePCRE2: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'TODO @roblourens' }; + comment: 'Fired when a text search is completed'; + reason?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Indicates which extension or UI feature triggered this search' }; + workspaceFolderCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The number of folders in the workspace' }; + endToEndTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The total search time' }; + scheme: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The uri scheme of the folder searched in' }; + error?: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The type of the error, if any' }; }; type TextSearchCompleteEvent = { reason?: string; @@ -400,7 +393,6 @@ export class SearchService extends Disposable implements ISearchService { endToEndTime: number; scheme: string; error?: string; - usePCRE2: boolean; }; this.telemetryService.publicLog2('textSearchComplete', { reason: query._reason, @@ -408,7 +400,6 @@ export class SearchService extends Disposable implements ISearchService { endToEndTime: endToEndTime, scheme, error: errorType, - usePCRE2: !!query.usePCRE2 }); } } From 56c7ffabc9a00f03345d3f7f453b27fda9b02e7a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 2 Aug 2022 15:51:43 +0200 Subject: [PATCH 141/303] clean up vsixs (#156893) * Fix #156696 * - clean up created vsixs - fix installing vsixs in local from remote --- .../extensions/browser/extensionsActions.ts | 50 ++++++++++++++++--- .../nativeExtensionManagementService.ts | 37 +++++++++++++- .../remoteExtensionManagementService.ts | 18 +++++-- 3 files changed, 92 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index d2247bf2519..1fe6a1b04b0 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -567,6 +567,8 @@ export abstract class InstallInOtherServerAction extends ExtensionAction { id: string, private readonly server: IExtensionManagementServer | null, private readonly canInstallAnyWhere: boolean, + @IFileService private readonly fileService: IFileService, + @ILogService private readonly logService: ILogService, @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService, @IExtensionManifestPropertiesService private readonly extensionManifestPropertiesService: IExtensionManifestPropertiesService, @@ -667,7 +669,15 @@ export abstract class InstallInOtherServerAction extends ExtensionAction { throw new Error(localize('incompatible', "Can't install '{0}' extension because it is not compatible.", this.extension.identifier.id)); } const vsix = await this.extension.server.extensionManagementService.zip(this.extension.local); - await this.server.extensionManagementService.install(vsix); + try { + await this.server.extensionManagementService.install(vsix); + } finally { + try { + await this.fileService.del(vsix); + } catch (error) { + this.logService.error(error); + } + } } protected abstract getInstallLabel(): string; @@ -677,12 +687,14 @@ export class RemoteInstallAction extends InstallInOtherServerAction { constructor( canInstallAnyWhere: boolean, + @IFileService fileService: IFileService, + @ILogService logService: ILogService, @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService, @IExtensionManifestPropertiesService extensionManifestPropertiesService: IExtensionManifestPropertiesService, @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, ) { - super(`extensions.remoteinstall`, extensionManagementServerService.remoteExtensionManagementServer, canInstallAnyWhere, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService, extensionGalleryService); + super(`extensions.remoteinstall`, extensionManagementServerService.remoteExtensionManagementServer, canInstallAnyWhere, fileService, logService, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService, extensionGalleryService); } protected getInstallLabel(): string { @@ -696,12 +708,14 @@ export class RemoteInstallAction extends InstallInOtherServerAction { export class LocalInstallAction extends InstallInOtherServerAction { constructor( + @IFileService fileService: IFileService, + @ILogService logService: ILogService, @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService, @IExtensionManifestPropertiesService extensionManifestPropertiesService: IExtensionManifestPropertiesService, @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, ) { - super(`extensions.localinstall`, extensionManagementServerService.localExtensionManagementServer, false, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService, extensionGalleryService); + super(`extensions.localinstall`, extensionManagementServerService.localExtensionManagementServer, false, fileService, logService, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService, extensionGalleryService); } protected getInstallLabel(): string { @@ -713,12 +727,14 @@ export class LocalInstallAction extends InstallInOtherServerAction { export class WebInstallAction extends InstallInOtherServerAction { constructor( + @IFileService fileService: IFileService, + @ILogService logService: ILogService, @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService, @IExtensionManifestPropertiesService extensionManifestPropertiesService: IExtensionManifestPropertiesService, @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, ) { - super(`extensions.webInstall`, extensionManagementServerService.webExtensionManagementServer, false, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService, extensionGalleryService); + super(`extensions.webInstall`, extensionManagementServerService.webExtensionManagementServer, false, fileService, logService, extensionsWorkbenchService, extensionManagementServerService, extensionManifestPropertiesService, extensionGalleryService); } protected getInstallLabel(): string { @@ -2807,7 +2823,9 @@ export class InstallLocalExtensionsInRemoteAction extends AbstractInstallExtensi @INotificationService notificationService: INotificationService, @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService, @IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService, - @IInstantiationService private readonly instantiationService: IInstantiationService + @IInstantiationService private readonly instantiationService: IInstantiationService, + @IFileService private readonly fileService: IFileService, + @ILogService private readonly logService: ILogService, ) { super('workbench.extensions.actions.installLocalExtensionsInRemote', extensionsWorkbenchService, quickInputService, notificationService, progressService); } @@ -2848,7 +2866,15 @@ export class InstallLocalExtensionsInRemoteAction extends AbstractInstallExtensi })); await Promises.settled(galleryExtensions.map(gallery => this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.installFromGallery(gallery))); - await Promises.settled(vsixs.map(vsix => this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.install(vsix))); + try { + await Promises.settled(vsixs.map(vsix => this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.install(vsix))); + } finally { + try { + await Promise.allSettled(vsixs.map(vsix => this.fileService.del(vsix))); + } catch (error) { + this.logService.error(error); + } + } } } @@ -2862,6 +2888,8 @@ export class InstallRemoteExtensionsInLocalAction extends AbstractInstallExtensi @INotificationService notificationService: INotificationService, @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService, @IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService, + @IFileService private readonly fileService: IFileService, + @ILogService private readonly logService: ILogService, ) { super(id, extensionsWorkbenchService, quickInputService, notificationService, progressService); } @@ -2897,7 +2925,15 @@ export class InstallRemoteExtensionsInLocalAction extends AbstractInstallExtensi })); await Promises.settled(galleryExtensions.map(gallery => this.extensionManagementServerService.localExtensionManagementServer!.extensionManagementService.installFromGallery(gallery))); - await Promises.settled(vsixs.map(vsix => this.extensionManagementServerService.localExtensionManagementServer!.extensionManagementService.install(vsix))); + try { + await Promises.settled(vsixs.map(vsix => this.extensionManagementServerService.localExtensionManagementServer!.extensionManagementService.install(vsix))); + } finally { + try { + await Promise.allSettled(vsixs.map(vsix => this.fileService.del(vsix))); + } catch (error) { + this.logService.error(error); + } + } } } diff --git a/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts index cdd2bdad7db..19b2e78f08c 100644 --- a/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts @@ -18,6 +18,12 @@ import { DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workb import { EXTENSIONS_RESOURCE_NAME } from 'vs/platform/userDataProfile/common/userDataProfile'; import { joinPath } from 'vs/base/common/resources'; import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; +import { Schemas } from 'vs/base/common/network'; +import { ILogService } from 'vs/platform/log/common/log'; +import { IDownloadService } from 'vs/platform/download/common/download'; +import { IFileService } from 'vs/platform/files/common/files'; +import { generateUuid } from 'vs/base/common/uuid'; +import { INativeEnvironmentService } from 'vs/platform/environment/common/environment'; export class NativeExtensionManagementService extends ExtensionManagementChannelClient implements IProfileAwareExtensionManagementService { @@ -40,6 +46,10 @@ export class NativeExtensionManagementService extends ExtensionManagementChannel @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, @IExtensionsProfileScannerService private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, + @IFileService private readonly fileService: IFileService, + @IDownloadService private readonly downloadService: IDownloadService, + @INativeEnvironmentService private readonly nativeEnvironmentService: INativeEnvironmentService, + @ILogService private readonly logService: ILogService, ) { super(channel); this._register(userDataProfileService.onDidChangeCurrentProfile(e => e.join(this.whenProfileChanged(e)))); @@ -49,8 +59,13 @@ export class NativeExtensionManagementService extends ExtensionManagementChannel return applicationScoped || this.uriIdentityService.extUri.isEqual(this.userDataProfileService.currentProfile.extensionsResource, profileLocation); } - override install(vsix: URI, options?: InstallVSIXOptions): Promise { - return super.install(vsix, { ...options, profileLocation: this.userDataProfileService.currentProfile.extensionsResource }); + override async install(vsix: URI, options?: InstallVSIXOptions): Promise { + const { location, cleanup } = await this.downloadVsix(vsix); + try { + return await super.install(location, { ...options, profileLocation: this.userDataProfileService.currentProfile.extensionsResource }); + } finally { + await cleanup(); + } } override installFromGallery(extension: IGalleryExtension, installOptions?: InstallOptions): Promise { @@ -65,6 +80,24 @@ export class NativeExtensionManagementService extends ExtensionManagementChannel return super.getInstalled(type, this.userDataProfileService.currentProfile.extensionsResource); } + private async downloadVsix(vsix: URI): Promise<{ location: URI; cleanup: () => Promise }> { + if (vsix.scheme === Schemas.file) { + return { location: vsix, async cleanup() { } }; + } + this.logService.trace('Downloading extension from', vsix.toString()); + const location = joinPath(URI.file(this.nativeEnvironmentService.extensionsDownloadPath), generateUuid()); + await this.downloadService.download(vsix, location); + this.logService.info('Downloaded extension to', location.toString()); + const cleanup = async () => { + try { + await this.fileService.del(location); + } catch (error) { + this.logService.error(error); + } + }; + return { location, cleanup }; + } + private async whenProfileChanged(e: DidChangeUserDataProfileEvent): Promise { const previousExtensionsResource = e.previous.extensionsResource ?? joinPath(e.previous.location, EXTENSIONS_RESOURCE_NAME); const oldExtensions = await super.getInstalled(ExtensionType.User, previousExtensionsResource); diff --git a/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts index b9202112131..f5a3e5ff80f 100644 --- a/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts @@ -23,6 +23,7 @@ import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/enviro import { Promises } from 'vs/base/common/async'; import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService'; import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; +import { IFileService } from 'vs/platform/files/common/files'; export class NativeRemoteExtensionManagementService extends ExtensionManagementChannelClient implements IProfileAwareExtensionManagementService { @@ -36,6 +37,7 @@ export class NativeRemoteExtensionManagementService extends ExtensionManagementC @IConfigurationService private readonly configurationService: IConfigurationService, @IProductService private readonly productService: IProductService, @INativeWorkbenchEnvironmentService private readonly environmentService: INativeWorkbenchEnvironmentService, + @IFileService private readonly fileService: IFileService, @IExtensionManifestPropertiesService private readonly extensionManifestPropertiesService: IExtensionManifestPropertiesService, ) { super(channel); @@ -94,13 +96,21 @@ export class NativeRemoteExtensionManagementService extends ExtensionManagementC private async downloadCompatibleAndInstall(extension: IGalleryExtension, installed: ILocalExtension[], installOptions: InstallOptions): Promise { const compatible = await this.checkAndGetCompatible(extension, !!installOptions.installPreReleaseVersion); - const location = joinPath(this.environmentService.tmpDir, generateUuid()); + const location = joinPath(URI.file(this.environmentService.extensionsDownloadPath), generateUuid()); this.logService.trace('Downloading extension:', compatible.identifier.id); await this.galleryService.download(compatible, location, installed.filter(i => areSameExtensions(i.identifier, compatible.identifier))[0] ? InstallOperation.Update : InstallOperation.Install); this.logService.info('Downloaded extension:', compatible.identifier.id, location.path); - const local = await super.install(location, installOptions); - this.logService.info(`Successfully installed '${compatible.identifier.id}' extension`); - return local; + try { + const local = await super.install(location, installOptions); + this.logService.info(`Successfully installed '${compatible.identifier.id}' extension`); + return local; + } finally { + try { + await this.fileService.del(location); + } catch (error) { + this.logService.error(error); + } + } } private async checkAndGetCompatible(extension: IGalleryExtension, includePreRelease: boolean): Promise { From 92697ad31b594d6b33df0545dda1859d3fae560e Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 2 Aug 2022 23:53:47 +0900 Subject: [PATCH 142/303] ci: fix armhf debian dependencies --- build/linux/debian/dep-lists.js | 1 - build/linux/debian/dep-lists.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/build/linux/debian/dep-lists.js b/build/linux/debian/dep-lists.js index c27672feda0..e965f69feb3 100644 --- a/build/linux/debian/dep-lists.js +++ b/build/linux/debian/dep-lists.js @@ -87,7 +87,6 @@ exports.referenceGeneratedDepsByArch = { 'libgbm1 (>= 8.1~0)', 'libgcc-s1 (>= 3.0)', 'libgcc-s1 (>= 3.5)', - 'libgcc1 (>= 1:3.5)', 'libglib2.0-0 (>= 2.16.0)', 'libglib2.0-0 (>= 2.39.4)', 'libgtk-3-0 (>= 3.9.10)', diff --git a/build/linux/debian/dep-lists.ts b/build/linux/debian/dep-lists.ts index 7d5e853063f..2ee76768da1 100644 --- a/build/linux/debian/dep-lists.ts +++ b/build/linux/debian/dep-lists.ts @@ -88,7 +88,6 @@ export const referenceGeneratedDepsByArch = { 'libgbm1 (>= 8.1~0)', 'libgcc-s1 (>= 3.0)', 'libgcc-s1 (>= 3.5)', - 'libgcc1 (>= 1:3.5)', 'libglib2.0-0 (>= 2.16.0)', 'libglib2.0-0 (>= 2.39.4)', 'libgtk-3-0 (>= 3.9.10)', From 3495573decb98ea499003f4d723ebdb0180778bd Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 2 Aug 2022 16:57:29 +0200 Subject: [PATCH 143/303] Increasing the character limit to 500 (#156880) (#156884) --- src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index 5100c6fac2c..4ad96167950 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -270,9 +270,9 @@ class StickyScrollCodeLine { const renderLineInput: RenderLineInput = new RenderLineInput(true, true, lineRenderingData.content, lineRenderingData.continuesWithWrappedLine, lineRenderingData.isBasicASCII, lineRenderingData.containsRTL, 0, lineRenderingData.tokens, actualInlineDecorations, lineRenderingData.tabSize, - lineRenderingData.startVisibleColumn, 1, 1, 1, 100, 'none', true, true, null); + lineRenderingData.startVisibleColumn, 1, 1, 1, 500, 'none', true, true, null); - const sb = createStringBuilder(400); + const sb = createStringBuilder(2000); renderViewLine(renderLineInput, sb); let newLine; From d2bab15175fb18d002fb66d65f6ac0ee1ef86e7b Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Tue, 2 Aug 2022 08:23:35 -0700 Subject: [PATCH 144/303] fix task reconnection issues (#156699) --- .../tasks/browser/abstractTaskService.ts | 95 ++++++++++-- .../contrib/tasks/browser/taskQuickPick.ts | 2 +- .../tasks/browser/terminalTaskSystem.ts | 143 +++++++++--------- .../contrib/tasks/common/taskService.ts | 2 +- .../contrib/tasks/common/taskSystem.ts | 1 + .../contrib/terminal/browser/terminal.ts | 5 + .../terminal/browser/xterm/xtermTerminal.ts | 13 ++ 7 files changed, 176 insertions(+), 85 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 18a68093766..7f856c3e91a 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -192,6 +192,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer // private static autoDetectTelemetryName: string = 'taskServer.autoDetect'; private static readonly RecentlyUsedTasks_Key = 'workbench.tasks.recentlyUsedTasks'; private static readonly RecentlyUsedTasks_KeyV2 = 'workbench.tasks.recentlyUsedTasks2'; + private static readonly PersistentTasks_Key = 'workbench.tasks.persistentTasks'; private static readonly IgnoreTask010DonotShowAgain_key = 'workbench.tasks.ignoreTask010Shown'; public _serviceBrand: undefined; @@ -218,6 +219,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private _recentlyUsedTasksV1: LRUCache | undefined; private _recentlyUsedTasks: LRUCache | undefined; + private _persistentTasks: LRUCache | undefined; + protected _taskRunningState: IContextKey; protected _outputChannel: IOutputChannel; @@ -346,11 +349,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private async _reconnectTasks(): Promise { - const recentlyUsedTasks = await this.readRecentTasks(); - if (!recentlyUsedTasks.length) { + const tasks = await this.getSavedTasks('persistent'); + if (!tasks.length) { return; } - for (const task of recentlyUsedTasks) { + for (const task of tasks) { if (ConfiguringTask.is(task)) { const resolved = await this.tryResolveTask(task); if (resolved) { @@ -889,7 +892,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return this._recentlyUsedTasksV1; } - private _getRecentlyUsedTasks(): LRUCache { + private _getTasksFromStorage(type: 'persistent' | 'historical'): LRUCache { + return type === 'persistent' ? this._getPersistentTasks() : this._getRecentTasks(); + } + + private _getRecentTasks(): LRUCache { if (this._recentlyUsedTasks) { return this._recentlyUsedTasks; } @@ -912,6 +919,29 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return this._recentlyUsedTasks; } + private _getPersistentTasks(): LRUCache { + if (this._persistentTasks) { + return this._persistentTasks; + } + //TODO: should this # be configurable? + this._persistentTasks = new LRUCache(10); + + const storageValue = this._storageService.get(AbstractTaskService.PersistentTasks_Key, StorageScope.WORKSPACE); + if (storageValue) { + try { + const values: [string, string][] = JSON.parse(storageValue); + if (Array.isArray(values)) { + for (const value of values) { + this._persistentTasks.set(value[0], value[1]); + } + } + } catch (error) { + // Ignore. We use the empty result + } + } + return this._persistentTasks; + } + private _getFolderFromTaskKey(key: string): { folder: string | undefined; isWorkspaceFile: boolean | undefined } { const keyValue: { folder: string | undefined; id: string | undefined } = JSON.parse(key); return { @@ -919,14 +949,14 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }; } - public async readRecentTasks(): Promise<(Task | ConfiguringTask)[]> { + public async getSavedTasks(type: 'persistent' | 'historical'): Promise<(Task | ConfiguringTask)[]> { const folderMap: IStringDictionary = Object.create(null); this.workspaceFolders.forEach(folder => { folderMap[folder.uri.toString()] = folder; }); const folderToTasksMap: Map = new Map(); const workspaceToTaskMap: Map = new Map(); - const recentlyUsedTasks = this._getRecentlyUsedTasks(); + const storedTasks = this._getTasksFromStorage(type); const tasks: (Task | ConfiguringTask)[] = []; function addTaskToMap(map: Map, folder: string | undefined, task: any) { @@ -937,7 +967,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer map.get(folder).push(task); } } - for (const entry of recentlyUsedTasks.entries()) { + for (const entry of storedTasks.entries()) { const key = entry[0]; const task = JSON.parse(entry[1]); const folderInfo = this._getFolderFromTaskKey(key); @@ -974,7 +1004,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } await readTasks(this, folderToTasksMap, false); await readTasks(this, workspaceToTaskMap, true); - for (const key of recentlyUsedTasks.keys()) { + for (const key of storedTasks.keys()) { if (readTasksMap.has(key)) { tasks.push(readTasksMap.get(key)!); } @@ -983,8 +1013,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } public removeRecentlyUsedTask(taskRecentlyUsedKey: string) { - if (this._getRecentlyUsedTasks().has(taskRecentlyUsedKey)) { - this._getRecentlyUsedTasks().delete(taskRecentlyUsedKey); + if (this._getTasksFromStorage('historical').has(taskRecentlyUsedKey)) { + this._getTasksFromStorage('historical').delete(taskRecentlyUsedKey); this._saveRecentlyUsedTasks(); } } @@ -1011,7 +1041,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer key = customized[configuration].getRecentlyUsedKey()!; } } - this._getRecentlyUsedTasks().set(key, JSON.stringify(customizations)); + this._getTasksFromStorage('historical').set(key, JSON.stringify(customizations)); this._saveRecentlyUsedTasks(); } } @@ -1036,6 +1066,41 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this._storageService.store(AbstractTaskService.RecentlyUsedTasks_KeyV2, JSON.stringify(keyValues), StorageScope.WORKSPACE, StorageTarget.USER); } + private async _setPersistentTask(task: Task): Promise { + if (!task.configurationProperties.isBackground || !this._tasksReconnected) { + return; + } + let key = task.getRecentlyUsedKey(); + if (!InMemoryTask.is(task) && key) { + const customizations = this._createCustomizableTask(task); + if (ContributedTask.is(task) && customizations) { + const custom: CustomTask[] = []; + const customized: IStringDictionary = Object.create(null); + await this._computeTasksForSingleConfig(task._source.workspaceFolder ?? this.workspaceFolders[0], { + version: '2.0.0', + tasks: [customizations] + }, TaskRunSource.System, custom, customized, TaskConfig.TaskConfigSource.TasksJson, true); + for (const configuration in customized) { + key = customized[configuration].getRecentlyUsedKey()!; + } + } + this._getTasksFromStorage('persistent').set(key, JSON.stringify(customizations)); + this._savePersistentTasks(); + } + } + + private _savePersistentTasks(): void { + if (!this._persistentTasks) { + return; + } + const keys = [...this._persistentTasks.keys()]; + const keyValues: [string, string][] = []; + for (const key of keys) { + keyValues.push([key, this._persistentTasks.get(key, Touch.None)!]); + } + this._storageService.store(AbstractTaskService.PersistentTasks_Key, JSON.stringify(keyValues), StorageScope.WORKSPACE, StorageTarget.USER); + } + private _openDocumentation(): void { this._openerService.open(URI.parse('https://code.visualstudio.com/docs/editor/tasks#_defining-a-problem-matcher')); } @@ -1776,6 +1841,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private async _handleExecuteResult(executeResult: ITaskExecuteResult, runSource?: TaskRunSource): Promise { + if (this._configurationService.getValue(TaskSettingId.Reconnection) === true) { + await this._setPersistentTask(executeResult.task); + } if (runSource === TaskRunSource.User) { await this._setRecentlyUsedTask(executeResult.task); } @@ -1804,6 +1872,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } } this._setRecentlyUsedTask(executeResult.task); + this._setPersistentTask(executeResult.task); return executeResult.promise; } @@ -2514,7 +2583,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (tasks.length === 1) { entries.push(TaskQuickPickEntry(tasks[0])); } else { - const recentlyUsedTasks = await this.readRecentTasks(); + const recentlyUsedTasks = await this.getSavedTasks('historical'); const recent: Task[] = []; const recentSet: Set = new Set(); let configured: Task[] = []; @@ -2647,7 +2716,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private _needsRecentTasksMigration(): boolean { - return (this.getRecentlyUsedTasksV1().size > 0) && (this._getRecentlyUsedTasks().size === 0); + return (this.getRecentlyUsedTasksV1().size > 0) && (this._getTasksFromStorage('historical').size === 0); } private async _migrateRecentTasks(tasks: Task[]) { diff --git a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts index bf48327fe5d..6a31c0d5225 100644 --- a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts +++ b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts @@ -171,7 +171,7 @@ export class TaskQuickPick extends Disposable { if (this._topLevelEntries !== undefined) { return { entries: this._topLevelEntries }; } - let recentTasks: (Task | ConfiguringTask)[] = (await this._taskService.readRecentTasks()).reverse(); + let recentTasks: (Task | ConfiguringTask)[] = (await this._taskService.getSavedTasks('historical')).reverse(); const configuredTasks: (Task | ConfiguringTask)[] = this._handleFolderTaskResult(await this._taskService.getWorkspaceTasks()); const extensionTaskTypes = this._taskService.taskTypes(); this._topLevelEntries = []; diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index ff02f515527..91e1316e1f6 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -192,7 +192,6 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { private _terminals: IStringDictionary; private _idleTaskTerminals: LinkedMap; private _sameTaskTerminals: IStringDictionary; - private _terminalForTask: ITerminalInstance | undefined; private _taskSystemInfoResolver: ITaskSystemInfoResolver; private _lastTask: VerifiedTask | undefined; // Should always be set in run @@ -203,8 +202,8 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { private _terminalStatusManager: TaskTerminalStatus; private _terminalCreationQueue: Promise = Promise.resolve(); private _hasReconnected: boolean = false; - private _tasksToReconnect: string[] = []; private readonly _onDidStateChange: Emitter; + private _reconnectTerminals: ITerminalInstance[] = []; get taskShellIntegrationStartSequence(): string { return this._configurationService.getValue(TaskSettingId.ShowDecorations) ? VSCodeSequence(VSCodeOscPt.PromptStart) + VSCodeSequence(VSCodeOscPt.Property, `${VSCodeOscProperty.Task}=True`) + VSCodeSequence(VSCodeOscPt.CommandStart) : ''; @@ -248,19 +247,6 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { this._register(this._terminalStatusManager = new TaskTerminalStatus(taskService)); } - private _reconnectToTerminals(terminals: ITerminalInstance[]): void { - for (const terminal of terminals) { - const taskForTerminal = terminal.shellLaunchConfig.attachPersistentProcess?.task; - if (taskForTerminal?.id && taskForTerminal?.lastTask) { - this._tasksToReconnect.push(taskForTerminal.id); - this._terminals[terminal.instanceId] = { terminal, lastTask: taskForTerminal.lastTask, group: taskForTerminal.group }; - } else { - this._logService.trace(`Could not reconnect to terminal ${terminal.instanceId} with process details ${terminal.shellLaunchConfig.attachPersistentProcess}`); - } - } - this._hasReconnected = true; - } - public get onDidStateChange(): Event { return this._onDidStateChange.event; } @@ -273,25 +259,15 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { this._outputService.showChannel(this._outputChannelId, true); } - public reconnect(task: Task, resolver: ITaskResolver, trigger: string = Triggers.command): ITaskExecuteResult | undefined { - const terminals = this._terminalService.getReconnectedTerminals(ReconnectionType); - if (!terminals || terminals?.length === 0) { + public reconnect(task: Task, resolver: ITaskResolver, trigger: string = Triggers.reconnect): ITaskExecuteResult | undefined { + this._reconnectTerminals = this._terminalService.getReconnectedTerminals(ReconnectionType) || []; + if (this._reconnectTerminals?.length === 0) { return; } - if (!this._hasReconnected && terminals && terminals.length > 0) { + if (!this._hasReconnected && this._reconnectTerminals && this._reconnectTerminals.length > 0) { this._reviveTerminals(); - this._reconnectToTerminals(terminals); } - if (this._tasksToReconnect.includes(task._id)) { - this._terminalForTask = terminals.find(t => t.shellLaunchConfig.attachPersistentProcess?.task?.id === task._id); - // Restore the waitOnExit value of the terminal because it may have been a function - // that cannot be persisted in the pty host - if ('command' in task && task.command.presentation && this._terminalForTask) { - this._terminalForTask.waitOnExit = getWaitOnExitValue(task.command.presentation, task.configurationProperties); - } - this.run(task, resolver, trigger); - } - return undefined; + return this.run(task, resolver, trigger); } public run(task: Task, resolver: ITaskResolver, trigger: string = Triggers.command): ITaskExecuteResult { @@ -546,38 +522,35 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { alreadyResolved = alreadyResolved ?? new Map(); const promises: Promise[] = []; if (task.configurationProperties.dependsOn) { - if (!this._terminalForTask) { - // we already handle dependent tasks when reconnecting, don't create extras - for (const dependency of task.configurationProperties.dependsOn) { - const dependencyTask = await resolver.resolve(dependency.uri, dependency.task!); - if (dependencyTask) { - this._adoptConfigurationForDependencyTask(dependencyTask, task); - const key = dependencyTask.getMapKey(); - let promise = this._activeTasks[key] ? this._getDependencyPromise(this._activeTasks[key]) : undefined; - if (!promise) { - this._fireTaskEvent(TaskEvent.create(TaskEventKind.DependsOnStarted, task)); - encounteredDependencies.add(task.getCommonTaskId()); - promise = this._executeDependencyTask(dependencyTask, resolver, trigger, encounteredDependencies, alreadyResolved); - } - promises.push(promise); - if (task.configurationProperties.dependsOrder === DependsOrder.sequence) { - const promiseResult = await promise; - if (promiseResult.exitCode === 0) { - promise = Promise.resolve(promiseResult); - } else { - promise = Promise.reject(promiseResult); - break; - } - } - promises.push(promise); - } else { - this._log(nls.localize('dependencyFailed', - 'Couldn\'t resolve dependent task \'{0}\' in workspace folder \'{1}\'', - Types.isString(dependency.task) ? dependency.task : JSON.stringify(dependency.task, undefined, 0), - dependency.uri.toString() - )); - this._showOutput(); + for (const dependency of task.configurationProperties.dependsOn) { + const dependencyTask = await resolver.resolve(dependency.uri, dependency.task!); + if (dependencyTask) { + this._adoptConfigurationForDependencyTask(dependencyTask, task); + const key = dependencyTask.getMapKey(); + let promise = this._activeTasks[key] ? this._getDependencyPromise(this._activeTasks[key]) : undefined; + if (!promise) { + this._fireTaskEvent(TaskEvent.create(TaskEventKind.DependsOnStarted, task)); + encounteredDependencies.add(task.getCommonTaskId()); + promise = this._executeDependencyTask(dependencyTask, resolver, trigger, encounteredDependencies, alreadyResolved); } + promises.push(promise); + if (task.configurationProperties.dependsOrder === DependsOrder.sequence) { + const promiseResult = await promise; + if (promiseResult.exitCode === 0) { + promise = Promise.resolve(promiseResult); + } else { + promise = Promise.reject(promiseResult); + break; + } + } + promises.push(promise); + } else { + this._log(nls.localize('dependencyFailed', + 'Couldn\'t resolve dependent task \'{0}\' in workspace folder \'{1}\'', + Types.isString(dependency.task) ? dependency.task : JSON.stringify(dependency.task, undefined, 0), + dependency.uri.toString() + )); + this._showOutput(); } } } @@ -889,8 +862,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { })); watchingProblemMatcher.aboutToStart(); let delayer: Async.Delayer | undefined = undefined; - [terminal, error] = this._terminalForTask ? [this._terminalForTask, undefined] : await this._createTerminal(task, resolver, workspaceFolder); - this._terminalForTask = undefined; + [terminal, error] = await this._createTerminal(task, resolver, workspaceFolder); if (error) { return Promise.reject(new Error((error).message)); @@ -970,9 +942,21 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { resolve({ exitCode: exitCode ?? undefined }); }); }); + if (trigger === Triggers.reconnect && !!terminal.xterm) { + const bufferLines = terminal.xterm.bufferLines; + for (let i = 0; i < bufferLines.length; i++) { + watchingProblemMatcher.processLine(bufferLines[i]); + } + if (!delayer) { + delayer = new Async.Delayer(3000); + } + delayer.trigger(() => { + watchingProblemMatcher.forceDelivery(); + delayer = undefined; + }); + } } else { - [terminal, error] = this._terminalForTask ? [this._terminalForTask, undefined] : await this._createTerminal(task, resolver, workspaceFolder); - this._terminalForTask = undefined; + [terminal, error] = await this._createTerminal(task, resolver, workspaceFolder); if (error) { return Promise.reject(new Error((error).message)); @@ -1189,7 +1173,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { }, 'Executing task in folder {0}: {1}', workspaceFolder.name, commandLine), { excludeLeadingNewLine: true }) + this.taskShellIntegrationOutputSequence; } else { shellLaunchConfig.initialText = this.taskShellIntegrationStartSequence + formatMessageForTerminal(nls.localize({ - key: 'task.executing', + key: 'task.executing.shellIntegration', comment: ['The task command line or label'] }, 'Executing task: {0}', commandLine), { excludeLeadingNewLine: true }) + this.taskShellIntegrationOutputSequence; } @@ -1232,7 +1216,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { }, 'Executing task in folder {0}: {1}', workspaceFolder.name, `${shellLaunchConfig.executable} ${getArgsToEcho(shellLaunchConfig.args)}`), { excludeLeadingNewLine: true }) + this.taskShellIntegrationOutputSequence; } else { shellLaunchConfig.initialText = this.taskShellIntegrationStartSequence + formatMessageForTerminal(nls.localize({ - key: 'task.executing', + key: 'task.executing.shell-integration', comment: ['The task command line or label'] }, 'Executing task: {0}', `${shellLaunchConfig.executable} ${getArgsToEcho(shellLaunchConfig.args)}`), { excludeLeadingNewLine: true }) + this.taskShellIntegrationOutputSequence; } @@ -1284,7 +1268,26 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { return combinedShellArgs; } - private async _doCreateTerminal(group: string | undefined, launchConfigs: IShellLaunchConfig): Promise { + private async _reconnectToTerminal(task: Task): Promise { + for (let i = 0; i < this._reconnectTerminals.length; i++) { + const terminal = this._reconnectTerminals[i]; + const taskForTerminal = terminal.shellLaunchConfig.attachPersistentProcess?.task; + if (taskForTerminal?.id && task.getRecentlyUsedKey() === taskForTerminal.lastTask) { + this._reconnectTerminals.splice(i, 1); + return terminal; + } + } + return undefined; + } + + private async _doCreateTerminal(task: Task, group: string | undefined, launchConfigs: IShellLaunchConfig): Promise { + const reconnectedTerminal = await this._reconnectToTerminal(task); + if (reconnectedTerminal) { + if ('command' in task && task.command.presentation) { + reconnectedTerminal.waitOnExit = getWaitOnExitValue(task.command.presentation, task.configurationProperties); + } + return reconnectedTerminal; + } if (group) { // Try to find an existing terminal to split. // Even if an existing terminal is found, the split can fail if the terminal width is too small. @@ -1423,9 +1426,9 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { return [terminalToReuse.terminal, undefined]; } - this._terminalCreationQueue = this._terminalCreationQueue.then(() => this._doCreateTerminal(group, launchConfigs!)); + this._terminalCreationQueue = this._terminalCreationQueue.then(() => this._doCreateTerminal(task, group, launchConfigs!)); const terminal: ITerminalInstance = (await this._terminalCreationQueue)!; - terminal.shellLaunchConfig.task = { lastTask: taskKey, group, label: task._label, id: task._id }; + terminal.shellLaunchConfig.task = { lastTask: task.getRecentlyUsedKey()!, group, label: task._label, id: task._id }; terminal.shellLaunchConfig.reconnectionOwner = ReconnectionType; const terminalKey = terminal.instanceId.toString(); const terminalData = { terminal: terminal, lastTask: taskKey, group }; diff --git a/src/vs/workbench/contrib/tasks/common/taskService.ts b/src/vs/workbench/contrib/tasks/common/taskService.ts index afc0ed385fa..be0fb4a5c5d 100644 --- a/src/vs/workbench/contrib/tasks/common/taskService.ts +++ b/src/vs/workbench/contrib/tasks/common/taskService.ts @@ -72,7 +72,7 @@ export interface ITaskService { tasks(filter?: ITaskFilter): Promise; taskTypes(): string[]; getWorkspaceTasks(runSource?: TaskRunSource): Promise>; - readRecentTasks(): Promise<(Task | ConfiguringTask)[]>; + getSavedTasks(type: 'persistent' | 'historical'): Promise<(Task | ConfiguringTask)[]>; removeRecentlyUsedTask(taskRecentlyUsedKey: string): void; /** * @param alias The task's name, label or defined identifier. diff --git a/src/vs/workbench/contrib/tasks/common/taskSystem.ts b/src/vs/workbench/contrib/tasks/common/taskSystem.ts index 7b7b67f3a19..cb4948c21fe 100644 --- a/src/vs/workbench/contrib/tasks/common/taskSystem.ts +++ b/src/vs/workbench/contrib/tasks/common/taskSystem.ts @@ -38,6 +38,7 @@ export class TaskError { export namespace Triggers { export const shortcut: string = 'shortcut'; export const command: string = 'command'; + export const reconnect: string = 'reconnect'; } export interface ITaskSummary { diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index ed6ba54d0eb..f340fd0bea8 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -917,6 +917,11 @@ export interface IXtermTerminal { */ readonly shellIntegration: IShellIntegration; + /** + * An array representing the buffer lines as strings + */ + readonly bufferLines: string[]; + readonly onDidChangeSelection: Event; /** diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index 88a89cb7a6c..2717727d01c 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -54,7 +54,20 @@ let SerializeAddon: typeof SerializeAddonType; export class XtermTerminal extends DisposableStore implements IXtermTerminal, IInternalXtermTerminal { /** The raw xterm.js instance */ readonly raw: RawXtermTerminal; + private _bufferLines: string[] = []; + get bufferLines(): string[] { + if (this.raw.buffer.active.length === this._bufferLines.length) { + return this._bufferLines; + } + for (let i = this._bufferLines.length; i < this.raw.buffer.active.length; i++) { + const line = this.raw.buffer.active.getLine(i)?.translateToString(); + if (line) { + this._bufferLines.push(line); + } + } + return this._bufferLines; + } private _core: IXtermCore; private static _suggestedRendererType: 'canvas' | 'dom' | undefined = undefined; private _container?: HTMLElement; From a3d2c539fe1729b2020fa883448f420c456323a7 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 2 Aug 2022 08:27:25 -0700 Subject: [PATCH 145/303] testing: clean up and compact test result storage (#156834) * testing: clean up and compact test result storage This PR does several chore things around test results: - Removes the persistence of test messages, which should reduce the size of stored results significantly (we only keep the state). This is the same as what IntelliJ does with some cursory testing, and I think it makes sense. - Brings back some of the notion of 'outdated' tests, so previously executed tests are shown in a more muted color. This is useful since they no longer are "full" results, and are instead just messages. - Previous results are no longer 'restored' to the extension host on boot, which directly fixes #151147 - Compacts the storage of terminal output: we'll now only keep the first 100 bytes of any terminal output associated with the test, and read from the disk on-demand when the full message is viewed. Later I want to make terminal messages fancier (see the #terminal channel). * fixup! remove unused imports --- .../api/browser/mainThreadTesting.ts | 13 --- .../api/common/extHostTypeConverters.ts | 17 ++-- .../hierarchalByLocation.ts | 2 + .../browser/explorerProjections/index.ts | 5 ++ .../contrib/testing/browser/media/testing.css | 7 +- .../testing/browser/testingDecorations.ts | 10 ++- .../testing/browser/testingExplorerView.ts | 10 +++ .../testing/browser/testingOutputPeek.ts | 8 +- .../browser/testingOutputTerminalService.ts | 2 +- .../contrib/testing/common/testResult.ts | 84 +++++++++++++------ .../testing/common/testResultStorage.ts | 24 +++++- .../contrib/testing/common/testTypes.ts | 28 ++++++- .../testing/common/testingContentProvider.ts | 23 +++-- .../test/common/testResultService.test.ts | 70 ++++++++++++++-- .../test/common/testResultStorage.test.ts | 14 +--- 15 files changed, 231 insertions(+), 86 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTesting.ts b/src/vs/workbench/api/browser/mainThreadTesting.ts index 280741c14a9..fb9a562b3d0 100644 --- a/src/vs/workbench/api/browser/mainThreadTesting.ts +++ b/src/vs/workbench/api/browser/mainThreadTesting.ts @@ -7,7 +7,6 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Disposable, DisposableStore, IDisposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { revive } from 'vs/base/common/marshalling'; -import { isDefined } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { Range } from 'vs/editor/common/core/range'; import { MutableObservableValue } from 'vs/workbench/contrib/testing/common/observableValue'; @@ -19,7 +18,6 @@ import { ITestResultService } from 'vs/workbench/contrib/testing/common/testResu import { IMainThreadTestController, ITestRootProvider, ITestService } from 'vs/workbench/contrib/testing/common/testService'; import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; import { ExtHostContext, ExtHostTestingShape, ILocationDto, ITestControllerPatch, MainContext, MainThreadTestingShape } from '../common/extHost.protocol'; -import { onUnexpectedError } from 'vs/base/common/errors'; @extHostNamedCustomer(MainContext.MainThreadTesting) export class MainThreadTesting extends Disposable implements MainThreadTestingShape, ITestRootProvider { @@ -41,17 +39,6 @@ export class MainThreadTesting extends Disposable implements MainThreadTestingSh super(); this.proxy = extHostContext.getProxy(ExtHostContext.ExtHostTesting); - const prevResults = resultService.results.map(r => r.toJSON()).filter(isDefined); - if (prevResults.length) { - try { - this.proxy.$publishTestResults(prevResults); - } catch (err) { - // See https://github.com/microsoft/vscode/issues/151147 - // Trying to send more than 1GB of data can cause the method to throw. - onUnexpectedError(err); - } - } - this._register(this.testService.onDidCancelTestRun(({ runId }) => { this.proxy.$cancelExtensionTestRun(runId); })); diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 52b5d2c712e..c71c6adcd1e 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -11,7 +11,7 @@ import { ResourceSet } from 'vs/base/common/map'; import { marked } from 'vs/base/common/marked/marked'; import { parse } from 'vs/base/common/marshalling'; import { cloneAndChange } from 'vs/base/common/objects'; -import { isDefined, isEmptyObject, isNumber, isString, isUndefinedOrNull, withNullAsUndefined } from 'vs/base/common/types'; +import { isEmptyObject, isNumber, isString, isUndefinedOrNull, withNullAsUndefined } from 'vs/base/common/types'; import { URI, UriComponents } from 'vs/base/common/uri'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions'; @@ -33,7 +33,7 @@ import { IViewBadge } from 'vs/workbench/common/views'; import * as notebooks from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange'; import * as search from 'vs/workbench/contrib/search/common/search'; -import { TestId } from 'vs/workbench/contrib/testing/common/testId'; +import { TestId, TestPosition } from 'vs/workbench/contrib/testing/common/testId'; import { CoverageDetails, denamespaceTestTag, DetailType, ICoveredCount, IFileCoverage, ISerializedTestResults, ITestErrorMessage, ITestItem, ITestTag, namespaceTestTag, TestMessageType, TestResultItem } from 'vs/workbench/contrib/testing/common/testTypes'; import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn'; import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; @@ -1811,6 +1811,14 @@ export namespace TestTag { export namespace TestResults { const convertTestResultItem = (item: TestResultItem.Serialized, byInternalId: Map): vscode.TestResultSnapshot => { + const children: TestResultItem.Serialized[] = []; + for (const [id, item] of byInternalId) { + if (TestId.compare(item.item.extId, id) === TestPosition.IsChild) { + byInternalId.delete(id); + children.push(item); + } + } + const snapshot: vscode.TestResultSnapshot = ({ ...TestItem.toPlain(item.item), parent: undefined, @@ -1821,10 +1829,7 @@ export namespace TestResults { .filter((m): m is ITestErrorMessage.Serialized => m.type === TestMessageType.Error) .map(TestMessage.to), })), - children: item.children - .map(c => byInternalId.get(c)) - .filter(isDefined) - .map(c => convertTestResultItem(c, byInternalId)) + children: children.map(c => convertTestResultItem(c, byInternalId)) }); for (const child of snapshot.children) { diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts index aabd2add651..d0929417060 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts @@ -105,6 +105,7 @@ export class HierarchicalByLocationProjection extends Disposable implements ITes // children and should trust whatever the result service gives us. const explicitComputed = item.children.size ? undefined : result.computedState; + item.retired = !!result.retired; item.ownState = result.ownComputedState; item.ownDuration = result.ownDuration; @@ -270,6 +271,7 @@ export class HierarchicalByLocationProjection extends Disposable implements ITes const prevState = this.results.getStateById(treeElement.test.item.extId)?.[1]; if (prevState) { + treeElement.retired = !!prevState.retired; treeElement.ownState = prevState.computedState; treeElement.ownDuration = prevState.ownDuration; diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts index b4fa7d0aad1..9edf6da2c25 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts @@ -119,6 +119,11 @@ export class TestItemTreeElement implements IActionableTestTreeElement { return this.test.item.sortText; } + /** + * Whether the node's test result is 'retired' -- from an outdated test run. + */ + public retired = false; + /** * @inheritdoc */ diff --git a/src/vs/workbench/contrib/testing/browser/media/testing.css b/src/vs/workbench/contrib/testing/browser/media/testing.css index d93803367a4..504ecb13ac7 100644 --- a/src/vs/workbench/contrib/testing/browser/media/testing.css +++ b/src/vs/workbench/contrib/testing/browser/media/testing.css @@ -76,6 +76,11 @@ margin-right: 0.25em; } +.test-explorer .computed-state.retired, +.testing-run-glyph.retired { + opacity: 0.7 !important; +} + .test-explorer .test-is-hidden { opacity: 0.8; } @@ -158,7 +163,7 @@ } /** -- filter */ -.testing-filter-action-bar { +.monaco-action-bar.testing-filter-action-bar { flex-shrink: 0; margin: 4px 12px; height: auto; diff --git a/src/vs/workbench/contrib/testing/browser/testingDecorations.ts b/src/vs/workbench/contrib/testing/browser/testingDecorations.ts index d42faa01aa9..1e91f8cdfd4 100644 --- a/src/vs/workbench/contrib/testing/browser/testingDecorations.ts +++ b/src/vs/workbench/contrib/testing/browser/testingDecorations.ts @@ -12,7 +12,6 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent'; import { Disposable, DisposableStore, IReference, MutableDisposable } from 'vs/base/common/lifecycle'; import { ResourceMap } from 'vs/base/common/map'; -import { removeAnsiEscapeCodes } from 'vs/base/common/strings'; import { Constants } from 'vs/base/common/uint'; import { URI } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; @@ -440,6 +439,7 @@ const createRunTestDecoration = (tests: readonly IncrementalTestCollectionItem[] let computedState = TestResultState.Unset; const hoverMessageParts: string[] = []; let testIdWithMessages: string | undefined; + let retired = false; for (let i = 0; i < tests.length; i++) { const test = tests[i]; const resultItem = states[i]; @@ -448,6 +448,7 @@ const createRunTestDecoration = (tests: readonly IncrementalTestCollectionItem[] hoverMessageParts.push(labelForTestInState(test.item.label, state)); } computedState = maxPriority(computedState, state); + retired = retired || !!resultItem?.retired; if (!testIdWithMessages && resultItem?.tasks.some(t => t.messages.length)) { testIdWithMessages = test.item.extId; } @@ -460,7 +461,10 @@ const createRunTestDecoration = (tests: readonly IncrementalTestCollectionItem[] let hoverMessage: IMarkdownString | undefined; - const glyphMarginClassName = ThemeIcon.asClassName(icon) + ' testing-run-glyph'; + let glyphMarginClassName = ThemeIcon.asClassName(icon) + ' testing-run-glyph'; + if (retired) { + glyphMarginClassName += ' retired'; + } return { range: firstLineRange(range), @@ -901,7 +905,7 @@ class TestMessageDecoration implements ITestDecoration { this.location = testMessage.location!; this.line = this.location.range.startLineNumber; const severity = testMessage.type; - const message = typeof testMessage.message === 'string' ? removeAnsiEscapeCodes(testMessage.message) : testMessage.message; + const message = testMessage.message; const options = editorService.resolveDecorationOptions(TestMessageDecoration.decorationId, true); options.hoverMessage = typeof message === 'string' ? new MarkdownString().appendText(message) : message; diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts index a326f747bc5..f293fadc69c 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts @@ -1015,6 +1015,13 @@ const getLabelForTestTreeElement = (element: TestItemTreeElement) => { comment: ['{0} is the original label in testing.treeElementLabel, {1} is a duration'], }, '{0}, in {1}', label, formatDuration(element.duration)); } + + if (element.retired) { + label = localize({ + key: 'testing.treeElementLabelOutdated', + comment: ['{0} is the original label in testing.treeElementLabel'], + }, '{0}, outdated result', label); + } } return label; @@ -1201,6 +1208,9 @@ class TestItemRenderer extends ActionableItemTemplateData { : node.element.state); data.icon.className = 'computed-state ' + (icon ? ThemeIcon.asClassName(icon) : ''); + if (node.element.retired) { + data.icon.className += ' retired'; + } data.label.title = getLabelForTestTreeElement(node.element); dom.reset(data.label, ...renderLabelWithIcons(node.element.label)); diff --git a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts index 988ad294015..82314464f23 100644 --- a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts +++ b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts @@ -27,7 +27,7 @@ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Lazy } from 'vs/base/common/lazy'; import { Disposable, DisposableStore, IDisposable, IReference, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { clamp } from 'vs/base/common/numbers'; -import { count, removeAnsiEscapeCodes } from 'vs/base/common/strings'; +import { count } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import { ICodeEditor, IDiffEditorConstructionOptions, isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction2 } from 'vs/editor/browser/editorExtensions'; @@ -1165,7 +1165,7 @@ class TestMessageElement implements ITreeElement { public readonly taskIndex: number, public readonly messageIndex: number, ) { - const { type, message, location } = test.tasks[taskIndex].messages[messageIndex]; + const { message, location } = test.tasks[taskIndex].messages[messageIndex]; this.location = location; this.uri = this.context = buildTestUri({ @@ -1178,9 +1178,7 @@ class TestMessageElement implements ITreeElement { this.id = this.uri.toString(); - const asPlaintext = type === TestMessageType.Output - ? removeAnsiEscapeCodes(message) - : renderStringAsPlaintext(message); + const asPlaintext = renderStringAsPlaintext(message); const lines = count(asPlaintext.trimRight(), '\n'); this.label = firstLine(asPlaintext); if (lines > 0) { diff --git a/src/vs/workbench/contrib/testing/browser/testingOutputTerminalService.ts b/src/vs/workbench/contrib/testing/browser/testingOutputTerminalService.ts index ebc63725a52..70f9d91907a 100644 --- a/src/vs/workbench/contrib/testing/browser/testingOutputTerminalService.ts +++ b/src/vs/workbench/contrib/testing/browser/testingOutputTerminalService.ts @@ -113,7 +113,7 @@ export class TestingOutputTerminalService implements ITestingOutputTerminalServi icon: testingViewIcon, customPtyImplementation: () => output, name: getTitle(result), - } + }, }), output, result); } diff --git a/src/vs/workbench/contrib/testing/common/testResult.ts b/src/vs/workbench/contrib/testing/common/testResult.ts index 368d43988d7..eb0114497e2 100644 --- a/src/vs/workbench/contrib/testing/common/testResult.ts +++ b/src/vs/workbench/contrib/testing/common/testResult.ts @@ -8,13 +8,13 @@ import { Emitter } from 'vs/base/common/event'; import { Lazy } from 'vs/base/common/lazy'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; -import { Range } from 'vs/editor/common/core/range'; import { localize } from 'vs/nls'; import { IComputedStateAccessor, refreshComputedState } from 'vs/workbench/contrib/testing/common/getComputedState'; import { IObservableValue, MutableObservableValue, staticObservableValue } from 'vs/workbench/contrib/testing/common/observableValue'; import { IRichLocation, ISerializedTestResults, ITestItem, ITestMessage, ITestOutputMessage, ITestRunTask, ITestTaskState, ResolvedTestRunRequest, TestItemExpandState, TestMessageType, TestResultItem, TestResultState } from 'vs/workbench/contrib/testing/common/testTypes'; import { TestCoverage } from 'vs/workbench/contrib/testing/common/testCoverage'; import { maxPriority, statesInOrder, terminalStatePriorities } from 'vs/workbench/contrib/testing/common/testingStates'; +import { removeAnsiEscapeCodes } from 'vs/base/common/strings'; export interface ITestRunTaskResults extends ITestRunTask { /** @@ -75,6 +75,11 @@ export interface ITestResult { */ getOutput(): Promise; + /** + * Loads an output of the result. + */ + getOutputRange(offset: number, length: number): Promise; + /** * Serializes the test result. Used to save and restore results * in the workspace. @@ -125,6 +130,7 @@ export const maxCountPriority = (counts: Readonly) => { return TestResultState.Unset; }; + /** * Deals with output of a {@link LiveTestResult}. By default we pass-through * data into the underlying write stream, but if a client requests to read it @@ -150,6 +156,7 @@ export class LiveOutputController { constructor( private readonly writer: Lazy<[VSBufferWriteableStream, Promise]>, private readonly reader: () => Promise, + private readonly rangeReader: (offset: number, length: number) => Promise, ) { } /** @@ -167,6 +174,34 @@ export class LiveOutputController { return this.writer.getValue()[0].write(data); } + /** + * Reads a range of data from the output. + */ + public getRange(offset: number, length: number) { + if (!this.previouslyWritten) { + return this.rangeReader(offset, length); + } + + const buffer = VSBuffer.alloc(length); + let pos = 0; + for (const chunk of this.previouslyWritten) { + if (pos + chunk.byteLength < offset) { + // no-op + } else if (pos > offset + length) { + break; + } else { + const cs = Math.max(0, offset - pos); + const bs = Math.max(0, pos - offset); + buffer.set(chunk.slice(cs, cs + Math.min(length - bs, chunk.byteLength - cs)), bs); + } + + pos += chunk.byteLength; + } + + const trailing = (offset + length) - pos; + return Promise.resolve(trailing > 0 ? buffer.slice(0, -trailing) : buffer); + } + /** * Reads the value of the stream. */ @@ -316,14 +351,17 @@ export class LiveTestResult implements ITestResult { * Appends output that occurred during the test run. */ public appendOutput(output: VSBuffer, taskId: string, location?: IRichLocation, testId?: string): void { - this.output.append(output); + const preview = output.byteLength > 100 ? output.slice(0, 100).toString() + '…' : output.toString(); const message: ITestOutputMessage = { location, - message: output.toString(), + message: removeAnsiEscapeCodes(preview), offset: this.output.offset, + length: output.byteLength, type: TestMessageType.Output, }; + this.output.append(output); + const index = this.mustGetTaskIndex(taskId); if (testId) { this.testById.get(testId)?.tasks[index].messages.push(message); @@ -416,6 +454,13 @@ export class LiveTestResult implements ITestResult { return this.output.read(); } + /** + * @inheritdoc + */ + public getOutputRange(offset: number, bytes: number) { + return this.output.getRange(offset, bytes); + } + /** * Marks the task in the test run complete. */ @@ -532,10 +577,10 @@ export class LiveTestResult implements ITestResult { private readonly doSerialize = new Lazy((): ISerializedTestResults => ({ id: this.id, completedAt: this.completedAt!, - tasks: this.tasks.map(t => ({ id: t.id, name: t.name, messages: t.otherMessages })), + tasks: this.tasks.map(t => ({ id: t.id, name: t.name })), name: this.name, request: this.request, - items: [...this.testById.values()].map(e => TestResultItem.serialize(e, [...e.children.map(c => c.item.extId)])), + items: [...this.testById.values()].map(TestResultItem.serializeWithoutMessages), })); } @@ -585,6 +630,7 @@ export class HydratedTestResult implements ITestResult { constructor( private readonly serialized: ISerializedTestResults, private readonly outputLoader: () => Promise, + private readonly outputRangeLoader: (offset: number, length: number) => Promise, private readonly persist = true, ) { this.id = serialized.id; @@ -594,15 +640,7 @@ export class HydratedTestResult implements ITestResult { name: task.name, running: false, coverage: staticObservableValue(undefined), - otherMessages: task.messages.map(m => ({ - message: m.message, - type: m.type, - offset: m.offset, - location: m.location && { - uri: URI.revive(m.location.uri), - range: Range.lift(m.location.range) - }, - })) + otherMessages: [] })); this.name = serialized.name; this.request = serialized.request; @@ -610,21 +648,19 @@ export class HydratedTestResult implements ITestResult { for (const item of serialized.items) { const cast: TestResultItem = { ...item } as any; cast.item.uri = URI.revive(cast.item.uri); - - for (const task of cast.tasks) { - for (const message of task.messages) { - if (message.location) { - message.location.uri = URI.revive(message.location.uri); - message.location.range = Range.lift(message.location.range); - } - } - } - + cast.retired = true; this.counts[item.ownComputedState]++; this.testById.set(item.item.extId, cast); } } + /** + * @inheritdoc + */ + public getOutputRange(offset: number, bytes: number) { + return this.outputRangeLoader(offset, bytes); + } + /** * @inheritdoc */ diff --git a/src/vs/workbench/contrib/testing/common/testResultStorage.ts b/src/vs/workbench/contrib/testing/common/testResultStorage.ts index d2d294aa081..db6b0e82c01 100644 --- a/src/vs/workbench/contrib/testing/common/testResultStorage.ts +++ b/src/vs/workbench/contrib/testing/common/testResultStorage.ts @@ -80,7 +80,7 @@ export abstract class BaseTestResultStorage implements ITestResultStorage { return undefined; } - return new HydratedTestResult(contents, () => this.readOutputForResultId(id)); + return new HydratedTestResult(contents, () => this.readOutputForResultId(id), (o, l) => this.readOutputRangeForResultId(id, o, l)); } catch (e) { this.logService.warn(`Error deserializing stored test result ${id}`, e); return undefined; @@ -101,6 +101,7 @@ export abstract class BaseTestResultStorage implements ITestResultStorage { return [stream, promise]; }), () => this.readOutputForResultId(resultId), + (o, l) => this.readOutputRangeForResultId(resultId, o, l) ); } @@ -169,10 +170,15 @@ export abstract class BaseTestResultStorage implements ITestResultStorage { protected abstract readForResultId(id: string): Promise; /** - * Reads serialized results for the test. Is allowed to throw. + * Reads output as a stream for the test. */ protected abstract readOutputForResultId(id: string): Promise; + /** + * Reads an output range for the test. + */ + protected abstract readOutputRangeForResultId(id: string, offset: number, length: number): Promise; + /** * Deletes serialized results for the test. */ @@ -213,6 +219,10 @@ export class InMemoryResultStorage extends BaseTestResultStorage { protected storeOutputForResultId(id: string, input: VSBufferWriteableStream): Promise { throw new Error('Method not implemented.'); } + + protected readOutputRangeForResultId(id: string, offset: number, length: number): Promise { + throw new Error('Method not implemented.'); + } } export class TestResultStorage extends BaseTestResultStorage { @@ -242,6 +252,16 @@ export class TestResultStorage extends BaseTestResultStorage { return this.fileService.del(this.getResultJsonPath(id)).catch(() => undefined); } + protected async readOutputRangeForResultId(id: string, offset: number, length: number): Promise { + try { + const { value } = await this.fileService.readFile(this.getResultOutputPath(id), { position: offset, length }); + return value; + } catch { + return VSBuffer.alloc(0); + } + } + + protected async readOutputForResultId(id: string): Promise { try { const { value } = await this.fileService.readFileStream(this.getResultOutputPath(id)); diff --git a/src/vs/workbench/contrib/testing/common/testTypes.ts b/src/vs/workbench/contrib/testing/common/testTypes.ts index 29ae1628071..4f9620cc4a8 100644 --- a/src/vs/workbench/contrib/testing/common/testTypes.ts +++ b/src/vs/workbench/contrib/testing/common/testTypes.ts @@ -158,6 +158,7 @@ export interface ITestOutputMessage { message: string; type: TestMessageType.Output; offset: number; + length: number; location: IRichLocation | undefined; } @@ -165,6 +166,7 @@ export namespace ITestOutputMessage { export interface Serialized { message: string; offset: number; + length: number; type: TestMessageType.Output; location: IRichLocation.Serialize | undefined; } @@ -173,6 +175,7 @@ export namespace ITestOutputMessage { message: message.message, type: TestMessageType.Output, offset: message.offset, + length: message.length, location: message.location && IRichLocation.serialize(message.location), }); @@ -180,6 +183,7 @@ export namespace ITestOutputMessage { message: message.message, type: TestMessageType.Output, offset: message.offset, + length: message.length, location: message.location && IRichLocation.deserialize(message.location), }); } @@ -209,6 +213,12 @@ export namespace ITestTaskState { messages: ITestMessage.Serialized[]; } + export const serializeWithoutMessages = (state: ITestTaskState): Serialized => ({ + state: state.state, + duration: state.duration, + messages: [], + }); + export const serialize = (state: ITestTaskState): Serialized => ({ state: state.state, duration: state.duration, @@ -420,23 +430,33 @@ export interface TestResultItem extends InternalTestItem { computedState: TestResultState; /** Max duration of the item's tasks (if run directly) */ ownDuration?: number; + /** Whether this test item is outdated */ + retired?: boolean; } export namespace TestResultItem { /** Serialized version of the TestResultItem */ export interface Serialized extends InternalTestItem.Serialized { - children: string[]; tasks: ITestTaskState.Serialized[]; ownComputedState: TestResultState; computedState: TestResultState; + retired?: boolean; } - export const serialize = (original: TestResultItem, children: string[]): Serialized => ({ + export const serializeWithoutMessages = (original: TestResultItem): Serialized => ({ + ...InternalTestItem.serialize(original), + ownComputedState: original.ownComputedState, + computedState: original.computedState, + tasks: original.tasks.map(ITestTaskState.serializeWithoutMessages), + retired: original.retired, + }); + + export const serialize = (original: TestResultItem): Serialized => ({ ...InternalTestItem.serialize(original), - children, ownComputedState: original.ownComputedState, computedState: original.computedState, tasks: original.tasks.map(ITestTaskState.serialize), + retired: original.retired, }); } @@ -448,7 +468,7 @@ export interface ISerializedTestResults { /** Subset of test result items */ items: TestResultItem.Serialized[]; /** Tasks involved in the run. */ - tasks: { id: string; name: string | undefined; messages: ITestOutputMessage.Serialized[] }[]; + tasks: { id: string; name: string | undefined }[]; /** Human-readable name of the test run. */ name: string; /** Test trigger informaton */ diff --git a/src/vs/workbench/contrib/testing/common/testingContentProvider.ts b/src/vs/workbench/contrib/testing/common/testingContentProvider.ts index 4ce00913d35..16be2168fde 100644 --- a/src/vs/workbench/contrib/testing/common/testingContentProvider.ts +++ b/src/vs/workbench/contrib/testing/common/testingContentProvider.ts @@ -42,7 +42,8 @@ export class TestingContentProvider implements IWorkbenchContribution, ITextMode return null; } - const test = this.resultService.getResult(parsed.resultId)?.getStateById(parsed.testExtId); + const result = this.resultService.getResult(parsed.resultId); + const test = result?.getStateById(parsed.testExtId); if (!test) { return null; @@ -63,15 +64,19 @@ export class TestingContentProvider implements IWorkbenchContribution, ITextMode } case TestUriType.ResultMessage: { const message = test.tasks[parsed.taskIndex].messages[parsed.messageIndex]; - if (message) { - if (typeof message.message === 'string') { - text = message.type === TestMessageType.Output ? removeAnsiEscapeCodes(message.message) : message.message; - } else { - text = message.message.value; - language = this.languageService.createById('markdown'); - } + if (!message) { + break; + } + + if (message.type === TestMessageType.Output) { + const content = await result!.getOutputRange(message.offset, message.length); + text = removeAnsiEscapeCodes(content.toString()); + } else if (typeof message.message === 'string') { + text = message.message; + } else { + text = message.message.value; + language = this.languageService.createById('markdown'); } - break; } } diff --git a/src/vs/workbench/contrib/testing/test/common/testResultService.test.ts b/src/vs/workbench/contrib/testing/test/common/testResultService.test.ts index 4452c491436..83d4a0a6703 100644 --- a/src/vs/workbench/contrib/testing/test/common/testResultService.test.ts +++ b/src/vs/workbench/contrib/testing/test/common/testResultService.test.ts @@ -14,13 +14,18 @@ import { TestId } from 'vs/workbench/contrib/testing/common/testId'; import { TestProfileService } from 'vs/workbench/contrib/testing/common/testProfileService'; import { HydratedTestResult, LiveOutputController, LiveTestResult, makeEmptyCounts, resultItemParents, TestResultItemChange, TestResultItemChangeReason } from 'vs/workbench/contrib/testing/common/testResult'; import { TestResultService } from 'vs/workbench/contrib/testing/common/testResultService'; -import { InMemoryResultStorage, ITestResultStorage } from 'vs/workbench/contrib/testing/common/testResultStorage'; +import { InMemoryResultStorage, ITestResultStorage, TestResultStorage } from 'vs/workbench/contrib/testing/common/testResultStorage'; import { getInitializedMainTestCollection, testStubs, TestTestCollection } from 'vs/workbench/contrib/testing/test/common/testStubs'; import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; +import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; +import { FileService } from 'vs/platform/files/common/fileService'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { URI } from 'vs/base/common/uri'; export const emptyOutputController = () => new LiveOutputController( new Lazy(() => [newWriteableBufferStream(), Promise.resolve()]), () => Promise.resolve(bufferToStream(VSBuffer.alloc(0))), + () => Promise.resolve(VSBuffer.alloc(0)), ); suite('Workbench - Test Results Service', () => { @@ -235,8 +240,10 @@ suite('Workbench - Test Results Service', () => { const [rehydrated, actual] = results.getStateById(tests.root.id)!; const expected: any = { ...r.getStateById(tests.root.id)! }; expected.item.uri = actual.item.uri; - expected.item.children = actual.item.children; - assert.deepStrictEqual(actual, { ...expected, children: [new TestId(['ctrlId', 'id-a']).toString()] }); + expected.item.children = undefined; + expected.retired = true; + delete expected.children; + assert.deepStrictEqual(actual, { ...expected }); assert.deepStrictEqual(rehydrated.counts, r.counts); assert.strictEqual(typeof rehydrated.completedAt, 'number'); }); @@ -275,7 +282,7 @@ suite('Workbench - Test Results Service', () => { const makeHydrated = async (completedAt = 42, state = TestResultState.Passed) => new HydratedTestResult({ completedAt, id: 'some-id', - tasks: [{ id: 't', messages: [], name: undefined }], + tasks: [{ id: 't', name: undefined }], name: 'hello world', request: defaultOpts([]), items: [{ @@ -283,9 +290,8 @@ suite('Workbench - Test Results Service', () => { tasks: [{ state, duration: 0, messages: [] }], computedState: state, ownComputedState: state, - children: [], }] - }, () => Promise.resolve(bufferToStream(VSBuffer.alloc(0)))); + }, () => Promise.resolve(bufferToStream(VSBuffer.alloc(0))), () => Promise.resolve(VSBuffer.alloc(0))); test('pushes hydrated results', async () => { results.push(r); @@ -322,4 +328,56 @@ suite('Workbench - Test Results Service', () => { r.getStateById(tests.root.id), ]); }); + + suite('output controller', () => { + + const disposables = new DisposableStore(); + const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' }); + let storage: TestResultStorage; + + setup(() => { + const logService = new NullLogService(); + const fileService = disposables.add(new FileService(logService)); + const fileSystemProvider = disposables.add(new InMemoryFileSystemProvider()); + disposables.add(fileService.registerProvider(ROOT.scheme, fileSystemProvider)); + + storage = new TestResultStorage( + new TestStorageService(), + new NullLogService(), + { getWorkspace: () => ({ id: 'test' }) } as any, + fileService, + { workspaceStorageHome: ROOT } as any + ); + }); + + teardown(() => disposables.clear()); + + test('reads live output ranges', async () => { + const ctrl = storage.getOutputController('a'); + + ctrl.append(VSBuffer.fromString('12345')); + ctrl.append(VSBuffer.fromString('67890')); + ctrl.append(VSBuffer.fromString('12345')); + ctrl.append(VSBuffer.fromString('67890')); + + assert.deepStrictEqual(await ctrl.getRange(0, 5), VSBuffer.fromString('12345')); + assert.deepStrictEqual(await ctrl.getRange(5, 5), VSBuffer.fromString('67890')); + assert.deepStrictEqual(await ctrl.getRange(7, 6), VSBuffer.fromString('890123')); + assert.deepStrictEqual(await ctrl.getRange(15, 5), VSBuffer.fromString('67890')); + assert.deepStrictEqual(await ctrl.getRange(15, 10), VSBuffer.fromString('67890')); + }); + + test('reads stored output ranges', async () => { + const ctrl = storage.getOutputController('a'); + + ctrl.append(VSBuffer.fromString('12345')); + ctrl.append(VSBuffer.fromString('67890')); + ctrl.append(VSBuffer.fromString('12345')); + ctrl.append(VSBuffer.fromString('67890')); + await ctrl.close(); + + // sanity: + assert.deepStrictEqual(await ctrl.getRange(0, 5), VSBuffer.fromString('12345')); + }); + }); }); diff --git a/src/vs/workbench/contrib/testing/test/common/testResultStorage.test.ts b/src/vs/workbench/contrib/testing/test/common/testResultStorage.test.ts index e10d994eb03..115095f4eef 100644 --- a/src/vs/workbench/contrib/testing/test/common/testResultStorage.test.ts +++ b/src/vs/workbench/contrib/testing/test/common/testResultStorage.test.ts @@ -6,7 +6,6 @@ import * as assert from 'assert'; import { range } from 'vs/base/common/arrays'; import { NullLogService } from 'vs/platform/log/common/log'; -import { TestId } from 'vs/workbench/contrib/testing/common/testId'; import { ITestResult, LiveTestResult } from 'vs/workbench/contrib/testing/common/testResult'; import { InMemoryResultStorage, RETAIN_MAX_RESULTS } from 'vs/workbench/contrib/testing/common/testResultStorage'; import { emptyOutputController } from 'vs/workbench/contrib/testing/test/common/testResultService.test'; @@ -16,7 +15,7 @@ import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServic suite('Workbench - Test Result Storage', () => { let storage: InMemoryResultStorage; - const makeResult = (addMessage?: string) => { + const makeResult = (taskName = 't') => { const t = new LiveTestResult( '', emptyOutputController(), @@ -24,7 +23,7 @@ suite('Workbench - Test Result Storage', () => { { targets: [] } ); - t.addTask({ id: 't', name: undefined, running: true }); + t.addTask({ id: taskName, name: undefined, running: true }); const tests = testStubs.nested(); tests.expand(tests.root.id, Infinity); t.addTestChainToRun('ctrlId', [ @@ -33,15 +32,6 @@ suite('Workbench - Test Result Storage', () => { tests.root.children.get('id-a')!.children.get('id-aa')!.toTestItem(), ]); - if (addMessage) { - t.appendMessage(new TestId(['ctrlId', 'id-a']).toString(), 't', { - message: addMessage, - actual: undefined, - expected: undefined, - location: undefined, - type: 0, - }); - } t.markComplete(); return t; }; From f236be6a6de89aa6cd6f41c25e532b4a3a114627 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 2 Aug 2022 17:35:25 +0200 Subject: [PATCH 146/303] Adding the click event to the dom.addDisposableListener. Fixes #156879. (#156891) * Adding the click event to the dom.addDisposableListener. Fixes #156879. * Register the disposable --- .../contrib/stickyScroll/browser/stickyScroll.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index 4ad96167950..90d4316cb2f 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore, dispose } from 'vs/base/common/lifecycle'; import { IActiveCodeEditor, ICodeEditor, IOverlayWidget, IOverlayWidgetPosition } from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; @@ -239,12 +239,13 @@ class StickyScrollController extends Disposable implements IEditorContribution { const _ttPolicy = window.trustedTypes?.createPolicy('stickyScrollViewLayer', { createHTML: value => value }); -class StickyScrollCodeLine { +class StickyScrollCodeLine extends Disposable { public readonly effectiveLineHeight: number = 0; constructor(private readonly _lineNumber: number, private readonly _depth: number, private readonly _editor: IActiveCodeEditor, private readonly _zIndex: number, private readonly _relativePosition: number) { + super(); this.effectiveLineHeight = this._editor.getOption(EditorOption.lineHeight) + this._relativePosition; } @@ -315,11 +316,11 @@ class StickyScrollCodeLine { innerLineNumberHTML.style.lineHeight = this._editor.getOption(EditorOption.lineHeight).toString() + 'px'; lineNumberHTMLNode.appendChild(innerLineNumberHTML); - root.onclick = e => { + this._register(dom.addDisposableListener(root, 'click', e => { e.stopPropagation(); e.preventDefault(); this._editor.revealPosition({ lineNumber: this._lineNumber - this._depth + 1, column: 1 }); - }; + })); root.onmouseover = e => { innerLineNumberHTML.style.background = `var(--vscode-editorStickyScrollHover-background)`; @@ -401,6 +402,7 @@ class StickyScrollWidget implements IOverlayWidget { } emptyRootNode() { + dispose(this.arrayOfCodeLines); this.arrayOfCodeLines.length = 0; dom.clearNode(this.rootDomNode); } From e93a125ac7aca6eae2a8e19f0fa7d7499b026027 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 2 Aug 2022 18:15:14 +0200 Subject: [PATCH 147/303] Extracting the CSS to a separate file (fixes #156876) (#156890) Extracting the CSS to a separate file. --- .../stickyScroll/browser/stickyScroll.css | 35 +++++++ .../stickyScroll/browser/stickyScroll.ts | 96 ++++++++----------- 2 files changed, 75 insertions(+), 56 deletions(-) create mode 100644 src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css new file mode 100644 index 00000000000..878cc212070 --- /dev/null +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.monaco-editor .sticky-line { + color : var(--vscode-editorLineNumber-foreground); + overflow : hidden; + white-space : nowrap; + display : inline-block; +} + +.monaco-editor .sticky-line-number { + text-align : right; + float : left; +} + +.monaco-editor .sticky-line-root { + background-color : var(--vscode-editorStickyScroll-background); + overflow : hidden; + white-space : nowrap; + width : 100%; +} + +.monaco-editor .sticky-line-root:hover { + background-color: var(--vscode-editorStickyScrollHover-background); + cursor : pointer; +} + +.monaco-editor .sticky-widget { + width : 100%; + box-shadow : var(--vscode-scrollbar-shadow) 0 6px 6px -6px; + z-index : 2; + background-color : var(--vscode-editorStickyScroll-background); +} diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index 90d4316cb2f..e31b5b3030d 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -11,7 +11,7 @@ import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeat import { OutlineModel, OutlineElement } from 'vs/editor/contrib/documentSymbols/browser/outlineModel'; import { CancellationToken, CancellationTokenSource, } from 'vs/base/common/cancellation'; import * as dom from 'vs/base/browser/dom'; -import { EditorOption } from 'vs/editor/common/config/editorOptions'; +import { EditorLayoutInfo, EditorOption } from 'vs/editor/common/config/editorOptions'; import { createStringBuilder } from 'vs/editor/common/core/stringBuilder'; import { RenderLineInput, renderViewLine } from 'vs/editor/common/viewLayout/viewLineRenderer'; import { SymbolKind } from 'vs/editor/common/languages'; @@ -19,6 +19,7 @@ import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations'; import { RunOnceScheduler } from 'vs/base/common/async'; import { IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents'; import { Position } from 'vs/editor/common/core/position'; +import 'vs/css!./stickyScroll'; import { Range } from 'vs/editor/common/core/range'; class StickyScrollController extends Disposable implements IEditorContribution { @@ -73,7 +74,7 @@ class StickyScrollController extends Disposable implements IEditorContribution { private _onDidResize() { const width = this._editor.getLayoutInfo().width - this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth - this._editor.getLayoutInfo().verticalScrollbarWidth; - this.stickyScrollWidget.getDomNode().style.width = width + 'px'; + this.stickyScrollWidget.getDomNode().style.width = `${width}px`; } private _needsUpdate(event: IModelTokensChangedEvent) { @@ -243,8 +244,13 @@ class StickyScrollCodeLine extends Disposable { public readonly effectiveLineHeight: number = 0; - constructor(private readonly _lineNumber: number, private readonly _depth: number, private readonly _editor: IActiveCodeEditor, - private readonly _zIndex: number, private readonly _relativePosition: number) { + constructor( + private readonly _lineNumber: number, + private readonly _depth: number, + private readonly _editor: IActiveCodeEditor, + private readonly _zIndex: number, + private readonly _relativePosition: number + ) { super(); this.effectiveLineHeight = this._editor.getOption(EditorOption.lineHeight) + this._relativePosition; } @@ -259,8 +265,10 @@ class StickyScrollCodeLine extends Disposable { const viewModel = this._editor._getViewModel(); const viewLineNumber = viewModel.coordinatesConverter.convertModelPositionToViewPosition(new Position(this._lineNumber, 1)).lineNumber; const lineRenderingData = viewModel.getViewLineRenderingData(viewLineNumber); - const width = this._editor.getLayoutInfo().width - this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth - this._editor.getLayoutInfo().verticalScrollbarWidth; + const layoutInfo = this._editor.getLayoutInfo(); + const width = layoutInfo.width - layoutInfo.minimap.minimapCanvasOuterWidth - layoutInfo.verticalScrollbarWidth; const minimapSide = this._editor.getOption(EditorOption.minimap).side; + const lineHeight = this._editor.getOption(EditorOption.lineHeight); let actualInlineDecorations: LineDecoration[]; try { @@ -269,9 +277,13 @@ class StickyScrollCodeLine extends Disposable { actualInlineDecorations = []; } - const renderLineInput: RenderLineInput = new RenderLineInput(true, true, lineRenderingData.content, lineRenderingData.continuesWithWrappedLine, - lineRenderingData.isBasicASCII, lineRenderingData.containsRTL, 0, lineRenderingData.tokens, actualInlineDecorations, lineRenderingData.tabSize, - lineRenderingData.startVisibleColumn, 1, 1, 1, 500, 'none', true, true, null); + const renderLineInput: RenderLineInput = + new RenderLineInput(true, true, lineRenderingData.content, + lineRenderingData.continuesWithWrappedLine, + lineRenderingData.isBasicASCII, lineRenderingData.containsRTL, 0, + lineRenderingData.tokens, actualInlineDecorations, + lineRenderingData.tabSize, lineRenderingData.startVisibleColumn, + 1, 1, 1, 500, 'none', true, true, null); const sb = createStringBuilder(2000); renderViewLine(renderLineInput, sb); @@ -284,36 +296,29 @@ class StickyScrollCodeLine extends Disposable { } const lineHTMLNode = document.createElement('span'); - lineHTMLNode.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; - lineHTMLNode.style.overflow = 'hidden'; - lineHTMLNode.style.whiteSpace = 'nowrap'; - lineHTMLNode.style.display = 'inline-block'; - lineHTMLNode.style.lineHeight = this._editor.getOption(EditorOption.lineHeight).toString() + 'px'; + lineHTMLNode.className = 'sticky-line'; + lineHTMLNode.style.lineHeight = `${lineHeight}px`; lineHTMLNode.innerHTML = newLine as string; const lineNumberHTMLNode = document.createElement('span'); + lineNumberHTMLNode.className = 'sticky-line'; + lineNumberHTMLNode.style.lineHeight = `${lineHeight}px`; if (minimapSide === 'left') { - lineNumberHTMLNode.style.width = this._editor.getLayoutInfo().contentLeft - this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth + 'px'; + lineNumberHTMLNode.style.width = `${layoutInfo.contentLeft - layoutInfo.minimap.minimapCanvasOuterWidth}px`; } else if (minimapSide === 'right') { - lineNumberHTMLNode.style.width = this._editor.getLayoutInfo().contentLeft.toString() + 'px'; + lineNumberHTMLNode.style.width = `${layoutInfo.contentLeft}px`; } - lineNumberHTMLNode.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; - lineNumberHTMLNode.style.color = 'var(--vscode-editorLineNumber-foreground)'; - lineNumberHTMLNode.style.display = 'inline-block'; - lineNumberHTMLNode.style.lineHeight = this._editor.getOption(EditorOption.lineHeight).toString() + 'px'; const innerLineNumberHTML = document.createElement('span'); innerLineNumberHTML.innerText = this._lineNumber.toString(); + innerLineNumberHTML.className = 'sticky-line-number'; + innerLineNumberHTML.style.lineHeight = `${lineHeight}px`; + innerLineNumberHTML.style.width = `${layoutInfo.lineNumbersWidth}px`; if (minimapSide === 'left') { - innerLineNumberHTML.style.paddingLeft = this._editor.getLayoutInfo().lineNumbersLeft - this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth + 'px'; + innerLineNumberHTML.style.paddingLeft = `${layoutInfo.lineNumbersLeft - layoutInfo.minimap.minimapCanvasOuterWidth}px`; } else if (minimapSide === 'right') { - innerLineNumberHTML.style.paddingLeft = this._editor.getLayoutInfo().lineNumbersLeft.toString() + 'px'; + innerLineNumberHTML.style.paddingLeft = `${layoutInfo.lineNumbersLeft}px`; } - innerLineNumberHTML.style.width = this._editor.getLayoutInfo().lineNumbersWidth.toString() + 'px'; - innerLineNumberHTML.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; - innerLineNumberHTML.style.textAlign = 'right'; - innerLineNumberHTML.style.float = 'left'; - innerLineNumberHTML.style.lineHeight = this._editor.getOption(EditorOption.lineHeight).toString() + 'px'; lineNumberHTMLNode.appendChild(innerLineNumberHTML); this._register(dom.addDisposableListener(root, 'click', e => { @@ -322,23 +327,6 @@ class StickyScrollCodeLine extends Disposable { this._editor.revealPosition({ lineNumber: this._lineNumber - this._depth + 1, column: 1 }); })); - root.onmouseover = e => { - innerLineNumberHTML.style.background = `var(--vscode-editorStickyScrollHover-background)`; - lineHTMLNode.style.backgroundColor = `var(--vscode-editorStickyScrollHover-background)`; - lineNumberHTMLNode.style.backgroundColor = `var(--vscode-editorStickyScrollHover-background)`; - root.style.backgroundColor = `var(--vscode-editorStickyScrollHover-background)`; - innerLineNumberHTML.style.cursor = `pointer`; - lineHTMLNode.style.cursor = `pointer`; - root.style.cursor = `pointer`; - lineNumberHTMLNode.style.cursor = `pointer`; - }; - root.onmouseleave = e => { - innerLineNumberHTML.style.background = `var(--vscode-editorStickyScroll-background)`; - lineHTMLNode.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; - lineNumberHTMLNode.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; - root.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; - }; - this._editor.applyFontInfo(lineHTMLNode); this._editor.applyFontInfo(innerLineNumberHTML); @@ -346,18 +334,15 @@ class StickyScrollCodeLine extends Disposable { root.appendChild(lineHTMLNode); root.style.zIndex = this._zIndex.toString(); - root.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; - root.style.overflow = 'hidden'; - root.style.whiteSpace = 'nowrap'; - root.style.width = width + 'px'; - root.style.lineHeight = this._editor.getOption(EditorOption.lineHeight).toString() + 'px'; - root.style.height = this._editor.getOption(EditorOption.lineHeight).toString() + 'px'; + root.className = 'sticky-line-root'; + root.style.lineHeight = `${lineHeight}px`; + root.style.width = `${width}px`; + root.style.height = `${lineHeight}px`; // Special case for last line of sticky scroll if (this._relativePosition) { root.style.position = 'relative'; root.style.top = this._relativePosition + 'px'; - root.style.width = width + 'px'; } return root; } @@ -367,13 +352,14 @@ class StickyScrollWidget implements IOverlayWidget { private readonly arrayOfCodeLines: StickyScrollCodeLine[] = []; private readonly rootDomNode: HTMLElement = document.createElement('div'); + private readonly layoutInfo: EditorLayoutInfo; constructor(public readonly _editor: ICodeEditor) { + this.layoutInfo = this._editor.getLayoutInfo(); this.rootDomNode = document.createElement('div'); - const width = this._editor.getLayoutInfo().width - this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth - this._editor.getLayoutInfo().verticalScrollbarWidth; - this.rootDomNode.style.width = width + 'px'; - this.rootDomNode.style.boxShadow = `var(--vscode-scrollbar-shadow) 0 6px 6px -6px`; - this.rootDomNode.style.overflow = 'hidden'; + this.rootDomNode.className = 'sticky-widget'; + const width = this.layoutInfo.width - this.layoutInfo.minimap.minimapCanvasOuterWidth - this.layoutInfo.verticalScrollbarWidth; + this.rootDomNode.style.width = `${width}px`; } get codeLineCount() { @@ -412,8 +398,6 @@ class StickyScrollWidget implements IOverlayWidget { } getDomNode(): HTMLElement { - this.rootDomNode.style.zIndex = '2'; - this.rootDomNode.style.backgroundColor = `var(--vscode-editorStickyScroll-background)`; const minimapSide = this._editor.getOption(EditorOption.minimap).side; if (minimapSide === 'left') { this.rootDomNode.style.marginLeft = this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth + 'px'; From 2842ae24814d9c37d96c49c4b8d5009d1c8e318c Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Tue, 2 Aug 2022 09:51:09 -0700 Subject: [PATCH 148/303] Make sure non-matching characters aren't included in highlights (#154537) --- src/vs/base/common/filters.ts | 13 ++++++++++++- src/vs/base/test/common/filters.test.ts | 10 +++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/vs/base/common/filters.ts b/src/vs/base/common/filters.ts index d0a8a09aa70..ebad3f5805d 100644 --- a/src/vs/base/common/filters.ts +++ b/src/vs/base/common/filters.ts @@ -316,7 +316,18 @@ function _matchesWords(word: string, target: string, i: number, j: number, conti nextWordIndex++; } } - return result === null ? null : join({ start: j, end: j + 1 }, result); + + if (!result) { + return null; + } + + // If the characters don't exactly match, then they must be word separators (see charactersMatch(...)). + // We don't want to include this in the matches but we don't want to throw the target out all together so we return `result`. + if (word.charCodeAt(i) !== target.charCodeAt(j)) { + return result; + } + + return join({ start: j, end: j + 1 }, result); } } diff --git a/src/vs/base/test/common/filters.test.ts b/src/vs/base/test/common/filters.test.ts index 8b890f21662..29754cc4eed 100644 --- a/src/vs/base/test/common/filters.test.ts +++ b/src/vs/base/test/common/filters.test.ts @@ -185,24 +185,28 @@ suite('Filters', () => { assert(matchesWords('Debug Console', 'Open: Debug Console')); filterOk(matchesWords, 'gp', 'Git: Pull', [{ start: 0, end: 1 }, { start: 5, end: 6 }]); - filterOk(matchesWords, 'g p', 'Git: Pull', [{ start: 0, end: 1 }, { start: 3, end: 4 }, { start: 5, end: 6 }]); + filterOk(matchesWords, 'g p', 'Git: Pull', [{ start: 0, end: 1 }, { start: 5, end: 6 }]); filterOk(matchesWords, 'gipu', 'Git: Pull', [{ start: 0, end: 2 }, { start: 5, end: 7 }]); filterOk(matchesWords, 'gp', 'Category: Git: Pull', [{ start: 10, end: 11 }, { start: 15, end: 16 }]); - filterOk(matchesWords, 'g p', 'Category: Git: Pull', [{ start: 10, end: 11 }, { start: 13, end: 14 }, { start: 15, end: 16 }]); + filterOk(matchesWords, 'g p', 'Category: Git: Pull', [{ start: 10, end: 11 }, { start: 15, end: 16 }]); filterOk(matchesWords, 'gipu', 'Category: Git: Pull', [{ start: 10, end: 12 }, { start: 15, end: 17 }]); filterNotOk(matchesWords, 'it', 'Git: Pull'); filterNotOk(matchesWords, 'll', 'Git: Pull'); filterOk(matchesWords, 'git: プル', 'git: プル', [{ start: 0, end: 7 }]); - filterOk(matchesWords, 'git プル', 'git: プル', [{ start: 0, end: 4 }, { start: 5, end: 7 }]); + filterOk(matchesWords, 'git プル', 'git: プル', [{ start: 0, end: 3 }, { start: 5, end: 7 }]); filterOk(matchesWords, 'öäk', 'Öhm: Älles Klar', [{ start: 0, end: 1 }, { start: 5, end: 6 }, { start: 11, end: 12 }]); // Handles issue #123915 filterOk(matchesWords, 'C++', 'C/C++: command', [{ start: 2, end: 5 }]); + // Handles issue #154533 + filterOk(matchesWords, '.', ':', []); + filterOk(matchesWords, '.', '.', [{ start: 0, end: 1 }]); + // assert.ok(matchesWords('gipu', 'Category: Git: Pull', true) === null); // assert.deepStrictEqual(matchesWords('pu', 'Category: Git: Pull', true), [{ start: 15, end: 17 }]); From 2bdfa39fab4dfb91c543101438e37c1954509d3b Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 2 Aug 2022 10:19:20 -0700 Subject: [PATCH 149/303] [main]: Update list support find context key name (#156905) Fix #156878. Update list support find context key name Co-authored-by: Connor Peet --- src/vs/platform/list/browser/listService.ts | 9 +++++---- src/vs/workbench/browser/actions/listCommands.ts | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 5af76e7958e..197fb970f66 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -120,12 +120,12 @@ export const WorkbenchListHasSelectionOrFocus = new RawContextKey('list export const WorkbenchListDoubleSelection = new RawContextKey('listDoubleSelection', false); export const WorkbenchListMultiSelection = new RawContextKey('listMultiSelection', false); export const WorkbenchListSelectionNavigation = new RawContextKey('listSelectionNavigation', false); +export const WorkbenchListSupportsFind = new RawContextKey('listSupportsFind', true); export const WorkbenchTreeElementCanCollapse = new RawContextKey('treeElementCanCollapse', false); export const WorkbenchTreeElementHasParent = new RawContextKey('treeElementHasParent', false); export const WorkbenchTreeElementCanExpand = new RawContextKey('treeElementCanExpand', false); export const WorkbenchTreeElementHasChild = new RawContextKey('treeElementHasChild', false); export const WorkbenchTreeFindOpen = new RawContextKey('treeFindOpen', false); -export const WorkbenchTreeSupportsFind = new RawContextKey('treeSupportsFind', true); const WorkbenchListTypeNavigationModeKey = 'listTypeNavigationMode'; /** @@ -1136,6 +1136,7 @@ class WorkbenchTreeInternals { readonly contextKeyService: IContextKeyService; private listSupportsMultiSelect: IContextKey; + private listSupportFindWidget: IContextKey; private hasSelectionOrFocus: IContextKey; private hasDoubleSelection: IContextKey; private hasMultiSelection: IContextKey; @@ -1144,7 +1145,6 @@ class WorkbenchTreeInternals { private treeElementCanExpand: IContextKey; private treeElementHasChild: IContextKey; private treeFindOpen: IContextKey; - private treeSupportFindWidget: IContextKey; private _useAltAsMultipleSelectionModifier: boolean; private disposables: IDisposable[] = []; private styler: IDisposable | undefined; @@ -1170,6 +1170,9 @@ class WorkbenchTreeInternals { const listSelectionNavigation = WorkbenchListSelectionNavigation.bindTo(this.contextKeyService); listSelectionNavigation.set(Boolean(options.selectionNavigation)); + this.listSupportFindWidget = WorkbenchListSupportsFind.bindTo(this.contextKeyService); + this.listSupportFindWidget.set(options.findWidgetEnabled ?? true); + this.hasSelectionOrFocus = WorkbenchListHasSelectionOrFocus.bindTo(this.contextKeyService); this.hasDoubleSelection = WorkbenchListDoubleSelection.bindTo(this.contextKeyService); this.hasMultiSelection = WorkbenchListMultiSelection.bindTo(this.contextKeyService); @@ -1180,8 +1183,6 @@ class WorkbenchTreeInternals { this.treeElementHasChild = WorkbenchTreeElementHasChild.bindTo(this.contextKeyService); this.treeFindOpen = WorkbenchTreeFindOpen.bindTo(this.contextKeyService); - this.treeSupportFindWidget = WorkbenchTreeSupportsFind.bindTo(this.contextKeyService); - this.treeSupportFindWidget.set(options.findWidgetEnabled ?? true); this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService); diff --git a/src/vs/workbench/browser/actions/listCommands.ts b/src/vs/workbench/browser/actions/listCommands.ts index f6d73f19284..de2713c7d0e 100644 --- a/src/vs/workbench/browser/actions/listCommands.ts +++ b/src/vs/workbench/browser/actions/listCommands.ts @@ -7,7 +7,7 @@ import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { List } from 'vs/base/browser/ui/list/listWidget'; -import { WorkbenchListFocusContextKey, IListService, WorkbenchListSupportsMultiSelectContextKey, ListWidget, WorkbenchListHasSelectionOrFocus, getSelectionKeyboardEvent, WorkbenchListWidget, WorkbenchListSelectionNavigation, WorkbenchTreeElementCanCollapse, WorkbenchTreeElementHasParent, WorkbenchTreeElementHasChild, WorkbenchTreeElementCanExpand, RawWorkbenchListFocusContextKey, WorkbenchTreeFindOpen, WorkbenchTreeSupportsFind } from 'vs/platform/list/browser/listService'; +import { WorkbenchListFocusContextKey, IListService, WorkbenchListSupportsMultiSelectContextKey, ListWidget, WorkbenchListHasSelectionOrFocus, getSelectionKeyboardEvent, WorkbenchListWidget, WorkbenchListSelectionNavigation, WorkbenchTreeElementCanCollapse, WorkbenchTreeElementHasParent, WorkbenchTreeElementHasChild, WorkbenchTreeElementCanExpand, RawWorkbenchListFocusContextKey, WorkbenchTreeFindOpen, WorkbenchListSupportsFind } from 'vs/platform/list/browser/listService'; import { PagedList } from 'vs/base/browser/ui/list/listPaging'; import { equals, range } from 'vs/base/common/arrays'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; @@ -634,7 +634,7 @@ CommandsRegistry.registerCommandAlias('list.toggleFilterOnType', 'list.toggleFin KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'list.find', weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(RawWorkbenchListFocusContextKey, WorkbenchTreeSupportsFind), + when: ContextKeyExpr.and(RawWorkbenchListFocusContextKey, WorkbenchListSupportsFind), primary: KeyMod.CtrlCmd | KeyCode.KeyF, secondary: [KeyCode.F3], handler: (accessor) => { From e7426f3a73337e0ad68a7c6aa5aca410e7731e2a Mon Sep 17 00:00:00 2001 From: John Murray Date: Tue, 2 Aug 2022 18:33:24 +0100 Subject: [PATCH 150/303] Issue Reporter: add link to guidance on wiki (#73512) (#156139) --- .../electron-sandbox/issue/issueReporterMain.ts | 6 +++--- .../electron-sandbox/issue/issueReporterPage.ts | 14 +++++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts index 046cb3929ff..6a0e7994b04 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts @@ -730,7 +730,7 @@ export class IssueReporter extends Disposable { } else if (!fileOnMarketplace) { show(extensionsBlock); } - reset(descriptionTitle, localize('stepsToReproduce', "Steps to Reproduce"), $('span.required-input', undefined, '*')); + reset(descriptionTitle, localize('stepsToReproduce', "Steps to Reproduce") + ' ', $('span.required-input', undefined, '*')); reset(descriptionSubtitle, localize('bugDescription', "Share the steps needed to reliably reproduce the problem. Please include actual and expected results. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.")); } else if (issueType === IssueType.PerformanceIssue) { show(problemSource); @@ -749,10 +749,10 @@ export class IssueReporter extends Disposable { show(extensionsBlock); } - reset(descriptionTitle, localize('stepsToReproduce', "Steps to Reproduce"), $('span.required-input', undefined, '*')); + reset(descriptionTitle, localize('stepsToReproduce', "Steps to Reproduce") + ' ', $('span.required-input', undefined, '*')); reset(descriptionSubtitle, localize('performanceIssueDesciption', "When did this performance issue happen? Does it occur on startup or after a specific series of actions? We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.")); } else if (issueType === IssueType.FeatureRequest) { - reset(descriptionTitle, localize('description', "Description"), $('span.required-input', undefined, '*')); + reset(descriptionTitle, localize('description', "Description") + ' ', $('span.required-input', undefined, '*')); reset(descriptionSubtitle, localize('featureRequestDescription', "Please describe the feature you would like to see. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.")); show(problemSource); diff --git a/src/vs/code/electron-sandbox/issue/issueReporterPage.ts b/src/vs/code/electron-sandbox/issue/issueReporterPage.ts index 99e6cc82420..6467d66bd36 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterPage.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterPage.ts @@ -11,11 +11,23 @@ const sendProcessInfoLabel = escape(localize('sendProcessInfo', "Include my curr const sendWorkspaceInfoLabel = escape(localize('sendWorkspaceInfo', "Include my workspace metadata")); const sendExtensionsLabel = escape(localize('sendExtensions', "Include my enabled extensions")); const sendExperimentsLabel = escape(localize('sendExperiments', "Include A/B experiment info")); +const reviewGuidanceLabel = localize( // intentionally not escaped because of its embedded tags + { + key: 'reviewGuidanceLabel', + comment: [ + '{Locked=""}', + '{Locked=""}' + ] + }, + 'Before you report an issue here please review the guidance we provide.' +); export default (): string => `
+
${reviewGuidanceLabel}
+
@@ -25,7 +37,7 @@ export default (): string => `
- + From ba30d11869db8c66f1faafd7d5fe573db160079b Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Tue, 2 Aug 2022 10:38:05 -0700 Subject: [PATCH 151/303] skip flaky tests to investigate (#156906) --- test/smoke/src/areas/terminal/terminal-profiles.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/src/areas/terminal/terminal-profiles.test.ts b/test/smoke/src/areas/terminal/terminal-profiles.test.ts index 388c71a53c2..7a23f9d364b 100644 --- a/test/smoke/src/areas/terminal/terminal-profiles.test.ts +++ b/test/smoke/src/areas/terminal/terminal-profiles.test.ts @@ -10,7 +10,7 @@ const CONTRIBUTED_PROFILE_NAME = `JavaScript Debug Terminal`; const ANY_PROFILE_NAME = '^((?!JavaScript Debug Terminal).)*$'; export function setup() { - describe('Terminal Profiles', () => { + describe.skip('Terminal Profiles', () => { // Acquire automation API let terminal: Terminal; let settingsEditor: SettingsEditor; From 2d5a77a478f71fc1cccf757053e4cd7b5119d132 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 2 Aug 2022 19:44:56 +0200 Subject: [PATCH 152/303] Create a new API proposal to move `openTunnel` into (#155835) First, just create the new proposal and don't delete the old proposal. This gives users of the proposal a chance to move off of the old on. --- .../common/extensionsApiProposals.ts | 1 + src/vscode-dts/vscode.proposed.tunnels.d.ts | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/vscode-dts/vscode.proposed.tunnels.d.ts diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index 65419fce737..7b67dcacb4e 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -66,6 +66,7 @@ export const allApiProposals = Object.freeze({ timeline: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.timeline.d.ts', tokenInformation: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.tokenInformation.d.ts', treeViewReveal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.treeViewReveal.d.ts', + tunnels: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.tunnels.d.ts', workspaceTrust: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.workspaceTrust.d.ts' }); export type ApiProposalName = keyof typeof allApiProposals; diff --git a/src/vscode-dts/vscode.proposed.tunnels.d.ts b/src/vscode-dts/vscode.proposed.tunnels.d.ts new file mode 100644 index 00000000000..d5c33cf7e1f --- /dev/null +++ b/src/vscode-dts/vscode.proposed.tunnels.d.ts @@ -0,0 +1,50 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode' { + + // tunnels @alexr00 + + export interface TunnelOptions { + remoteAddress: { port: number; host: string }; + // The desired local port. If this port can't be used, then another will be chosen. + localAddressPort?: number; + label?: string; + privacy?: string; + protocol?: string; + } + + export interface TunnelDescription { + remoteAddress: { port: number; host: string }; + //The complete local address(ex. localhost:1234) + localAddress: { port: number; host: string } | string; + privacy?: string; + // If protocol is not provided it is assumed to be http, regardless of the localAddress. + protocol?: string; + } + + export namespace workspace { + /** + * Forwards a port. If the current resolver implements RemoteAuthorityResolver:forwardPort then that will be used to make the tunnel. + * By default, openTunnel only support localhost; however, RemoteAuthorityResolver:tunnelFactory can be used to support other ips. + * + * @throws When run in an environment without a remote. + * + * @param tunnelOptions The `localPort` is a suggestion only. If that port is not available another will be chosen. + */ + export function openTunnel(tunnelOptions: TunnelOptions): Thenable; + + /** + * Gets an array of the currently available tunnels. This does not include environment tunnels, only tunnels that have been created by the user. + * Note that these are of type TunnelDescription and cannot be disposed. + */ + // export let tunnels: Thenable; + + /** + * Fired when the list of tunnels has changed. + */ + // export const onDidChangeTunnels: Event; + } +} From 424fe151f180bd42c9dc9e039d363dcf8ddbcac3 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 2 Aug 2022 11:00:22 -0700 Subject: [PATCH 153/303] Add patch for enabling new TS plugins on web approach (#149186) * Add patch for enabling new TS plugins on web approach https://github.com/microsoft/TypeScript/pull/47377 To run plugins on web, we need to shim out `dynamicImport`. This is done in a file call `tsserverWeb.js`, which is added by the linked PR * Update for new files names --- .../extension-browser.webpack.config.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/extensions/typescript-language-features/extension-browser.webpack.config.js b/extensions/typescript-language-features/extension-browser.webpack.config.js index e7ad156bf94..e7dbbe999fa 100644 --- a/extensions/typescript-language-features/extension-browser.webpack.config.js +++ b/extensions/typescript-language-features/extension-browser.webpack.config.js @@ -8,6 +8,8 @@ 'use strict'; const CopyPlugin = require('copy-webpack-plugin'); const Terser = require('terser'); +const fs = require('fs'); +const path = require('path'); const defaultConfig = require('../shared.webpack.config'); const withBrowserDefaults = defaultConfig.browser; @@ -64,9 +66,12 @@ module.exports = withBrowserDefaults({ { from: '../node_modules/typescript/lib/tsserver.js', to: 'typescript/tsserver.web.js', - transform: (content) => { - return Terser.minify(content.toString()).then(output => output.code); + transform: async (content) => { + const dynamicImportCompatPath = path.join(__dirname, '..', 'node_modules', 'typescript', 'lib', 'dynamicImportCompat.js'); + const prefix = fs.existsSync(dynamicImportCompatPath) ? fs.readFileSync(dynamicImportCompatPath) : undefined; + const output = await Terser.minify(content.toString()); + return prefix + '\n' + output.code; }, transformPath: (targetPath) => { return targetPath.replace('tsserver.js', 'tsserver.web.js'); From 13e4a97bf168c56ec7b3ba48a809250a415c02c7 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Tue, 2 Aug 2022 11:28:02 -0700 Subject: [PATCH 154/303] Add perf marks for auto resuming edit sessions (#156309) --- .../contrib/editSessions/browser/editSessions.contribution.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts index abcadc9ca07..46eed6e6a06 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -99,6 +99,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo super(); if (this.environmentService.editSessionId !== undefined) { + performance.mark('code/willResumeEditSessionFromIdentifier'); type ResumeEvent = {}; type ResumeClassification = { owner: 'joyceerhl'; comment: 'Reporting when an action is resumed from an edit session identifier.'; @@ -106,6 +107,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo this.telemetryService.publicLog2('editSessions.continue.resume'); void this.resumeEditSession(this.environmentService.editSessionId).finally(() => this.environmentService.editSessionId = undefined); + performance.mark('code/didResumeEditSessionFromIdentifier'); } this.configurationService.onDidChangeConfiguration((e) => { From 3a5a458643eab4a198af55cffa961e8baa406b7b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 2 Aug 2022 11:32:02 -0700 Subject: [PATCH 155/303] Clear markdown diagnostics when file is closed (#156912) --- .../server/src/languageFeatures/diagnostics.ts | 17 +++++++++++++---- .../server/src/server.ts | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts b/extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts index 6a51b2e986d..9640f052ceb 100644 --- a/extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts +++ b/extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts @@ -48,13 +48,13 @@ export function registerValidateSupport( workspace: VsCodeClientWorkspace, ls: md.IMdLanguageService, config: ConfigurationManager, + logger: md.ILogger, ): Disposable { let diagnosticOptions: md.DiagnosticOptions = defaultDiagnosticOptions; function updateDiagnosticsSetting(): void { diagnosticOptions = getDiagnosticsOptions(config); } - const subs: Disposable[] = []; const manager = ls.createPullDiagnosticsManager(); subs.push(manager); @@ -64,14 +64,23 @@ export function registerValidateSupport( connection.languages.diagnostics.refresh(); })); + const emptyDiagnosticsResponse = Object.freeze({ kind: 'full', items: [] }); + connection.languages.diagnostics.on(async (params, token): Promise => { + logger.log(md.LogLevel.Trace, 'Server: connection.languages.diagnostics.on', params.textDocument.uri); + if (!config.getSettings()?.markdown.experimental.validate.enabled) { - return { kind: 'full', items: [] }; + return emptyDiagnosticsResponse; } - const document = await workspace.openMarkdownDocument(URI.parse(params.textDocument.uri)); + const uri = URI.parse(params.textDocument.uri); + if (!workspace.hasMarkdownDocument(uri)) { + return emptyDiagnosticsResponse; + } + + const document = await workspace.openMarkdownDocument(uri); if (!document) { - return { kind: 'full', items: [] }; + return emptyDiagnosticsResponse; } const diagnostics = await manager.computeDiagnostics(document, diagnosticOptions, token); diff --git a/extensions/markdown-language-features/server/src/server.ts b/extensions/markdown-language-features/server/src/server.ts index 63a3d5d4b99..d16c2d0d34e 100644 --- a/extensions/markdown-language-features/server/src/server.ts +++ b/extensions/markdown-language-features/server/src/server.ts @@ -48,7 +48,7 @@ export async function startServer(connection: Connection) { }); registerCompletionsSupport(connection, documents, provider, configurationManager); - registerValidateSupport(connection, workspace, provider, configurationManager); + registerValidateSupport(connection, workspace, provider, configurationManager, logger); workspace.workspaceFolders = (params.workspaceFolders ?? []).map(x => URI.parse(x.uri)); return { From cf424081234c6811713035a1665829adc29e5116 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Tue, 2 Aug 2022 14:42:26 -0400 Subject: [PATCH 156/303] Support multiple partial registrations to resolver (#156672) * Revert "Revert "Support multiple partial registrations to resolver (#155859)" (#156157)" This reverts commit 2af49c5bea16250ca4feea573c56ec1c81255257. * Fix perf issue * Fix tests * Support opening merge via resolver * Ensure merge editor has an id --- src/vs/base/common/types.ts | 6 ++ src/vs/workbench/browser/layout.ts | 2 +- src/vs/workbench/common/editor.ts | 6 +- .../mergeEditor/browser/commands/commands.ts | 23 +++-- .../browser/commands/devCommands.ts | 23 +++-- .../mergeEditor/browser/mergeEditorInput.ts | 10 ++- .../mergeEditor/browser/view/mergeEditor.ts | 43 +++------- .../userDataSync/browser/userDataSync.ts | 16 ++-- src/vs/workbench/electron-sandbox/window.ts | 2 +- .../editor/browser/editorResolverService.ts | 83 +++++++++++++++++-- .../editor/common/editorResolverService.ts | 10 ++- .../browser/editorResolverService.test.ts | 63 ++++++++++++++ .../host/browser/browserHostService.ts | 2 +- 13 files changed, 203 insertions(+), 86 deletions(-) diff --git a/src/vs/base/common/types.ts b/src/vs/base/common/types.ts index 3e1cb2a7354..e3844cd39e8 100644 --- a/src/vs/base/common/types.ts +++ b/src/vs/base/common/types.ts @@ -275,3 +275,9 @@ export type UriDto = { [K in keyof T]: T[K] extends URI export function assertNever(value: never, message = 'Unreachable'): never { throw new Error(message); } + +/** + * Given an object with all optional properties, requires at least one to be defined. + * i.e. AtLeastOne; + */ +export type AtLeastOne }> = Partial & U[keyof U]; diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 9151c945a6c..d5f339775a3 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -578,7 +578,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi input2: { resource: filesToMerge[1].resource }, base: { resource: filesToMerge[2].resource }, result: { resource: filesToMerge[3].resource }, - options: { pinned: true, override: 'mergeEditor.Input' } // TODO@bpasero remove the override once the resolver is ready + options: { pinned: true } }]; } diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 6f6ab509248..a886ffaee13 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -484,6 +484,8 @@ export interface IResourceDiffEditorInput extends IBaseUntypedEditorInput { readonly modified: IResourceEditorInput | ITextResourceEditorInput | IUntitledTextResourceEditorInput; } +export type IResourceMergeEditorInputSide = (IResourceEditorInput | ITextResourceEditorInput) & { detail?: string }; + /** * A resource merge editor input compares multiple editors * highlighting the differences for merging. @@ -496,12 +498,12 @@ export interface IResourceMergeEditorInput extends IBaseUntypedEditorInput { /** * The one changed version of the file. */ - readonly input1: IResourceEditorInput | ITextResourceEditorInput; + readonly input1: IResourceMergeEditorInputSide; /** * The second changed version of the file. */ - readonly input2: IResourceEditorInput | ITextResourceEditorInput; + readonly input2: IResourceMergeEditorInputSide; /** * The base common ancestor of the file to merge. diff --git a/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts b/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts index 2f1dfdaef94..36870ec2433 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts @@ -9,11 +9,11 @@ import { localize } from 'vs/nls'; import { ILocalizedString } from 'vs/platform/action/common/action'; import { Action2, IAction2Options, MenuId } from 'vs/platform/actions/common/actions'; import { ICommandService } from 'vs/platform/commands/common/commands'; -import { EditorResolution } from 'vs/platform/editor/common/editor'; -import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { API_OPEN_DIFF_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands'; -import { MergeEditorInput, MergeEditorInputData } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput'; +import { IResourceMergeEditorInput } from 'vs/workbench/common/editor'; +import { MergeEditorInputData } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput'; import { MergeEditor } from 'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor'; import { MergeEditorViewModel } from 'vs/workbench/contrib/mergeEditor/browser/view/viewModel'; import { ctxIsMergeEditor, ctxMergeEditorLayout } from 'vs/workbench/contrib/mergeEditor/common/mergeEditor'; @@ -48,15 +48,14 @@ export class OpenMergeEditor extends Action2 { run(accessor: ServicesAccessor, ...args: unknown[]): void { const validatedArgs = IRelaxedOpenArgs.validate(args[0]); - const instaService = accessor.get(IInstantiationService); - const input = instaService.createInstance( - MergeEditorInput, - validatedArgs.base, - validatedArgs.input1, - validatedArgs.input2, - validatedArgs.output, - ); - accessor.get(IEditorService).openEditor(input, { preserveFocus: true, override: EditorResolution.DISABLED }); + const input: IResourceMergeEditorInput = { + base: { resource: validatedArgs.base }, + input1: { resource: validatedArgs.input1.uri, label: validatedArgs.input1.title, description: validatedArgs.input1.description, detail: validatedArgs.input1.detail }, + input2: { resource: validatedArgs.input2.uri, label: validatedArgs.input2.title, description: validatedArgs.input2.description, detail: validatedArgs.input2.detail }, + result: { resource: validatedArgs.output }, + options: { preserveFocus: true } + }; + accessor.get(IEditorService).openEditor(input); } } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts b/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts index 17df90e7d26..42cd0f7cc5a 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts @@ -10,16 +10,15 @@ import { localize } from 'vs/nls'; import { Action2 } from 'vs/platform/actions/common/actions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; -import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { MergeEditor } from 'vs/workbench/contrib/mergeEditor/browser/view/mergeEditor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IWorkbenchFileService } from 'vs/workbench/services/files/common/files'; import { URI } from 'vs/base/common/uri'; -import { MergeEditorInput } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput'; +import { IResourceMergeEditorInput } from 'vs/workbench/common/editor'; import { ctxIsMergeEditor } from 'vs/workbench/contrib/mergeEditor/common/mergeEditor'; -import { EditorResolution } from 'vs/platform/editor/common/editor'; interface MergeEditorContents { languageId: string; @@ -99,11 +98,10 @@ export class MergeEditorOpenContents extends Action2 { async run(accessor: ServicesAccessor): Promise { const service = accessor.get(IWorkbenchFileService); - const instaService = accessor.get(IInstantiationService); - const editorService = accessor.get(IEditorService); const inputService = accessor.get(IQuickInputService); const clipboardService = accessor.get(IClipboardService); const textModelService = accessor.get(ITextModelService); + const editorService = accessor.get(IEditorService); const result = await inputService.input({ prompt: localize('mergeEditor.enterJSON', 'Enter JSON'), @@ -154,13 +152,12 @@ export class MergeEditorOpenContents extends Action2 { setLanguageId(resultUri, content.languageId), ]); - const input = instaService.createInstance( - MergeEditorInput, - baseUri, - { uri: input1Uri, title: 'Input 1', description: 'Input 1', detail: '(from JSON)' }, - { uri: input2Uri, title: 'Input 2', description: 'Input 2', detail: '(from JSON)' }, - resultUri, - ); - editorService.openEditor(input, { override: EditorResolution.DISABLED }); + const input: IResourceMergeEditorInput = { + base: { resource: baseUri }, + input1: { resource: input1Uri, label: 'Input 1', description: 'Input 1', detail: '(from JSON)' }, + input2: { resource: input2Uri, label: 'Input 2', description: 'Input 2', detail: '(from JSON)' }, + result: { resource: resultUri }, + }; + editorService.openEditor(input); } } diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts index 9a4286f26b6..7c9f7c2274a 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts @@ -13,7 +13,7 @@ import { ConfirmResult, IDialogService } from 'vs/platform/dialogs/common/dialog import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILabelService } from 'vs/platform/label/common/label'; -import { EditorInputCapabilities, IEditorIdentifier, IResourceMergeEditorInput, isResourceMergeEditorInput, IUntypedEditorInput } from 'vs/workbench/common/editor'; +import { DEFAULT_EDITOR_ASSOCIATION, EditorInputCapabilities, IEditorIdentifier, IResourceMergeEditorInput, isResourceMergeEditorInput, IUntypedEditorInput } from 'vs/workbench/common/editor'; import { EditorInput, IEditorCloseHandler } from 'vs/workbench/common/editor/editorInput'; import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { EditorWorkerServiceDiffComputer } from 'vs/workbench/contrib/mergeEditor/browser/model/diffComputer'; @@ -84,6 +84,10 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements return MergeEditorInput.ID; } + override get editorId(): string { + return DEFAULT_EDITOR_ASSOCIATION.id; + } + override get capabilities(): EditorInputCapabilities { return super.capabilities | EditorInputCapabilities.MultipleEditors; } @@ -140,8 +144,8 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements override toUntyped(): IResourceMergeEditorInput { return { - input1: { resource: this.input1.uri, label: this.input1.title, description: this.input1.description }, - input2: { resource: this.input2.uri, label: this.input2.title, description: this.input2.description }, + input1: { resource: this.input1.uri, label: this.input1.title, description: this.input1.description, detail: this.input1.detail }, + input2: { resource: this.input2.uri, label: this.input2.title, description: this.input2.description, detail: this.input2.detail }, base: { resource: this.base }, result: { resource: this.result }, options: { diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts index b17a1e8eebf..46aee59e160 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts @@ -47,7 +47,7 @@ import { MergeEditorViewModel } from 'vs/workbench/contrib/mergeEditor/browser/v import { ctxMergeBaseUri, ctxIsMergeEditor, ctxMergeEditorLayout, ctxMergeResultUri, MergeEditorLayoutTypes } from 'vs/workbench/contrib/mergeEditor/common/mergeEditor'; import { settingsSashBorder } from 'vs/workbench/contrib/preferences/common/settingsEditorColorRegistry'; import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { EditorInputFactoryFunction, IEditorResolverService, MergeEditorInputFactoryFunction, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'; +import { IEditorResolverService, MergeEditorInputFactoryFunction, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import './colors'; import { InputCodeEditorView } from './editors/inputCodeEditorView'; @@ -559,28 +559,6 @@ export class MergeEditorResolverContribution extends Disposable { ) { super(); - const editorInputFactory: EditorInputFactoryFunction = (editor) => { - return { - editor: instantiationService.createInstance( - MergeEditorInput, - editor.resource, - { - uri: editor.resource, - title: '', - description: '', - detail: '' - }, - { - uri: editor.resource, - title: '', - description: '', - detail: '' - }, - editor.resource - ) - }; - }; - const mergeEditorInputFactory: MergeEditorInputFactoryFunction = (mergeEditor: IResourceMergeEditorInput): EditorInputWithOptions => { return { editor: instantiationService.createInstance( @@ -588,15 +566,15 @@ export class MergeEditorResolverContribution extends Disposable { mergeEditor.base.resource, { uri: mergeEditor.input1.resource, - title: basename(mergeEditor.input1.resource), - description: '', - detail: '' + title: mergeEditor.input1.label ?? basename(mergeEditor.input1.resource), + description: mergeEditor.input1.description ?? '', + detail: mergeEditor.input1.detail }, { uri: mergeEditor.input2.resource, - title: basename(mergeEditor.input2.resource), - description: '', - detail: '' + title: mergeEditor.input2.label ?? basename(mergeEditor.input2.resource), + description: mergeEditor.input2.description ?? '', + detail: mergeEditor.input2.detail }, mergeEditor.result.resource ) @@ -606,14 +584,13 @@ export class MergeEditorResolverContribution extends Disposable { this._register(editorResolverService.registerEditor( `*`, { - id: MergeEditorInput.ID, - label: localize('editor.mergeEditor.label', "Merge Editor"), + id: DEFAULT_EDITOR_ASSOCIATION.id, + label: DEFAULT_EDITOR_ASSOCIATION.displayName, detail: DEFAULT_EDITOR_ASSOCIATION.providerDisplayName, - priority: RegisteredEditorPriority.option + priority: RegisteredEditorPriority.builtin }, {}, { - createEditorInput: editorInputFactory, createMergeEditorInput: mergeEditorInputFactory } )); diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts index 55f61b3c685..d201a99a8a6 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts @@ -57,10 +57,8 @@ import { IUserDataInitializationService } from 'vs/workbench/services/userData/b import { MarkdownString } from 'vs/base/common/htmlContent'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; -import { MergeEditorInput } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { ctxIsMergeEditor, ctxMergeBaseUri } from 'vs/workbench/contrib/mergeEditor/common/mergeEditor'; -import { EditorResolution } from 'vs/platform/editor/common/editor'; const CONTEXT_CONFLICTS_SOURCES = new RawContextKey('conflictsSources', ''); @@ -730,14 +728,12 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo for (const conflict of conflicts) { const remoteResourceName = localize({ key: 'remoteResourceName', comment: ['remote as in file in cloud'] }, "{0} (Remote)", basename(conflict.remoteResource)); const localResourceName = localize('localResourceName', "{0} (Local)", basename(conflict.remoteResource)); - const input = this.instantiationService.createInstance( - MergeEditorInput, - conflict.baseResource, - { title: localize('Yours', 'Yours'), description: localResourceName, detail: undefined, uri: conflict.localResource }, - { title: localize('Theirs', 'Theirs'), description: remoteResourceName, detail: undefined, uri: conflict.remoteResource }, - conflict.previewResource, - ); - await this.editorService.openEditor(input, { override: EditorResolution.DISABLED }); + await this.editorService.openEditor({ + input1: { resource: conflict.remoteResource, label: localize('Theirs', 'Theirs'), description: remoteResourceName }, + input2: { resource: conflict.localResource, label: localize('Yours', 'Yours'), description: localResourceName }, + base: { resource: conflict.baseResource }, + result: { resource: conflict.previewResource } + }); } } diff --git a/src/vs/workbench/electron-sandbox/window.ts b/src/vs/workbench/electron-sandbox/window.ts index f044363676a..b1987e81a3c 100644 --- a/src/vs/workbench/electron-sandbox/window.ts +++ b/src/vs/workbench/electron-sandbox/window.ts @@ -862,7 +862,7 @@ export class NativeWindow extends Disposable { input2: { resource: resources[1].resource }, base: { resource: resources[2].resource }, result: { resource: resources[3].resource }, - options: { pinned: true, override: 'mergeEditor.Input' } // TODO@bpasero remove the override once the resolver is ready + options: { pinned: true } }; editors.push(mergeEditor); } else if (diffMode && isResourceEditorInput(resources[0]) && isResourceEditorInput(resources[1])) { diff --git a/src/vs/workbench/services/editor/browser/editorResolverService.ts b/src/vs/workbench/services/editor/browser/editorResolverService.ts index ec9fc2b563b..853daff7507 100644 --- a/src/vs/workbench/services/editor/browser/editorResolverService.ts +++ b/src/vs/workbench/services/editor/browser/editorResolverService.ts @@ -51,7 +51,9 @@ export class EditorResolverService extends Disposable implements IEditorResolver private static readonly conflictingDefaultsStorageID = 'editorOverrideService.conflictingDefaults'; // Data Stores - private _editors: Map = new Map(); + private _editors: Map> = new Map>(); + private _flattenedEditors: Map = new Map(); + private _shouldReFlattenEditors: boolean = true; private cache: Set | undefined; constructor( @@ -112,6 +114,9 @@ export class EditorResolverService extends Disposable implements IEditorResolver } async resolveEditor(editor: EditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise { + // Update the flattened editors + this._flattenedEditors = this._flattenEditorsMap(); + // Special case: side by side editors requires us to // independently resolve both sides and then build // a side by side editor with the result @@ -160,8 +165,17 @@ export class EditorResolverService extends Disposable implements IEditorResolver // Resolved the editor ID as much as possible, now find a given editor (cast here is ok because we resolve down to a string above) let { editor: selectedEditor, conflictingDefault } = this.getEditor(resource, untypedEditor.options?.override as (string | EditorResolution.EXCLUSIVE_ONLY | undefined)); - if (!selectedEditor) { + // If no editor was found and this was a typed editor or an editor with an explicit override we could not resolve it + if (!selectedEditor && (untypedEditor.options?.override || isEditorInputWithOptions(editor))) { return ResolvedStatus.NONE; + } else if (!selectedEditor) { + // Simple untyped editors that we could not resolve will be resolved to the default editor + const resolvedEditor = this.getEditor(resource, DEFAULT_EDITOR_ASSOCIATION.id); + selectedEditor = resolvedEditor?.editor; + conflictingDefault = resolvedEditor?.conflictingDefault; + if (!selectedEditor) { + return ResolvedStatus.NONE; + } } // In the special case of diff editors we do some more work to determine the correct editor for both sides @@ -235,18 +249,29 @@ export class EditorResolverService extends Disposable implements IEditorResolver ): IDisposable { let registeredEditor = this._editors.get(globPattern); if (registeredEditor === undefined) { - registeredEditor = []; + registeredEditor = new Map(); this._editors.set(globPattern, registeredEditor); } - const remove = insert(registeredEditor, { + + let editorsWithId = registeredEditor.get(editorInfo.id); + if (editorsWithId === undefined) { + editorsWithId = []; + } + const remove = insert(editorsWithId, { globPattern, editorInfo, options, editorFactoryObject }); + registeredEditor.set(editorInfo.id, editorsWithId); + this._shouldReFlattenEditors = true; this._onDidChangeEditorRegistrations.fire(); return toDisposable(() => { remove(); + if (editorsWithId && editorsWithId.length === 0) { + registeredEditor?.delete(editorInfo.id); + } + this._shouldReFlattenEditors = true; this._onDidChangeEditorRegistrations.fire(); }); } @@ -281,11 +306,49 @@ export class EditorResolverService extends Disposable implements IEditorResolver return associations; } + /** + * Given the nested nature of the editors map, we merge factories of the same glob and id to make it flat + * and easier to work with + */ + private _flattenEditorsMap() { + // If we shouldn't be re-flattening (due to lack of update) then return early + if (!this._shouldReFlattenEditors) { + return this._flattenedEditors; + } + this._shouldReFlattenEditors = false; + const editors = new Map(); + for (const [glob, value] of this._editors) { + const registeredEditors: RegisteredEditors = []; + for (const editors of value.values()) { + let registeredEditor: RegisteredEditor | undefined = undefined; + // Merge all editors with the same id and glob pattern together + for (const editor of editors) { + if (!registeredEditor) { + registeredEditor = { + editorInfo: editor.editorInfo, + globPattern: editor.globPattern, + options: {}, + editorFactoryObject: {} + }; + } + // Merge options and factories + registeredEditor.options = { ...registeredEditor.options, ...editor.options }; + registeredEditor.editorFactoryObject = { ...registeredEditor.editorFactoryObject, ...editor.editorFactoryObject }; + } + if (registeredEditor) { + registeredEditors.push(registeredEditor); + } + } + editors.set(glob, registeredEditors); + } + return editors; + } + /** * Returns all editors as an array. Possible to contain duplicates */ private get _registeredEditors(): RegisteredEditors { - return flatten(Array.from(this._editors.values())); + return flatten(Array.from(this._flattenedEditors.values())); } updateUserAssociations(globPattern: string, editorID: string): void { @@ -306,7 +369,7 @@ export class EditorResolverService extends Disposable implements IEditorResolver const userSettings = this.getAssociationsForResource(resource); const matchingEditors: RegisteredEditor[] = []; // Then all glob patterns - for (const [key, editors] of this._editors) { + for (const [key, editors] of this._flattenedEditors) { for (const editor of editors) { const foundInSettings = userSettings.find(setting => setting.viewType === editor.editorInfo.id); if ((foundInSettings && editor.editorInfo.priority !== RegisteredEditorPriority.exclusive) || globMatchesResource(key, resource)) { @@ -325,6 +388,7 @@ export class EditorResolverService extends Disposable implements IEditorResolver } public getEditors(resource?: URI): RegisteredEditorInfo[] { + this._flattenedEditors = this._flattenEditorsMap(); // By resource if (URI.isUri(resource)) { @@ -446,6 +510,11 @@ export class EditorResolverService extends Disposable implements IEditorResolver } } + // If no factory is above, return flow back to caller letting them know we could not resolve it + if (!selectedEditor.editorFactoryObject.createEditorInput) { + return; + } + // Respect options passed back const inputWithOptions = await selectedEditor.editorFactoryObject.createEditorInput(editor, group); options = inputWithOptions.options ?? options; @@ -739,7 +808,7 @@ export class EditorResolverService extends Disposable implements IEditorResolver const cacheStorage: Set = new Set(); // Store just the relative pattern pieces without any path info - for (const [globPattern, contribPoint] of this._editors) { + for (const [globPattern, contribPoint] of this._flattenedEditors) { const nonOptional = !!contribPoint.find(c => c.editorInfo.priority !== RegisteredEditorPriority.option && c.editorInfo.id !== DEFAULT_EDITOR_ASSOCIATION.id); // Don't keep a cache of the optional ones as those wouldn't be opened on start anyways if (!nonOptional) { diff --git a/src/vs/workbench/services/editor/common/editorResolverService.ts b/src/vs/workbench/services/editor/common/editorResolverService.ts index b4e47e8d4f2..9de7b992657 100644 --- a/src/vs/workbench/services/editor/common/editorResolverService.ts +++ b/src/vs/workbench/services/editor/common/editorResolverService.ts @@ -19,6 +19,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { EditorInputWithOptions, EditorInputWithOptionsAndGroup, IResourceDiffEditorInput, IResourceMergeEditorInput, IUntitledTextResourceEditorInput, IUntypedEditorInput } from 'vs/workbench/common/editor'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import { PreferredGroup } from 'vs/workbench/services/editor/common/editorService'; +import { AtLeastOne } from 'vs/base/common/types'; export const IEditorResolverService = createDecorator('editorResolverService'); @@ -109,13 +110,15 @@ export type DiffEditorInputFactoryFunction = (diffEditorInput: IResourceDiffEdit export type MergeEditorInputFactoryFunction = (mergeEditorInput: IResourceMergeEditorInput, group: IEditorGroup) => EditorInputFactoryResult; -export type EditorInputFactoryObject = { - createEditorInput: EditorInputFactoryFunction; +type EditorInputFactories = { + createEditorInput?: EditorInputFactoryFunction; createUntitledEditorInput?: UntitledEditorInputFactoryFunction; createDiffEditorInput?: DiffEditorInputFactoryFunction; createMergeEditorInput?: MergeEditorInputFactoryFunction; }; +export type EditorInputFactoryObject = AtLeastOne; + export interface IEditorResolverService { readonly _serviceBrand: undefined; /** @@ -138,7 +141,8 @@ export interface IEditorResolverService { readonly onDidChangeEditorRegistrations: Event; /** - * Registers a specific editor. + * Registers a specific editor. Editors with the same glob pattern and ID will be grouped together by the resolver. + * This allows for registration of the factories in different locations * @param globPattern The glob pattern for this registration * @param editorInfo Information about the registration * @param options Specific options which apply to this registration diff --git a/src/vs/workbench/services/editor/test/browser/editorResolverService.test.ts b/src/vs/workbench/services/editor/test/browser/editorResolverService.test.ts index 5bfe40ad314..2b3a585ed5c 100644 --- a/src/vs/workbench/services/editor/test/browser/editorResolverService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorResolverService.test.ts @@ -382,4 +382,67 @@ suite('EditorResolverService', () => { assert.strictEqual(service.getEditors().length, editors.length); assert.strictEqual(service.getEditors().some(editor => editor.id === 'TEST_EDITOR'), false); }); + + test('Multiple registrations to same glob and id #155859', async () => { + const [part, service, accessor] = await createEditorResolverService(); + const testEditorInfo = { + id: 'TEST_EDITOR', + label: 'Test Editor Label', + detail: 'Test Editor Details', + priority: RegisteredEditorPriority.default + }; + const registeredSingleEditor = service.registerEditor('*.test', + testEditorInfo, + {}, + { + createEditorInput: ({ resource, options }, group) => ({ editor: new TestFileEditorInput(URI.parse(resource.toString()), TEST_EDITOR_INPUT_ID) }) + } + ); + + const registeredDiffEditor = service.registerEditor('*.test', + testEditorInfo, + {}, + { + createDiffEditorInput: ({ modified, original, options }, group) => ({ + editor: accessor.instantiationService.createInstance( + DiffEditorInput, + 'name', + 'description', + new TestFileEditorInput(URI.parse(original.toString()), TEST_EDITOR_INPUT_ID), + new TestFileEditorInput(URI.parse(modified.toString()), TEST_EDITOR_INPUT_ID), + undefined) + }) + } + ); + + // Resolve a diff + let resultingResolution = await service.resolveEditor({ + original: { resource: URI.file('my://resource-basics.test') }, + modified: { resource: URI.file('my://resource-basics.test') } + }, part.activeGroup); + assert.ok(resultingResolution); + assert.notStrictEqual(typeof resultingResolution, 'number'); + if (resultingResolution !== ResolvedStatus.ABORT && resultingResolution !== ResolvedStatus.NONE) { + assert.strictEqual(resultingResolution.editor.typeId, 'workbench.editors.diffEditorInput'); + resultingResolution.editor.dispose(); + } else { + assert.fail(); + } + + // Remove diff registration + registeredDiffEditor.dispose(); + + // Resolve a diff again, expected failure + resultingResolution = await service.resolveEditor({ + original: { resource: URI.file('my://resource-basics.test') }, + modified: { resource: URI.file('my://resource-basics.test') } + }, part.activeGroup); + assert.ok(resultingResolution); + assert.strictEqual(typeof resultingResolution, 'number'); + if (resultingResolution !== ResolvedStatus.NONE) { + assert.fail(); + } + + registeredSingleEditor.dispose(); + }); }); diff --git a/src/vs/workbench/services/host/browser/browserHostService.ts b/src/vs/workbench/services/host/browser/browserHostService.ts index 0aebd31d5b9..25fca6a0136 100644 --- a/src/vs/workbench/services/host/browser/browserHostService.ts +++ b/src/vs/workbench/services/host/browser/browserHostService.ts @@ -268,7 +268,7 @@ export class BrowserHostService extends Disposable implements IHostService { input2: { resource: editors[1].resource }, base: { resource: editors[2].resource }, result: { resource: editors[3].resource }, - options: { pinned: true, override: 'mergeEditor.Input' } // TODO@bpasero remove the override once the resolver is ready + options: { pinned: true } }); } From 1097f3e440d24e57e1308480a11f365f81acf998 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 2 Aug 2022 12:51:07 -0700 Subject: [PATCH 157/303] Use finalized vscode-languageserver version (#156910) Use finalized vscode-languageserver build --- .../server/package.json | 2 +- .../server/yarn.lock | 38 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/extensions/markdown-language-features/server/package.json b/extensions/markdown-language-features/server/package.json index a6ef241f4ff..3408c6cca8d 100644 --- a/extensions/markdown-language-features/server/package.json +++ b/extensions/markdown-language-features/server/package.json @@ -10,7 +10,7 @@ "main": "./out/node/main", "browser": "./dist/browser/main", "dependencies": { - "vscode-languageserver": "^8.0.2-next.5`", + "vscode-languageserver": "^8.0.2`", "vscode-languageserver-textdocument": "^1.0.5", "vscode-languageserver-types": "^3.17.1", "vscode-markdown-languageservice": "^0.0.0-alpha.12", diff --git a/extensions/markdown-language-features/server/yarn.lock b/extensions/markdown-language-features/server/yarn.lock index d0d31f59987..f8234a6cbd6 100644 --- a/extensions/markdown-language-features/server/yarn.lock +++ b/extensions/markdown-language-features/server/yarn.lock @@ -12,40 +12,40 @@ picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -vscode-jsonrpc@8.0.2-next.1: - version "8.0.2-next.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2-next.1.tgz#6bdc39fd194782032e34047eeefce562941259c6" - integrity sha512-sbbvGSWja7NVBLHPGawtgezc8DHYJaP4qfr/AaJiyDapWcSFtHyPtm18+LnYMLTmB7bhOUW/lf5PeeuLpP6bKA== +vscode-jsonrpc@8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2.tgz#f239ed2cd6004021b6550af9fd9d3e47eee3cac9" + integrity sha512-RY7HwI/ydoC1Wwg4gJ3y6LpU9FJRZAUnTYMXthqhFXXu77ErDd/xkREpGuk4MyYkk4a+XDWAMqe0S3KkelYQEQ== -vscode-languageserver-protocol@3.17.2-next.6: - version "3.17.2-next.6" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.6.tgz#8f1dc0fcb29366b85f623a3f9af726de433b5fcc" - integrity sha512-WtsebNOOkWyNn4oFYoAMPC8Q/ZDoJ/K7Ja53OzTixiitvrl/RpXZETrtzH79R8P5kqCyx6VFBPb6KQILJfkDkA== +vscode-languageserver-protocol@3.17.2: + version "3.17.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2.tgz#beaa46aea06ed061576586c5e11368a9afc1d378" + integrity sha512-8kYisQ3z/SQ2kyjlNeQxbkkTNmVFoQCqkmGrzLH6A9ecPlgTbp3wDTnUNqaUxYr4vlAcloxx8zwy7G5WdguYNg== dependencies: - vscode-jsonrpc "8.0.2-next.1" - vscode-languageserver-types "3.17.2-next.2" + vscode-jsonrpc "8.0.2" + vscode-languageserver-types "3.17.2" vscode-languageserver-textdocument@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.5.tgz#838769940ece626176ec5d5a2aa2d0aa69f5095c" integrity sha512-1ah7zyQjKBudnMiHbZmxz5bYNM9KKZYz+5VQLj+yr8l+9w3g+WAhCkUkWbhMEdC5u0ub4Ndiye/fDyS8ghIKQg== -vscode-languageserver-types@3.17.2-next.2: - version "3.17.2-next.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2-next.2.tgz#af5d6978eee7682aab87c1419323f5b141ac6596" - integrity sha512-TiAkLABgqkVWdAlC3XlOfdhdjIAdVU4YntPUm9kKGbXr+MGwpVnKz2KZMNBcvG0CFx8Hi8qliL0iq+ndPB720w== +vscode-languageserver-types@3.17.2: + version "3.17.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz#b2c2e7de405ad3d73a883e91989b850170ffc4f2" + integrity sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA== vscode-languageserver-types@^3.17.1: version "3.17.1" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.1.tgz#c2d87fa7784f8cac389deb3ff1e2d9a7bef07e16" integrity sha512-K3HqVRPElLZVVPtMeKlsyL9aK0GxGQpvtAUTfX4k7+iJ4mc1M+JM+zQwkgGy2LzY0f0IAafe8MKqIkJrxfGGjQ== -vscode-languageserver@^8.0.2-next.5`: - version "8.0.2-next.5" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.2-next.5.tgz#39a2dd4c504fb88042375e7ac706a714bdaab4e5" - integrity sha512-2ZDb7O/4atS9mJKufPPz637z+51kCyZfgnobFW5eSrUdS3c0UB/nMS4Ng1EavYTX84GVaVMKCrmP0f2ceLmR0A== +vscode-languageserver@^8.0.2`: + version "8.0.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.2.tgz#cfe2f0996d9dfd40d3854e786b2821604dfec06d" + integrity sha512-bpEt2ggPxKzsAOZlXmCJ50bV7VrxwCS5BI4+egUmure/oI/t4OlFzi/YNtVvY24A2UDOZAgwFGgnZPwqSJubkA== dependencies: - vscode-languageserver-protocol "3.17.2-next.6" + vscode-languageserver-protocol "3.17.2" vscode-markdown-languageservice@^0.0.0-alpha.12: version "0.0.0-alpha.12" From e3267b75c669021d916e437d9245ce9f0c0c8680 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 2 Aug 2022 13:18:08 -0700 Subject: [PATCH 158/303] Fix onDidDeleteMarkdownDocument not hooked up (#156913) --- .../markdown-language-features/server/src/workspace.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/extensions/markdown-language-features/server/src/workspace.ts b/extensions/markdown-language-features/server/src/workspace.ts index 09147851016..e1dca9f20c5 100644 --- a/extensions/markdown-language-features/server/src/workspace.ts +++ b/extensions/markdown-language-features/server/src/workspace.ts @@ -63,7 +63,12 @@ export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching { }); documents.onDidClose(e => { - this._documentCache.delete(URI.parse(e.document.uri)); + const uri = URI.parse(e.document.uri); + this._documentCache.delete(uri); + + if (this.isRelevantMarkdownDocument(e.document)) { + this._onDidDeleteMarkdownDocument.fire(uri); + } }); connection.onDidChangeWatchedFiles(async ({ changes }) => { From 5f8c264b4fab68c8f0e081ecf574ff68743d837d Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Tue, 2 Aug 2022 13:49:54 -0700 Subject: [PATCH 159/303] add separation to task detection notification (#156919) fix #156287 --- src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts index 6a31c0d5225..335e13df336 100644 --- a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts +++ b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts @@ -208,8 +208,9 @@ export class TaskQuickPick extends Disposable { const yesButton = nls.localize('TaskQuickPick.changeSettingYes', "Yes"); const changeSettingResult = await this._dialogService.show(Severity.Warning, nls.localize('TaskQuickPick.changeSettingDetails', - "Task detection for {0} tasks causes files in any workspace you open to be run as code. Enabling {0} task detection is a user setting and will apply to any workspace you open. Do you want to enable {0} task detection for all workspaces?", selectedType), - [noButton, yesButton]); + "Task detection for {0} tasks causes files in any workspace you open to be run as code. Enabling {0} task detection is a user setting and will apply to any workspace you open. \n\n Do you want to enable {0} task detection for all workspaces?", selectedType), + [noButton, yesButton] + ); if (changeSettingResult.choice === 1) { await this._configurationService.updateValue(`${selectedType}.autoDetect`, 'on'); await new Promise(resolve => setTimeout(() => resolve(), 100)); From 7e400c71379efb21bea32c451cd15a0ead4686e3 Mon Sep 17 00:00:00 2001 From: John Murray Date: Tue, 2 Aug 2022 21:51:41 +0100 Subject: [PATCH 160/303] Provide valid markdown-specific default for `editor.quickSuggestions` setting (#156686) (#156689) Co-authored-by: Matt Bierner --- extensions/markdown-language-features/package.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 952abb1a463..cae88bf134f 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -515,7 +515,11 @@ "configurationDefaults": { "[markdown]": { "editor.wordWrap": "on", - "editor.quickSuggestions": false + "editor.quickSuggestions": { + "comments": "off", + "strings": "off", + "other": "off" + } } }, "jsonValidation": [ From 4b551dab3579ac62e8228f0d6ddf91a7ca33f786 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 2 Aug 2022 14:20:00 -0700 Subject: [PATCH 161/303] Turn on notebook document test. (#156932) --- .../src/singlefolder-tests/notebook.document.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts index 9fb4248687e..8a92bb7324e 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import * as vscode from 'vscode'; import * as utils from '../utils'; -suite.skip('Notebook Document', function () { +suite('Notebook Document', function () { const simpleContentProvider = new class implements vscode.NotebookSerializer { deserializeNotebook(_data: Uint8Array): vscode.NotebookData | Thenable { From 8b27dcb1f8e7e67ec9391f341ebc0f2ba6b2f724 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 2 Aug 2022 14:31:58 -0700 Subject: [PATCH 162/303] Pick up latest markdown language service (#156933) --- extensions/markdown-language-features/server/package.json | 4 ++-- extensions/markdown-language-features/server/yarn.lock | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/extensions/markdown-language-features/server/package.json b/extensions/markdown-language-features/server/package.json index 3408c6cca8d..ada9661b0b2 100644 --- a/extensions/markdown-language-features/server/package.json +++ b/extensions/markdown-language-features/server/package.json @@ -1,7 +1,7 @@ { "name": "vscode-markdown-languageserver", "description": "Markdown language server", - "version": "0.0.0-alpha-1", + "version": "0.0.0-alpha-2", "author": "Microsoft Corporation", "license": "MIT", "engines": { @@ -13,7 +13,7 @@ "vscode-languageserver": "^8.0.2`", "vscode-languageserver-textdocument": "^1.0.5", "vscode-languageserver-types": "^3.17.1", - "vscode-markdown-languageservice": "^0.0.0-alpha.12", + "vscode-markdown-languageservice": "^0.0.0-alpha.13", "vscode-uri": "^3.0.3" }, "devDependencies": { diff --git a/extensions/markdown-language-features/server/yarn.lock b/extensions/markdown-language-features/server/yarn.lock index f8234a6cbd6..e01f1001c29 100644 --- a/extensions/markdown-language-features/server/yarn.lock +++ b/extensions/markdown-language-features/server/yarn.lock @@ -47,10 +47,10 @@ vscode-languageserver@^8.0.2`: dependencies: vscode-languageserver-protocol "3.17.2" -vscode-markdown-languageservice@^0.0.0-alpha.12: - version "0.0.0-alpha.12" - resolved "https://registry.yarnpkg.com/vscode-markdown-languageservice/-/vscode-markdown-languageservice-0.0.0-alpha.12.tgz#5a3c7559969c3cb455d508d48129c8e221589630" - integrity sha512-9dJ/GL6A9UUOcB1TpvgsbcwqsYjnxHx4jxDaqeZZEMWFSUySfp0PAn1ge2S2Qj00zypvsu0eCTGUNd56G1/BNQ== +vscode-markdown-languageservice@^0.0.0-alpha.13: + version "0.0.0-alpha.13" + resolved "https://registry.yarnpkg.com/vscode-markdown-languageservice/-/vscode-markdown-languageservice-0.0.0-alpha.13.tgz#28cd8dd8eca451aaa3db1c92ec97ace53623dd5d" + integrity sha512-jgRVBQmdO0aC5Svap1RcAd3x2XOSNWla01GF/rzaVx9M5pEcel4SPz+2H9PYXul6jRKe1oKJF9OOciaiE7pSXQ== dependencies: picomatch "^2.3.1" vscode-languageserver-textdocument "^1.0.5" From ca48c64699f221b18e487875b782f97c7523c7cd Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 2 Aug 2022 15:27:16 -0700 Subject: [PATCH 163/303] build: cache built-in extensions to avoid rate limiting (#156918) --- build/azure-pipelines/product-compile.yml | 12 ++++++++++++ build/gulpfile.extensions.js | 2 +- build/gulpfile.vscode.web.js | 2 +- build/lib/builtInExtensions.js | 20 +++++++++++++++++--- build/lib/builtInExtensions.ts | 21 ++++++++++++++++++--- build/lib/extensions.js | 8 ++++---- build/lib/extensions.ts | 8 ++++---- 7 files changed, 57 insertions(+), 16 deletions(-) diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index 381d49ee75a..7df5d1505f2 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -56,6 +56,13 @@ steps: cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache + # Cache built-in extensions to avoid GH rate limits. + - task: Cache@2 + inputs: + key: '"$(Agent.OS)" | product.json' + path: .build/builtInExtensions + displayName: Restore built-in extensions + - script: | set -e tar -xzf .build/node_modules_cache/cache.tgz @@ -109,6 +116,11 @@ steps: node build/azure-pipelines/mixin displayName: Mix in quality + - script: | + set -e + node build/lib/builtInExtensions.js + displayName: Download missing built-in extensions + - script: | set -e yarn npm-run-all -lp core-ci extensions-ci hygiene eslint valid-layers-check diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index bb893f02923..04132cd4400 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -236,8 +236,8 @@ exports.compileExtensionMediaBuildTask = compileExtensionMediaBuildTask; const cleanExtensionsBuildTask = task.define('clean-extensions-build', util.rimraf('.build/extensions')); const compileExtensionsBuildTask = task.define('compile-extensions-build', task.series( cleanExtensionsBuildTask, + task.define('bundle-marketplace-extensions-build', () => ext.packageMarketplaceExtensionsStream(false).pipe(gulp.dest('.build'))), task.define('bundle-extensions-build', () => ext.packageLocalExtensionsStream(false).pipe(gulp.dest('.build'))), - task.define('bundle-marketplace-extensions-build', () => ext.packageMarketplaceExtensionsStream(false, product.extensionsGallery?.serviceUrl).pipe(gulp.dest('.build'))), )); gulp.task(compileExtensionsBuildTask); diff --git a/build/gulpfile.vscode.web.js b/build/gulpfile.vscode.web.js index 4c1259c241c..56b08474033 100644 --- a/build/gulpfile.vscode.web.js +++ b/build/gulpfile.vscode.web.js @@ -229,7 +229,7 @@ function packageTask(sourceFolderName, destinationFolderName) { const compileWebExtensionsBuildTask = task.define('compile-web-extensions-build', task.series( task.define('clean-web-extensions-build', util.rimraf('.build/web/extensions')), task.define('bundle-web-extensions-build', () => extensions.packageLocalExtensionsStream(true).pipe(gulp.dest('.build/web'))), - task.define('bundle-marketplace-web-extensions-build', () => extensions.packageMarketplaceExtensionsStream(true, product.extensionsGallery?.serviceUrl).pipe(gulp.dest('.build/web'))), + task.define('bundle-marketplace-web-extensions-build', () => extensions.packageMarketplaceExtensionsStream(true).pipe(gulp.dest('.build/web'))), task.define('bundle-web-extension-media-build', () => extensions.buildExtensionMedia(false, '.build/web/extensions')), )); gulp.task(compileWebExtensionsBuildTask); diff --git a/build/lib/builtInExtensions.js b/build/lib/builtInExtensions.js index f38871c36d7..38c30234b7e 100644 --- a/build/lib/builtInExtensions.js +++ b/build/lib/builtInExtensions.js @@ -4,7 +4,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); -exports.getBuiltInExtensions = void 0; +exports.getBuiltInExtensions = exports.getExtensionStream = void 0; const fs = require("fs"); const path = require("path"); const os = require("os"); @@ -44,6 +44,21 @@ function isUpToDate(extension) { return false; } } +function getExtensionDownloadStream(extension) { + const galleryServiceUrl = productjson.extensionsGallery?.serviceUrl; + return (galleryServiceUrl ? ext.fromMarketplace(galleryServiceUrl, extension) : ext.fromGithub(extension)) + .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); +} +function getExtensionStream(extension) { + // if the extension exists on disk, use those files instead of downloading anew + if (isUpToDate(extension)) { + log('[extensions]', `${extension.name}@${extension.version} up to date`, ansiColors.green('✔︎')); + return vfs.src(['**'], { cwd: getExtensionPath(extension), dot: true }) + .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); + } + return getExtensionDownloadStream(extension); +} +exports.getExtensionStream = getExtensionStream; function syncMarketplaceExtension(extension) { const galleryServiceUrl = productjson.extensionsGallery?.serviceUrl; const source = ansiColors.blue(galleryServiceUrl ? '[marketplace]' : '[github]'); @@ -52,8 +67,7 @@ function syncMarketplaceExtension(extension) { return es.readArray([]); } rimraf.sync(getExtensionPath(extension)); - return (galleryServiceUrl ? ext.fromMarketplace(galleryServiceUrl, extension) : ext.fromGithub(extension)) - .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)) + return getExtensionDownloadStream(extension) .pipe(vfs.dest('.build/builtInExtensions')) .on('end', () => log(source, extension.name, ansiColors.green('✔︎'))); } diff --git a/build/lib/builtInExtensions.ts b/build/lib/builtInExtensions.ts index 971847c8756..912e05653ac 100644 --- a/build/lib/builtInExtensions.ts +++ b/build/lib/builtInExtensions.ts @@ -68,10 +68,26 @@ function isUpToDate(extension: IExtensionDefinition): boolean { } } +function getExtensionDownloadStream(extension: IExtensionDefinition) { + const galleryServiceUrl = productjson.extensionsGallery?.serviceUrl; + return (galleryServiceUrl ? ext.fromMarketplace(galleryServiceUrl, extension) : ext.fromGithub(extension)) + .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); +} + +export function getExtensionStream(extension: IExtensionDefinition) { + // if the extension exists on disk, use those files instead of downloading anew + if (isUpToDate(extension)) { + log('[extensions]', `${extension.name}@${extension.version} up to date`, ansiColors.green('✔︎')); + return vfs.src(['**'], { cwd: getExtensionPath(extension), dot: true }) + .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); + } + + return getExtensionDownloadStream(extension); +} + function syncMarketplaceExtension(extension: IExtensionDefinition): Stream { const galleryServiceUrl = productjson.extensionsGallery?.serviceUrl; const source = ansiColors.blue(galleryServiceUrl ? '[marketplace]' : '[github]'); - if (isUpToDate(extension)) { log(source, `${extension.name}@${extension.version}`, ansiColors.green('✔︎')); return es.readArray([]); @@ -79,8 +95,7 @@ function syncMarketplaceExtension(extension: IExtensionDefinition): Stream { rimraf.sync(getExtensionPath(extension)); - return (galleryServiceUrl ? ext.fromMarketplace(galleryServiceUrl, extension) : ext.fromGithub(extension)) - .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)) + return getExtensionDownloadStream(extension) .pipe(vfs.dest('.build/builtInExtensions')) .on('end', () => log(source, extension.name, ansiColors.green('✔︎'))); } diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 808d817b815..009bbe4b014 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -25,6 +25,7 @@ const buffer = require('gulp-buffer'); const jsoncParser = require("jsonc-parser"); const dependencies_1 = require("./dependencies"); const _ = require("underscore"); +const builtInExtensions_1 = require("./builtInExtensions"); const util = require('./util'); const root = path.dirname(path.dirname(__dirname)); const commit = util.getVersion(root); @@ -312,16 +313,15 @@ function packageLocalExtensionsStream(forWeb) { .pipe(util2.setExecutableBit(['**/*.sh']))); } exports.packageLocalExtensionsStream = packageLocalExtensionsStream; -function packageMarketplaceExtensionsStream(forWeb, galleryServiceUrl) { +function packageMarketplaceExtensionsStream(forWeb) { const marketplaceExtensionsDescriptions = [ ...builtInExtensions.filter(({ name }) => (forWeb ? !marketplaceWebExtensionsExclude.has(name) : true)), ...(forWeb ? webBuiltInExtensions : []) ]; const marketplaceExtensionsStream = minifyExtensionResources(es.merge(...marketplaceExtensionsDescriptions .map(extension => { - const input = (galleryServiceUrl ? fromMarketplace(galleryServiceUrl, extension) : fromGithub(extension)) - .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - return updateExtensionPackageJSON(input, (data) => { + const src = (0, builtInExtensions_1.getExtensionStream)(extension).pipe(rename(p => p.dirname = `extensions/${p.dirname}`)); + return updateExtensionPackageJSON(src, (data) => { delete data.scripts; delete data.dependencies; delete data.devDependencies; diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index ddcb25483fb..d14ddca2f8a 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -25,6 +25,7 @@ import * as jsoncParser from 'jsonc-parser'; import webpack = require('webpack'); import { getProductionDependencies } from './dependencies'; import _ = require('underscore'); +import { getExtensionStream } from './builtInExtensions'; const util = require('./util'); const root = path.dirname(path.dirname(__dirname)); const commit = util.getVersion(root); @@ -381,7 +382,7 @@ export function packageLocalExtensionsStream(forWeb: boolean): Stream { ); } -export function packageMarketplaceExtensionsStream(forWeb: boolean, galleryServiceUrl?: string): Stream { +export function packageMarketplaceExtensionsStream(forWeb: boolean): Stream { const marketplaceExtensionsDescriptions = [ ...builtInExtensions.filter(({ name }) => (forWeb ? !marketplaceWebExtensionsExclude.has(name) : true)), ...(forWeb ? webBuiltInExtensions : []) @@ -390,9 +391,8 @@ export function packageMarketplaceExtensionsStream(forWeb: boolean, galleryServi es.merge( ...marketplaceExtensionsDescriptions .map(extension => { - const input = (galleryServiceUrl ? fromMarketplace(galleryServiceUrl, extension) : fromGithub(extension)) - .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - return updateExtensionPackageJSON(input, (data: any) => { + const src = getExtensionStream(extension).pipe(rename(p => p.dirname = `extensions/${p.dirname}`)); + return updateExtensionPackageJSON(src, (data: any) => { delete data.scripts; delete data.dependencies; delete data.devDependencies; From c9df538b06fceeb547979dcd9628fee7b845c8bb Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 2 Aug 2022 16:26:17 -0700 Subject: [PATCH 164/303] build: apply built-in ext cache to the rest of the pipeline (#156939) --- .../darwin/product-build-darwin-sign.yml | 13 +++++++++++++ .../darwin/product-build-darwin-universal.yml | 13 +++++++++++++ .../darwin/product-build-darwin.yml | 13 +++++++++++++ .../azure-pipelines/linux/product-build-alpine.yml | 13 +++++++++++++ .../linux/product-build-linux-client.yml | 13 +++++++++++++ build/azure-pipelines/product-build-pr-cache.yml | 13 +++++++++++++ build/azure-pipelines/product-compile.yml | 12 +++++++----- build/azure-pipelines/web/product-build-web.yml | 13 +++++++++++++ .../azure-pipelines/win32/product-build-win32.yml | 14 ++++++++++++++ 9 files changed, 112 insertions(+), 5 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin-sign.yml b/build/azure-pipelines/darwin/product-build-darwin-sign.yml index 059e848c0b1..c7baec86b5f 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-sign.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-sign.yml @@ -47,6 +47,12 @@ steps: cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache + - task: Cache@2 + inputs: + key: '"$(Agent.OS)" | product.json' + path: .build/builtInExtensions + displayName: Restore built-in extensions + - script: | set -e tar -xzf .build/node_modules_cache/cache.tgz @@ -88,6 +94,13 @@ steps: displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | + set -e + node build/lib/builtInExtensions.js + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Download missing built-in extensions + - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt diff --git a/build/azure-pipelines/darwin/product-build-darwin-universal.yml b/build/azure-pipelines/darwin/product-build-darwin-universal.yml index 929aaf42038..80c16f5acff 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-universal.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-universal.yml @@ -47,6 +47,12 @@ steps: cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache + - task: Cache@2 + inputs: + key: '"$(Agent.OS)" | product.json' + path: .build/builtInExtensions + displayName: Restore built-in extensions + - script: | set -e tar -xzf .build/node_modules_cache/cache.tgz @@ -88,6 +94,13 @@ steps: displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | + set -e + node build/lib/builtInExtensions.js + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Download missing built-in extensions + - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index eda79c53cf9..f33df4096d6 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -81,6 +81,12 @@ steps: cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache + - task: Cache@2 + inputs: + key: '"$(Agent.OS)" | product.json' + path: .build/builtInExtensions + displayName: Restore built-in extensions + - script: | set -e tar -xzf .build/node_modules_cache/cache.tgz @@ -115,6 +121,13 @@ steps: displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | + set -e + node build/lib/builtInExtensions.js + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Download missing built-in extensions + - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt diff --git a/build/azure-pipelines/linux/product-build-alpine.yml b/build/azure-pipelines/linux/product-build-alpine.yml index 3aef7279243..0faef3e7571 100644 --- a/build/azure-pipelines/linux/product-build-alpine.yml +++ b/build/azure-pipelines/linux/product-build-alpine.yml @@ -67,6 +67,12 @@ steps: cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache + - task: Cache@2 + inputs: + key: '"$(Agent.OS)" | product.json' + path: .build/builtInExtensions + displayName: Restore built-in extensions + - script: | set -e tar -xzf .build/node_modules_cache/cache.tgz @@ -98,6 +104,13 @@ steps: displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | + set -e + node build/lib/builtInExtensions.js + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Download missing built-in extensions + - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt diff --git a/build/azure-pipelines/linux/product-build-linux-client.yml b/build/azure-pipelines/linux/product-build-linux-client.yml index 97a9cf31d66..2031e1d9f38 100644 --- a/build/azure-pipelines/linux/product-build-linux-client.yml +++ b/build/azure-pipelines/linux/product-build-linux-client.yml @@ -109,6 +109,12 @@ steps: cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache + - task: Cache@2 + inputs: + key: '"$(Agent.OS)" | product.json' + path: .build/builtInExtensions + displayName: Restore built-in extensions + - script: | set -e tar -xzf .build/node_modules_cache/cache.tgz @@ -187,6 +193,13 @@ steps: displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | + set -e + node build/lib/builtInExtensions.js + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Download missing built-in extensions + - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: | set -e diff --git a/build/azure-pipelines/product-build-pr-cache.yml b/build/azure-pipelines/product-build-pr-cache.yml index 067afa7492d..17dd3b71919 100644 --- a/build/azure-pipelines/product-build-pr-cache.yml +++ b/build/azure-pipelines/product-build-pr-cache.yml @@ -19,6 +19,12 @@ steps: cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache + - task: Cache@2 + inputs: + key: '"$(Agent.OS)" | product.json' + path: .build/builtInExtensions + displayName: Restore built-in extensions + - script: | set -e tar -xzf .build/node_modules_cache/cache.tgz @@ -50,6 +56,13 @@ steps: displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | + set -e + node build/lib/builtInExtensions.js + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Download missing built-in extensions + - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index 7df5d1505f2..5b67ef001f5 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -101,6 +101,13 @@ steps: displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | + set -e + node build/lib/builtInExtensions.js + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Download missing built-in extensions + - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt @@ -116,11 +123,6 @@ steps: node build/azure-pipelines/mixin displayName: Mix in quality - - script: | - set -e - node build/lib/builtInExtensions.js - displayName: Download missing built-in extensions - - script: | set -e yarn npm-run-all -lp core-ci extensions-ci hygiene eslint valid-layers-check diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 376f14c6bc6..01130cf089a 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -58,6 +58,12 @@ steps: cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache + - task: Cache@2 + inputs: + key: '"$(Agent.OS)" | product.json' + path: .build/builtInExtensions + displayName: Restore built-in extensions + - script: | set -e tar -xzf .build/node_modules_cache/cache.tgz @@ -89,6 +95,13 @@ steps: displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | + set -e + node build/lib/builtInExtensions.js + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Download missing built-in extensions + - script: | set -e node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 41f0a8da8c2..a12612737c0 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -89,6 +89,12 @@ steps: cacheHitVar: NODE_MODULES_RESTORED displayName: Restore node_modules cache + - task: Cache@2 + inputs: + key: '"$(Agent.OS)" | product.json' + path: .build/builtInExtensions + displayName: Restore built-in extensions + - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" @@ -119,6 +125,14 @@ steps: displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { node build/lib/builtInExtensions.js } + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Download missing built-in extensions + - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" From 418b944396033443fffdefb710e22641a0b1068b Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 2 Aug 2022 16:42:53 -0700 Subject: [PATCH 165/303] debt: move insert command towards unit tests. (#156929) --- .../src/singlefolder-tests/notebook.test.ts | 205 ++---------------- .../test/browser/cellOperations.test.ts | 24 +- 2 files changed, 42 insertions(+), 187 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts index 126eabe5661..9582ed49c0c 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts @@ -178,89 +178,15 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { await saveAllFilesAndCloseAll(); }); - test.skip('editor editing event', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/152145 + test('edit API batch edits', async function () { const notebook = await openRandomNotebookDocument(); - const editor = await vscode.window.showNotebookDocument(notebook); - const cellsChangeEvent = asPromise(vscode.workspace.onDidChangeNotebookDocument); - await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow'); - const cellChangeEventRet = await cellsChangeEvent; - assert.strictEqual(cellChangeEventRet.notebook, editor.notebook); - assert.strictEqual(cellChangeEventRet.contentChanges.length, 1); - assert.deepStrictEqual(cellChangeEventRet.contentChanges[0], { - range: new vscode.NotebookRange(1, 1), - removedCells: [], - addedCells: [editor.notebook.cellAt(1)] - }); - - // const moveCellEvent = asPromise(vscode.workspace.onDidChangeNotebookDocument); - // await vscode.commands.executeCommand('notebook.cell.moveUp'); - // await moveCellEvent; - - const cellOutputChange = asPromise(vscode.workspace.onDidChangeNotebookDocument); - await vscode.commands.executeCommand('notebook.cell.execute'); - const cellOutputsAddedRet = await cellOutputChange; - - assert.strictEqual(cellOutputsAddedRet.notebook.uri.toString(), editor.notebook.uri.toString()); - assert.strictEqual(cellOutputsAddedRet.metadata, undefined); - assert.strictEqual(cellOutputsAddedRet.contentChanges.length, 0); - assert.strictEqual(cellOutputsAddedRet.cellChanges.length, 1); - assert.deepStrictEqual(cellOutputsAddedRet.cellChanges[0].cell, editor.notebook.cellAt(0)); - assert.deepStrictEqual(cellOutputsAddedRet.cellChanges[0].executionSummary, { executionOrder: undefined, success: undefined, timing: undefined }); // TODO@jrieken should this be undefined instead all empty? - assert.strictEqual(cellOutputsAddedRet.cellChanges[0].document, undefined); - assert.strictEqual(cellOutputsAddedRet.cellChanges[0].metadata, undefined); - assert.strictEqual(cellOutputsAddedRet.cellChanges[0].outputs, undefined); - assert.strictEqual(cellOutputsAddedRet.cellChanges[0].cell.outputs.length, 1); - - const cellOutputClear = asPromise(vscode.workspace.onDidChangeNotebookDocument); - await vscode.commands.executeCommand('notebook.cell.clearOutputs'); - const cellOutputsCleardRet = await cellOutputClear; - assert.deepStrictEqual(cellOutputsCleardRet, { - notebook: editor.notebook, - metadata: undefined, - contentChanges: [], - cellChanges: [{ - cell: editor.notebook.cellAt(0), - document: undefined, - executionSummary: undefined, - metadata: undefined, - outputs: editor.notebook.cellAt(0).outputs - }], - }); - assert.strictEqual(cellOutputsCleardRet.cellChanges[0].cell.outputs.length, 0); - - // const cellChangeLanguage = getEventOncePromise(vscode.notebooks.onDidChangeCellLanguage); - // await vscode.commands.executeCommand('notebook.cell.changeToMarkdown'); - // const cellChangeLanguageRet = await cellChangeLanguage; - // assert.deepStrictEqual(cellChangeLanguageRet, { - // document: vscode.window.activeNotebookEditor!.document, - // cells: vscode.window.activeNotebookEditor!.document.cellAt(0), - // language: 'markdown' - // }); - }); - - test('edit API batch edits', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/155808 - const notebook = await openRandomNotebookDocument(); - const editor = await vscode.window.showNotebookDocument(notebook); - - const version = editor.notebook.version; const edit = new vscode.WorkspaceEdit(); - const cellEdit = vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(1, 0), [{ kind: vscode.NotebookCellKind.Code, languageId: 'javascript', value: 'test 2', outputs: [], metadata: undefined }]); const metdataEdit = vscode.NotebookEdit.updateNotebookMetadata({ ...notebook.metadata, custom: { ...(notebook.metadata.custom || {}), extraNotebookMetadata: true } }); - edit.set(notebook.uri, [cellEdit, metdataEdit]); - let success = await vscode.workspace.applyEdit(edit); + edit.set(notebook.uri, [metdataEdit]); + const success = await vscode.workspace.applyEdit(edit); assert.equal(success, true); - - const edit2 = new vscode.WorkspaceEdit(); - const cellMetadataEdit = vscode.NotebookEdit.updateCellMetadata(0, { extraCellMetadata: true }); - edit2.set(notebook.uri, [cellMetadataEdit]); - success = await vscode.workspace.applyEdit(edit2); - assert.equal(success, true); - - assert.strictEqual(version + 2, editor.notebook.version); - const cell = editor.notebook.cellAt(0); - assert.ok(editor.notebook.metadata.custom.extraNotebookMetadata, `Test metadata not found`); - assert.ok(cell.metadata.extraCellMetadata, `Test cell metdata not found`); + assert.ok(notebook.metadata.custom.extraNotebookMetadata, `Test metadata not found`); }); test('notebook open', async function () { @@ -288,22 +214,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'test'); assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript'); - // ---- insert cell below and focus ---- // - await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow'); - assert.strictEqual(getFocusedCell(editor)?.document.getText(), ''); - - // ---- insert cell above and focus ---- // - await vscode.commands.executeCommand('notebook.cell.insertCodeCellAbove'); let activeCell = getFocusedCell(editor); - assert.notStrictEqual(getFocusedCell(editor), undefined); - assert.strictEqual(activeCell!.document.getText(), ''); - assert.strictEqual(editor.notebook.cellCount, 4); - assert.strictEqual(editor.notebook.getCells().indexOf(activeCell!), 1); - - // ---- focus bottom ---- // - await vscode.commands.executeCommand('notebook.focusBottom'); - activeCell = getFocusedCell(editor); - assert.strictEqual(editor.notebook.getCells().indexOf(activeCell!), 3); // ---- focus top and then copy down ---- // await vscode.commands.executeCommand('notebook.focusTop'); @@ -315,10 +226,10 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { assert.strictEqual(editor.notebook.getCells().indexOf(activeCell!), 1); assert.strictEqual(activeCell?.document.getText(), 'test'); + // delete focused cell { const focusedCell = getFocusedCell(editor); assert.strictEqual(focusedCell !== undefined, true); - // delete focused cell const edit = new vscode.WorkspaceEdit(); edit.replaceNotebookCells(focusedCell!.notebook.uri, new vscode.NotebookRange(focusedCell!.index, focusedCell!.index + 1), []); await vscode.workspace.applyEdit(edit); @@ -326,16 +237,15 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { activeCell = getFocusedCell(editor); assert.strictEqual(editor.notebook.getCells().indexOf(activeCell!), 1); - assert.strictEqual(activeCell?.document.getText(), ''); + assert.strictEqual(activeCell?.document.getText(), 'test2'); // ---- focus top and then copy up ---- // await vscode.commands.executeCommand('notebook.focusTop'); await vscode.commands.executeCommand('notebook.cell.copyUp'); - assert.strictEqual(editor.notebook.cellCount, 5); + assert.strictEqual(editor.notebook.cellCount, 3); assert.strictEqual(editor.notebook.cellAt(0).document.getText(), 'test'); assert.strictEqual(editor.notebook.cellAt(1).document.getText(), 'test'); - assert.strictEqual(editor.notebook.cellAt(2).document.getText(), ''); - assert.strictEqual(editor.notebook.cellAt(3).document.getText(), ''); + assert.strictEqual(editor.notebook.cellAt(2).document.getText(), 'test2'); activeCell = getFocusedCell(editor); assert.strictEqual(editor.notebook.getCells().indexOf(activeCell!), 0); @@ -503,89 +413,6 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { listener.dispose(); }); - test('notebook cell document workspace edit', async function () { - const notebook = await openRandomNotebookDocument(); - const editor = await vscode.window.showNotebookDocument(notebook); - assert.strictEqual(vscode.window.activeNotebookEditor === editor, true, 'notebook first'); - assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'test'); - assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript'); - - await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow'); - assert.strictEqual(getFocusedCell(editor)?.document.getText(), ''); - - await vscode.commands.executeCommand('notebook.cell.insertCodeCellAbove'); - const activeCell = getFocusedCell(editor); - assert.notStrictEqual(getFocusedCell(editor), undefined); - assert.strictEqual(activeCell!.document.getText(), ''); - assert.strictEqual(editor.notebook.cellCount, 4); - assert.strictEqual(editor.notebook.getCells().indexOf(activeCell!), 1); - - await withEvent(vscode.workspace.onDidChangeTextDocument, async event => { - const edit = new vscode.WorkspaceEdit(); - edit.insert(activeCell!.document.uri, new vscode.Position(0, 0), 'var abc = 0;'); - await vscode.workspace.applyEdit(edit); - await event; - assert.strictEqual(vscode.window.activeNotebookEditor === editor, true); - assert.deepStrictEqual(editor.notebook.cellAt(1), getFocusedCell(editor)); - assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'var abc = 0;'); - }); - }); - - test.skip('multiple tabs: dirty + clean', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/140285 - const notebook = await openRandomNotebookDocument(); - await vscode.window.showNotebookDocument(notebook); - await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow'); - assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.getText(), ''); - - await vscode.commands.executeCommand('notebook.cell.insertCodeCellAbove'); - const edit = new vscode.WorkspaceEdit(); - edit.insert(getFocusedCell(vscode.window.activeNotebookEditor)!.document.uri, new vscode.Position(0, 0), 'var abc = 0;'); - await vscode.workspace.applyEdit(edit); - - const secondNotebook = await openRandomNotebookDocument(); - await vscode.window.showNotebookDocument(secondNotebook); - await vscode.commands.executeCommand('workbench.action.closeActiveEditor'); - - // make sure that the previous dirty editor is still restored in the extension host and no data loss - assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true); - assert.deepStrictEqual(vscode.window.activeNotebookEditor?.notebook.cellAt(1), getFocusedCell(vscode.window.activeNotebookEditor)); - assert.deepStrictEqual(vscode.window.activeNotebookEditor?.notebook.cellCount, 4); - assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.getText(), 'var abc = 0;'); - - }); - - test.skip('multiple tabs: two dirty tabs and switching', async function () { - const notebook = await openRandomNotebookDocument(); - await vscode.window.showNotebookDocument(notebook); - await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow'); - assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.getText(), ''); - - await vscode.commands.executeCommand('notebook.cell.insertCodeCellAbove'); - const edit = new vscode.WorkspaceEdit(); - edit.insert(getFocusedCell(vscode.window.activeNotebookEditor)!.document.uri, new vscode.Position(0, 0), 'var abc = 0;'); - await vscode.workspace.applyEdit(edit); - - const secondNotebook = await openRandomNotebookDocument(); - await vscode.window.showNotebookDocument(secondNotebook); - await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow'); - assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.getText(), ''); - - // switch to the first editor - await vscode.window.showNotebookDocument(notebook); - assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true); - assert.deepStrictEqual(vscode.window.activeNotebookEditor?.notebook.cellAt(1), getFocusedCell(vscode.window.activeNotebookEditor)); - assert.deepStrictEqual(vscode.window.activeNotebookEditor?.notebook.cellCount, 4); - assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.getText(), 'var abc = 0;'); - - // switch to the second editor - await vscode.window.showNotebookDocument(secondNotebook); - assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true); - assert.deepStrictEqual(vscode.window.activeNotebookEditor?.notebook.cellAt(1), getFocusedCell(vscode.window.activeNotebookEditor)); - assert.deepStrictEqual(vscode.window.activeNotebookEditor?.notebook.cellCount, 3); - assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.getText(), ''); - - }); - test('multiple tabs: different editors with same document', async function () { const notebook = await openRandomNotebookDocument(); @@ -639,15 +466,15 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { test('#97830, #97764. Support switch to other editor types', async function () { const notebook = await openRandomNotebookDocument(); const editor = await vscode.window.showNotebookDocument(notebook); - await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow'); const edit = new vscode.WorkspaceEdit(); - edit.insert(getFocusedCell(editor)!.document.uri, new vscode.Position(0, 0), 'var abc = 0;'); + const focusedCell = getFocusedCell(editor); + assert.ok(focusedCell); + edit.replace(focusedCell.document.uri, focusedCell.document.lineAt(0).range, 'var abc = 0;'); await vscode.workspace.applyEdit(edit); assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'var abc = 0;'); // no kernel -> no default language - // assert.strictEqual(vscode.window.activeNotebookEditor!.kernel, undefined); assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript'); await vscode.commands.executeCommand('vscode.openWith', notebook.uri, 'default'); @@ -807,7 +634,10 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { const notebook = await openRandomNotebookDocument(); const editor = await vscode.window.showNotebookDocument(notebook); const cell0 = editor.notebook.cellAt(0); - await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow'); + const notebookEdit = new vscode.NotebookEdit(new vscode.NotebookRange(1, 1), [new vscode.NotebookCellData(vscode.NotebookCellKind.Code, 'test 2', 'javascript')]); + const edit = new vscode.WorkspaceEdit(); + edit.set(notebook.uri, [notebookEdit]); + await vscode.workspace.applyEdit(edit); const cell1 = editor.notebook.cellAt(1); const nextCellKernel = new class extends Kernel { @@ -844,7 +674,10 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { const notebook = await openRandomNotebookDocument(); const editor = await vscode.window.showNotebookDocument(notebook); const cell0 = editor.notebook.cellAt(0); - await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow'); + const notebookEdit = new vscode.NotebookEdit(new vscode.NotebookRange(1, 1), [new vscode.NotebookCellData(vscode.NotebookCellKind.Code, 'test 2', 'javascript')]); + const edit = new vscode.WorkspaceEdit(); + edit.set(notebook.uri, [notebookEdit]); + await vscode.workspace.applyEdit(edit); const cell1 = editor.notebook.cellAt(1); const nextCellKernel = new class extends Kernel { diff --git a/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts b/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts index 51c9d9a4798..c35be948647 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts @@ -5,12 +5,13 @@ import * as assert from 'assert'; import { FoldingModel, updateFoldingStateAtIndex } from 'vs/workbench/contrib/notebook/browser/viewModel/foldingModel'; -import { changeCellToKind, computeCellLinesContents, copyCellRange, joinNotebookCells, moveCellRange, runDeleteAction } from 'vs/workbench/contrib/notebook/browser/controller/cellOperations'; +import { changeCellToKind, computeCellLinesContents, copyCellRange, insertCell, joinNotebookCells, moveCellRange, runDeleteAction } from 'vs/workbench/contrib/notebook/browser/controller/cellOperations'; import { CellEditType, CellKind, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { withTestNotebook } from 'vs/workbench/contrib/notebook/test/browser/testNotebookEditor'; import { Range } from 'vs/editor/common/core/range'; import { ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits'; +import { ILanguageService } from 'vs/editor/common/languages/language'; suite('CellOperations', () => { test('Move cells - single cell', async function () { @@ -501,4 +502,25 @@ suite('CellOperations', () => { ); }); + test('Insert cell', async function () { + await withTestNotebook( + [ + ['# header a', 'markdown', CellKind.Markup, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['# header b', 'markdown', CellKind.Markup, [], {}], + ['var b = 2;', 'javascript', CellKind.Code, [], {}], + ['var c = 3;', 'javascript', CellKind.Code, [], {}] + ], + async (editor, viewModel, accessor) => { + const languageService = accessor.get(ILanguageService); + + const insertedCellAbove = insertCell(languageService, editor, 4, CellKind.Code, 'above', 'var a = 0;'); + assert.strictEqual(viewModel.length, 6); + assert.strictEqual(viewModel.cellAt(4), insertedCellAbove); + + const insertedCellBelow = insertCell(languageService, editor, 1, CellKind.Code, 'below', 'var a = 0;'); + assert.strictEqual(viewModel.length, 7); + assert.strictEqual(viewModel.cellAt(2), insertedCellBelow); + }); + }); }); From c95adcfda2fe9290e434eee32fd711c25b24dedb Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Tue, 2 Aug 2022 16:48:38 -0700 Subject: [PATCH 166/303] clear decorations on window reload (#156924) --- .../contrib/terminal/browser/xterm/decorationAddon.ts | 5 ++++- .../terminal/test/browser/xterm/decorationAddon.test.ts | 3 +++ .../terminal/test/browser/xterm/xtermTerminal.test.ts | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts index 54373968a49..dedbc805e9b 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts @@ -27,6 +27,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProcess'; import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { Codicon } from 'vs/base/common/codicons'; +import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle'; const enum DecorationSelector { CommandDecoration = 'terminal-command-decoration', @@ -68,7 +69,8 @@ export class DecorationAddon extends Disposable implements ITerminalAddon { @IConfigurationService private readonly _configurationService: IConfigurationService, @IThemeService private readonly _themeService: IThemeService, @IOpenerService private readonly _openerService: IOpenerService, - @IQuickInputService private readonly _quickInputService: IQuickInputService + @IQuickInputService private readonly _quickInputService: IQuickInputService, + @ILifecycleService lifecycleService: ILifecycleService ) { super(); this._register(toDisposable(() => this._dispose())); @@ -108,6 +110,7 @@ export class DecorationAddon extends Disposable implements ITerminalAddon { } } })); + this._register(lifecycleService.onWillShutdown(() => this._disposeAllDecorations())); } private _updateDecorationVisibility(): void { diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts index ddcbd66e3b2..35583034f54 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts @@ -18,6 +18,8 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle'; +import { TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices'; class TestTerminal extends Terminal { override registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined { @@ -56,6 +58,7 @@ suite('DecorationAddon', () => { instantiationService.stub(IContextMenuService, instantiationService.createInstance(ContextMenuService)); const capabilities = new TerminalCapabilityStore(); capabilities.add(TerminalCapability.CommandDetection, new CommandDetectionCapability(xterm, new NullLogService())); + instantiationService.stub(ILifecycleService, new TestLifecycleService()); decorationAddon = instantiationService.createInstance(DecorationAddon, capabilities); xterm.loadAddon(decorationAddon); instantiationService.stub(ILogService, NullLogService); diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts index 99bc8e0b095..1d344fe1f47 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts @@ -27,6 +27,8 @@ import { TerminalLocation } from 'vs/platform/terminal/common/terminal'; import { TerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; +import { TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle'; class TestWebglAddon { static shouldThrow = false; @@ -111,6 +113,7 @@ suite('XtermTerminal', () => { instantiationService.stub(IThemeService, themeService); instantiationService.stub(IViewDescriptorService, viewDescriptorService); instantiationService.stub(IContextMenuService, instantiationService.createInstance(ContextMenuService)); + instantiationService.stub(ILifecycleService, new TestLifecycleService()); configHelper = instantiationService.createInstance(TerminalConfigHelper); xterm = instantiationService.createInstance(TestXtermTerminal, Terminal, configHelper, 80, 30, TerminalLocation.Panel, new TerminalCapabilityStore(), true); From c07ff2eb1d8d024accf1f5deba8b6bce384d4cb6 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 2 Aug 2022 16:53:57 -0700 Subject: [PATCH 167/303] Remove types.isArray (#156930) This function was simply calling Array.isArray --- src/vs/base/browser/indexedDB.ts | 3 +-- src/vs/base/common/objects.ts | 4 ++-- src/vs/base/common/paging.ts | 3 +-- src/vs/base/common/types.ts | 7 ------- src/vs/base/test/common/types.test.ts | 18 ------------------ .../editor/contrib/folding/browser/folding.ts | 2 +- .../configuration/common/configuration.ts | 2 +- .../common/extensionStorage.ts | 4 ++-- .../common/extensionsScannerService.ts | 4 ++-- .../userDataSync/common/userDataSync.ts | 4 ++-- .../common/userDataSyncServiceIpc.ts | 3 +-- .../common/userDataSyncStoreService.ts | 4 ++-- .../api/common/extHostLanguageFeatures.ts | 10 +++++----- src/vs/workbench/api/common/extHostTypes.ts | 4 ++-- .../browser/parts/editor/textDiffEditor.ts | 4 ++-- .../browser/extensions.contribution.ts | 3 +-- .../extensions/browser/webRecommendations.ts | 3 +-- .../preferences/browser/settingsEditor2.ts | 4 ++-- .../preferences/browser/settingsTree.ts | 10 +++++----- .../preferences/browser/settingsTreeModels.ts | 6 +++--- .../tasks/browser/abstractTaskService.ts | 2 +- .../tasks/browser/terminalTaskSystem.ts | 2 +- .../contrib/tasks/common/problemMatcher.ts | 6 +++--- .../contrib/tasks/common/taskConfiguration.ts | 6 +++--- src/vs/workbench/electron-sandbox/window.ts | 4 ++-- .../baseConfigurationResolverService.ts | 4 ++-- .../common/variableResolver.ts | 2 +- .../keybinding/browser/keybindingService.ts | 3 +-- .../keybinding/common/keybindingEditing.ts | 3 +-- .../preferences/browser/preferencesService.ts | 4 ++-- .../preferences/common/preferencesModels.ts | 8 ++++---- .../common/preferencesValidation.ts | 18 +++++++++--------- .../search/common/textSearchManager.ts | 3 +-- .../services/themes/common/colorThemeData.ts | 4 ++-- .../test/browser/workbenchTestServices.ts | 4 ++-- 35 files changed, 71 insertions(+), 104 deletions(-) diff --git a/src/vs/base/browser/indexedDB.ts b/src/vs/base/browser/indexedDB.ts index 25651932124..a4319aaf5d4 100644 --- a/src/vs/base/browser/indexedDB.ts +++ b/src/vs/base/browser/indexedDB.ts @@ -6,7 +6,6 @@ import { toErrorMessage } from 'vs/base/common/errorMessage'; import { getErrorMessage } from 'vs/base/common/errors'; import { mark } from 'vs/base/common/performance'; -import { isArray } from 'vs/base/common/types'; class MissingStoresError extends Error { constructor(readonly db: IDBDatabase) { @@ -122,7 +121,7 @@ export class IndexedDB { this.pendingTransactions.push(transaction); return new Promise((c, e) => { transaction.oncomplete = () => { - if (isArray(request)) { + if (Array.isArray(request)) { c(request.map(r => r.result)); } else { c(request.result); diff --git a/src/vs/base/common/objects.ts b/src/vs/base/common/objects.ts index 7c7c4483bd9..52d27bc3080 100644 --- a/src/vs/base/common/objects.ts +++ b/src/vs/base/common/objects.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { isArray, isTypedArray, isObject, isUndefinedOrNull } from 'vs/base/common/types'; +import { isTypedArray, isObject, isUndefinedOrNull } from 'vs/base/common/types'; export function deepClone(obj: T): T { if (!obj || typeof obj !== 'object') { @@ -61,7 +61,7 @@ function _cloneAndChange(obj: any, changer: (orig: any) => any, seen: Set): return changed; } - if (isArray(obj)) { + if (Array.isArray(obj)) { const r1: any[] = []; for (const e of obj) { r1.push(_cloneAndChange(e, changer, seen)); diff --git a/src/vs/base/common/paging.ts b/src/vs/base/common/paging.ts index 60f72b407c3..1d9b7938169 100644 --- a/src/vs/base/common/paging.ts +++ b/src/vs/base/common/paging.ts @@ -6,7 +6,6 @@ import { range } from 'vs/base/common/arrays'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { canceled } from 'vs/base/common/errors'; -import { isArray } from 'vs/base/common/types'; /** * A Pager is a stateless abstraction over a paged collection. @@ -65,7 +64,7 @@ export class PagedModel implements IPagedModel { get length(): number { return this.pager.total; } constructor(arg: IPager | T[]) { - this.pager = isArray(arg) ? singlePagePager(arg) : arg; + this.pager = Array.isArray(arg) ? singlePagePager(arg) : arg; const totalPages = Math.ceil(this.pager.total / this.pager.pageSize); diff --git a/src/vs/base/common/types.ts b/src/vs/base/common/types.ts index e3844cd39e8..36e532e5695 100644 --- a/src/vs/base/common/types.ts +++ b/src/vs/base/common/types.ts @@ -5,13 +5,6 @@ import { URI, UriComponents } from 'vs/base/common/uri'; -/** - * @returns whether the provided parameter is a JavaScript Array or not. - */ -export function isArray(array: any): array is any[] { - return Array.isArray(array); -} - /** * @returns whether the provided parameter is a JavaScript String or not. */ diff --git a/src/vs/base/test/common/types.test.ts b/src/vs/base/test/common/types.test.ts index cb7dedbe272..1f5e7d0b812 100644 --- a/src/vs/base/test/common/types.test.ts +++ b/src/vs/base/test/common/types.test.ts @@ -82,24 +82,6 @@ suite('Types', () => { assert(types.isEmptyObject({})); }); - test('isArray', () => { - assert(!types.isArray(undefined)); - assert(!types.isArray(null)); - assert(!types.isArray('foo')); - assert(!types.isArray(5)); - assert(!types.isArray(true)); - assert(!types.isArray({})); - assert(!types.isArray(/test/)); - assert(!types.isArray(new RegExp(''))); - assert(!types.isArray(new Date())); - assert(!types.isArray(assert)); - assert(!types.isArray(function foo() { /**/ })); - assert(!types.isArray({ foo: 'bar' })); - - assert(types.isArray([])); - assert(types.isArray([1, 2, '3'])); - }); - test('isString', () => { assert(!types.isString(undefined)); assert(!types.isString(null)); diff --git a/src/vs/editor/contrib/folding/browser/folding.ts b/src/vs/editor/contrib/folding/browser/folding.ts index c35cdb69a65..2ec75651190 100644 --- a/src/vs/editor/contrib/folding/browser/folding.ts +++ b/src/vs/editor/contrib/folding/browser/folding.ts @@ -565,7 +565,7 @@ function foldingArgumentsConstraint(args: any) { if (!types.isUndefined(foldingArgs.direction) && !types.isString(foldingArgs.direction)) { return false; } - if (!types.isUndefined(foldingArgs.selectionLines) && (!types.isArray(foldingArgs.selectionLines) || !foldingArgs.selectionLines.every(types.isNumber))) { + if (!types.isUndefined(foldingArgs.selectionLines) && (!Array.isArray(foldingArgs.selectionLines) || !foldingArgs.selectionLines.every(types.isNumber))) { return false; } } diff --git a/src/vs/platform/configuration/common/configuration.ts b/src/vs/platform/configuration/common/configuration.ts index 4ea7a9bce8d..0afd5a8707c 100644 --- a/src/vs/platform/configuration/common/configuration.ts +++ b/src/vs/platform/configuration/common/configuration.ts @@ -26,7 +26,7 @@ export interface IConfigurationOverrides { export function isConfigurationUpdateOverrides(thing: any): thing is IConfigurationUpdateOverrides { return thing && typeof thing === 'object' - && (!thing.overrideIdentifiers || types.isArray(thing.overrideIdentifiers)) + && (!thing.overrideIdentifiers || Array.isArray(thing.overrideIdentifiers)) && !thing.overrideIdentifier && (!thing.resource || thing.resource instanceof URI); } diff --git a/src/vs/platform/extensionManagement/common/extensionStorage.ts b/src/vs/platform/extensionManagement/common/extensionStorage.ts index 52b35c6cb28..b7eb08a88b2 100644 --- a/src/vs/platform/extensionManagement/common/extensionStorage.ts +++ b/src/vs/platform/extensionManagement/common/extensionStorage.ts @@ -12,7 +12,7 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { distinct } from 'vs/base/common/arrays'; import { ILogService } from 'vs/platform/log/common/log'; import { IExtension } from 'vs/platform/extensions/common/extensions'; -import { isArray, isString } from 'vs/base/common/types'; +import { isString } from 'vs/base/common/types'; import { IStringDictionary } from 'vs/base/common/collections'; import { IExtensionManagementService, IGalleryExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -197,7 +197,7 @@ export class ExtensionStorageService extends Disposable implements IExtensionSto const value = this.storageService.get('extensionStorage.migrationList', StorageScope.APPLICATION, '[]'); try { const migrationList = JSON.parse(value); - if (isArray(migrationList)) { + if (Array.isArray(migrationList)) { return migrationList; } } catch (error) { /* ignore */ } diff --git a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts index b51075daec1..4de8730750a 100644 --- a/src/vs/platform/extensionManagement/common/extensionsScannerService.ts +++ b/src/vs/platform/extensionManagement/common/extensionsScannerService.ts @@ -18,7 +18,7 @@ import * as platform from 'vs/base/common/platform'; import { basename, isEqual, joinPath } from 'vs/base/common/resources'; import * as semver from 'vs/base/common/semver/semver'; import Severity from 'vs/base/common/severity'; -import { isArray, isEmptyObject, isObject, isString } from 'vs/base/common/types'; +import { isEmptyObject, isObject, isString } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -821,7 +821,7 @@ class ExtensionsScanner extends Disposable { k === 'commands' ? processEntry(value, k, true) : processEntry(value, k, command); } } - } else if (isArray(value)) { + } else if (Array.isArray(value)) { for (let i = 0; i < value.length; i++) { processEntry(value, i, command); } diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index 6973141914f..6f6bf364d98 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -10,7 +10,7 @@ import { FormattingOptions } from 'vs/base/common/jsonFormatter'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IExtUri, isEqualOrParent, joinPath } from 'vs/base/common/resources'; -import { isArray, isObject, isString } from 'vs/base/common/types'; +import { isObject, isString } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { IHeaders } from 'vs/base/parts/request/common/request'; import { localize } from 'vs/nls'; @@ -128,7 +128,7 @@ export function isAuthenticationProvider(thing: any): thing is IAuthenticationPr return thing && isObject(thing) && isString(thing.id) - && isArray(thing.scopes); + && Array.isArray(thing.scopes); } export const enum SyncResource { diff --git a/src/vs/platform/userDataSync/common/userDataSyncServiceIpc.ts b/src/vs/platform/userDataSync/common/userDataSyncServiceIpc.ts index c945029e6a3..dea1952371d 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncServiceIpc.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncServiceIpc.ts @@ -6,7 +6,6 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { isArray } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc'; import { ILogService } from 'vs/platform/log/common/log'; @@ -184,7 +183,7 @@ export class UserDataSyncChannelClient extends Disposable implements IUserDataSy const that = this; const manualSyncTaskChannelClient = new ManualSyncTaskChannelClient(id, manifest, status, { async call(command: string, arg?: any, cancellationToken?: CancellationToken): Promise { - return that.channel.call(`manualSync/${command}`, [id, ...(isArray(arg) ? arg : [arg])], cancellationToken); + return that.channel.call(`manualSync/${command}`, [id, ...(Array.isArray(arg) ? arg : [arg])], cancellationToken); }, listen(event: string, arg?: any): Event { return Event.map( diff --git a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts index 2b7bd79e2b8..c3fe6a3db6c 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts @@ -12,7 +12,7 @@ import { Mimes } from 'vs/base/common/mime'; import { isWeb } from 'vs/base/common/platform'; import { ConfigurationSyncStore } from 'vs/base/common/product'; import { joinPath, relativePath } from 'vs/base/common/resources'; -import { isArray, isObject, isString } from 'vs/base/common/types'; +import { isObject, isString } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; import { IHeaders, IRequestContext, IRequestOptions } from 'vs/base/parts/request/common/request'; @@ -72,7 +72,7 @@ export abstract class AbstractUserDataSyncStoreManagementService extends Disposa if (value && isString(value.url) && isObject(value.authenticationProviders) - && Object.keys(value.authenticationProviders).every(authenticationProviderId => isArray(value!.authenticationProviders![authenticationProviderId].scopes)) + && Object.keys(value.authenticationProviders).every(authenticationProviderId => Array.isArray(value!.authenticationProviders![authenticationProviderId].scopes)) ) { const syncStore = value as ConfigurationSyncStore; const canSwitch = !!syncStore.canSwitch && !configuredStore?.url; diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index d9244952ab0..17d1d86c2d7 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -18,7 +18,7 @@ import { regExpLeadsToEndlessLoop, regExpFlags } from 'vs/base/common/strings'; import { IPosition } from 'vs/editor/common/core/position'; import { IRange, Range as EditorRange } from 'vs/editor/common/core/range'; import { isFalsyOrEmpty, isNonEmptyArray, coalesce } from 'vs/base/common/arrays'; -import { isArray, isObject } from 'vs/base/common/types'; +import { isObject } from 'vs/base/common/types'; import { ISelection, Selection } from 'vs/editor/common/core/selection'; import { ILogService } from 'vs/platform/log/common/log'; import { CancellationToken } from 'vs/base/common/cancellation'; @@ -1124,8 +1124,8 @@ class InlineCompletionAdapter extends InlineCompletionAdapterBase { return undefined; } - const normalizedResult = isArray(result) ? result : result.items; - const commands = this._isAdditionsProposedApiEnabled ? isArray(result) ? [] : result.commands || [] : []; + const normalizedResult = Array.isArray(result) ? result : result.items; + const commands = this._isAdditionsProposedApiEnabled ? Array.isArray(result) ? [] : result.commands || [] : []; let disposableStore: DisposableStore | undefined = undefined; const pid = this._references.createReferenceId({ @@ -1230,8 +1230,8 @@ class InlineCompletionAdapterNew extends InlineCompletionAdapterBase { return undefined; } - const normalizedResult = isArray(result) ? result : result.items; - const commands = isArray(result) ? [] : result.commands || []; + const normalizedResult = Array.isArray(result) ? result : result.items; + const commands = Array.isArray(result) ? [] : result.commands || []; let disposableStore: DisposableStore | undefined = undefined; const pid = this._references.createReferenceId({ diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 987ca4c4a30..d1dd009b1ba 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -10,7 +10,7 @@ import { MarkdownString as BaseMarkdownString } from 'vs/base/common/htmlContent import { ResourceMap } from 'vs/base/common/map'; import { Mimes, normalizeMimeType } from 'vs/base/common/mime'; import { nextCharLength } from 'vs/base/common/strings'; -import { isArray, isString, isStringArray } from 'vs/base/common/types'; +import { isString, isStringArray } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; import { FileSystemProviderErrorCode, markAsFileSystemProviderError } from 'vs/platform/files/common/files'; @@ -3449,7 +3449,7 @@ export class NotebookCellOutput { if (!candidate || typeof candidate !== 'object') { return false; } - return typeof (candidate).id === 'string' && isArray((candidate).items); + return typeof (candidate).id === 'string' && Array.isArray((candidate).items); } static ensureUniqueMimeTypes(items: NotebookCellOutputItem[], warn: boolean = false): NotebookCellOutputItem[] { diff --git a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts index a638504849a..f0a9e78c2c8 100644 --- a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts @@ -5,7 +5,7 @@ import { localize } from 'vs/nls'; import { deepClone } from 'vs/base/common/objects'; -import { isObject, isArray, assertIsDefined, withUndefinedAsNull, withNullAsUndefined } from 'vs/base/common/types'; +import { isObject, assertIsDefined, withUndefinedAsNull, withNullAsUndefined } from 'vs/base/common/types'; import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { IDiffEditorOptions, IEditorOptions as ICodeEditorOptions } from 'vs/editor/common/config/editorOptions'; import { AbstractTextEditor, IEditorConfiguration } from 'vs/workbench/browser/parts/editor/textEditor'; @@ -259,7 +259,7 @@ export class TextDiffEditor extends AbstractTextEditor imp private isFileBinaryError(error: Error[]): boolean; private isFileBinaryError(error: Error): boolean; private isFileBinaryError(error: Error | Error[]): boolean { - if (isArray(error)) { + if (Array.isArray(error)) { const errors = error; return errors.some(error => this.isFileBinaryError(error)); diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 13edddae38d..6c9c087bb9b 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -61,7 +61,6 @@ import { ExtensionEnablementWorkspaceTrustTransitionParticipant } from 'vs/workb import { clearSearchResultsIcon, configureRecommendedIcon, extensionsViewIcon, filterIcon, installWorkspaceRecommendedIcon, refreshIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons'; import { EXTENSION_CATEGORIES } from 'vs/platform/extensions/common/extensions'; import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; -import { isArray } from 'vs/base/common/types'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; import { mnemonicButtonLabel } from 'vs/base/common/labels'; @@ -1549,7 +1548,7 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi } private registerExtensionAction(extensionActionOptions: IExtensionActionOptions): IDisposable { - const menus = extensionActionOptions.menu ? isArray(extensionActionOptions.menu) ? extensionActionOptions.menu : [extensionActionOptions.menu] : []; + const menus = extensionActionOptions.menu ? Array.isArray(extensionActionOptions.menu) ? extensionActionOptions.menu : [extensionActionOptions.menu] : []; let menusWithOutTitles: ({ id: MenuId } & Omit)[] = []; const menusWithTitles: { id: MenuId; item: IMenuItem }[] = []; if (extensionActionOptions.menuTitles) { diff --git a/src/vs/workbench/contrib/extensions/browser/webRecommendations.ts b/src/vs/workbench/contrib/extensions/browser/webRecommendations.ts index 12e005319e2..8688c14b824 100644 --- a/src/vs/workbench/contrib/extensions/browser/webRecommendations.ts +++ b/src/vs/workbench/contrib/extensions/browser/webRecommendations.ts @@ -6,7 +6,6 @@ import { ExtensionRecommendations, ExtensionRecommendation } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations'; import { IProductService } from 'vs/platform/product/common/productService'; import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; -import { isArray } from 'vs/base/common/types'; import { localize } from 'vs/nls'; import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; @@ -24,7 +23,7 @@ export class WebRecommendations extends ExtensionRecommendations { protected async doActivate(): Promise { const isOnlyWeb = this.extensionManagementServerService.webExtensionManagementServer && !this.extensionManagementServerService.localExtensionManagementServer && !this.extensionManagementServerService.remoteExtensionManagementServer; - if (isOnlyWeb && isArray(this.productService.webExtensionTips)) { + if (isOnlyWeb && Array.isArray(this.productService.webExtensionTips)) { this._recommendations = this.productService.webExtensionTips.map(extensionId => ({ extensionId: extensionId.toLowerCase(), reason: { diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index a506b12de3d..252f5e99204 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -20,7 +20,7 @@ import { Iterable } from 'vs/base/common/iterator'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore, dispose } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; -import { isArray, withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types'; +import { withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import 'vs/css!./media/settingsEditor2'; import { localize } from 'vs/nls'; @@ -133,7 +133,7 @@ export class SettingsEditor2 extends EditorPane { ]; private static shouldSettingUpdateFast(type: SettingValueType | SettingValueType[]): boolean { - if (isArray(type)) { + if (Array.isArray(type)) { // nullable integer/number or complex return false; } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index 2ad3516e3e9..362212fc944 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -26,7 +26,7 @@ import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore, dispose, toDisposable } from 'vs/base/common/lifecycle'; import { isIOS } from 'vs/base/common/platform'; import { escapeRegExpCharacters } from 'vs/base/common/strings'; -import { isArray, isDefined, isUndefinedOrNull } from 'vs/base/common/types'; +import { isDefined, isUndefinedOrNull } from 'vs/base/common/types'; import { localize } from 'vs/nls'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -348,7 +348,7 @@ function parseNumericObjectValues(dataElement: SettingsTreeSettingElement, v: Re } function getListDisplayValue(element: SettingsTreeSettingElement): IListDataItem[] { - if (!element.value || !isArray(element.value)) { + if (!element.value || !Array.isArray(element.value)) { return []; } @@ -1192,9 +1192,9 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr private computeNewList(template: ISettingListItemTemplate, e: ISettingListChangeEvent): string[] | undefined { if (template.context) { let newValue: string[] = []; - if (isArray(template.context.scopeValue)) { + if (Array.isArray(template.context.scopeValue)) { newValue = [...template.context.scopeValue]; - } else if (isArray(template.context.value)) { + } else if (Array.isArray(template.context.value)) { newValue = [...template.context.value]; } @@ -1229,7 +1229,7 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr if ( template.context.defaultValue && - isArray(template.context.defaultValue) && + Array.isArray(template.context.defaultValue) && template.context.defaultValue.length === newValue.length && template.context.defaultValue.join() === newValue.join() ) { diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts index 8238b7b7ee2..23092ada5f9 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts @@ -5,7 +5,7 @@ import * as arrays from 'vs/base/common/arrays'; import { escapeRegExpCharacters, isFalsyOrWhitespace } from 'vs/base/common/strings'; -import { isArray, withUndefinedAsNull, isUndefinedOrNull } from 'vs/base/common/types'; +import { withUndefinedAsNull, isUndefinedOrNull } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { ConfigurationTarget, IConfigurationValue } from 'vs/platform/configuration/common/configuration'; import { SettingsTarget } from 'vs/workbench/contrib/preferences/browser/preferencesWidgets'; @@ -321,7 +321,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { } else if (this.setting.type === 'array' && this.setting.arrayItemType && ['string', 'enum', 'number', 'integer'].includes(this.setting.arrayItemType)) { this.valueType = SettingValueType.Array; - } else if (isArray(this.setting.type) && this.setting.type.includes(SettingValueType.Null) && this.setting.type.length === 2) { + } else if (Array.isArray(this.setting.type) && this.setting.type.includes(SettingValueType.Null) && this.setting.type.length === 2) { if (this.setting.type.includes(SettingValueType.Integer)) { this.valueType = SettingValueType.NullableInteger; } else if (this.setting.type.includes(SettingValueType.Number)) { @@ -805,7 +805,7 @@ function isObjectSetting({ function settingTypeEnumRenderable(_type: string | string[]) { const enumRenderableSettingTypes = ['string', 'boolean', 'null', 'integer', 'number']; - const type = isArray(_type) ? _type : [_type]; + const type = Array.isArray(_type) ? _type : [_type]; return type.every(type => enumRenderableSettingTypes.includes(type)); } diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 7f856c3e91a..cb53a27ac62 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -3625,7 +3625,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } else if (suppressTaskName) { configElement.command = task._source.config.element.command; } - if (task.command.args && (!Types.isArray(task.command.args) || (task.command.args.length > 0))) { + if (task.command.args && (!Array.isArray(task.command.args) || (task.command.args.length > 0))) { if (!globalConfig.windows?.args && !globalConfig.osx?.args && !globalConfig.linux?.args) { configElement.args = task.command.args; } else { diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 91e1316e1f6..eed6a1d6cf2 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -1565,7 +1565,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { private _collectDefinitionVariables(variables: Set, definition: any): void { if (Types.isString(definition)) { this._collectVariables(variables, definition); - } else if (Types.isArray(definition)) { + } else if (Array.isArray(definition)) { definition.forEach((element: any) => this._collectDefinitionVariables(variables, element)); } else if (Types.isObject(definition)) { for (const key in definition) { diff --git a/src/vs/workbench/contrib/tasks/common/problemMatcher.ts b/src/vs/workbench/contrib/tasks/common/problemMatcher.ts index 7e2fb354129..de370e64892 100644 --- a/src/vs/workbench/contrib/tasks/common/problemMatcher.ts +++ b/src/vs/workbench/contrib/tasks/common/problemMatcher.ts @@ -236,7 +236,7 @@ export interface ILineMatcher { export function createLineMatcher(matcher: ProblemMatcher, fileService?: IFileService): ILineMatcher { const pattern = matcher.pattern; - if (Types.isArray(pattern)) { + if (Array.isArray(pattern)) { return new MultiLineMatcher(matcher, fileService); } else { return new SingleLineMatcher(matcher, fileService); @@ -644,7 +644,7 @@ export namespace Config { export namespace MultiLineProblemPattern { export function is(value: any): value is MultiLineProblemPattern { - return value && Types.isArray(value); + return value && Array.isArray(value); } } @@ -684,7 +684,7 @@ export namespace Config { export namespace NamedMultiLineCheckedProblemPattern { export function is(value: any): value is INamedMultiLineCheckedProblemPattern { const candidate = value as INamedMultiLineCheckedProblemPattern; - return candidate && Types.isString(candidate.name) && Types.isArray(candidate.patterns) && MultiLineCheckedProblemPattern.is(candidate.patterns); + return candidate && Types.isString(candidate.name) && Array.isArray(candidate.patterns) && MultiLineCheckedProblemPattern.is(candidate.patterns); } } diff --git a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts index 0bb00f57620..8ea82730adf 100644 --- a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts +++ b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts @@ -1150,7 +1150,7 @@ export namespace ProblemMatcherConverter { export function namedFrom(this: void, declares: ProblemMatcherConfig.INamedProblemMatcher[] | undefined, context: IParseContext): IStringDictionary { const result: IStringDictionary = Object.create(null); - if (!Types.isArray(declares)) { + if (!Array.isArray(declares)) { return result; } (declares).forEach((value) => { @@ -1213,7 +1213,7 @@ export namespace ProblemMatcherConverter { function getProblemMatcherKind(this: void, value: ProblemMatcherConfig.ProblemMatcherType): ProblemMatcherKind { if (Types.isString(value)) { return ProblemMatcherKind.String; - } else if (Types.isArray(value)) { + } else if (Array.isArray(value)) { return ProblemMatcherKind.Array; } else if (!Types.isUndefined(value)) { return ProblemMatcherKind.ProblemMatcher; @@ -1365,7 +1365,7 @@ namespace ConfigurationProperties { } result.group = GroupKind.from(external.group); if (external.dependsOn !== undefined) { - if (Types.isArray(external.dependsOn)) { + if (Array.isArray(external.dependsOn)) { result.dependsOn = external.dependsOn.reduce((dependencies: Tasks.ITaskDependency[], item): Tasks.ITaskDependency[] => { const dependency = TaskDependency.from(item, context, source); if (dependency) { diff --git a/src/vs/workbench/electron-sandbox/window.ts b/src/vs/workbench/electron-sandbox/window.ts index b1987e81a3c..2978c4157db 100644 --- a/src/vs/workbench/electron-sandbox/window.ts +++ b/src/vs/workbench/electron-sandbox/window.ts @@ -40,7 +40,7 @@ import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/ import { coalesce } from 'vs/base/common/arrays'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { assertIsDefined, isArray } from 'vs/base/common/types'; +import { assertIsDefined } from 'vs/base/common/types'; import { IOpenerService, OpenOptions } from 'vs/platform/opener/common/opener'; import { Schemas } from 'vs/base/common/network'; import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; @@ -753,7 +753,7 @@ export class NativeWindow extends Disposable { const disabled = this.configurationService.getValue('keyboard.touchbar.enabled') === false; const touchbarIgnored = this.configurationService.getValue('keyboard.touchbar.ignored'); - const ignoredItems = isArray(touchbarIgnored) ? touchbarIgnored : []; + const ignoredItems = Array.isArray(touchbarIgnored) ? touchbarIgnored : []; // Fill actions into groups respecting order this.touchBarDisposables.add(createAndFillInActionBarActions(this.touchBarMenu, undefined, actions)); diff --git a/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts b/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts index 07053d26b4d..4fe9ddc5505 100644 --- a/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts @@ -261,7 +261,7 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR variables.push(contributed); } } - } else if (Types.isArray(object)) { + } else if (Array.isArray(object)) { for (const value of object) { this.findVariables(value, variables); @@ -315,7 +315,7 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR if (!Types.isString(info.description)) { missingAttribute('description'); } - if (Types.isArray(info.options)) { + if (Array.isArray(info.options)) { for (const pickOption of info.options) { if (!Types.isString(pickOption) && !Types.isString(pickOption.value)) { missingAttribute('value'); diff --git a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts index 8cbb4be2848..b3183db14bc 100644 --- a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts @@ -138,7 +138,7 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe private async recursiveResolve(environment: Environment, folderUri: uri | undefined, value: any, commandValueMapping?: IStringDictionary, resolvedVariables?: Map): Promise { if (types.isString(value)) { return this.resolveString(environment, folderUri, value, commandValueMapping, resolvedVariables); - } else if (types.isArray(value)) { + } else if (Array.isArray(value)) { return Promise.all(value.map(s => this.recursiveResolve(environment, folderUri, s, commandValueMapping, resolvedVariables))); } else if (types.isObject(value)) { const result: IStringDictionary | string[]> = Object.create(null); diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index f75556ad8a3..a7c13b7c53e 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -41,7 +41,6 @@ import { parse } from 'vs/base/common/json'; import * as objects from 'vs/base/common/objects'; import { IKeyboardLayoutService } from 'vs/platform/keyboardLayout/common/keyboardLayout'; import { getDispatchConfig } from 'vs/platform/keyboardLayout/common/dispatchConfig'; -import { isArray } from 'vs/base/common/types'; import { INavigatorWithKeyboard, IKeyboard } from 'vs/workbench/services/keybinding/browser/navigatorKeyboard'; import { flatten } from 'vs/base/common/arrays'; import { BrowserFeatures, KeyboardSupport } from 'vs/base/browser/canIUse'; @@ -767,7 +766,7 @@ class UserKeybindings extends Disposable { try { const content = await this.fileService.readFile(this.userDataProfileService.currentProfile.keybindingsResource); const value = parse(content.value.toString()); - this._keybindings = isArray(value) ? value : []; + this._keybindings = Array.isArray(value) ? value : []; } catch (e) { this._keybindings = []; } diff --git a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts index 9cecbd01bb3..a064d35bee6 100644 --- a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts +++ b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts @@ -10,7 +10,6 @@ import * as objects from 'vs/base/common/objects'; import { setProperty } from 'vs/base/common/jsonEdit'; import { Edit } from 'vs/base/common/jsonFormatter'; import { Disposable, IReference } from 'vs/base/common/lifecycle'; -import { isArray } from 'vs/base/common/types'; import { EditOperation } from 'vs/editor/common/core/editOperation'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; @@ -267,7 +266,7 @@ export class KeybindingsEditingService extends Disposable implements IKeybinding return Promise.reject(new Error(localize('parseErrors', "Unable to write to the keybindings configuration file. Please open it to correct errors/warnings in the file and try again."))); } if (parsed.result) { - if (!isArray(parsed.result)) { + if (!Array.isArray(parsed.result)) { reference.dispose(); return Promise.reject(new Error(localize('errorInvalidConfiguration', "Unable to write to the keybindings configuration file. It has an object which is not of type Array. Please open the file to clean up and try again."))); } diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index fa24a64d7af..9e17f9dca37 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -42,7 +42,7 @@ import { defaultKeybindingsContents, DefaultKeybindingsEditorModel, DefaultRawSe import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { ITextEditorService } from 'vs/workbench/services/textfile/common/textEditorService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { isArray, isObject } from 'vs/base/common/types'; +import { isObject } from 'vs/base/common/types'; import { SuggestController } from 'vs/editor/contrib/suggest/browser/suggestController'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; @@ -577,7 +577,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic if (setting) { if (edit) { - if (isObject(setting.value) || isArray(setting.value)) { + if (isObject(setting.value) || Array.isArray(setting.value)) { position = { lineNumber: setting.valueRange.startLineNumber, column: setting.valueRange.startColumn + 1 }; codeEditor.setPosition(position); await CoreEditingCommands.LineBreakInsert.runEditorCommand(null, codeEditor, null); diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 96d09e3a041..93ce790df86 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -21,7 +21,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { Registry } from 'vs/platform/registry/common/platform'; import { EditorModel } from 'vs/workbench/common/editor/editorModel'; import { IFilterMetadata, IFilterResult, IGroupFilter, IKeybindingsEditorModel, ISearchResultGroup, ISetting, ISettingMatch, ISettingMatcher, ISettingsEditorModel, ISettingsGroup, SettingMatchType } from 'vs/workbench/services/preferences/common/preferences'; -import { withNullAsUndefined, isArray } from 'vs/base/common/types'; +import { withNullAsUndefined } from 'vs/base/common/types'; import { FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; import { createValidator } from 'vs/workbench/services/preferences/common/preferencesValidation'; @@ -677,10 +677,10 @@ export class DefaultSettings extends Disposable { const descriptionLines = description.split('\n'); const overrides = OVERRIDE_PROPERTY_REGEX.test(key) ? this.parseOverrideSettings(prop.default) : []; let listItemType: string | undefined; - if (prop.type === 'array' && prop.items && !isArray(prop.items) && prop.items.type) { + if (prop.type === 'array' && prop.items && !Array.isArray(prop.items) && prop.items.type) { if (prop.items.enum) { listItemType = 'enum'; - } else if (!isArray(prop.items.type)) { + } else if (!Array.isArray(prop.items.type)) { listItemType = prop.items.type; } } @@ -692,7 +692,7 @@ export class DefaultSettings extends Disposable { let enumToUse = prop.enum; let enumDescriptions = prop.markdownEnumDescriptions ?? prop.enumDescriptions; let enumDescriptionsAreMarkdown = !!prop.markdownEnumDescriptions; - if (listItemType === 'enum' && !isArray(prop.items)) { + if (listItemType === 'enum' && !Array.isArray(prop.items)) { enumToUse = prop.items!.enum; enumDescriptions = prop.items!.markdownEnumDescriptions ?? prop.items!.enumDescriptions; enumDescriptionsAreMarkdown = !!prop.items!.markdownEnumDescriptions; diff --git a/src/vs/workbench/services/preferences/common/preferencesValidation.ts b/src/vs/workbench/services/preferences/common/preferencesValidation.ts index 14772a9ee3a..5dd0a2dfdda 100644 --- a/src/vs/workbench/services/preferences/common/preferencesValidation.ts +++ b/src/vs/workbench/services/preferences/common/preferencesValidation.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { JSONSchemaType } from 'vs/base/common/jsonSchema'; import { Color } from 'vs/base/common/color'; -import { isArray, isObject, isUndefinedOrNull, isString, isStringArray } from 'vs/base/common/types'; +import { isObject, isUndefinedOrNull, isString, isStringArray } from 'vs/base/common/types'; import { IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry'; type Validator = { enabled: boolean; isValid: (value: T) => boolean; message: string }; @@ -20,7 +20,7 @@ function isNullOrEmpty(value: unknown): boolean { } export function createValidator(prop: IConfigurationPropertySchema): (value: any) => (string | null) { - const type: (string | undefined)[] = isArray(prop.type) ? prop.type : [prop.type]; + const type: (string | undefined)[] = Array.isArray(prop.type) ? prop.type : [prop.type]; const isNullable = canBeType(type, 'null'); const isNumeric = (canBeType(type, 'number') || canBeType(type, 'integer')) && (type.length === 1 || type.length === 2 && isNullable); @@ -85,7 +85,7 @@ export function getInvalidTypeError(value: any, type: undefined | string | strin return; } - const typeArr = isArray(type) ? type : [type]; + const typeArr = Array.isArray(type) ? type : [type]; if (!typeArr.some(_type => valueValidatesAsType(value, _type))) { return nls.localize('invalidTypeError', "Setting has an invalid type, expected {0}. Fix in JSON.", JSON.stringify(type)); } @@ -98,11 +98,11 @@ function valueValidatesAsType(value: any, type: string): boolean { if (type === 'boolean') { return valueType === 'boolean'; } else if (type === 'object') { - return value && !isArray(value) && valueType === 'object'; + return value && !Array.isArray(value) && valueType === 'object'; } else if (type === 'null') { return value === null; } else if (type === 'array') { - return isArray(value); + return Array.isArray(value); } else if (type === 'string') { return valueType === 'string'; } else if (type === 'number' || type === 'integer') { @@ -170,7 +170,7 @@ function getStringValidators(prop: IConfigurationPropertySchema) { } function getNumericValidators(prop: IConfigurationPropertySchema): Validator[] { - const type: (string | undefined)[] = isArray(prop.type) ? prop.type : [prop.type]; + const type: (string | undefined)[] = Array.isArray(prop.type) ? prop.type : [prop.type]; const isNullable = canBeType(type, 'null'); const isIntegral = (canBeType(type, 'integer')) && (type.length === 1 || type.length === 2 && isNullable); @@ -229,9 +229,9 @@ function getNumericValidators(prop: IConfigurationPropertySchema): Validator (string | null)) | null { - if (prop.type === 'array' && prop.items && !isArray(prop.items)) { + if (prop.type === 'array' && prop.items && !Array.isArray(prop.items)) { const propItems = prop.items; - if (propItems && !isArray(propItems.type)) { + if (propItems && !Array.isArray(propItems.type)) { const withQuotes = (s: string) => `'` + s + `'`; return value => { if (!value) { @@ -240,7 +240,7 @@ function getArrayValidator(prop: IConfigurationPropertySchema): ((value: any) => let message = ''; - if (!isArray(value)) { + if (!Array.isArray(value)) { message += nls.localize('validations.arrayIncorrectType', 'Incorrect type. Expected an array.'); message += '\n'; return message; diff --git a/src/vs/workbench/services/search/common/textSearchManager.ts b/src/vs/workbench/services/search/common/textSearchManager.ts index 2b6eb1befc7..68dcacea828 100644 --- a/src/vs/workbench/services/search/common/textSearchManager.ts +++ b/src/vs/workbench/services/search/common/textSearchManager.ts @@ -10,7 +10,6 @@ import { toErrorMessage } from 'vs/base/common/errorMessage'; import { Schemas } from 'vs/base/common/network'; import * as path from 'vs/base/common/path'; import * as resources from 'vs/base/common/resources'; -import { isArray } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { hasSiblingPromiseFn, IExtendedExtensionSearchOptions, IFileMatch, IFolderQuery, IPatternInfo, ISearchCompleteStats, ITextQuery, ITextSearchContext, ITextSearchMatch, ITextSearchResult, ITextSearchStats, QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/common/search'; import { Range, TextSearchComplete, TextSearchMatch, TextSearchOptions, TextSearchProvider, TextSearchQuery, TextSearchResult } from 'vs/workbench/services/search/common/searchExtTypes'; @@ -73,7 +72,7 @@ export class TextSearchManager { limitHit: this.isLimitHit || someFolderHitLImit, messages: flatten(results.map(result => { if (!result?.message) { return []; } - if (isArray(result.message)) { return result.message; } + if (Array.isArray(result.message)) { return result.message; } else { return [result.message]; } })), stats: { diff --git a/src/vs/workbench/services/themes/common/colorThemeData.ts b/src/vs/workbench/services/themes/common/colorThemeData.ts index 5013b0db476..5ccb9e5f93d 100644 --- a/src/vs/workbench/services/themes/common/colorThemeData.ts +++ b/src/vs/workbench/services/themes/common/colorThemeData.ts @@ -440,7 +440,7 @@ export class ColorThemeData implements IWorkbenchColorTheme { let themeSpecificColors; for (const key in colors) { const scopedColors = colors[key]; - if (this.isThemeScope(key) && scopedColors instanceof Object && !types.isArray(scopedColors)) { + if (this.isThemeScope(key) && scopedColors instanceof Object && !Array.isArray(scopedColors)) { const themeScopeList = key.match(themeScopeRegex) || []; for (const themeScope of themeScopeList) { const themeId = themeScope.substring(1, themeScope.length - 1); @@ -452,7 +452,7 @@ export class ColorThemeData implements IWorkbenchColorTheme { for (const subkey in scopedThemeSpecificColors) { const originalColors = themeSpecificColors[subkey]; const overrideColors = scopedThemeSpecificColors[subkey]; - if (types.isArray(originalColors) && types.isArray(overrideColors)) { + if (Array.isArray(originalColors) && Array.isArray(overrideColors)) { themeSpecificColors[subkey] = originalColors.concat(overrideColors); } else if (overrideColors) { themeSpecificColors[subkey] = overrideColors; diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index de310cbfb0d..34c472eca2b 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -124,7 +124,7 @@ import { IWorkspaceTrustManagementService, IWorkspaceTrustRequestService } from import { TestWorkspaceTrustManagementService, TestWorkspaceTrustRequestService } from 'vs/workbench/services/workspaces/test/common/testWorkspaceTrustService'; import { IExtensionTerminalProfile, IShellLaunchConfig, ITerminalProfile, TerminalIcon, TerminalLocation, TerminalShellType } from 'vs/platform/terminal/common/terminal'; import { ICreateTerminalOptions, IDeserializedTerminalEditorInput, ITerminalEditorService, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal'; -import { assertIsDefined, isArray } from 'vs/base/common/types'; +import { assertIsDefined } from 'vs/base/common/types'; import { IRegisterContributedProfileArgs, IShellLaunchConfigResolveOptions, ITerminalBackend, ITerminalProfileProvider, ITerminalProfileResolverService, ITerminalProfileService } from 'vs/workbench/contrib/terminal/common/terminal'; import { EditorResolverService } from 'vs/workbench/services/editor/browser/editorResolverService'; import { FILE_EDITOR_INPUT_ID } from 'vs/workbench/contrib/files/common/files'; @@ -1888,7 +1888,7 @@ export class TestQuickInputService implements IQuickInputService { pick(picks: Promise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: true }, token?: CancellationToken): Promise; pick(picks: Promise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: false }, token?: CancellationToken): Promise; async pick(picks: Promise[]> | QuickPickInput[], options?: Omit, 'canPickMany'>, token?: CancellationToken): Promise { - if (isArray(picks)) { + if (Array.isArray(picks)) { return { label: 'selectedPick', description: 'pick description', value: 'selectedPick' }; } else { return undefined; From 342394d1e7d43d3324dc2ede1d634cffd52ba159 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 2 Aug 2022 16:56:56 -0700 Subject: [PATCH 168/303] Use optional chaining for more method calls (#156938) This rewrites code such as: ```ts if (thing) { thing.method(); } ``` To the more concise: ```ts thing?.method(); ``` This was done using a simple find replace. I tried to keep the change pretty conservative so it only touches simple cases like above --- src/vs/base/browser/dom.ts | 4 +- src/vs/base/browser/indexedDB.ts | 4 +- src/vs/base/browser/mouseEvent.ts | 8 +--- .../browser/ui/actionbar/actionViewItems.ts | 8 +--- .../browser/ui/centered/centeredViewLayout.ts | 4 +- src/vs/base/browser/ui/dropdown/dropdown.ts | 4 +- .../ui/dropdown/dropdownActionViewItem.ts | 4 +- .../base/browser/ui/findinput/replaceInput.ts | 12 ++--- src/vs/base/browser/ui/inputbox/inputBox.ts | 4 +- src/vs/base/browser/ui/list/listPaging.ts | 4 +- src/vs/base/browser/ui/list/listWidget.ts | 4 +- src/vs/base/browser/ui/menu/menu.ts | 4 +- src/vs/base/browser/ui/menu/menubar.ts | 4 +- src/vs/base/common/cancellation.ts | 4 +- src/vs/base/node/zip.ts | 4 +- .../parts/ipc/electron-main/ipc.electron.ts | 4 +- src/vs/base/parts/ipc/node/ipc.cp.ts | 4 +- .../parts/quickinput/browser/quickInput.ts | 4 +- src/vs/base/test/browser/indexedDB.test.ts | 4 +- .../issue/issueReporterMain.ts | 8 +--- .../editor/browser/widget/diffEditorWidget.ts | 4 +- src/vs/editor/browser/widget/diffReview.ts | 8 +--- .../editor/common/viewModel/viewModelImpl.ts | 8 +--- .../editor/contrib/folding/browser/folding.ts | 12 ++--- .../browser/peek/referencesController.ts | 4 +- .../contrib/hover/browser/contentHover.ts | 4 +- .../inPlaceReplace/browser/inPlaceReplace.ts | 8 +--- .../browser/ghostTextController.ts | 4 +- .../suggestWidgetInlineCompletionProvider.ts | 8 +--- .../snippet/browser/snippetController2.ts | 8 +--- .../browser/wordHighlighter.ts | 8 +--- .../contrib/zoneWidget/browser/zoneWidget.ts | 8 +--- .../accessibilityHelp/accessibilityHelp.ts | 4 +- .../browser/inspectTokens/inspectTokens.ts | 4 +- .../contextview/browser/contextMenuHandler.ts | 8 +--- .../browser/contextScopedHistoryWidget.ts | 8 +--- .../issue/electron-main/issueMainService.ts | 8 +--- src/vs/platform/log/common/bufferLog.ts | 8 +--- .../electron-main/nativeHostMainService.ts | 12 ++--- .../remote/common/remoteAgentConnection.ts | 4 +- .../sharedProcessWorkerMain.ts | 4 +- .../terminal/common/terminalDataBuffering.ts | 4 +- src/vs/platform/tunnel/node/tunnelService.ts | 4 +- .../common/userDataAutoSyncService.ts | 4 +- .../common/userDataSyncService.ts | 4 +- .../platform/windows/electron-main/window.ts | 4 +- .../mainThreadDocumentContentProviders.ts | 4 +- .../api/browser/mainThreadOutputService.ts | 4 +- .../workbench/api/common/extHostComments.ts | 4 +- .../api/common/extHostLanguageFeatures.ts | 8 +--- .../workbench/api/common/extHostNotebook.ts | 4 +- .../workbench/api/common/extHostProgress.ts | 4 +- .../workbench/api/common/extHostQuickOpen.ts | 8 +--- src/vs/workbench/browser/layout.ts | 12 ++--- .../parts/activitybar/activitybarPart.ts | 12 ++--- .../parts/auxiliarybar/auxiliaryBarActions.ts | 4 +- .../workbench/browser/parts/compositeBar.ts | 8 +--- .../parts/editor/breadcrumbsControl.ts | 4 +- .../browser/parts/editor/editorActions.ts | 4 +- .../browser/parts/editor/editorCommands.ts | 4 +- .../notifications/notificationsCommands.ts | 12 ++--- .../notifications/notificationsStatus.ts | 4 +- .../browser/parts/panel/panelActions.ts | 4 +- .../browser/parts/panel/panelPart.ts | 4 +- .../browser/parts/sidebar/sidebarActions.ts | 4 +- .../browser/parts/titlebar/menubarControl.ts | 12 ++--- .../common/editor/diffEditorInput.ts | 4 +- src/vs/workbench/common/notifications.ts | 4 +- .../browser/preview/bulkEdit.contribution.ts | 24 +++------- .../browser/accessibility/accessibility.ts | 4 +- .../inspectEditorTokens.ts | 4 +- .../contrib/comments/browser/commentNode.ts | 16 ++----- .../contrib/comments/browser/commentReply.ts | 4 +- .../browser/commentsEditorContribution.ts | 12 ++--- .../browser/breakpointEditorContribution.ts | 12 ++--- .../contrib/debug/browser/breakpointsView.ts | 4 +- .../contrib/debug/browser/debugService.ts | 4 +- .../contrib/debug/browser/debugStatus.ts | 4 +- .../contrib/debug/browser/debugToolBar.ts | 4 +- .../contrib/debug/browser/rawDebugSession.ts | 4 +- .../workbench/contrib/debug/browser/repl.ts | 12 ++--- .../contrib/debug/browser/replFilter.ts | 8 +--- .../debug/common/debugContentProvider.ts | 4 +- .../experimentService.test.ts | 4 +- .../extensions/browser/extensionEditor.ts | 4 +- .../extensions/browser/extensionsViewlet.ts | 4 +- .../extensions/browser/extensionsWidgets.ts | 4 +- .../extensionRecommendationsService.test.ts | 4 +- .../editors/textFileSaveErrorHandler.ts | 4 +- .../contrib/files/browser/explorerService.ts | 4 +- .../files/browser/views/explorerView.ts | 4 +- .../browser/inlayHintsAccessibilty.ts | 8 +--- .../interactive/browser/interactiveEditor.ts | 12 ++--- .../contrib/markers/browser/markersView.ts | 4 +- .../markers/browser/markersViewActions.ts | 8 +--- .../browser/diff/notebookTextDiffEditor.ts | 8 +--- .../notebook/browser/notebookEditor.ts | 4 +- .../notebook/browser/notebookEditorWidget.ts | 4 +- .../browser/viewModel/baseCellViewModel.ts | 4 +- .../contrib/output/browser/outputView.ts | 4 +- .../output/common/outputChannelModel.ts | 4 +- .../browser/preferences.contribution.ts | 8 +--- .../preferences/browser/settingsEditor2.ts | 4 +- .../preferences/browser/settingsTree.ts | 4 +- .../preferences/browser/settingsWidgets.ts | 4 +- .../browser/relauncher.contribution.ts | 4 +- .../contrib/remote/browser/remote.ts | 8 +--- .../contrib/remote/browser/remoteExplorer.ts | 20 +++------ .../search/browser/patternInputWidget.ts | 4 +- .../contrib/search/browser/replaceService.ts | 4 +- .../search/browser/search.contribution.ts | 8 +--- .../contrib/search/browser/searchActions.ts | 44 +++++-------------- .../tasks/browser/abstractTaskService.ts | 8 +--- .../terminal/browser/terminalEditor.ts | 4 +- .../terminal/browser/terminalFindWidget.ts | 4 +- .../contrib/terminal/browser/terminalView.ts | 4 +- .../welcomeOverlay/browser/welcomeOverlay.ts | 4 +- .../common/viewsWelcomeContribution.ts | 4 +- .../test/browser/decorationsService.test.ts | 4 +- .../common/abstractExtensionService.ts | 4 +- .../electronExtensionService.ts | 4 +- .../progress/browser/progressService.ts | 4 +- .../search/common/fileSearchManager.ts | 4 +- .../services/search/node/fileSearch.ts | 4 +- .../search/node/ripgrepTextSearchEngine.ts | 8 +--- .../common/textFileEditorModelManager.ts | 4 +- .../workspaces/common/workspaceTrust.ts | 8 +--- 127 files changed, 198 insertions(+), 594 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 06d13c90d93..d378b5f6542 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -1149,9 +1149,7 @@ export function removeTabIndexAndUpdateFocus(node: HTMLElement): void { // in the hierarchy of the parent DOM nodes. if (document.activeElement === node) { const parentFocusable = findParentWithAttribute(node.parentElement, 'tabIndex'); - if (parentFocusable) { - parentFocusable.focus(); - } + parentFocusable?.focus(); } node.removeAttribute('tabindex'); diff --git a/src/vs/base/browser/indexedDB.ts b/src/vs/base/browser/indexedDB.ts index a4319aaf5d4..5d985a1e571 100644 --- a/src/vs/base/browser/indexedDB.ts +++ b/src/vs/base/browser/indexedDB.ts @@ -105,9 +105,7 @@ export class IndexedDB { if (this.pendingTransactions.length) { this.pendingTransactions.splice(0, this.pendingTransactions.length).forEach(transaction => transaction.abort()); } - if (this.database) { - this.database.close(); - } + this.database?.close(); this.database = null; } diff --git a/src/vs/base/browser/mouseEvent.ts b/src/vs/base/browser/mouseEvent.ts index a4f106a6c19..7a0ebca76cf 100644 --- a/src/vs/base/browser/mouseEvent.ts +++ b/src/vs/base/browser/mouseEvent.ts @@ -211,14 +211,10 @@ export class StandardWheelEvent { } public preventDefault(): void { - if (this.browserEvent) { - this.browserEvent.preventDefault(); - } + this.browserEvent?.preventDefault(); } public stopPropagation(): void { - if (this.browserEvent) { - this.browserEvent.stopPropagation(); - } + this.browserEvent?.stopPropagation(); } } diff --git a/src/vs/base/browser/ui/actionbar/actionViewItems.ts b/src/vs/base/browser/ui/actionbar/actionViewItems.ts index 7d0833e27be..6883fb11764 100644 --- a/src/vs/base/browser/ui/actionbar/actionViewItems.ts +++ b/src/vs/base/browser/ui/actionbar/actionViewItems.ts @@ -439,15 +439,11 @@ export class SelectActionViewItem extends BaseActionViewItem { } override focus(): void { - if (this.selectBox) { - this.selectBox.focus(); - } + this.selectBox?.focus(); } override blur(): void { - if (this.selectBox) { - this.selectBox.blur(); - } + this.selectBox?.blur(); } override render(container: HTMLElement): void { diff --git a/src/vs/base/browser/ui/centered/centeredViewLayout.ts b/src/vs/base/browser/ui/centered/centeredViewLayout.ts index b16ac4334ca..b746382e57a 100644 --- a/src/vs/base/browser/ui/centered/centeredViewLayout.ts +++ b/src/vs/base/browser/ui/centered/centeredViewLayout.ts @@ -159,9 +159,7 @@ export class CenteredViewLayout implements IDisposable { this.container.removeChild(this.splitView.el); } this.splitViewDisposables.clear(); - if (this.splitView) { - this.splitView.dispose(); - } + this.splitView?.dispose(); this.splitView = undefined; this.emptyViews = undefined; this.container.appendChild(this.view.element); diff --git a/src/vs/base/browser/ui/dropdown/dropdown.ts b/src/vs/base/browser/ui/dropdown/dropdown.ts index d389e0f0e78..b0f07682dd6 100644 --- a/src/vs/base/browser/ui/dropdown/dropdown.ts +++ b/src/vs/base/browser/ui/dropdown/dropdown.ts @@ -192,9 +192,7 @@ export class Dropdown extends BaseDropdown { override hide(): void { super.hide(); - if (this.contextViewProvider) { - this.contextViewProvider.hideContextView(); - } + this.contextViewProvider?.hideContextView(); } protected renderContents(container: HTMLElement): IDisposable | null { diff --git a/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts b/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts index 00b21774ea0..00da36a947b 100644 --- a/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts +++ b/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts @@ -155,9 +155,7 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem { } show(): void { - if (this.dropdownMenu) { - this.dropdownMenu.show(); - } + this.dropdownMenu?.show(); } protected override updateEnabled(): void { diff --git a/src/vs/base/browser/ui/findinput/replaceInput.ts b/src/vs/base/browser/ui/findinput/replaceInput.ts index a80c5a1faaf..2861edde0b8 100644 --- a/src/vs/base/browser/ui/findinput/replaceInput.ts +++ b/src/vs/base/browser/ui/findinput/replaceInput.ts @@ -353,9 +353,7 @@ export class ReplaceInput extends Widget { } public validate(): void { - if (this.inputBox) { - this.inputBox.validate(); - } + this.inputBox?.validate(); } public showMessage(message: InputBoxMessage): void { @@ -363,15 +361,11 @@ export class ReplaceInput extends Widget { } public clearMessage(): void { - if (this.inputBox) { - this.inputBox.hideMessage(); - } + this.inputBox?.hideMessage(); } private clearValidation(): void { - if (this.inputBox) { - this.inputBox.hideMessage(); - } + this.inputBox?.hideMessage(); } public set width(newWidth: number) { diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index a3087e1c9c1..ae89cb33f38 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -621,9 +621,7 @@ export class InputBox extends Widget { this.message = null; - if (this.actionbar) { - this.actionbar.dispose(); - } + this.actionbar?.dispose(); super.dispose(); } diff --git a/src/vs/base/browser/ui/list/listPaging.ts b/src/vs/base/browser/ui/list/listPaging.ts index ba2b55040f5..a5f3a920e38 100644 --- a/src/vs/base/browser/ui/list/listPaging.ts +++ b/src/vs/base/browser/ui/list/listPaging.ts @@ -38,9 +38,7 @@ class PagedRenderer implements IListRenderer, height: number | undefined): void { - if (data.disposable) { - data.disposable.dispose(); - } + data.disposable?.dispose(); if (!data.data) { return; diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index f89a2f5d237..0cea984085d 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -1528,9 +1528,7 @@ export class List implements ISpliceable, IThemable, IDisposable { } triggerTypeNavigation(): void { - if (this.typeNavigationController) { - this.typeNavigationController.trigger(); - } + this.typeNavigationController?.trigger(); } setSelection(indexes: number[], browserEvent?: UIEvent): void { diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 7a22cb35038..5e4410b5005 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -552,9 +552,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem { override focus(): void { super.focus(); - if (this.item) { - this.item.focus(); - } + this.item?.focus(); this.applyStyle(); } diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index 572b33983cc..fa843ff260a 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -985,9 +985,7 @@ export class MenuBar extends Disposable { this.focusedMenu.holder.remove(); } - if (this.focusedMenu.widget) { - this.focusedMenu.widget.dispose(); - } + this.focusedMenu.widget?.dispose(); this.focusedMenu = { index: this.focusedMenu.index }; } diff --git a/src/vs/base/common/cancellation.ts b/src/vs/base/common/cancellation.ts index 9cc02257cab..78e01b75ec1 100644 --- a/src/vs/base/common/cancellation.ts +++ b/src/vs/base/common/cancellation.ts @@ -129,9 +129,7 @@ export class CancellationTokenSource { if (cancel) { this.cancel(); } - if (this._parentListener) { - this._parentListener.dispose(); - } + this._parentListener?.dispose(); if (!this._token) { // ensure to initialize with an empty token if we had none this._token = CancellationToken.None; diff --git a/src/vs/base/node/zip.ts b/src/vs/base/node/zip.ts index c815e61861a..2033f7cd98e 100644 --- a/src/vs/base/node/zip.ts +++ b/src/vs/base/node/zip.ts @@ -81,9 +81,7 @@ function extractEntry(stream: Readable, fileName: string, mode: number, targetPa let istream: WriteStream; token.onCancellationRequested(() => { - if (istream) { - istream.destroy(); - } + istream?.destroy(); }); return Promise.resolve(Promises.mkdir(targetDirName, { recursive: true })).then(() => new Promise((c, e) => { diff --git a/src/vs/base/parts/ipc/electron-main/ipc.electron.ts b/src/vs/base/parts/ipc/electron-main/ipc.electron.ts index f0d395c4bfa..b40d381cffb 100644 --- a/src/vs/base/parts/ipc/electron-main/ipc.electron.ts +++ b/src/vs/base/parts/ipc/electron-main/ipc.electron.ts @@ -37,9 +37,7 @@ export class Server extends IPCServer { const id = webContents.id; const client = Server.Clients.get(id); - if (client) { - client.dispose(); - } + client?.dispose(); const onDidClientReconnect = new Emitter(); Server.Clients.set(id, toDisposable(() => onDidClientReconnect.fire())); diff --git a/src/vs/base/parts/ipc/node/ipc.cp.ts b/src/vs/base/parts/ipc/node/ipc.cp.ts index fa6d8073ab7..90595976349 100644 --- a/src/vs/base/parts/ipc/node/ipc.cp.ts +++ b/src/vs/base/parts/ipc/node/ipc.cp.ts @@ -241,9 +241,7 @@ export class Client implements IChannelClient, IDisposable { console.warn('IPC "' + this.options.serverName + '" crashed with exit code ' + code + ' and signal ' + signal); } - if (this.disposeDelayer) { - this.disposeDelayer.cancel(); - } + this.disposeDelayer?.cancel(); this.disposeClient(); this._onDidProcessExit.fire({ code, signal }); }); diff --git a/src/vs/base/parts/quickinput/browser/quickInput.ts b/src/vs/base/parts/quickinput/browser/quickInput.ts index 58a09cc29e5..2b906e565f4 100644 --- a/src/vs/base/parts/quickinput/browser/quickInput.ts +++ b/src/vs/base/parts/quickinput/browser/quickInput.ts @@ -1610,9 +1610,7 @@ export class QuickInputController extends Disposable { this.onShowEmitter.fire(); const oldController = this.controller; this.controller = controller; - if (oldController) { - oldController.didHide(); - } + oldController?.didHide(); this.setEnabled(true); ui.leftActionBar.clear(); diff --git a/src/vs/base/test/browser/indexedDB.test.ts b/src/vs/base/test/browser/indexedDB.test.ts index 581b6719148..ba9dcd0f51c 100644 --- a/src/vs/base/test/browser/indexedDB.test.ts +++ b/src/vs/base/test/browser/indexedDB.test.ts @@ -16,9 +16,7 @@ flakySuite('IndexedDB', () => { }); teardown(() => { - if (indexedDB) { - indexedDB.close(); - } + indexedDB?.close(); }); test('runInTransaction', async () => { diff --git a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts index 6a0e7994b04..dc4a1692710 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts @@ -151,14 +151,10 @@ export class IssueReporter extends Disposable { const { fileOnExtension } = this.issueReporterModel.getData(); if (fileOnExtension) { const issueTitle = document.getElementById('issue-title'); - if (issueTitle) { - issueTitle.focus(); - } + issueTitle?.focus(); } else { const issueType = document.getElementById('issue-type'); - if (issueType) { - issueType.focus(); - } + issueType?.focus(); } } diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index ef1aa278e53..6dc7769a008 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -1324,9 +1324,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE } private _setStrategy(newStrategy: DiffEditorWidgetStyle): void { - if (this._strategy) { - this._strategy.dispose(); - } + this._strategy?.dispose(); this._strategy = newStrategy; newStrategy.applyColors(this._themeService.getColorTheme()); diff --git a/src/vs/editor/browser/widget/diffReview.ts b/src/vs/editor/browser/widget/diffReview.ts index 38ae5e81a32..449e9c46436 100644 --- a/src/vs/editor/browser/widget/diffReview.ts +++ b/src/vs/editor/browser/widget/diffReview.ts @@ -846,9 +846,7 @@ class DiffReviewNext extends EditorAction { public run(accessor: ServicesAccessor, editor: ICodeEditor): void { const diffEditor = findFocusedDiffEditor(accessor); - if (diffEditor) { - diffEditor.diffReviewNext(); - } + diffEditor?.diffReviewNext(); } } @@ -869,9 +867,7 @@ class DiffReviewPrev extends EditorAction { public run(accessor: ServicesAccessor, editor: ICodeEditor): void { const diffEditor = findFocusedDiffEditor(accessor); - if (diffEditor) { - diffEditor.diffReviewPrev(); - } + diffEditor?.diffReviewPrev(); } } diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index a241643468e..819e9d02e0c 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -761,13 +761,9 @@ export class ViewModel extends Disposable implements IViewModel { const decorations = this.model.getOverviewRulerDecorations(); for (const decoration of decorations) { const opts1 = decoration.options.overviewRuler; - if (opts1) { - opts1.invalidateCachedColor(); - } + opts1?.invalidateCachedColor(); const opts2 = decoration.options.minimap; - if (opts2) { - opts2.invalidateCachedColor(); - } + opts2?.invalidateCachedColor(); } } diff --git a/src/vs/editor/contrib/folding/browser/folding.ts b/src/vs/editor/contrib/folding/browser/folding.ts index 2ec75651190..e375b721408 100644 --- a/src/vs/editor/contrib/folding/browser/folding.ts +++ b/src/vs/editor/contrib/folding/browser/folding.ts @@ -245,17 +245,13 @@ export class FoldingController extends Disposable implements IEditorContribution this.foldingRegionPromise.cancel(); this.foldingRegionPromise = null; } - if (this.updateScheduler) { - this.updateScheduler.cancel(); - } + this.updateScheduler?.cancel(); this.updateScheduler = null; this.foldingModel = null; this.foldingModelPromise = null; this.hiddenRangeModel = null; this.cursorChangedScheduler = null; - if (this.rangeProvider) { - this.rangeProvider.dispose(); - } + this.rangeProvider?.dispose(); this.rangeProvider = null; } }); @@ -263,9 +259,7 @@ export class FoldingController extends Disposable implements IEditorContribution } private onFoldingStrategyChanged() { - if (this.rangeProvider) { - this.rangeProvider.dispose(); - } + this.rangeProvider?.dispose(); this.rangeProvider = null; this.triggerFoldingModelChanged(); } diff --git a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesController.ts b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesController.ts index d675e5b8852..b35ba50247d 100644 --- a/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesController.ts +++ b/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesController.ts @@ -238,9 +238,7 @@ export abstract class ReferencesController implements IEditorContribution { } private _gotoReference(ref: Location): Promise { - if (this._widget) { - this._widget.hide(); - } + this._widget?.hide(); this._ignoreModelChangeEvent = true; const range = Range.lift(ref.range).collapseToStart(); diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 93941e6172c..666337b5614 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -428,9 +428,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (visibleData.stoleFocus) { this._hover.containerDomNode.focus(); } - if (visibleData.colorPicker) { - visibleData.colorPicker.layout(); - } + visibleData.colorPicker?.layout(); } public hide(): void { diff --git a/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.ts b/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.ts index a2c7a5acbe7..19e0e394120 100644 --- a/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.ts +++ b/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.ts @@ -56,9 +56,7 @@ class InPlaceReplaceController implements IEditorContribution { public run(source: string, up: boolean): Promise | undefined { // cancel any pending request - if (this.currentRequest) { - this.currentRequest.cancel(); - } + this.currentRequest?.cancel(); const editorSelection = this.editor.getSelection(); const model = this.editor.getModel(); @@ -121,9 +119,7 @@ class InPlaceReplaceController implements IEditorContribution { }]); // remove decoration after delay - if (this.decorationRemover) { - this.decorationRemover.cancel(); - } + this.decorationRemover?.cancel(); this.decorationRemover = timeout(350); this.decorationRemover.then(() => this.decorations.clear()).catch(onUnexpectedError); diff --git a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextController.ts b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextController.ts index b9896b5a061..92dd4007425 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/ghostTextController.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/ghostTextController.ts @@ -247,8 +247,6 @@ export class TriggerInlineSuggestionAction extends EditorAction { public async run(accessor: ServicesAccessor | undefined, editor: ICodeEditor): Promise { const controller = GhostTextController.get(editor); - if (controller) { - controller.trigger(); - } + controller?.trigger(); } } diff --git a/src/vs/editor/contrib/inlineCompletions/browser/suggestWidgetInlineCompletionProvider.ts b/src/vs/editor/contrib/inlineCompletions/browser/suggestWidgetInlineCompletionProvider.ts index 2871642c472..b2d9acaf0ba 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/suggestWidgetInlineCompletionProvider.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/suggestWidgetInlineCompletionProvider.ts @@ -182,16 +182,12 @@ export class SuggestWidgetInlineCompletionProvider extends Disposable { public stopForceRenderingAbove(): void { const suggestController = SuggestController.get(this.editor); - if (suggestController) { - suggestController.stopForceRenderingAbove(); - } + suggestController?.stopForceRenderingAbove(); } public forceRenderingAbove(): void { const suggestController = SuggestController.get(this.editor); - if (suggestController) { - suggestController.forceRenderingAbove(); - } + suggestController?.forceRenderingAbove(); } } diff --git a/src/vs/editor/contrib/snippet/browser/snippetController2.ts b/src/vs/editor/contrib/snippet/browser/snippetController2.ts index 862f3a20493..c3f773e8e9f 100644 --- a/src/vs/editor/contrib/snippet/browser/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/browser/snippetController2.ts @@ -280,16 +280,12 @@ export class SnippetController2 implements IEditorContribution { } prev(): void { - if (this._session) { - this._session.prev(); - } + this._session?.prev(); this._updateState(); } next(): void { - if (this._session) { - this._session.next(); - } + this._session?.next(); this._updateState(); } diff --git a/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts b/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts index bf7d87de82b..1b8a60d8093 100644 --- a/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts +++ b/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts @@ -550,15 +550,11 @@ class WordHighlighterContribution extends Disposable implements IEditorContribut } public moveNext() { - if (this.wordHighlighter) { - this.wordHighlighter.moveNext(); - } + this.wordHighlighter?.moveNext(); } public moveBack() { - if (this.wordHighlighter) { - this.wordHighlighter.moveBack(); - } + this.wordHighlighter?.moveBack(); } public restoreViewState(state: boolean | undefined): void { diff --git a/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts b/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts index 8850f9d9507..6f863ad803d 100644 --- a/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts +++ b/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts @@ -287,9 +287,7 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider { this._doLayout(containerHeight, this._getWidth(layoutInfo)); } - if (this._resizeSash) { - this._resizeSash.layout(); - } + this._resizeSash?.layout(); } get position(): Position | undefined { @@ -323,9 +321,7 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider { this.editor.removeOverlayWidget(this._overlayWidget); this._overlayWidget = null; } - if (this._arrow) { - this._arrow.hide(); - } + this._arrow?.hide(); } private _decoratingElementsHeight(): number { diff --git a/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts b/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts index 4e3eb751577..8601905af40 100644 --- a/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts +++ b/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts @@ -340,9 +340,7 @@ class ShowAccessibilityHelpAction extends EditorAction { public run(accessor: ServicesAccessor, editor: ICodeEditor): void { const controller = AccessibilityHelpController.get(editor); - if (controller) { - controller.show(); - } + controller?.show(); } } diff --git a/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts b/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts index 6ac269a0f8c..cc3d4cef52e 100644 --- a/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts +++ b/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts @@ -89,9 +89,7 @@ class InspectTokens extends EditorAction { public run(accessor: ServicesAccessor, editor: ICodeEditor): void { const controller = InspectTokensController.get(editor); - if (controller) { - controller.launch(); - } + controller?.launch(); } } diff --git a/src/vs/platform/contextview/browser/contextMenuHandler.ts b/src/vs/platform/contextview/browser/contextMenuHandler.ts index aa6612d89ff..e71f33b5891 100644 --- a/src/vs/platform/contextview/browser/contextMenuHandler.ts +++ b/src/vs/platform/contextview/browser/contextMenuHandler.ts @@ -134,9 +134,7 @@ export class ContextMenuHandler { this.block = null; } - if (this.focusToReturn) { - this.focusToReturn.focus(); - } + this.focusToReturn?.focus(); } }, shadowRootElement, !!shadowRootElement); } @@ -147,9 +145,7 @@ export class ContextMenuHandler { this.contextViewService.hideContextView(false); // Restore focus here - if (this.focusToReturn) { - this.focusToReturn.focus(); - } + this.focusToReturn?.focus(); } private onDidActionRun(e: IRunEvent): void { diff --git a/src/vs/platform/history/browser/contextScopedHistoryWidget.ts b/src/vs/platform/history/browser/contextScopedHistoryWidget.ts index 7791293a449..af357a69ffa 100644 --- a/src/vs/platform/history/browser/contextScopedHistoryWidget.ts +++ b/src/vs/platform/history/browser/contextScopedHistoryWidget.ts @@ -118,9 +118,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ primary: KeyCode.UpArrow, secondary: [KeyMod.Alt | KeyCode.UpArrow], handler: (accessor) => { - if (lastFocusedWidget) { - lastFocusedWidget.showPreviousValue(); - } + lastFocusedWidget?.showPreviousValue(); } }); @@ -135,8 +133,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ primary: KeyCode.DownArrow, secondary: [KeyMod.Alt | KeyCode.DownArrow], handler: (accessor) => { - if (lastFocusedWidget) { - lastFocusedWidget.showNextValue(); - } + lastFocusedWidget?.showNextValue(); } }); diff --git a/src/vs/platform/issue/electron-main/issueMainService.ts b/src/vs/platform/issue/electron-main/issueMainService.ts index e283eb85e95..a3edd3cc7dd 100644 --- a/src/vs/platform/issue/electron-main/issueMainService.ts +++ b/src/vs/platform/issue/electron-main/issueMainService.ts @@ -176,15 +176,11 @@ export class IssueMainService implements ICommonIssueService { }); validatedIpcMain.on('vscode:closeIssueReporter', event => { - if (this.issueReporterWindow) { - this.issueReporterWindow.close(); - } + this.issueReporterWindow?.close(); }); validatedIpcMain.on('vscode:closeProcessExplorer', event => { - if (this.processExplorerWindow) { - this.processExplorerWindow.close(); - } + this.processExplorerWindow?.close(); }); validatedIpcMain.on('vscode:windowsInfoRequest', async event => { diff --git a/src/vs/platform/log/common/bufferLog.ts b/src/vs/platform/log/common/bufferLog.ts index 58b9e41e60c..76b3bfdc6c1 100644 --- a/src/vs/platform/log/common/bufferLog.ts +++ b/src/vs/platform/log/common/bufferLog.ts @@ -81,14 +81,10 @@ export class BufferLogService extends AbstractLogger implements ILogService { } override dispose(): void { - if (this._logger) { - this._logger.dispose(); - } + this._logger?.dispose(); } flush(): void { - if (this._logger) { - this._logger.flush(); - } + this._logger?.flush(); } } diff --git a/src/vs/platform/native/electron-main/nativeHostMainService.ts b/src/vs/platform/native/electron-main/nativeHostMainService.ts index a4b9b303b87..a8fa55f59bf 100644 --- a/src/vs/platform/native/electron-main/nativeHostMainService.ts +++ b/src/vs/platform/native/electron-main/nativeHostMainService.ts @@ -173,16 +173,12 @@ export class NativeHostMainService extends Disposable implements INativeHostMain async toggleFullScreen(windowId: number | undefined): Promise { const window = this.windowById(windowId); - if (window) { - window.toggleFullScreen(); - } + window?.toggleFullScreen(); } async handleTitleDoubleClick(windowId: number | undefined): Promise { const window = this.windowById(windowId); - if (window) { - window.handleTitleDoubleClick(); - } + window?.handleTitleDoubleClick(); } async isMaximized(windowId: number | undefined): Promise { @@ -665,9 +661,7 @@ export class NativeHostMainService extends Disposable implements INativeHostMain async notifyReady(windowId: number | undefined): Promise { const window = this.windowById(windowId); - if (window) { - window.setReady(); - } + window?.setReady(); } async relaunch(windowId: number | undefined, options?: { addArgs?: string[]; removeArgs?: string[] }): Promise { diff --git a/src/vs/platform/remote/common/remoteAgentConnection.ts b/src/vs/platform/remote/common/remoteAgentConnection.ts index fde30c2d8a6..d6883c9f3d9 100644 --- a/src/vs/platform/remote/common/remoteAgentConnection.ts +++ b/src/vs/platform/remote/common/remoteAgentConnection.ts @@ -333,9 +333,7 @@ async function connectToRemoteExtensionHostAgentAndReadOneMessage(options: IS } result.reject(error); } else { - if (options.reconnectionProtocol) { - options.reconnectionProtocol.endAcceptReconnection(); - } + options.reconnectionProtocol?.endAcceptReconnection(); options.logService.trace(`${logPrefix} 6/6. handshake finished, connection is up and running after ${logElapsed(startTime)}!`); result.resolve({ protocol, firstMessage: msg }); } diff --git a/src/vs/platform/sharedProcess/electron-browser/sharedProcessWorkerMain.ts b/src/vs/platform/sharedProcess/electron-browser/sharedProcessWorkerMain.ts index 165268c5e12..f05f360ce5e 100644 --- a/src/vs/platform/sharedProcess/electron-browser/sharedProcessWorkerMain.ts +++ b/src/vs/platform/sharedProcess/electron-browser/sharedProcessWorkerMain.ts @@ -102,9 +102,7 @@ class SharedProcessWorkerMain { private terminate(configuration: ISharedProcessWorkerConfiguration): void { const processDisposable = this.processes.get(hash(configuration)); - if (processDisposable) { - processDisposable.dispose(); - } + processDisposable?.dispose(); } } diff --git a/src/vs/platform/terminal/common/terminalDataBuffering.ts b/src/vs/platform/terminal/common/terminalDataBuffering.ts index 21432ca631e..276b01c5467 100644 --- a/src/vs/platform/terminal/common/terminalDataBuffering.ts +++ b/src/vs/platform/terminal/common/terminalDataBuffering.ts @@ -51,9 +51,7 @@ export class TerminalDataBufferer implements IDisposable { stopBuffering(id: number) { const buffer = this._terminalBufferMap.get(id); - if (buffer) { - buffer.dispose(); - } + buffer?.dispose(); } flushBuffer(id: number): void { diff --git a/src/vs/platform/tunnel/node/tunnelService.ts b/src/vs/platform/tunnel/node/tunnelService.ts index 178247f60c5..7cdd91afd53 100644 --- a/src/vs/platform/tunnel/node/tunnelService.ts +++ b/src/vs/platform/tunnel/node/tunnelService.ts @@ -20,9 +20,7 @@ import { ISignService } from 'vs/platform/sign/common/sign'; async function createRemoteTunnel(options: IConnectionOptions, defaultTunnelHost: string, tunnelRemoteHost: string, tunnelRemotePort: number, tunnelLocalPort?: number): Promise { let readyTunnel: NodeRemoteTunnel | undefined; for (let attempts = 3; attempts; attempts--) { - if (readyTunnel) { - readyTunnel.dispose(); - } + readyTunnel?.dispose(); const tunnel = new NodeRemoteTunnel(options, defaultTunnelHost, tunnelRemoteHost, tunnelRemotePort, tunnelLocalPort); readyTunnel = await tunnel.waitForReady(); if ((tunnelLocalPort && BROWSER_RESTRICTED_PORTS[tunnelLocalPort]) || !BROWSER_RESTRICTED_PORTS[readyTunnel.tunnelLocalPort]) { diff --git a/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts b/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts index bf59598603b..e77ce86c963 100644 --- a/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts +++ b/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts @@ -408,9 +408,7 @@ class AutoSync extends Disposable { this.logService.info('Auto sync: Cancelled sync that is in progress'); this.syncPromise = undefined; } - if (this.syncTask) { - this.syncTask.stop(); - } + this.syncTask?.stop(); this.logService.info('Auto Sync: Stopped'); })); this.logService.info('Auto Sync: Started'); diff --git a/src/vs/platform/userDataSync/common/userDataSyncService.ts b/src/vs/platform/userDataSync/common/userDataSyncService.ts index d5e5b74cb7f..cb02de94e91 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncService.ts @@ -118,9 +118,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ return cancellablePromise.finally(() => cancellablePromise = undefined); }, async stop(): Promise { - if (cancellablePromise) { - cancellablePromise.cancel(); - } + cancellablePromise?.cancel(); if (that.status !== SyncStatus.Idle) { return that.stop(synchronizers); } diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts index c1e6bb0b70b..e11613b3ca9 100644 --- a/src/vs/platform/windows/electron-main/window.ts +++ b/src/vs/platform/windows/electron-main/window.ts @@ -1408,9 +1408,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { } close(): void { - if (this._win) { - this._win.close(); - } + this._win?.close(); } sendWhenReady(channel: string, token: CancellationToken, ...args: any[]): void { diff --git a/src/vs/workbench/api/browser/mainThreadDocumentContentProviders.ts b/src/vs/workbench/api/browser/mainThreadDocumentContentProviders.ts index 4ecd40a83e9..47e1f32ed47 100644 --- a/src/vs/workbench/api/browser/mainThreadDocumentContentProviders.ts +++ b/src/vs/workbench/api/browser/mainThreadDocumentContentProviders.ts @@ -71,9 +71,7 @@ export class MainThreadDocumentContentProviders implements MainThreadDocumentCon // cancel and dispose an existing update const pending = this._pendingUpdate.get(model.id); - if (pending) { - pending.cancel(); - } + pending?.cancel(); // create and keep update token const myToken = new CancellationTokenSource(); diff --git a/src/vs/workbench/api/browser/mainThreadOutputService.ts b/src/vs/workbench/api/browser/mainThreadOutputService.ts index 85f8495e80d..39e110e3f22 100644 --- a/src/vs/workbench/api/browser/mainThreadOutputService.ts +++ b/src/vs/workbench/api/browser/mainThreadOutputService.ts @@ -80,9 +80,7 @@ export class MainThreadOutputService extends Disposable implements MainThreadOut public async $dispose(channelId: string): Promise { const channel = this._getChannel(channelId); - if (channel) { - channel.dispose(); - } + channel?.dispose(); } private _getChannel(channelId: string): IOutputChannel | undefined { diff --git a/src/vs/workbench/api/common/extHostComments.ts b/src/vs/workbench/api/common/extHostComments.ts index 2259201d139..226c3d0dc12 100644 --- a/src/vs/workbench/api/common/extHostComments.ts +++ b/src/vs/workbench/api/common/extHostComments.ts @@ -620,9 +620,7 @@ export function createExtHostComments(mainContext: IMainContext, commands: ExtHo $deleteCommentThread(threadHandle: number): void { const thread = this._threads.get(threadHandle); - if (thread) { - thread.dispose(); - } + thread?.dispose(); this._threads.delete(threadHandle); } diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index 17d1d86c2d7..dfd947cba96 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -1130,9 +1130,7 @@ class InlineCompletionAdapter extends InlineCompletionAdapterBase { let disposableStore: DisposableStore | undefined = undefined; const pid = this._references.createReferenceId({ dispose() { - if (disposableStore) { - disposableStore.dispose(); - } + disposableStore?.dispose(); }, items: normalizedResult }); @@ -1236,9 +1234,7 @@ class InlineCompletionAdapterNew extends InlineCompletionAdapterBase { let disposableStore: DisposableStore | undefined = undefined; const pid = this._references.createReferenceId({ dispose() { - if (disposableStore) { - disposableStore.dispose(); - } + disposableStore?.dispose(); }, items: normalizedResult }); diff --git a/src/vs/workbench/api/common/extHostNotebook.ts b/src/vs/workbench/api/common/extHostNotebook.ts index 7c9cc4c0eb0..6a1df44dc0e 100644 --- a/src/vs/workbench/api/common/extHostNotebook.ts +++ b/src/vs/workbench/api/common/extHostNotebook.ts @@ -215,9 +215,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { return new extHostTypes.Disposable(() => { this._notebookStatusBarItemProviders.delete(handle); this._notebookProxy.$unregisterNotebookCellStatusBarItemProvider(handle, eventHandle); - if (subscription) { - subscription.dispose(); - } + subscription?.dispose(); }); } diff --git a/src/vs/workbench/api/common/extHostProgress.ts b/src/vs/workbench/api/common/extHostProgress.ts index 83b833b35b2..12cffddda11 100644 --- a/src/vs/workbench/api/common/extHostProgress.ts +++ b/src/vs/workbench/api/common/extHostProgress.ts @@ -42,9 +42,7 @@ export class ExtHostProgress implements ExtHostProgressShape { const progressEnd = (handle: number): void => { this._proxy.$progressEnd(handle); this._mapHandleToCancellationSource.delete(handle); - if (source) { - source.dispose(); - } + source?.dispose(); }; let p: Thenable; diff --git a/src/vs/workbench/api/common/extHostQuickOpen.ts b/src/vs/workbench/api/common/extHostQuickOpen.ts index 1bc50dd99e2..6d7ab756c8c 100644 --- a/src/vs/workbench/api/common/extHostQuickOpen.ts +++ b/src/vs/workbench/api/common/extHostQuickOpen.ts @@ -223,9 +223,7 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx $onDidAccept(sessionId: number): void { const session = this._sessions.get(sessionId); - if (session) { - session._fireDidAccept(); - } + session?._fireDidAccept(); } $onDidChangeActive(sessionId: number, handles: number[]): void { @@ -256,9 +254,7 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx $onDidHide(sessionId: number): void { const session = this._sessions.get(sessionId); - if (session) { - session._fireDidHide(); - } + session?._fireDidHide(); } } diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index d5f339775a3..ef74671541d 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -902,16 +902,12 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi break; case Parts.PANEL_PART: { const activePanel = this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Panel); - if (activePanel) { - activePanel.focus(); - } + activePanel?.focus(); break; } case Parts.SIDEBAR_PART: { const activeViewlet = this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Sidebar); - if (activeViewlet) { - activeViewlet.focus(); - } + activeViewlet?.focus(); break; } case Parts.ACTIVITYBAR_PART: @@ -922,9 +918,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi default: { // Title Bar & Banner simply pass focus to container const container = this.getContainer(part); - if (container) { - container.focus(); - } + container?.focus(); } } } diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index 5ee5d6e78ac..fedd79ca5e7 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -483,9 +483,7 @@ export class ActivitybarPart extends Part implements IPaneCompositeSelectorPart this.keyboardNavigationDisposables.add(addDisposableListener(this.menuBarContainer, EventType.KEY_DOWN, e => { const kbEvent = new StandardKeyboardEvent(e); if (kbEvent.equals(KeyCode.DownArrow) || kbEvent.equals(KeyCode.RightArrow)) { - if (this.compositeBar) { - this.compositeBar.focus(); - } + this.compositeBar?.focus(); } })); } @@ -497,9 +495,7 @@ export class ActivitybarPart extends Part implements IPaneCompositeSelectorPart if (kbEvent.equals(KeyCode.DownArrow) || kbEvent.equals(KeyCode.RightArrow)) { this.globalActivityActionBar?.focus(true); } else if (kbEvent.equals(KeyCode.UpArrow) || kbEvent.equals(KeyCode.LeftArrow)) { - if (this.menuBar) { - this.menuBar.toggleFocus(); - } + this.menuBar?.toggleFocus(); } })); } @@ -628,9 +624,7 @@ export class ActivitybarPart extends Part implements IPaneCompositeSelectorPart private onDidDeregisterViewContainer(viewContainer: ViewContainer): void { const disposable = this.viewContainerDisposables.get(viewContainer.id); - if (disposable) { - disposable.dispose(); - } + disposable?.dispose(); this.viewContainerDisposables.delete(viewContainer.id); this.removeComposite(viewContainer.id); diff --git a/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarActions.ts b/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarActions.ts index cf521c32e16..4603210c471 100644 --- a/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarActions.ts +++ b/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarActions.ts @@ -63,9 +63,7 @@ class FocusAuxiliaryBarAction extends Action { // Focus into active composite const composite = this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.AuxiliaryBar); - if (composite) { - composite.focus(); - } + composite?.focus(); } } diff --git a/src/vs/workbench/browser/parts/compositeBar.ts b/src/vs/workbench/browser/parts/compositeBar.ts index d15c1f36d96..0de81263555 100644 --- a/src/vs/workbench/browser/parts/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositeBar.ts @@ -557,9 +557,7 @@ export class CompositeBar extends Widget implements ICompositeBar { this.compositeOverflowAction.dispose(); this.compositeOverflowAction = undefined; - if (this.compositeOverflowActionViewItem) { - this.compositeOverflowActionViewItem.dispose(); - } + this.compositeOverflowActionViewItem?.dispose(); this.compositeOverflowActionViewItem = undefined; } @@ -596,9 +594,7 @@ export class CompositeBar extends Widget implements ICompositeBar { // Add overflow action as needed if (totalComposites > compositesToShow.length && !this.compositeOverflowAction) { this.compositeOverflowAction = this.instantiationService.createInstance(CompositeOverflowActivityAction, () => { - if (this.compositeOverflowActionViewItem) { - this.compositeOverflowActionViewItem.showMenu(); - } + this.compositeOverflowActionViewItem?.showMenu(); }); this.compositeOverflowActionViewItem = this.instantiationService.createInstance( CompositeOverflowActivityActionViewItem, diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 0ef796ae3fa..120b7c0343a 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -711,9 +711,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } widget.setFocused(undefined); widget.setSelection(undefined); - if (groups.activeGroup.activeEditorPane) { - groups.activeGroup.activeEditorPane.focus(); - } + groups.activeGroup.activeEditorPane?.focus(); } }); KeybindingsRegistry.registerCommandAndKeybindingRule({ diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index c93f52e60c6..78a4f548c34 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -278,9 +278,7 @@ abstract class AbstractFocusGroupAction extends Action { override async run(): Promise { const group = this.editorGroupService.findGroup(this.scope, this.editorGroupService.activeGroup, true); - if (group) { - group.focus(); - } + group?.focus(); } } diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index ab5ebcce987..264ba8fba9b 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -1035,9 +1035,7 @@ function registerFocusEditorGroupWihoutWrapCommands(): void { const editorGroupService = accessor.get(IEditorGroupsService); const group = editorGroupService.findGroup({ direction: command.direction }, editorGroupService.activeGroup, false); - if (group) { - group.focus(); - } + group?.focus(); }); } } diff --git a/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts b/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts index 7649aba7b08..e474515f5bd 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts @@ -133,9 +133,7 @@ export function registerNotificationCommands(center: INotificationsCenterControl primary: KeyCode.RightArrow, handler: (accessor, args?) => { const notification = getNotificationFromContext(accessor.get(IListService), args); - if (notification) { - notification.expand(); - } + notification?.expand(); } }); @@ -147,9 +145,7 @@ export function registerNotificationCommands(center: INotificationsCenterControl primary: KeyCode.LeftArrow, handler: (accessor, args?) => { const notification = getNotificationFromContext(accessor.get(IListService), args); - if (notification) { - notification.collapse(); - } + notification?.collapse(); } }); @@ -162,9 +158,7 @@ export function registerNotificationCommands(center: INotificationsCenterControl secondary: [KeyCode.Enter], handler: accessor => { const notification = getNotificationFromContext(accessor.get(IListService)); - if (notification) { - notification.toggle(); - } + notification?.toggle(); } }); diff --git a/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts b/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts index 670e5f35cae..ae61fa84403 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts @@ -217,9 +217,7 @@ export class NotificationsStatus extends Disposable { clearTimeout(hideHandle); } - if (statusMessageEntry) { - statusMessageEntry.dispose(); - } + statusMessageEntry?.dispose(); } }; diff --git a/src/vs/workbench/browser/parts/panel/panelActions.ts b/src/vs/workbench/browser/parts/panel/panelActions.ts index b23e8bd6fa3..074fafd9d61 100644 --- a/src/vs/workbench/browser/parts/panel/panelActions.ts +++ b/src/vs/workbench/browser/parts/panel/panelActions.ts @@ -70,9 +70,7 @@ class FocusPanelAction extends Action { // Focus into active panel const panel = this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Panel); - if (panel) { - panel.focus(); - } + panel?.focus(); } } diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 2263ec0769e..5d299207fe5 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -292,9 +292,7 @@ export abstract class BasePanelPart extends CompositePart impleme private async onDidDeregisterPanel(panelId: string): Promise { const disposable = this.panelDisposables.get(panelId); - if (disposable) { - disposable.dispose(); - } + disposable?.dispose(); this.panelDisposables.delete(panelId); const activeContainers = this.viewDescriptorService.getViewContainersByLocation(this.viewContainerLocation) diff --git a/src/vs/workbench/browser/parts/sidebar/sidebarActions.ts b/src/vs/workbench/browser/parts/sidebar/sidebarActions.ts index f1ab76ec17b..9ebb1e99eb7 100644 --- a/src/vs/workbench/browser/parts/sidebar/sidebarActions.ts +++ b/src/vs/workbench/browser/parts/sidebar/sidebarActions.ts @@ -42,9 +42,7 @@ export class FocusSideBarAction extends Action2 { // Focus into active viewlet const viewlet = paneCompositeService.getActivePaneComposite(ViewContainerLocation.Sidebar); - if (viewlet) { - viewlet.focus(); - } + viewlet?.focus(); } } diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index b431d4df48e..cff3e83c064 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -535,9 +535,7 @@ export class CustomMenubarControl extends MenubarControl { } async run(): Promise { - if (that.menubar) { - that.menubar.toggleFocus(); - } + that.menubar?.toggleFocus(); } })); } @@ -849,9 +847,7 @@ export class CustomMenubarControl extends MenubarControl { this.container.classList.remove('inactive'); } else { this.container.classList.add('inactive'); - if (this.menubar) { - this.menubar.blur(); - } + this.menubar?.blur(); } } } @@ -928,8 +924,6 @@ export class CustomMenubarControl extends MenubarControl { } toggleFocus() { - if (this.menubar) { - this.menubar.toggleFocus(); - } + this.menubar?.toggleFocus(); } } diff --git a/src/vs/workbench/common/editor/diffEditorInput.ts b/src/vs/workbench/common/editor/diffEditorInput.ts index 878ebaca825..c9917b2f6b9 100644 --- a/src/vs/workbench/common/editor/diffEditorInput.ts +++ b/src/vs/workbench/common/editor/diffEditorInput.ts @@ -171,9 +171,7 @@ export class DiffEditorInput extends SideBySideEditorInput implements IDiffEdito // inputs that need to be loaded again and thus we always recreate the model and dispose // the previous one - if any. const resolvedModel = await this.createModel(); - if (this.cachedModel) { - this.cachedModel.dispose(); - } + this.cachedModel?.dispose(); this.cachedModel = resolvedModel; diff --git a/src/vs/workbench/common/notifications.ts b/src/vs/workbench/common/notifications.ts index 815fe8a43d1..0536faa369e 100644 --- a/src/vs/workbench/common/notifications.ts +++ b/src/vs/workbench/common/notifications.ts @@ -195,9 +195,7 @@ export class NotificationsModel extends Disposable implements INotificationsMode // Deduplicate const duplicate = this.findNotification(item); - if (duplicate) { - duplicate.close(); - } + duplicate?.close(); // Add to list as first entry this._notifications.splice(0, 0, item); diff --git a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEdit.contribution.ts b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEdit.contribution.ts index 57a34f2c7d0..7f26aedafc4 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEdit.contribution.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEdit.contribution.ts @@ -189,9 +189,7 @@ registerAction2(class ApplyAction extends Action2 { async run(accessor: ServicesAccessor): Promise { const viewsService = accessor.get(IViewsService); const view = await getBulkEditPane(viewsService); - if (view) { - view.accept(); - } + view?.accept(); } }); @@ -215,9 +213,7 @@ registerAction2(class DiscardAction extends Action2 { async run(accessor: ServicesAccessor): Promise { const viewsService = accessor.get(IViewsService); const view = await getBulkEditPane(viewsService); - if (view) { - view.discard(); - } + view?.discard(); } }); @@ -246,9 +242,7 @@ registerAction2(class ToggleAction extends Action2 { async run(accessor: ServicesAccessor): Promise { const viewsService = accessor.get(IViewsService); const view = await getBulkEditPane(viewsService); - if (view) { - view.toggleChecked(); - } + view?.toggleChecked(); } }); @@ -275,9 +269,7 @@ registerAction2(class GroupByFile extends Action2 { async run(accessor: ServicesAccessor): Promise { const viewsService = accessor.get(IViewsService); const view = await getBulkEditPane(viewsService); - if (view) { - view.groupByFile(); - } + view?.groupByFile(); } }); @@ -302,9 +294,7 @@ registerAction2(class GroupByType extends Action2 { async run(accessor: ServicesAccessor): Promise { const viewsService = accessor.get(IViewsService); const view = await getBulkEditPane(viewsService); - if (view) { - view.groupByType(); - } + view?.groupByType(); } }); @@ -328,9 +318,7 @@ registerAction2(class ToggleGrouping extends Action2 { async run(accessor: ServicesAccessor): Promise { const viewsService = accessor.get(IViewsService); const view = await getBulkEditPane(viewsService); - if (view) { - view.toggleGrouping(); - } + view?.toggleGrouping(); } }); diff --git a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts index d2542d854ba..fc37bc604af 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts @@ -307,9 +307,7 @@ class ShowAccessibilityHelpAction extends Action2 { if (activeEditor) { const controller = AccessibilityHelpController.get(activeEditor); - if (controller) { - controller.show(); - } + controller?.show(); } } } diff --git a/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts b/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts index 9a655b6983a..34ca4a85e99 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/inspectEditorTokens/inspectEditorTokens.ts @@ -126,9 +126,7 @@ class InspectEditorTokens extends EditorAction { public run(accessor: ServicesAccessor, editor: ICodeEditor): void { const controller = InspectEditorTokensController.get(editor); - if (controller) { - controller.toggle(); - } + controller?.toggle(); } } diff --git a/src/vs/workbench/contrib/comments/browser/commentNode.ts b/src/vs/workbench/contrib/comments/browser/commentNode.ts index 674ea47d406..a9b5e980e4b 100644 --- a/src/vs/workbench/contrib/comments/browser/commentNode.ts +++ b/src/vs/workbench/contrib/comments/browser/commentNode.ts @@ -281,9 +281,7 @@ export class CommentNode extends Disposable { private createReactionPicker(reactionGroup: languages.CommentReaction[]): ToggleReactionsAction { const toggleReactionAction = this._register(new ToggleReactionsAction(() => { - if (toggleReactionActionViewItem) { - toggleReactionActionViewItem.show(); - } + toggleReactionActionViewItem?.show(); }, nls.localize('commentToggleReaction', "Toggle Reaction"))); let reactionMenuActions: Action[] = []; @@ -438,9 +436,7 @@ export class CommentNode extends Disposable { } this._body.classList.remove('hidden'); - if (this._commentEditorModel) { - this._commentEditorModel.dispose(); - } + this._commentEditorModel?.dispose(); this._commentEditorDisposables.forEach(dispose => dispose.dispose()); this._commentEditorDisposables = []; @@ -547,13 +543,9 @@ export class CommentNode extends Disposable { } // update comment reactions - if (this._reactionActionsContainer) { - this._reactionActionsContainer.remove(); - } + this._reactionActionsContainer?.remove(); - if (this._reactionsActionBar) { - this._reactionsActionBar.clear(); - } + this._reactionsActionBar?.clear(); if (this.comment.commentReactions && this.comment.commentReactions.some(reaction => !!reaction.count)) { this.createReactionsContainer(this._commentDetailsContainer); diff --git a/src/vs/workbench/contrib/comments/browser/commentReply.ts b/src/vs/workbench/contrib/comments/browser/commentReply.ts index 68eda2e6e39..c085e3ccf0c 100644 --- a/src/vs/workbench/contrib/comments/browser/commentReply.ts +++ b/src/vs/workbench/contrib/comments/browser/commentReply.ts @@ -163,9 +163,7 @@ export class CommentReply extends Disposable { } async submitComment(): Promise { - if (this._commentFormActions) { - this._commentFormActions.triggerDefaultAction(); - } + this._commentFormActions?.triggerDefaultAction(); } setCommentEditorDecorations() { diff --git a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts index 5f859a45b0a..280430dba93 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts @@ -595,9 +595,7 @@ export class CommentController implements IEditorContribution { this._computeCommentingRangeScheduler = new Delayer(200); this.localToDispose.add({ dispose: () => { - if (this._computeCommentingRangeScheduler) { - this._computeCommentingRangeScheduler.cancel(); - } + this._computeCommentingRangeScheduler?.cancel(); this._computeCommentingRangeScheduler = null; } }); @@ -974,9 +972,7 @@ export class NextCommentThreadAction extends EditorAction { public run(accessor: ServicesAccessor, editor: ICodeEditor): void { const controller = CommentController.get(editor); - if (controller) { - controller.nextCommentThread(); - } + controller?.nextCommentThread(); } } @@ -997,9 +993,7 @@ export class PreviousCommentThreadAction extends EditorAction { public run(accessor: ServicesAccessor, editor: ICodeEditor): void { const controller = CommentController.get(editor); - if (controller) { - controller.previousCommentThread(); - } + controller?.previousCommentThread(); } } diff --git a/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts index 8fdc2c1f303..defa4f43cd0 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts @@ -510,9 +510,7 @@ export class BreakpointEditorContribution implements IBreakpointEditorContributi activeCodeEditor.changeDecorations((changeAccessor) => { const decorationIds = changeAccessor.deltaDecorations(this.breakpointDecorations.map(bpd => bpd.decorationId), desiredBreakpointDecorations); this.breakpointDecorations.forEach(bpd => { - if (bpd.inlineWidget) { - bpd.inlineWidget.dispose(); - } + bpd.inlineWidget?.dispose(); }); this.breakpointDecorations = decorationIds.map((decorationId, index) => { let inlineWidget: InlineBreakpointWidget | undefined = undefined; @@ -613,9 +611,7 @@ export class BreakpointEditorContribution implements IBreakpointEditorContributi // breakpoint widget showBreakpointWidget(lineNumber: number, column: number | undefined, context?: BreakpointWidgetContext): void { - if (this.breakpointWidget) { - this.breakpointWidget.dispose(); - } + this.breakpointWidget?.dispose(); this.breakpointWidget = this.instantiationService.createInstance(BreakpointWidget, this.editor, lineNumber, column, context); this.breakpointWidget.show({ lineNumber, column: 1 }); @@ -632,9 +628,7 @@ export class BreakpointEditorContribution implements IBreakpointEditorContributi } dispose(): void { - if (this.breakpointWidget) { - this.breakpointWidget.dispose(); - } + this.breakpointWidget?.dispose(); this.editor.removeDecorations(this.breakpointDecorations.map(bpd => bpd.decorationId)); dispose(this.toDispose); } diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 8772e62d4f9..5e00363d505 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -221,9 +221,7 @@ export class BreakpointsView extends ViewPane { override focus(): void { super.focus(); - if (this.list) { - this.list.domFocus(); - } + this.list?.domFocus(); } renderInputBox(data: InputBoxData | undefined): void { diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index f6db1acdb80..ffdaa1c43eb 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -174,9 +174,7 @@ export class DebugService implements IDebugService { })); this.disposables.add(this.model.onDidChangeCallStack(() => { const numberOfSessions = this.model.getSessions().filter(s => !s.parentSession).length; - if (this.activity) { - this.activity.dispose(); - } + this.activity?.dispose(); if (numberOfSessions > 0) { const viewContainer = this.viewDescriptorService.getViewContainerByViewId(CALLSTACK_VIEW_ID); if (viewContainer) { diff --git a/src/vs/workbench/contrib/debug/browser/debugStatus.ts b/src/vs/workbench/contrib/debug/browser/debugStatus.ts index c4a8ef6be74..1addcfce1ec 100644 --- a/src/vs/workbench/contrib/debug/browser/debugStatus.ts +++ b/src/vs/workbench/contrib/debug/browser/debugStatus.ts @@ -72,9 +72,7 @@ export class DebugStatusContribution implements IWorkbenchContribution { } dispose(): void { - if (this.entryAccessor) { - this.entryAccessor.dispose(); - } + this.entryAccessor?.dispose(); dispose(this.toDispose); } } diff --git a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts index 3fd1c0238b8..89a1fcc4f5d 100644 --- a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts +++ b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts @@ -259,9 +259,7 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution { override dispose(): void { super.dispose(); - if (this.$el) { - this.$el.remove(); - } + this.$el?.remove(); if (this.disposeOnUpdate) { dispose(this.disposeOnUpdate); } diff --git a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts index 848245e3978..78921744a50 100644 --- a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts @@ -709,9 +709,7 @@ export class RawDebugSession implements IDisposable { let cancelationListener: IDisposable; const requestId = this.debugAdapter.sendRequest(command, args, (response: DebugProtocol.Response) => { - if (cancelationListener) { - cancelationListener.dispose(); - } + cancelationListener?.dispose(); if (response.success) { completeDispatch(response); diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 7fcf2fa1c08..8f27f11bcf6 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -226,9 +226,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget { private async onDidFocusSession(session: IDebugSession | undefined): Promise { if (session) { sessionsToIgnore.delete(session); - if (this.completionItemProvider) { - this.completionItemProvider.dispose(); - } + this.completionItemProvider?.dispose(); if (session.capabilities.supportsCompletionsRequest) { this.completionItemProvider = this.languageFeaturesService.completionProvider.register({ scheme: DEBUG_SCHEME, pattern: '**/replinput', hasAccessToAllModels: true }, { triggerCharacters: session.capabilities.completionTriggerCharacters || ['.'], @@ -408,9 +406,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget { } } if (session) { - if (this.replElementsChangeListener) { - this.replElementsChangeListener.dispose(); - } + this.replElementsChangeListener?.dispose(); this.replElementsChangeListener = session.onDidChangeReplElements(() => { this.refreshReplElements(session!.getReplElements().length === 0); }); @@ -748,9 +744,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget { override dispose(): void { this.replInput.dispose(); - if (this.replElementsChangeListener) { - this.replElementsChangeListener.dispose(); - } + this.replElementsChangeListener?.dispose(); this.refreshScheduler.dispose(); this.modelChangeListener.dispose(); super.dispose(); diff --git a/src/vs/workbench/contrib/debug/browser/replFilter.ts b/src/vs/workbench/contrib/debug/browser/replFilter.ts index 84b1faf07e3..368979c2d24 100644 --- a/src/vs/workbench/contrib/debug/browser/replFilter.ts +++ b/src/vs/workbench/contrib/debug/browser/replFilter.ts @@ -159,15 +159,11 @@ export class ReplFilterActionViewItem extends BaseActionViewItem { } override focus(): void { - if (this.filterInputBox) { - this.filterInputBox.focus(); - } + this.filterInputBox?.focus(); } override blur(): void { - if (this.filterInputBox) { - this.filterInputBox.blur(); - } + this.filterInputBox?.blur(); } override setFocusable(): void { diff --git a/src/vs/workbench/contrib/debug/common/debugContentProvider.ts b/src/vs/workbench/contrib/debug/common/debugContentProvider.ts index 5cdb5c988cb..e7c4d271d2e 100644 --- a/src/vs/workbench/contrib/debug/common/debugContentProvider.ts +++ b/src/vs/workbench/contrib/debug/common/debugContentProvider.ts @@ -110,9 +110,7 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC // cancel and dispose an existing update const cancellationSource = this.pendingUpdates.get(model.id); - if (cancellationSource) { - cancellationSource.cancel(); - } + cancellationSource?.cancel(); // create and keep update token const myToken = new CancellationTokenSource(); diff --git a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts index 7c111e51eda..2388b7ee9e0 100644 --- a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts +++ b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts @@ -106,9 +106,7 @@ suite('Experiment Service', () => { }); teardown(() => { - if (testObject) { - testObject.dispose(); - } + testObject?.dispose(); }); }); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index d155971ec3a..8e402047041 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -1737,9 +1737,7 @@ registerAction2(class ShowExtensionEditorFindAction extends Action2 { } run(accessor: ServicesAccessor): any { const extensionEditor = getExtensionEditor(accessor); - if (extensionEditor) { - extensionEditor.showFind(); - } + extensionEditor?.showFind(); } }); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index ae27fb19d2b..27a701f84cb 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -586,9 +586,7 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE } override focus(): void { - if (this.searchBox) { - this.searchBox.focus(); - } + this.searchBox?.focus(); } override layout(dimension: Dimension): void { diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts index 0271565b5fd..64d97457b03 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts @@ -388,9 +388,7 @@ export class ExtensionPackCountWidget extends ExtensionWidget { } private clear(): void { - if (this.element) { - this.element.remove(); - } + this.element?.remove(); } render(): void { diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts index 030f0b5ca87..d9176de598a 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts @@ -258,9 +258,7 @@ suite('ExtensionRecommendationsService Test', () => { }); suiteTeardown(() => { - if (experimentService) { - experimentService.dispose(); - } + experimentService?.dispose(); }); setup(() => { diff --git a/src/vs/workbench/contrib/files/browser/editors/textFileSaveErrorHandler.ts b/src/vs/workbench/contrib/files/browser/editors/textFileSaveErrorHandler.ts index 659469ef968..c82b09ff0e1 100644 --- a/src/vs/workbench/contrib/files/browser/editors/textFileSaveErrorHandler.ts +++ b/src/vs/workbench/contrib/files/browser/editors/textFileSaveErrorHandler.ts @@ -196,9 +196,7 @@ const pendingResolveSaveConflictMessages: INotificationHandle[] = []; function clearPendingResolveSaveConflictMessages(): void { while (pendingResolveSaveConflictMessages.length > 0) { const item = pendingResolveSaveConflictMessages.pop(); - if (item) { - item.close(); - } + item?.close(); } } diff --git a/src/vs/workbench/contrib/files/browser/explorerService.ts b/src/vs/workbench/contrib/files/browser/explorerService.ts index bfa4654c1e2..549f75f919f 100644 --- a/src/vs/workbench/contrib/files/browser/explorerService.ts +++ b/src/vs/workbench/contrib/files/browser/explorerService.ts @@ -121,9 +121,7 @@ export class ExplorerService implements IExplorerService { } })); this.disposables.add(this.model.onDidChangeRoots(() => { - if (this.view) { - this.view.setTreeInput(); - } + this.view?.setTreeInput(); })); // Refresh explorer when window gets focus to compensate for missing file events #126817 diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 6e15cf4d9c8..16b99312386 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -889,9 +889,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { } override dispose(): void { - if (this.dragHandler) { - this.dragHandler.dispose(); - } + this.dragHandler?.dispose(); super.dispose(); } } diff --git a/src/vs/workbench/contrib/inlayHints/browser/inlayHintsAccessibilty.ts b/src/vs/workbench/contrib/inlayHints/browser/inlayHintsAccessibilty.ts index e3d83192f51..1cd411eb22c 100644 --- a/src/vs/workbench/contrib/inlayHints/browser/inlayHintsAccessibilty.ts +++ b/src/vs/workbench/contrib/inlayHints/browser/inlayHintsAccessibilty.ts @@ -185,9 +185,7 @@ registerAction2(class StartReadHints extends EditorAction2 { runEditorCommand(_accessor: ServicesAccessor, editor: ICodeEditor) { const ctrl = InlayHintsAccessibility.get(editor); - if (ctrl) { - ctrl.startInlayHintsReading(); - } + ctrl?.startInlayHintsReading(); } }); @@ -211,9 +209,7 @@ registerAction2(class StopReadHints extends EditorAction2 { runEditorCommand(_accessor: ServicesAccessor, editor: ICodeEditor) { const ctrl = InlayHintsAccessibility.get(editor); - if (ctrl) { - ctrl.stopInlayHintsReading(); - } + ctrl?.stopInlayHintsReading(); } }); diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts index 549ca51417f..f1155751058 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts @@ -316,13 +316,9 @@ export class InteractiveEditor extends EditorPane { // there currently is a widget which we still own so // we need to hide it before getting a new widget - if (this.#notebookWidget.value) { - this.#notebookWidget.value.onWillHide(); - } + this.#notebookWidget.value?.onWillHide(); - if (this.#codeEditorWidget) { - this.#codeEditorWidget.dispose(); - } + this.#codeEditorWidget?.dispose(); this.#widgetDisposableStore.clear(); @@ -665,9 +661,7 @@ export class InteractiveEditor extends EditorPane { this.#notebookWidget.value.onWillHide(); } - if (this.#codeEditorWidget) { - this.#codeEditorWidget.dispose(); - } + this.#codeEditorWidget?.dispose(); this.#notebookWidget = { value: undefined }; this.#widgetDisposableStore.clear(); diff --git a/src/vs/workbench/contrib/markers/browser/markersView.ts b/src/vs/workbench/contrib/markers/browser/markersView.ts index 1b322657c38..826270e143a 100644 --- a/src/vs/workbench/contrib/markers/browser/markersView.ts +++ b/src/vs/workbench/contrib/markers/browser/markersView.ts @@ -427,9 +427,7 @@ export class MarkersView extends ViewPane implements IMarkersView { for (const element of elements) { if (element instanceof Marker) { const viewModel = this.markersViewModel.getViewModel(element); - if (viewModel) { - viewModel.showLightBulb(); - } + viewModel?.showLightBulb(); } } })); diff --git a/src/vs/workbench/contrib/markers/browser/markersViewActions.ts b/src/vs/workbench/contrib/markers/browser/markersViewActions.ts index a8857968647..d1d3e232cf8 100644 --- a/src/vs/workbench/contrib/markers/browser/markersViewActions.ts +++ b/src/vs/workbench/contrib/markers/browser/markersViewActions.ts @@ -284,15 +284,11 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem { } override focus(): void { - if (this.filterInputBox) { - this.filterInputBox.focus(); - } + this.filterInputBox?.focus(); } override blur(): void { - if (this.filterInputBox) { - this.filterInputBox.blur(); - } + this.filterInputBox?.blur(); } override setFocusable(): void { diff --git a/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffEditor.ts b/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffEditor.ts index bfaa6a81660..9c4bcd48dae 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffEditor.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffEditor.ts @@ -430,9 +430,7 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD } private async _createModifiedWebview(id: string, resource: URI): Promise { - if (this._modifiedWebview) { - this._modifiedWebview.dispose(); - } + this._modifiedWebview?.dispose(); this._modifiedWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, { ...this._notebookOptions.computeDiffWebviewOptions(), @@ -449,9 +447,7 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD } private async _createOriginalWebview(id: string, resource: URI): Promise { - if (this._originalWebview) { - this._originalWebview.dispose(); - } + this._originalWebview?.dispose(); this._originalWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, { ...this._notebookOptions.computeDiffWebviewOptions(), diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts index 084590f8a0c..d82c4b964b9 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts @@ -182,9 +182,7 @@ export class NotebookEditor extends EditorPane implements IEditorPaneWithSelecti // there currently is a widget which we still own so // we need to hide it before getting a new widget - if (this._widget.value) { - this._widget.value.onWillHide(); - } + this._widget.value?.onWillHide(); this._widget = >this._instantiationService.invokeFunction(this._notebookWidgetService.retrieveWidget, group, input); diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index fc6500ceba8..80053311f5a 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -2530,9 +2530,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD } findStop() { - if (this._webview) { - this._webview.findStop(); - } + this._webview?.findStop(); } //#endregion diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts index b41c7a096f5..178477466b7 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts @@ -608,9 +608,7 @@ export abstract class BaseCellViewModel extends Disposable { this._undoRedoService.removeElements(this.uri); } - if (this._textModelRef) { - this._textModelRef.dispose(); - } + this._textModelRef?.dispose(); } toJSON(): object { diff --git a/src/vs/workbench/contrib/output/browser/outputView.ts b/src/vs/workbench/contrib/output/browser/outputView.ts index a3b51602a06..c6909ba0556 100644 --- a/src/vs/workbench/contrib/output/browser/outputView.ts +++ b/src/vs/workbench/contrib/output/browser/outputView.ts @@ -149,9 +149,7 @@ export class OutputViewPane extends ViewPane { const input = this.createInput(channel); if (!this.editor.input || !input.matches(this.editor.input)) { - if (this.editorPromise) { - this.editorPromise.cancel(); - } + this.editorPromise?.cancel(); this.editorPromise = createCancelablePromise(token => this.editor.setInput(this.createInput(channel), { preserveFocus: true }, Object.create(null), token) .then(() => this.editor)); } diff --git a/src/vs/workbench/contrib/output/common/outputChannelModel.ts b/src/vs/workbench/contrib/output/common/outputChannelModel.ts index 58f8374650b..0f6012d6842 100644 --- a/src/vs/workbench/contrib/output/common/outputChannelModel.ts +++ b/src/vs/workbench/contrib/output/common/outputChannelModel.ts @@ -278,9 +278,7 @@ export class FileOutputChannelModel extends Disposable implements IOutputChannel } protected cancelModelUpdate(): void { - if (this.modelUpdateCancellationSource.value) { - this.modelUpdateCancellationSource.value.cancel(); - } + this.modelUpdateCancellationSource.value?.cancel(); this.modelUpdateCancellationSource.value = undefined; this.appendThrottler.cancel(); this.replacePromise = undefined; diff --git a/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts b/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts index 55c802041c0..e1aab482fb5 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts @@ -613,9 +613,7 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon function settingsEditorFocusSearch(accessor: ServicesAccessor) { const preferencesEditor = getPreferencesEditor(accessor); - if (preferencesEditor) { - preferencesEditor.focusSearch(); - } + preferencesEditor?.focusSearch(); } registerAction2(class extends Action2 { @@ -655,9 +653,7 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon run(accessor: ServicesAccessor) { const preferencesEditor = getPreferencesEditor(accessor); - if (preferencesEditor) { - preferencesEditor.clearSearchResults(); - } + preferencesEditor?.clearSearchResults(); } }); diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index 252f5e99204..25bb124f3c0 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -1208,9 +1208,7 @@ export class SettingsEditor2 extends EditorPane { } } - if (this.searchResultModel) { - this.searchResultModel.updateChildren(); - } + this.searchResultModel?.updateChildren(); if (this.settingsTreeModel) { this.settingsTreeModel.update(resolvedSettingsRoot); diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index 362212fc944..d5081f01397 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -1006,9 +1006,7 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre } disposeElement(_element: ITreeNode, _index: number, template: IDisposableTemplate, _height: number | undefined): void { - if ((template as ISettingItemTemplate).elementDisposables) { - (template as ISettingItemTemplate).elementDisposables.clear(); - } + (template as ISettingItemTemplate).elementDisposables?.clear(); } } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts index 756f928dbc4..521bb5b72b1 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts @@ -624,9 +624,7 @@ export class ListSettingWidget extends AbstractListSettingWidget this.listDisposables.add(DOM.addDisposableListener(rowElement, DOM.EventType.DRAG_END, (ev) => { counter = 0; rowElement.classList.remove('drag-hover'); - if (ev.dataTransfer) { - ev.dataTransfer.clearData(); - } + ev.dataTransfer?.clearData(); if (this.dragDetails) { this.dragDetails = undefined; } diff --git a/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts b/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts index 2f96395016a..8e749ba806c 100644 --- a/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts +++ b/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts @@ -185,9 +185,7 @@ export class WorkspaceChangeExtHostRelauncher extends Disposable implements IWor }); this._register(toDisposable(() => { - if (this.onDidChangeWorkspaceFoldersUnbind) { - this.onDidChangeWorkspaceFoldersUnbind.dispose(); - } + this.onDidChangeWorkspaceFoldersUnbind?.dispose(); })); } diff --git a/src/vs/workbench/contrib/remote/browser/remote.ts b/src/vs/workbench/contrib/remote/browser/remote.ts index e5ebb7468a5..8d3bf427980 100644 --- a/src/vs/workbench/contrib/remote/browser/remote.ts +++ b/src/vs/workbench/contrib/remote/browser/remote.ts @@ -766,9 +766,7 @@ export class RemoteAgentConnectionStatusListener extends Disposable implements I const reconnectButton = { label: nls.localize('reconnectNow', "Reconnect Now"), callback: () => { - if (reconnectWaitEvent) { - reconnectWaitEvent.skipWait(); - } + reconnectWaitEvent?.skipWait(); } }; @@ -808,9 +806,7 @@ export class RemoteAgentConnectionStatusListener extends Disposable implements I // ReconnectionRunning -> ConnectionGain, ReconnectionPermanentFailure connection.onDidStateChange((e) => { - if (visibleProgress) { - visibleProgress.stopTimer(); - } + visibleProgress?.stopTimer(); if (disposableListener) { disposableListener.dispose(); diff --git a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts index 10abb46d232..b7fcc95447b 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts @@ -112,9 +112,7 @@ export class ForwardedPortsView extends Disposable implements IWorkbenchContribu } private async updateActivityBadge() { - if (this._activityBadge) { - this._activityBadge.dispose(); - } + this._activityBadge?.dispose(); if (this.remoteExplorerService.tunnelModel.forwarded.size > 0) { this._activityBadge = this.activityService.showViewActivity(TUNNEL_VIEW_ID, { badge: new NumberBadge(this.remoteExplorerService.tunnelModel.forwarded.size, n => n === 1 ? nls.localize('1forwardedPort', "1 forwarded port") : nls.localize('nForwardedPorts', "{0} forwarded ports", n)) @@ -334,9 +332,7 @@ class OnAutoForwardedAction extends Disposable { return; } - if (this.lastNotification) { - this.lastNotification.close(); - } + this.lastNotification?.close(); let message = this.basicMessage(tunnel); const choices = [this.openBrowserChoice(tunnel)]; if (!isWeb) { @@ -391,9 +387,7 @@ class OnAutoForwardedAction extends Disposable { if (!newTunnel) { return; } - if (this.lastNotification) { - this.lastNotification.close(); - } + this.lastNotification?.close(); this.lastShownPort = newTunnel.tunnelRemotePort; this.lastNotification = this.notificationService.prompt(Severity.Info, this.basicMessage(newTunnel) + this.linkMessage(), @@ -453,9 +447,7 @@ class OutputAutomaticPortForwarding extends Disposable { if (!this.urlFinder && !this.remoteExplorerService.portsFeaturesEnabled) { return; } - if (this.portsFeatures) { - this.portsFeatures.dispose(); - } + this.portsFeatures?.dispose(); this.urlFinder = this._register(new UrlFinder(this.terminalService, this.debugService)); this._register(this.urlFinder.onDidMatchLocalUrl(async (localUrl) => { if (mapHasAddressLocalhostOrAllInterfaces(this.remoteExplorerService.tunnelModel.detected, localUrl.host, localUrl.port)) { @@ -543,9 +535,7 @@ class ProcAutomaticPortForwarding extends Disposable { if (this.candidateListener || !this.remoteExplorerService.portsFeaturesEnabled) { return; } - if (this.portsFeatures) { - this.portsFeatures.dispose(); - } + this.portsFeatures?.dispose(); // Capture list of starting candidates so we don't auto forward them later. await this.setInitialCandidates(); diff --git a/src/vs/workbench/contrib/search/browser/patternInputWidget.ts b/src/vs/workbench/contrib/search/browser/patternInputWidget.ts index 5e9bedd5609..30e8ca1e9ea 100644 --- a/src/vs/workbench/contrib/search/browser/patternInputWidget.ts +++ b/src/vs/workbench/contrib/search/browser/patternInputWidget.ts @@ -70,9 +70,7 @@ export class PatternInputWidget extends Widget implements IThemable { override dispose(): void { super.dispose(); - if (this.inputFocusTracker) { - this.inputFocusTracker.dispose(); - } + this.inputFocusTracker?.dispose(); } setWidth(newWidth: number): void { diff --git a/src/vs/workbench/contrib/search/browser/replaceService.ts b/src/vs/workbench/contrib/search/browser/replaceService.ts index ba8ebda0f19..d653f377203 100644 --- a/src/vs/workbench/contrib/search/browser/replaceService.ts +++ b/src/vs/workbench/contrib/search/browser/replaceService.ts @@ -128,9 +128,7 @@ export class ReplaceService implements IReplaceService { }); const input = editor?.input; const disposable = fileMatch.onDispose(() => { - if (input) { - input.dispose(); - } + input?.dispose(); disposable.dispose(); }); await this.updateReplacePreview(fileMatch); diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 099169c6ab3..9a7057668d8 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -88,9 +88,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ primary: KeyMod.CtrlCmd | KeyCode.UpArrow, handler: (accessor, args: any) => { const searchView = getSearchView(accessor.get(IViewsService)); - if (searchView) { - searchView.focusPreviousInputBox(); - } + searchView?.focusPreviousInputBox(); } }); @@ -576,9 +574,7 @@ CommandsRegistry.registerCommand({ if (mode === 'view') { const searchView = await openSearchView(accessor.get(IViewsService), true); - if (searchView) { - searchView.searchInFolders(); - } + searchView?.searchInFolders(); } else { return accessor.get(ICommandService).executeCommand(SearchEditorConstants.OpenEditorCommandId, { diff --git a/src/vs/workbench/contrib/search/browser/searchActions.ts b/src/vs/workbench/contrib/search/browser/searchActions.ts index 4b503feac04..4c60e7d9bd9 100644 --- a/src/vs/workbench/contrib/search/browser/searchActions.ts +++ b/src/vs/workbench/contrib/search/browser/searchActions.ts @@ -65,30 +65,22 @@ function doAppendKeyBindingLabel(label: string, keyBinding: ResolvedKeybinding | export const toggleCaseSensitiveCommand = (accessor: ServicesAccessor) => { const searchView = getSearchView(accessor.get(IViewsService)); - if (searchView) { - searchView.toggleCaseSensitive(); - } + searchView?.toggleCaseSensitive(); }; export const toggleWholeWordCommand = (accessor: ServicesAccessor) => { const searchView = getSearchView(accessor.get(IViewsService)); - if (searchView) { - searchView.toggleWholeWords(); - } + searchView?.toggleWholeWords(); }; export const toggleRegexCommand = (accessor: ServicesAccessor) => { const searchView = getSearchView(accessor.get(IViewsService)); - if (searchView) { - searchView.toggleRegex(); - } + searchView?.toggleRegex(); }; export const togglePreserveCaseCommand = (accessor: ServicesAccessor) => { const searchView = getSearchView(accessor.get(IViewsService)); - if (searchView) { - searchView.togglePreserveCase(); - } + searchView?.togglePreserveCase(); }; export class FocusNextInputAction extends Action { @@ -110,9 +102,7 @@ export class FocusNextInputAction extends Action { } const searchView = getSearchView(this.viewsService); - if (searchView) { - searchView.focusNextInputBox(); - } + searchView?.focusNextInputBox(); } } @@ -135,9 +125,7 @@ export class FocusPreviousInputAction extends Action { } const searchView = getSearchView(this.viewsService); - if (searchView) { - searchView.focusPreviousInputBox(); - } + searchView?.focusPreviousInputBox(); } } @@ -275,17 +263,13 @@ export function expandAll(accessor: ServicesAccessor) { export function clearSearchResults(accessor: ServicesAccessor) { const viewsService = accessor.get(IViewsService); const searchView = getSearchView(viewsService); - if (searchView) { - searchView.clearSearchResults(); - } + searchView?.clearSearchResults(); } export function cancelSearch(accessor: ServicesAccessor) { const viewsService = accessor.get(IViewsService); const searchView = getSearchView(viewsService); - if (searchView) { - searchView.cancelSearch(); - } + searchView?.cancelSearch(); } export function refreshSearch(accessor: ServicesAccessor) { @@ -352,9 +336,7 @@ export class FocusNextSearchResultAction extends Action { } return openSearchView(this.viewsService).then(searchView => { - if (searchView) { - searchView.selectNextMatch(); - } + searchView?.selectNextMatch(); }); } } @@ -378,9 +360,7 @@ export class FocusPreviousSearchResultAction extends Action { } return openSearchView(this.viewsService).then(searchView => { - if (searchView) { - searchView.selectPreviousMatch(); - } + searchView?.selectPreviousMatch(); }); } } @@ -819,9 +799,7 @@ export const clearHistoryCommand: ICommandHandler = accessor => { export const focusSearchListCommand: ICommandHandler = accessor => { const viewsService = accessor.get(IViewsService); openSearchView(viewsService).then(searchView => { - if (searchView) { - searchView.moveFocusToResults(); - } + searchView?.moveFocusToResults(); }); }; diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index cb53a27ac62..3d67e09cef9 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -594,9 +594,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } protected _disposeTaskSystemListeners(): void { - if (this._taskSystemListener) { - this._taskSystemListener.dispose(); - } + this._taskSystemListener?.dispose(); } public registerTaskProvider(provider: ITaskProvider, type: string): IDisposable { @@ -1394,9 +1392,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const twoTabs = insertSpaces ? ' '.repeat(tabSize * 2) : '\t\t'; stringValue = twoTabs + stringified.slice(0, stringified.length - 1) + twoTabs + stringified.slice(stringified.length - 1); } finally { - if (reference) { - reference.dispose(); - } + reference?.dispose(); } return stringValue; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts index 61412cfb781..0bdd65b70eb 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts @@ -137,9 +137,7 @@ export class TerminalEditor extends EditorPane { // Drop selection and focus terminal on Linux to enable middle button paste when click // occurs on the selection itself. const terminal = this._terminalEditorService.activeInstance; - if (terminal) { - terminal.focus(); - } + terminal?.focus(); } else if (event.which === 3) { const rightClickBehavior = this._terminalService.configHelper.config.rightClickBehavior; if (rightClickBehavior === 'nothing') { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts b/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts index ec5a3cb0aa9..07efa9f5527 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts @@ -87,9 +87,7 @@ export class TerminalFindWidget extends SimpleFindWidget { super.hide(); this._findWidgetVisible.reset(); const instance = this._terminalService.activeInstance; - if (instance) { - instance.focus(); - } + instance?.focus(); // Terminals in a group currently share a find widget, so hide // all decorations for terminals in this group const activeGroup = this._terminalGroupService.activeGroup; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalView.ts b/src/vs/workbench/contrib/terminal/browser/terminalView.ts index 81916e856ef..7a2505d71bf 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalView.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalView.ts @@ -240,9 +240,7 @@ export class TerminalViewPane extends ViewPane { return this._instantiationService.createInstance(SingleTerminalTabActionViewItem, action, actions); } case TerminalCommandId.CreateWithProfileButton: { - if (this._tabButtons) { - this._tabButtons.dispose(); - } + this._tabButtons?.dispose(); const actions = getTerminalActionBarArgs(TerminalLocation.Panel, this._terminalProfileService.availableProfiles, this._getDefaultProfileName(), this._terminalProfileService.contributedProfiles, this._instantiationService, this._terminalService, this._contextKeyService, this._commandService, this._dropdownMenu); this._tabButtons = new DropdownWithPrimaryActionViewItem(actions.primaryAction, actions.dropdownAction, actions.dropdownMenuActions, actions.className, this._contextMenuService, {}, this._keybindingService, this._notificationService, this._contextKeyService, this._themeService); diff --git a/src/vs/workbench/contrib/welcomeOverlay/browser/welcomeOverlay.ts b/src/vs/workbench/contrib/welcomeOverlay/browser/welcomeOverlay.ts index f3a0b3d96ac..78cd06a4e0f 100644 --- a/src/vs/workbench/contrib/welcomeOverlay/browser/welcomeOverlay.ts +++ b/src/vs/workbench/contrib/welcomeOverlay/browser/welcomeOverlay.ts @@ -144,9 +144,7 @@ export class HideWelcomeOverlayAction extends Action { } public override run(): Promise { - if (welcomeOverlay) { - welcomeOverlay.hide(); - } + welcomeOverlay?.hide(); return Promise.resolve(); } } diff --git a/src/vs/workbench/contrib/welcomeViews/common/viewsWelcomeContribution.ts b/src/vs/workbench/contrib/welcomeViews/common/viewsWelcomeContribution.ts index e296e0d82a1..13b7e3560be 100644 --- a/src/vs/workbench/contrib/welcomeViews/common/viewsWelcomeContribution.ts +++ b/src/vs/workbench/contrib/welcomeViews/common/viewsWelcomeContribution.ts @@ -27,9 +27,7 @@ export class ViewsWelcomeContribution extends Disposable implements IWorkbenchCo for (const welcome of contribution.value) { const disposable = this.viewWelcomeContents.get(welcome); - if (disposable) { - disposable.dispose(); - } + disposable?.dispose(); } } diff --git a/src/vs/workbench/services/decorations/test/browser/decorationsService.test.ts b/src/vs/workbench/services/decorations/test/browser/decorationsService.test.ts index c98a7d69195..c1a086d323f 100644 --- a/src/vs/workbench/services/decorations/test/browser/decorationsService.test.ts +++ b/src/vs/workbench/services/decorations/test/browser/decorationsService.test.ts @@ -20,9 +20,7 @@ suite('DecorationsService', function () { let service: DecorationsService; setup(function () { - if (service) { - service.dispose(); - } + service?.dispose(); service = new DecorationsService( new class extends mock() { override extUri = resources.extUri; diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index 24259163505..c53aba431d5 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -538,9 +538,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx } } finally { this._inHandleDeltaExtensions = false; - if (lock) { - lock.dispose(); - } + lock?.dispose(); } } diff --git a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts index ee051e3d1f1..4077c1661e4 100644 --- a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts +++ b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts @@ -615,9 +615,7 @@ export abstract class ElectronExtensionService extends AbstractExtensionService // Dispose the management connection to avoid reconnecting after the extension host exits const connection = this._remoteAgentService.getConnection(); - if (connection) { - connection.dispose(); - } + connection?.dispose(); if (this._isExtensionDevTestFromCli) { // When CLI testing make sure to exit with proper exit code diff --git a/src/vs/workbench/services/progress/browser/progressService.ts b/src/vs/workbench/services/progress/browser/progressService.ts index c39c0a727da..faca26a6b76 100644 --- a/src/vs/workbench/services/progress/browser/progressService.ts +++ b/src/vs/workbench/services/progress/browser/progressService.ts @@ -505,9 +505,7 @@ export class ProgressService extends Disposable implements IProgressService { // Infinite else { - if (discreteProgressRunner) { - discreteProgressRunner.done(); - } + discreteProgressRunner?.done(); progressIndicator.showWhile(promise, options.delay); } diff --git a/src/vs/workbench/services/search/common/fileSearchManager.ts b/src/vs/workbench/services/search/common/fileSearchManager.ts index c5c8b2d10b4..4a1199ecbaf 100644 --- a/src/vs/workbench/services/search/common/fileSearchManager.ts +++ b/src/vs/workbench/services/search/common/fileSearchManager.ts @@ -300,9 +300,7 @@ export class FileSearchManager { clearCache(cacheKey: string): void { const sessionTokenSource = this.getSessionTokenSource(cacheKey); - if (sessionTokenSource) { - sessionTokenSource.cancel(); - } + sessionTokenSource?.cancel(); } private getSessionTokenSource(cacheKey: string | undefined): CancellationTokenSource | undefined { diff --git a/src/vs/workbench/services/search/node/fileSearch.ts b/src/vs/workbench/services/search/node/fileSearch.ts index a7afc5cae5b..76eec9e5ad6 100644 --- a/src/vs/workbench/services/search/node/fileSearch.ts +++ b/src/vs/workbench/services/search/node/fileSearch.ts @@ -315,9 +315,7 @@ export class FileWalker { if (err || last) { onData = () => { }; - if (this.cmdSW) { - this.cmdSW.stop(); - } + this.cmdSW?.stop(); } cb(err, stdout, last); }; diff --git a/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts b/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts index 466b5ec5349..6224ae3a1d2 100644 --- a/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts +++ b/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts @@ -66,13 +66,9 @@ export class RipgrepTextSearchEngine { const cancel = () => { isDone = true; - if (rgProc) { - rgProc.kill(); - } + rgProc?.kill(); - if (ripgrepParser) { - ripgrepParser.cancel(); - } + ripgrepParser?.cancel(); }; let limitHit = false; diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts index 900a7bba75b..a778f289a95 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts @@ -501,9 +501,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE // dispose any previously stored dispose listener for this resource const disposeListener = this.mapResourceToDisposeListener.get(resource); - if (disposeListener) { - disposeListener.dispose(); - } + disposeListener?.dispose(); // store in cache but remove when model gets disposed this.mapResourceToModel.set(resource, model); diff --git a/src/vs/workbench/services/workspaces/common/workspaceTrust.ts b/src/vs/workbench/services/workspaces/common/workspaceTrust.ts index eefe8b7ffcd..ba2e1715254 100644 --- a/src/vs/workbench/services/workspaces/common/workspaceTrust.ts +++ b/src/vs/workbench/services/workspaces/common/workspaceTrust.ts @@ -873,9 +873,7 @@ class WorkspaceTrustMemento { set acceptsOutOfWorkspaceFiles(value: boolean) { this._mementoObject[this._acceptsOutOfWorkspaceFilesKey] = value; - if (this._memento) { - this._memento.saveMemento(); - } + this._memento?.saveMemento(); } get isEmptyWorkspaceTrusted(): boolean | undefined { @@ -885,9 +883,7 @@ class WorkspaceTrustMemento { set isEmptyWorkspaceTrusted(value: boolean | undefined) { this._mementoObject[this._isEmptyWorkspaceTrustedKey] = value; - if (this._memento) { - this._memento.saveMemento(); - } + this._memento?.saveMemento(); } } From f1c0f68fb5b6298f0ee1885c2b28a73be3e86cb2 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Tue, 2 Aug 2022 17:10:22 -0700 Subject: [PATCH 169/303] enable task reconnection by default and fix for windows (#156909) * set task reconnection to true when there are 0 and check problem matchers not isBackground * enable by default --- .../workbench/contrib/tasks/browser/abstractTaskService.ts | 3 ++- src/vs/workbench/contrib/tasks/browser/task.contribution.ts | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 3d67e09cef9..2504a1240a5 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -351,6 +351,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private async _reconnectTasks(): Promise { const tasks = await this.getSavedTasks('persistent'); if (!tasks.length) { + this._tasksReconnected = true; return; } for (const task of tasks) { @@ -1065,7 +1066,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } private async _setPersistentTask(task: Task): Promise { - if (!task.configurationProperties.isBackground || !this._tasksReconnected) { + if (!task.configurationProperties.problemMatchers || !this._tasksReconnected) { return; } let key = task.getRecentlyUsedKey(); diff --git a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts index 9e62a8604dc..7671ffb7db8 100644 --- a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts +++ b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts @@ -515,9 +515,8 @@ configurationRegistry.registerConfiguration({ }, [TaskSettingId.Reconnection]: { type: 'boolean', - description: nls.localize('task.experimental.reconnection', "On window reload, reconnect to running watch/background tasks. Note that this is experimental, so you could encounter issues."), - default: false, - tags: ['experimental'] + description: nls.localize('task.reconnection', "On window reload, reconnect to tasks that have problem matchers."), + default: true }, [TaskSettingId.SaveBeforeRun]: { markdownDescription: nls.localize( From 9f8e6e9a51c36f5d01a40293b018369c9169efac Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Tue, 2 Aug 2022 17:10:36 -0700 Subject: [PATCH 170/303] .then -> await (#156634) --- .../tasks/browser/abstractTaskService.ts | 864 +++++++++--------- 1 file changed, 415 insertions(+), 449 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 2504a1240a5..0cd4dd22539 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -63,7 +63,7 @@ import { getTemplates as getTaskTemplates } from 'vs/workbench/contrib/tasks/com import * as TaskConfig from '../common/taskConfiguration'; import { TerminalTaskSystem } from './terminalTaskSystem'; -import { IQuickInputService, IQuickPickItem, QuickPickInput, IQuickPick } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickPickItem, QuickPickInput, IQuickPick, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { TaskDefinitionRegistry } from 'vs/workbench/contrib/tasks/common/taskDefinitionRegistry'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; @@ -74,7 +74,7 @@ import { IPathService } from 'vs/workbench/services/path/common/pathService'; import { toFormattedString } from 'vs/base/common/jsonFormatter'; import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; import { EditorResourceAccessor, SaveReason } from 'vs/workbench/common/editor'; -import { ITextEditorSelection, TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor'; +import { TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { IViewsService, IViewDescriptorService } from 'vs/workbench/common/views'; @@ -296,9 +296,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer })); this._taskRunningState = TASK_RUNNING_STATE.bindTo(_contextKeyService); this._onDidStateChange = this._register(new Emitter()); - this._registerCommands().then(() => { - TaskCommandsRegistered.bindTo(this._contextKeyService).set(true); - }); + this._registerCommands().then(() => TaskCommandsRegistered.bindTo(this._contextKeyService).set(true)); this._configurationResolverService.contributeVariable('defaultBuildTask', async (): Promise => { let tasks = await this._getTasksForGroup(TaskGroup.Build); if (tasks.length > 0) { @@ -734,16 +732,15 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } // We didn't find the task, so we need to ask all resolvers about it - return this._getGroupedTasks().then((map) => { - let values = map.get(folder); - values = values.concat(map.get(USER_TASKS_GROUP_KEY)); + const map = await this._getGroupedTasks(); + let values = map.get(folder); + values = values.concat(map.get(USER_TASKS_GROUP_KEY)); - if (!values) { - return undefined; - } - values = values.filter(task => task.matches(key, compareId)).sort(task => task._source.kind === TaskSourceKind.Extension ? 1 : -1); - return values.length > 0 ? values[0] : undefined; - }); + if (!values) { + return undefined; + } + values = values.filter(task => task.matches(key, compareId)).sort(task => task._source.kind === TaskSourceKind.Extension ? 1 : -1); + return values.length > 0 ? values[0] : undefined; } public async tryResolveTask(configuringTask: ConfiguringTask): Promise { @@ -1125,21 +1122,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (tryBuildShortcut) { return tryBuildShortcut; } - - return this._getGroupedTasks().then((tasks) => { - const runnable = this._createRunnableTask(tasks, TaskGroup.Build); - if (!runnable || !runnable.task) { - if (this.schemaVersion === JsonSchemaVersion.V0_1_0) { - throw new TaskError(Severity.Info, nls.localize('TaskService.noBuildTask1', 'No build task defined. Mark a task with \'isBuildCommand\' in the tasks.json file.'), TaskErrors.NoBuildTask); - } else { - throw new TaskError(Severity.Info, nls.localize('TaskService.noBuildTask2', 'No build task defined. Mark a task with as a \'build\' group in the tasks.json file.'), TaskErrors.NoBuildTask); - } - } - return this._executeTask(runnable.task, runnable.resolver, TaskRunSource.User); - }).then(value => value, (error) => { - this._handleError(error); - return Promise.reject(error); - }); + return this._getGroupedTasksAndExecute(); } private async _runTest(): Promise { @@ -1148,20 +1131,35 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return tryTestShortcut; } - return this._getGroupedTasks().then((tasks) => { - const runnable = this._createRunnableTask(tasks, TaskGroup.Test); - if (!runnable || !runnable.task) { + return this._getGroupedTasksAndExecute(true); + } + + private async _getGroupedTasksAndExecute(test?: boolean): Promise { + const tasks = await this._getGroupedTasks(); + const runnable = this._createRunnableTask(tasks, test ? TaskGroup.Test : TaskGroup.Build); + if (!runnable || !runnable.task) { + if (test) { if (this.schemaVersion === JsonSchemaVersion.V0_1_0) { throw new TaskError(Severity.Info, nls.localize('TaskService.noTestTask1', 'No test task defined. Mark a task with \'isTestCommand\' in the tasks.json file.'), TaskErrors.NoTestTask); } else { throw new TaskError(Severity.Info, nls.localize('TaskService.noTestTask2', 'No test task defined. Mark a task with as a \'test\' group in the tasks.json file.'), TaskErrors.NoTestTask); } + } else { + if (this.schemaVersion === JsonSchemaVersion.V0_1_0) { + throw new TaskError(Severity.Info, nls.localize('TaskService.noBuildTask1', 'No build task defined. Mark a task with \'isBuildCommand\' in the tasks.json file.'), TaskErrors.NoBuildTask); + } else { + throw new TaskError(Severity.Info, nls.localize('TaskService.noBuildTask2', 'No build task defined. Mark a task with as a \'build\' group in the tasks.json file.'), TaskErrors.NoBuildTask); + } } - return this._executeTask(runnable.task, runnable.resolver, TaskRunSource.User); - }).then(value => value, (error) => { + } + let executeTaskResult: ITaskSummary; + try { + executeTaskResult = await this._executeTask(runnable.task, runnable.resolver, TaskRunSource.User); + } catch (error) { this._handleError(error); return Promise.reject(error); - }); + } + return executeTaskResult; } public async run(task: Task | undefined, options?: IProblemMatcherRunOptions, runSource: TaskRunSource = TaskRunSource.System): Promise { @@ -1172,31 +1170,26 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (!task) { throw new TaskError(Severity.Info, nls.localize('TaskServer.noTask', 'Task to execute is undefined'), TaskErrors.TaskNotFound); } - - return new Promise((resolve) => { - const resolver = this._createResolver(); + const resolver = this._createResolver(); + let executeTaskResult: ITaskSummary | undefined; + try { if (options && options.attachProblemMatcher && this._shouldAttachProblemMatcher(task) && !InMemoryTask.is(task)) { - this._attachProblemMatcher(task).then(toExecute => { - if (toExecute) { - resolve(this._executeTask(toExecute, resolver, runSource)); - } else { - resolve(undefined); - } - }); + const taskToExecute = await this._attachProblemMatcher(task); + if (taskToExecute) { + executeTaskResult = await this._executeTask(taskToExecute, resolver, runSource); + } } else { - resolve(this._executeTask(task, resolver, runSource)); + executeTaskResult = await this._executeTask(task, resolver, runSource); } - }).then((value) => { if (runSource === TaskRunSource.User) { - this.getWorkspaceTasks().then(workspaceTasks => { - RunAutomaticTasks.promptForPermission(this, this._storageService, this._notificationService, this._workspaceTrustManagementService, this._openerService, this._configurationService, workspaceTasks); - }); + const workspaceTasks = await this.getWorkspaceTasks(); + RunAutomaticTasks.promptForPermission(this, this._storageService, this._notificationService, this._workspaceTrustManagementService, this._openerService, this._configurationService, workspaceTasks); } - return value; - }, (error) => { + return executeTaskResult; + } catch (error) { this._handleError(error); return Promise.reject(error); - }); + } } private _isProvideTasksEnabled(): boolean { @@ -1266,7 +1259,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return this._configurationService.updateValue(PROBLEM_MATCHER_NEVER_CONFIG, newValue); } - private _attachProblemMatcher(task: ContributedTask | CustomTask): Promise { + private async _attachProblemMatcher(task: ContributedTask | CustomTask): Promise { interface IProblemMatcherPickEntry extends IQuickPickItem { matcher: INamedProblemMatcher | undefined; never?: boolean; @@ -1289,77 +1282,73 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); } } - if (entries.length > 0) { - entries = entries.sort((a, b) => { - if (a.label && b.label) { - return a.label.localeCompare(b.label); - } else { - return 0; - } - }); - entries.unshift({ type: 'separator', label: nls.localize('TaskService.associate', 'associate') }); - let taskType: string; - if (CustomTask.is(task)) { - const configProperties: TaskConfig.IConfigurationProperties = task._source.config.element; - taskType = (configProperties).type; - } else { - taskType = task.getDefinition().type; - } - entries.unshift( - { label: nls.localize('TaskService.attachProblemMatcher.continueWithout', 'Continue without scanning the task output'), matcher: undefined }, - { label: nls.localize('TaskService.attachProblemMatcher.never', 'Never scan the task output for this task'), matcher: undefined, never: true }, - { label: nls.localize('TaskService.attachProblemMatcher.neverType', 'Never scan the task output for {0} tasks', taskType), matcher: undefined, setting: taskType }, - { label: nls.localize('TaskService.attachProblemMatcher.learnMoreAbout', 'Learn more about scanning the task output'), matcher: undefined, learnMore: true } - ); - return this._quickInputService.pick(entries, { - placeHolder: nls.localize('selectProblemMatcher', 'Select for which kind of errors and warnings to scan the task output'), - }).then(async (selected) => { - if (selected) { - if (selected.learnMore) { - this._openDocumentation(); - return undefined; - } else if (selected.never) { - this.customize(task, { problemMatcher: [] }, true); - return task; - } else if (selected.matcher) { - const newTask = task.clone(); - const matcherReference = `$${selected.matcher.name}`; - const properties: ICustomizationProperties = { problemMatcher: [matcherReference] }; - newTask.configurationProperties.problemMatchers = [matcherReference]; - const matcher = ProblemMatcherRegistry.get(selected.matcher.name); - if (matcher && matcher.watching !== undefined) { - properties.isBackground = true; - newTask.configurationProperties.isBackground = true; - } - this.customize(task, properties, true); - return newTask; - } else if (selected.setting) { - await this._updateNeverProblemMatcherSetting(selected.setting); - return task; - } else { - return task; - } - } else { - return undefined; - } - }); + if (entries.length === 0) { + return; } - return Promise.resolve(task); + entries = entries.sort((a, b) => { + if (a.label && b.label) { + return a.label.localeCompare(b.label); + } else { + return 0; + } + }); + entries.unshift({ type: 'separator', label: nls.localize('TaskService.associate', 'associate') }); + let taskType: string; + if (CustomTask.is(task)) { + const configProperties: TaskConfig.IConfigurationProperties = task._source.config.element; + taskType = (configProperties).type; + } else { + taskType = task.getDefinition().type; + } + entries.unshift( + { label: nls.localize('TaskService.attachProblemMatcher.continueWithout', 'Continue without scanning the task output'), matcher: undefined }, + { label: nls.localize('TaskService.attachProblemMatcher.never', 'Never scan the task output for this task'), matcher: undefined, never: true }, + { label: nls.localize('TaskService.attachProblemMatcher.neverType', 'Never scan the task output for {0} tasks', taskType), matcher: undefined, setting: taskType }, + { label: nls.localize('TaskService.attachProblemMatcher.learnMoreAbout', 'Learn more about scanning the task output'), matcher: undefined, learnMore: true } + ); + const problemMatcher = await this._quickInputService.pick(entries, { placeHolder: nls.localize('selectProblemMatcher', 'Select for which kind of errors and warnings to scan the task output') }); + if (!problemMatcher) { + return task; + } + if (problemMatcher.learnMore) { + this._openDocumentation(); + return undefined; + } + if (problemMatcher.never) { + this.customize(task, { problemMatcher: [] }, true); + return task; + } + if (problemMatcher.matcher) { + const newTask = task.clone(); + const matcherReference = `$${problemMatcher.matcher.name}`; + const properties: ICustomizationProperties = { problemMatcher: [matcherReference] }; + newTask.configurationProperties.problemMatchers = [matcherReference]; + const matcher = ProblemMatcherRegistry.get(problemMatcher.matcher.name); + if (matcher && matcher.watching !== undefined) { + properties.isBackground = true; + newTask.configurationProperties.isBackground = true; + } + this.customize(task, properties, true); + return newTask; + } + if (problemMatcher.setting) { + await this._updateNeverProblemMatcherSetting(problemMatcher.setting); + } + return task; } - private _getTasksForGroup(group: TaskGroup): Promise { - return this._getGroupedTasks().then((groups) => { - const result: Task[] = []; - groups.forEach((tasks) => { - for (const task of tasks) { - const configTaskGroup = TaskGroup.from(task.configurationProperties.group); - if (configTaskGroup?._id === group._id) { - result.push(task); - } + private async _getTasksForGroup(group: TaskGroup): Promise { + const groups = await this._getGroupedTasks(); + const result: Task[] = []; + groups.forEach(tasks => { + for (const task of tasks) { + const configTaskGroup = TaskGroup.from(task.configurationProperties.group); + if (configTaskGroup?._id === group._id) { + result.push(task); } - }); - return result; + } }); + return result; } public needsFolderQualification(): boolean { @@ -1398,58 +1387,56 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return stringValue; } - private _openEditorAtTask(resource: URI | undefined, task: TaskConfig.ICustomTask | TaskConfig.IConfiguringTask | string | undefined, configIndex: number = -1): Promise { + private async _openEditorAtTask(resource: URI | undefined, task: TaskConfig.ICustomTask | TaskConfig.IConfiguringTask | string | undefined, configIndex: number = -1): Promise { if (resource === undefined) { return Promise.resolve(false); } - let selection: ITextEditorSelection | undefined; - return this._fileService.readFile(resource).then(content => content.value).then(async content => { - if (!content) { - return false; + const fileContent = await this._fileService.readFile(resource); + const content = fileContent.value; + if (!content || !task) { + return false; + } + const contentValue = content.toString(); + let stringValue: string | undefined; + if (configIndex !== -1) { + const json: TaskConfig.IExternalTaskRunnerConfiguration = this._configurationService.getValue('tasks', { resource }); + if (json.tasks && (json.tasks.length > configIndex)) { + stringValue = await this._formatTaskForJson(resource, json.tasks[configIndex]); } - if (task) { - const contentValue = content.toString(); - let stringValue: string | undefined; - if (configIndex !== -1) { - const json: TaskConfig.IExternalTaskRunnerConfiguration = this._configurationService.getValue('tasks', { resource }); - if (json.tasks && (json.tasks.length > configIndex)) { - stringValue = await this._formatTaskForJson(resource, json.tasks[configIndex]); - } - } - if (!stringValue) { - if (typeof task === 'string') { - stringValue = task; - } else { - stringValue = await this._formatTaskForJson(resource, task); - } - } - - const index = contentValue.indexOf(stringValue); - let startLineNumber = 1; - for (let i = 0; i < index; i++) { - if (contentValue.charAt(i) === '\n') { - startLineNumber++; - } - } - let endLineNumber = startLineNumber; - for (let i = 0; i < stringValue.length; i++) { - if (stringValue.charAt(i) === '\n') { - endLineNumber++; - } - } - selection = startLineNumber > 1 ? { startLineNumber, startColumn: startLineNumber === endLineNumber ? 4 : 3, endLineNumber, endColumn: startLineNumber === endLineNumber ? undefined : 4 } : undefined; + } + if (!stringValue) { + if (typeof task === 'string') { + stringValue = task; + } else { + stringValue = await this._formatTaskForJson(resource, task); } + } - return this._editorService.openEditor({ - resource, - options: { - pinned: false, - forceReload: true, // because content might have changed - selection, - selectionRevealType: TextEditorSelectionRevealType.CenterIfOutsideViewport - } - }).then(() => !!selection); + const index = contentValue.indexOf(stringValue); + let startLineNumber = 1; + for (let i = 0; i < index; i++) { + if (contentValue.charAt(i) === '\n') { + startLineNumber++; + } + } + let endLineNumber = startLineNumber; + for (let i = 0; i < stringValue.length; i++) { + if (stringValue.charAt(i) === '\n') { + endLineNumber++; + } + } + const selection = startLineNumber > 1 ? { startLineNumber, startColumn: startLineNumber === endLineNumber ? 4 : 3, endLineNumber, endColumn: startLineNumber === endLineNumber ? undefined : 4 } : undefined; + + await this._editorService.openEditor({ + resource, + options: { + pinned: false, + forceReload: true, // because content might have changed + selection, + selectionRevealType: TextEditorSelectionRevealType.CenterIfOutsideViewport + } }); + return !!selection; } private _createCustomizableTask(task: ContributedTask | CustomTask | ConfiguringTask): TaskConfig.ICustomTask | TaskConfig.IConfiguringTask | undefined { @@ -1515,7 +1502,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } } - let promise: Promise | undefined; if (!fileConfig) { const value = { version: '2.0.0', @@ -1529,16 +1515,16 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (editorConfig.editor.insertSpaces) { content = content.replace(/(\n)(\t+)/g, (_, s1, s2) => s1 + ' '.repeat(s2.length * editorConfig.editor.tabSize)); } - promise = this._textFileService.create([{ resource: workspaceFolder.toResource('.vscode/tasks.json'), value: content }]).then(() => { }); + await this._textFileService.create([{ resource: workspaceFolder.toResource('.vscode/tasks.json'), value: content }]); } else { // We have a global task configuration if ((index === -1) && properties) { if (properties.problemMatcher !== undefined) { fileConfig.problemMatcher = properties.problemMatcher; - promise = this._writeConfiguration(workspaceFolder, 'tasks.problemMatchers', fileConfig.problemMatcher, task._source.kind); + await this._writeConfiguration(workspaceFolder, 'tasks.problemMatchers', fileConfig.problemMatcher, task._source.kind); } else if (properties.group !== undefined) { fileConfig.group = properties.group; - promise = this._writeConfiguration(workspaceFolder, 'tasks.group', fileConfig.group, task._source.kind); + await this._writeConfiguration(workspaceFolder, 'tasks.group', fileConfig.group, task._source.kind); } } else { if (!Array.isArray(fileConfig.tasks)) { @@ -1549,17 +1535,13 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } else { fileConfig.tasks[index] = toCustomize; } - promise = this._writeConfiguration(workspaceFolder, 'tasks.tasks', fileConfig.tasks, task._source.kind); + await this._writeConfiguration(workspaceFolder, 'tasks.tasks', fileConfig.tasks, task._source.kind); } } - if (!promise) { - return Promise.resolve(undefined); + + if (openConfig) { + this._openEditorAtTask(this._getResourceForTask(task), toCustomize); } - return promise.then(() => { - if (openConfig) { - this._openEditorAtTask(this._getResourceForTask(task), toCustomize); - } - }); } private _writeConfiguration(workspaceFolder: IWorkspaceFolder, key: string, value: any, source?: string): Promise | undefined { @@ -1873,20 +1855,20 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return executeResult.promise; } - private _restart(task: Task): void { + private async _restart(task: Task): Promise { if (!this._taskSystem) { return; } - this._taskSystem.terminate(task).then((response) => { - if (response.success) { - this.run(task).then(undefined, reason => { - // eat the error, it has already been surfaced to the user and we don't care about it here - }); - } else { - this._notificationService.warn(nls.localize('TaskSystem.restartFailed', 'Failed to terminate and restart task {0}', Types.isString(task) ? task : task.configurationProperties.name)); + const response = await this._taskSystem.terminate(task); + if (response.success) { + try { + await this.run(task); + } catch { + // eat the error, we don't care about it here } - return response; - }); + } else { + this._notificationService.warn(nls.localize('TaskSystem.restartFailed', 'Failed to terminate and restart task {0}', Types.isString(task) ? task : task.configurationProperties.name)); + } } public async terminate(task: Task): Promise { @@ -1939,222 +1921,222 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return !definition || !definition.when || this._contextKeyService.contextMatchesRules(definition.when); } - private _getGroupedTasks(type?: string): Promise { + private async _getGroupedTasks(type?: string): Promise { const needsRecentTasksMigration = this._needsRecentTasksMigration(); - return this._activateTaskProviders(type).then(() => { - const validTypes: IStringDictionary = Object.create(null); - TaskDefinitionRegistry.all().forEach(definition => validTypes[definition.taskType] = true); - validTypes['shell'] = true; - validTypes['process'] = true; - return new Promise(resolve => { - const result: ITaskSet[] = []; - let counter: number = 0; - const done = (value: ITaskSet | undefined) => { - if (value) { - result.push(value); + await this._activateTaskProviders(type); + const validTypes: IStringDictionary = Object.create(null); + TaskDefinitionRegistry.all().forEach(definition => validTypes[definition.taskType] = true); + validTypes['shell'] = true; + validTypes['process'] = true; + const contributedTaskSets = await new Promise(resolve => { + const result: ITaskSet[] = []; + let counter: number = 0; + const done = (value: ITaskSet | undefined) => { + if (value) { + result.push(value); + } + if (--counter === 0) { + resolve(result); + } + }; + const error = (error: any) => { + try { + if (error && Types.isString(error.message)) { + this._outputChannel.append('Error: '); + this._outputChannel.append(error.message); + this._outputChannel.append('\n'); + this._showOutput(); + } else { + this._outputChannel.append('Unknown error received while collecting tasks from providers.\n'); + this._showOutput(); } + } finally { if (--counter === 0) { resolve(result); } - }; - const error = (error: any) => { - try { - if (error && Types.isString(error.message)) { - this._outputChannel.append('Error: '); - this._outputChannel.append(error.message); - this._outputChannel.append('\n'); - this._showOutput(); - } else { - this._outputChannel.append('Unknown error received while collecting tasks from providers.\n'); - this._showOutput(); + } + }; + if (this._isProvideTasksEnabled() && (this.schemaVersion === JsonSchemaVersion.V2_0_0) && (this._providers.size > 0)) { + let foundAnyProviders = false; + for (const [handle, provider] of this._providers) { + const providerType = this._providerTypes.get(handle); + if ((type === undefined) || (type === providerType)) { + if (providerType && !this._isTaskProviderEnabled(providerType)) { + continue; } - } finally { - if (--counter === 0) { - resolve(result); - } - } - }; - if (this._isProvideTasksEnabled() && (this.schemaVersion === JsonSchemaVersion.V2_0_0) && (this._providers.size > 0)) { - let foundAnyProviders = false; - for (const [handle, provider] of this._providers) { - const providerType = this._providerTypes.get(handle); - if ((type === undefined) || (type === providerType)) { - if (providerType && !this._isTaskProviderEnabled(providerType)) { - continue; - } - foundAnyProviders = true; - counter++; - provider.provideTasks(validTypes).then((taskSet: ITaskSet) => { - // Check that the tasks provided are of the correct type - for (const task of taskSet.tasks) { - if (task.type !== this._providerTypes.get(handle)) { - this._outputChannel.append(nls.localize('unexpectedTaskType', "The task provider for \"{0}\" tasks unexpectedly provided a task of type \"{1}\".\n", this._providerTypes.get(handle), task.type)); - if ((task.type !== 'shell') && (task.type !== 'process')) { - this._showOutput(); - } - break; + foundAnyProviders = true; + counter++; + provider.provideTasks(validTypes).then((taskSet: ITaskSet) => { + // Check that the tasks provided are of the correct type + for (const task of taskSet.tasks) { + if (task.type !== this._providerTypes.get(handle)) { + this._outputChannel.append(nls.localize('unexpectedTaskType', "The task provider for \"{0}\" tasks unexpectedly provided a task of type \"{1}\".\n", this._providerTypes.get(handle), task.type)); + if ((task.type !== 'shell') && (task.type !== 'process')) { + this._showOutput(); } + break; } - return done(taskSet); - }, error); - } + } + return done(taskSet); + }, error); } - if (!foundAnyProviders) { - resolve(result); - } - } else { + } + if (!foundAnyProviders) { resolve(result); } - }); - }).then((contributedTaskSets) => { - const result: TaskMap = new TaskMap(); - const contributedTasks: TaskMap = new TaskMap(); + } else { + resolve(result); + } + }); - for (const set of contributedTaskSets) { - for (const task of set.tasks) { - const workspaceFolder = task.getWorkspaceFolder(); - if (workspaceFolder) { - contributedTasks.add(workspaceFolder, task); - } + const result: TaskMap = new TaskMap(); + const contributedTasks: TaskMap = new TaskMap(); + + for (const set of contributedTaskSets) { + for (const task of set.tasks) { + const workspaceFolder = task.getWorkspaceFolder(); + if (workspaceFolder) { + contributedTasks.add(workspaceFolder, task); } } + } - return this.getWorkspaceTasks().then(async (customTasks) => { - const customTasksKeyValuePairs = Array.from(customTasks); - const customTasksPromises = customTasksKeyValuePairs.map(async ([key, folderTasks]) => { - const contributed = contributedTasks.get(key); - if (!folderTasks.set) { - if (contributed) { - result.add(key, ...contributed); - } - return; + try { + const customTasks = await this.getWorkspaceTasks(); + const customTasksKeyValuePairs = Array.from(customTasks); + const customTasksPromises = customTasksKeyValuePairs.map(async ([key, folderTasks]) => { + const contributed = contributedTasks.get(key); + if (!folderTasks.set) { + if (contributed) { + result.add(key, ...contributed); } + return; + } - if (this._contextService.getWorkbenchState() === WorkbenchState.EMPTY) { - result.add(key, ...folderTasks.set.tasks); - } else { - const configurations = folderTasks.configurations; - const legacyTaskConfigurations = folderTasks.set ? this._getLegacyTaskConfigurations(folderTasks.set) : undefined; - const customTasksToDelete: Task[] = []; - if (configurations || legacyTaskConfigurations) { - const unUsedConfigurations: Set = new Set(); - if (configurations) { - Object.keys(configurations.byIdentifier).forEach(key => unUsedConfigurations.add(key)); + if (this._contextService.getWorkbenchState() === WorkbenchState.EMPTY) { + result.add(key, ...folderTasks.set.tasks); + } else { + const configurations = folderTasks.configurations; + const legacyTaskConfigurations = folderTasks.set ? this._getLegacyTaskConfigurations(folderTasks.set) : undefined; + const customTasksToDelete: Task[] = []; + if (configurations || legacyTaskConfigurations) { + const unUsedConfigurations: Set = new Set(); + if (configurations) { + Object.keys(configurations.byIdentifier).forEach(key => unUsedConfigurations.add(key)); + } + for (const task of contributed) { + if (!ContributedTask.is(task)) { + continue; } - for (const task of contributed) { - if (!ContributedTask.is(task)) { - continue; - } - if (configurations) { - const configuringTask = configurations.byIdentifier[task.defines._key]; - if (configuringTask) { - unUsedConfigurations.delete(task.defines._key); - result.add(key, TaskConfig.createCustomTask(task, configuringTask)); - } else { - result.add(key, task); - } - } else if (legacyTaskConfigurations) { - const configuringTask = legacyTaskConfigurations[task.defines._key]; - if (configuringTask) { - result.add(key, TaskConfig.createCustomTask(task, configuringTask)); - customTasksToDelete.push(configuringTask); - } else { - result.add(key, task); - } + if (configurations) { + const configuringTask = configurations.byIdentifier[task.defines._key]; + if (configuringTask) { + unUsedConfigurations.delete(task.defines._key); + result.add(key, TaskConfig.createCustomTask(task, configuringTask)); } else { result.add(key, task); } - } - if (customTasksToDelete.length > 0) { - const toDelete = customTasksToDelete.reduce>((map, task) => { - map[task._id] = true; - return map; - }, Object.create(null)); - for (const task of folderTasks.set.tasks) { - if (toDelete[task._id]) { - continue; - } + } else if (legacyTaskConfigurations) { + const configuringTask = legacyTaskConfigurations[task.defines._key]; + if (configuringTask) { + result.add(key, TaskConfig.createCustomTask(task, configuringTask)); + customTasksToDelete.push(configuringTask); + } else { result.add(key, task); } } else { - result.add(key, ...folderTasks.set.tasks); + result.add(key, task); } - - const unUsedConfigurationsAsArray = Array.from(unUsedConfigurations); - - const unUsedConfigurationPromises = unUsedConfigurationsAsArray.map(async (value) => { - const configuringTask = configurations!.byIdentifier[value]; - if (type && (type !== configuringTask.configures.type)) { - return; + } + if (customTasksToDelete.length > 0) { + const toDelete = customTasksToDelete.reduce>((map, task) => { + map[task._id] = true; + return map; + }, Object.create(null)); + for (const task of folderTasks.set.tasks) { + if (toDelete[task._id]) { + continue; } - - let requiredTaskProviderUnavailable: boolean = false; - - for (const [handle, provider] of this._providers) { - const providerType = this._providerTypes.get(handle); - if (configuringTask.type === providerType) { - if (providerType && !this._isTaskProviderEnabled(providerType)) { - requiredTaskProviderUnavailable = true; - continue; - } - - try { - const resolvedTask = await provider.resolveTask(configuringTask); - if (resolvedTask && (resolvedTask._id === configuringTask._id)) { - result.add(key, TaskConfig.createCustomTask(resolvedTask, configuringTask)); - return; - } - } catch (error) { - // Ignore errors. The task could not be provided by any of the providers. - } - } - } - - if (requiredTaskProviderUnavailable) { - this._outputChannel.append(nls.localize( - 'TaskService.providerUnavailable', - 'Warning: {0} tasks are unavailable in the current environment.\n', - configuringTask.configures.type - )); - } else { - this._outputChannel.append(nls.localize( - 'TaskService.noConfiguration', - 'Error: The {0} task detection didn\'t contribute a task for the following configuration:\n{1}\nThe task will be ignored.\n', - configuringTask.configures.type, - JSON.stringify(configuringTask._source.config.element, undefined, 4) - )); - this._showOutput(); - } - }); - - await Promise.all(unUsedConfigurationPromises); + result.add(key, task); + } } else { result.add(key, ...folderTasks.set.tasks); - result.add(key, ...contributed); } - } - }); - await Promise.all(customTasksPromises); - if (needsRecentTasksMigration) { - // At this point we have all the tasks and can migrate the recently used tasks. - await this._migrateRecentTasks(result.all()); - } - return result; - }, () => { - // If we can't read the tasks.json file provide at least the contributed tasks - const result: TaskMap = new TaskMap(); - for (const set of contributedTaskSets) { - for (const task of set.tasks) { - const folder = task.getWorkspaceFolder(); - if (folder) { - result.add(folder, task); - } + const unUsedConfigurationsAsArray = Array.from(unUsedConfigurations); + + const unUsedConfigurationPromises = unUsedConfigurationsAsArray.map(async (value) => { + const configuringTask = configurations!.byIdentifier[value]; + if (type && (type !== configuringTask.configures.type)) { + return; + } + + let requiredTaskProviderUnavailable: boolean = false; + + for (const [handle, provider] of this._providers) { + const providerType = this._providerTypes.get(handle); + if (configuringTask.type === providerType) { + if (providerType && !this._isTaskProviderEnabled(providerType)) { + requiredTaskProviderUnavailable = true; + continue; + } + + try { + const resolvedTask = await provider.resolveTask(configuringTask); + if (resolvedTask && (resolvedTask._id === configuringTask._id)) { + result.add(key, TaskConfig.createCustomTask(resolvedTask, configuringTask)); + return; + } + } catch (error) { + // Ignore errors. The task could not be provided by any of the providers. + } + } + } + + if (requiredTaskProviderUnavailable) { + this._outputChannel.append(nls.localize( + 'TaskService.providerUnavailable', + 'Warning: {0} tasks are unavailable in the current environment.\n', + configuringTask.configures.type + )); + } else { + this._outputChannel.append(nls.localize( + 'TaskService.noConfiguration', + 'Error: The {0} task detection didn\'t contribute a task for the following configuration:\n{1}\nThe task will be ignored.\n', + configuringTask.configures.type, + JSON.stringify(configuringTask._source.config.element, undefined, 4) + )); + this._showOutput(); + } + }); + + await Promise.all(unUsedConfigurationPromises); + } else { + result.add(key, ...folderTasks.set.tasks); + result.add(key, ...contributed); } } - return result; }); - }); + + await Promise.all(customTasksPromises); + if (needsRecentTasksMigration) { + // At this point we have all the tasks and can migrate the recently used tasks. + await this._migrateRecentTasks(result.all()); + } + return result; + } catch { + // If we can't read the tasks.json file provide at least the contributed tasks + const result: TaskMap = new TaskMap(); + for (const set of contributedTaskSets) { + for (const task of set.tasks) { + const folder = task.getWorkspaceFolder(); + if (folder) { + result.add(folder, task); + } + } + } + return result; + } } private _getLegacyTaskConfigurations(workspaceTasks: ITaskSet): IStringDictionary | undefined { @@ -2208,75 +2190,69 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return folder; } - protected _computeWorkspaceTasks(runSource: TaskRunSource = TaskRunSource.User): Promise> { + protected async _computeWorkspaceTasks(runSource: TaskRunSource = TaskRunSource.User): Promise> { const promises: Promise[] = []; for (const folder of this.workspaceFolders) { promises.push(this._computeWorkspaceFolderTasks(folder, runSource).then((value) => value, () => undefined)); } - return Promise.all(promises).then(async (values) => { - const result = new Map(); - for (const value of values) { - if (value) { - result.set(value.workspaceFolder.uri.toString(), value); - } + const values = await Promise.all(promises); + const result = new Map(); + for (const value of values) { + if (value) { + result.set(value.workspaceFolder.uri.toString(), value); } + } - const folder = await this._getAFolder(); - if (this._contextService.getWorkbenchState() !== WorkbenchState.EMPTY) { - const workspaceFileTasks = await this._computeWorkspaceFileTasks(folder, runSource).then((value) => value, () => undefined); - if (workspaceFileTasks && this._workspace && this._workspace.configuration) { - result.set(this._workspace.configuration.toString(), workspaceFileTasks); - } + const folder = await this._getAFolder(); + if (this._contextService.getWorkbenchState() !== WorkbenchState.EMPTY) { + const workspaceFileTasks = await this._computeWorkspaceFileTasks(folder, runSource).then((value) => value, () => undefined); + if (workspaceFileTasks && this._workspace && this._workspace.configuration) { + result.set(this._workspace.configuration.toString(), workspaceFileTasks); } + } - const userTasks = await this._computeUserTasks(folder, runSource).then((value) => value, () => undefined); - if (userTasks) { - result.set(USER_TASKS_GROUP_KEY, userTasks); - } - return result; - }); + const userTasks = await this._computeUserTasks(folder, runSource).then((value) => value, () => undefined); + if (userTasks) { + result.set(USER_TASKS_GROUP_KEY, userTasks); + } + return result; } private get _jsonTasksSupported(): boolean { return ShellExecutionSupportedContext.getValue(this._contextKeyService) === true && ProcessExecutionSupportedContext.getValue(this._contextKeyService) === true; } - private _computeWorkspaceFolderTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise { - return (this._executionEngine === ExecutionEngine.Process - ? this._computeLegacyConfiguration(workspaceFolder) - : this._computeConfiguration(workspaceFolder)). - then((workspaceFolderConfiguration) => { - if (!workspaceFolderConfiguration || !workspaceFolderConfiguration.config || workspaceFolderConfiguration.hasErrors) { - return Promise.resolve({ workspaceFolder, set: undefined, configurations: undefined, hasErrors: workspaceFolderConfiguration ? workspaceFolderConfiguration.hasErrors : false }); - } - return ProblemMatcherRegistry.onReady().then(async (): Promise => { - const taskSystemInfo: ITaskSystemInfo | undefined = this._getTaskSystemInfo(workspaceFolder.uri.scheme); - const problemReporter = new ProblemReporter(this._outputChannel); - const parseResult = TaskConfig.parse(workspaceFolder, undefined, taskSystemInfo ? taskSystemInfo.platform : Platform.platform, workspaceFolderConfiguration.config!, problemReporter, TaskConfig.TaskConfigSource.TasksJson, this._contextKeyService); - let hasErrors = false; - if (!parseResult.validationStatus.isOK() && (parseResult.validationStatus.state !== ValidationState.Info)) { - hasErrors = true; - this._showOutput(runSource); - } - if (problemReporter.status.isFatal()) { - problemReporter.fatal(nls.localize('TaskSystem.configurationErrors', 'Error: the provided task configuration has validation errors and can\'t not be used. Please correct the errors first.')); - return { workspaceFolder, set: undefined, configurations: undefined, hasErrors }; - } - let customizedTasks: { byIdentifier: IStringDictionary } | undefined; - if (parseResult.configured && parseResult.configured.length > 0) { - customizedTasks = { - byIdentifier: Object.create(null) - }; - for (const task of parseResult.configured) { - customizedTasks.byIdentifier[task.configures._key] = task; - } - } - if (!this._jsonTasksSupported && (parseResult.custom.length > 0)) { - console.warn('Custom workspace tasks are not supported.'); - } - return { workspaceFolder, set: { tasks: this._jsonTasksSupported ? parseResult.custom : [] }, configurations: customizedTasks, hasErrors }; - }); - }); + private async _computeWorkspaceFolderTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise { + const workspaceFolderConfiguration = (this._executionEngine === ExecutionEngine.Process ? await this._computeLegacyConfiguration(workspaceFolder) : await this._computeConfiguration(workspaceFolder)); + if (!workspaceFolderConfiguration || !workspaceFolderConfiguration.config || workspaceFolderConfiguration.hasErrors) { + return Promise.resolve({ workspaceFolder, set: undefined, configurations: undefined, hasErrors: workspaceFolderConfiguration ? workspaceFolderConfiguration.hasErrors : false }); + } + await ProblemMatcherRegistry.onReady(); + const taskSystemInfo: ITaskSystemInfo | undefined = this._getTaskSystemInfo(workspaceFolder.uri.scheme); + const problemReporter = new ProblemReporter(this._outputChannel); + const parseResult = TaskConfig.parse(workspaceFolder, undefined, taskSystemInfo ? taskSystemInfo.platform : Platform.platform, workspaceFolderConfiguration.config!, problemReporter, TaskConfig.TaskConfigSource.TasksJson, this._contextKeyService); + let hasErrors = false; + if (!parseResult.validationStatus.isOK() && (parseResult.validationStatus.state !== ValidationState.Info)) { + hasErrors = true; + this._showOutput(runSource); + } + if (problemReporter.status.isFatal()) { + problemReporter.fatal(nls.localize('TaskSystem.configurationErrors', 'Error: the provided task configuration has validation errors and can\'t not be used. Please correct the errors first.')); + return { workspaceFolder, set: undefined, configurations: undefined, hasErrors }; + } + let customizedTasks: { byIdentifier: IStringDictionary } | undefined; + if (parseResult.configured && parseResult.configured.length > 0) { + customizedTasks = { + byIdentifier: Object.create(null) + }; + for (const task of parseResult.configured) { + customizedTasks.byIdentifier[task.configures._key] = task; + } + } + if (!this._jsonTasksSupported && (parseResult.custom.length > 0)) { + console.warn('Custom workspace tasks are not supported.'); + } + return { workspaceFolder, set: { tasks: this._jsonTasksSupported ? parseResult.custom : [] }, configurations: customizedTasks, hasErrors }; } private _testParseExternalConfig(config: TaskConfig.IExternalTaskRunnerConfiguration | undefined, location: string): { config: TaskConfig.IExternalTaskRunnerConfiguration | undefined; hasParseErrors: boolean } { @@ -2639,13 +2615,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private async _showQuickPick(tasks: Promise | Task[], placeHolder: string, defaultEntry?: ITaskQuickPickEntry, group: boolean = false, sort: boolean = false, selectedEntry?: ITaskQuickPickEntry, additionalEntries?: ITaskQuickPickEntry[], filter?: string): Promise { const tokenSource = new CancellationTokenSource(); const cancellationToken: CancellationToken = tokenSource.token; - const createEntries = new Promise[]>((resolve) => { - if (Array.isArray(tasks)) { - resolve(this._createTaskQuickPickEntries(tasks, group, sort, selectedEntry)); - } else { - resolve(tasks.then((tasks) => this._createTaskQuickPickEntries(tasks, group, sort, selectedEntry))); - } - }); + const taskArray = Array.isArray(tasks) ? tasks : await tasks; + const createEntries = this._createTaskQuickPickEntries(taskArray, group, sort, selectedEntry); const timeout: boolean = await Promise.race([new Promise((resolve) => { createEntries.then(() => resolve(false)); @@ -2659,19 +2630,16 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (!timeout && ((await createEntries).length === 1) && this._configurationService.getValue(QUICKOPEN_SKIP_CONFIG)) { return ((await createEntries)[0]); } - - const pickEntries = createEntries.then((entries) => { - if ((entries.length === 1) && this._configurationService.getValue(QUICKOPEN_SKIP_CONFIG)) { - tokenSource.cancel(); - } else if ((entries.length === 0) && defaultEntry) { - entries.push(defaultEntry); - } else if (entries.length > 1 && additionalEntries && additionalEntries.length > 0) { - entries.push({ type: 'separator', label: '' }); - entries.push(additionalEntries[0]); - } - return entries; - }); - + //TODO: weird that this type doesn't exist already/ should be shared + const pickEntries: (ITaskQuickPickEntry | IQuickPickSeparator)[] = await createEntries; + if ((pickEntries.length === 1) && this._configurationService.getValue(QUICKOPEN_SKIP_CONFIG)) { + tokenSource.cancel(); + } else if ((pickEntries.length === 0) && defaultEntry) { + pickEntries.push(defaultEntry); + } else if (pickEntries.length > 1 && additionalEntries && additionalEntries.length > 0) { + pickEntries.push({ type: 'separator', label: '' }); + pickEntries.push(additionalEntries[0]); + } const picker: IQuickPick = this._quickInputService.createQuickPick(); picker.placeholder = placeHolder; picker.matchOnDescription = true; @@ -2685,10 +2653,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } }); picker.busy = true; - pickEntries.then(entries => { - picker.busy = false; - picker.items = entries; - }); + picker.busy = false; + picker.items = pickEntries; picker.show(); if (filter) { picker.value = filter; From e369a2bca0c647c961a0901aaa75041025540008 Mon Sep 17 00:00:00 2001 From: Justin Chen <54879025+justschen@users.noreply.github.com> Date: Tue, 2 Aug 2022 17:18:11 -0700 Subject: [PATCH 171/303] Enabled Code Action Widget by default + disabled action hovers * added disabled hover * code cleanup on disabled option hovers * removed comments * widget enabled by default * code cleanup and fix on build * clean up on css removed unused importants * small patch for css rules * minor refactor on codeactionitems --- .../codeAction/browser/codeActionMenu.ts | 64 ++++++++++--------- .../browser/codeActionWidgetContribution.ts | 2 +- .../codeAction/browser/media/action.css | 21 +++--- 3 files changed, 44 insertions(+), 43 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts index aa51bc780af..9a583b49409 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts @@ -63,11 +63,8 @@ export interface CodeActionShowOptions { readonly fromLightbulb?: boolean; } export interface ICodeActionMenuItem { - title: string; - detail: string; action: IAction; - decoratorRight?: string; - isSeparator?: boolean; + isSeparator: boolean; isEnabled: boolean; isDocumentation: boolean; index: number; @@ -115,18 +112,34 @@ class CodeMenuRenderer implements IListRenderer { + const [accept, preview] = this.acceptKeybindings; + data.root.title = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Refactor, Shift+F2 to Preview"'] }, "{0} to Refactor, {1} to Preview", this.keybindingService.lookupKeybinding(accept)?.getLabel(), this.keybindingService.lookupKeybinding(preview)?.getLabel()); + }; + updateLabel(); + } + } + } data.text.textContent = text; - // data.detail.textContent = detail; - if (!isEnabled) { + if (!element.isEnabled) { data.root.classList.add('option-disabled'); data.root.style.backgroundColor = 'transparent !important'; } else { @@ -138,15 +151,6 @@ class CodeMenuRenderer implements IListRenderer { - const [accept, preview] = this.acceptKeybindings; - data.root.title = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Refactor, Shift+F2 to Preview"'] }, "{0} to Refactor, {1} to Preview", this.keybindingService.lookupKeybinding(accept)?.getLabel(), this.keybindingService.lookupKeybinding(preview)?.getLabel()); - // data.root.title = this.keybindingService.lookupKeybinding(accept)?.getLabel() + ' to Refactor, ' + this.keybindingService.lookupKeybinding(preview)?.getLabel() + ' to Preview'; - }; - updateLabel(); - } - } disposeTemplate(templateData: ICodeActionMenuTemplateData): void { templateData.disposables = dispose(templateData.disposables); @@ -162,7 +166,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { private viewItems: ICodeActionMenuItem[] = []; private focusedEnabledItem: number | undefined; private currSelectedItem: number | undefined; - private hasSeperator: boolean = false; + private hasSeparator: boolean = false; private block?: HTMLElement; public static readonly documentationID: string = '_documentation'; @@ -279,17 +283,15 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { // Populating the list widget and tracking enabled options. inputArray.forEach((item, index) => { + const currIsSeparator = item.class === 'separator'; - let isDocumentation = false; - if (item instanceof CodeActionAction) { - isDocumentation = item.action.kind === CodeActionMenu.documentationID; - } if (currIsSeparator) { - // set to true forever - this.hasSeperator = true; + // set to true forever because there is a separator + this.hasSeparator = true; } - const menuItem = { title: item.label, detail: item.tooltip, action: inputArray[index], isEnabled: item.enabled, isSeparator: currIsSeparator, index, isDocumentation }; + + const menuItem = { action: inputArray[index], isEnabled: item.enabled, isSeparator: currIsSeparator, index }; if (item.enabled) { this.viewItems.push(menuItem); } @@ -298,7 +300,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { this.codeActionList.value.splice(0, this.codeActionList.value.length, this.options); - const height = this.hasSeperator ? (inputArray.length - 1) * codeActionLineHeight + 10 : inputArray.length * codeActionLineHeight; + const height = this.hasSeparator ? (inputArray.length - 1) * codeActionLineHeight + 10 : inputArray.length * codeActionLineHeight; renderMenu.style.height = String(height) + 'px'; this.codeActionList.value.layout(height); @@ -409,7 +411,7 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { this.viewItems = []; this.focusedEnabledItem = 0; this.currSelectedItem = undefined; - this.hasSeperator = false; + this.hasSeparator = false; this._contextViewService.hideContextView({ source: this }); } diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionWidgetContribution.ts b/src/vs/editor/contrib/codeAction/browser/codeActionWidgetContribution.ts index 3e7c2df8fda..a65230f38a7 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionWidgetContribution.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionWidgetContribution.ts @@ -16,7 +16,7 @@ Registry.as(Extensions.Configuration).registerConfigurat tags: ['experimental'], scope: ConfigurationScope.LANGUAGE_OVERRIDABLE, description: nls.localize('codeActionWidget', "Enabling this adjusts how the code action menu is rendered."), - default: false, + default: true, }, } }); diff --git a/src/vs/editor/contrib/codeAction/browser/media/action.css b/src/vs/editor/contrib/codeAction/browser/media/action.css index 52faf076802..9d442e57d47 100644 --- a/src/vs/editor/contrib/codeAction/browser/media/action.css +++ b/src/vs/editor/contrib/codeAction/browser/media/action.css @@ -30,10 +30,10 @@ z-index: 5; /* make sure we are on top of the tree items */ content: ""; pointer-events: none; /* enable click through */ - outline: 0px solid !important; /* we still need to handle the empty tree or no focus item case */ - outline-width: 0px !important; - outline-style: none !important; - outline-offset: 0px !important; + outline: 0px solid; /* we still need to handle the empty tree or no focus item case */ + outline-width: 0px; + outline-style: none; + outline-offset: 0px; } .codeActionMenuWidget .monaco-list { @@ -44,11 +44,6 @@ border-width: 0px !important; } -/* .codeActionMenuWidget .monaco-list:not(.element-focus) { - border: none !important; - border-width: 0px !important; -} */ - .codeActionMenuWidget .monaco-list .monaco-scrollable-element .monaco-list-rows { height: 100% !important; } @@ -79,15 +74,19 @@ } .codeActionMenuWidget .monaco-list .option-disabled, -.codeActionMenuWidget .monaco-list .option-disabled .focused { - pointer-events: none; +.codeActionMenuWidget .monaco-list .option-disabled:before, +.codeActionMenuWidget .monaco-list .option-disabled .focused, +.codeActionMenuWidget .monaco-list .option-disabled .focused:before { + cursor: default !important; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; + background-color: var(--vscode-menu-background) !important; color: var(--vscode-disabledForeground) !important; + outline: 0px solid !important; } .codeActionMenuWidget .monaco-list .separator { From c48d775f05ff892c119fd57bb509d8ae5740a199 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 2 Aug 2022 18:46:22 -0700 Subject: [PATCH 172/303] Remove ReadonlyMapView (#156927) This types does not appear to be used anywhere --- src/vs/base/common/map.ts | 44 --------------------------------------- 1 file changed, 44 deletions(-) diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index 3710827d559..2a78f7afb18 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -1355,47 +1355,3 @@ export class LRUCache extends LinkedMap { } } } - -/** - * Wraps the map in type that only implements readonly properties. Useful - * in the extension host to prevent the consumer from making any mutations. - */ -export class ReadonlyMapView implements ReadonlyMap{ - readonly #source: ReadonlyMap; - - public get size() { - return this.#source.size; - } - - constructor(source: ReadonlyMap) { - this.#source = source; - } - - forEach(callbackfn: (value: V, key: K, map: ReadonlyMap) => void, thisArg?: any): void { - this.#source.forEach(callbackfn, thisArg); - } - - get(key: K): V | undefined { - return this.#source.get(key); - } - - has(key: K): boolean { - return this.#source.has(key); - } - - entries(): IterableIterator<[K, V]> { - return this.#source.entries(); - } - - keys(): IterableIterator { - return this.#source.keys(); - } - - values(): IterableIterator { - return this.#source.values(); - } - - [Symbol.iterator](): IterableIterator<[K, V]> { - return this.#source.entries(); - } -} From 0c7d70ea4fbb3856d9009fa5454b2818f1a393f4 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 2 Aug 2022 18:46:57 -0700 Subject: [PATCH 173/303] Remove IDataTransfer type (#156934) We can use the standard dom DataTransfer type instead --- src/vs/base/browser/mouseEvent.ts | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/vs/base/browser/mouseEvent.ts b/src/vs/base/browser/mouseEvent.ts index 7a0ebca76cf..e6f5d3b5a4b 100644 --- a/src/vs/base/browser/mouseEvent.ts +++ b/src/vs/base/browser/mouseEvent.ts @@ -88,28 +88,14 @@ export class StandardMouseEvent implements IMouseEvent { } } -export interface IDataTransfer { - dropEffect: string; - effectAllowed: string; - types: any[]; - files: any[]; - - setData(type: string, data: string): void; - setDragImage(image: any, x: number, y: number): void; - - getData(type: string): string; - clearData(types?: string[]): void; -} - export class DragMouseEvent extends StandardMouseEvent { - public readonly dataTransfer: IDataTransfer; + public readonly dataTransfer: DataTransfer; constructor(e: MouseEvent) { super(e); this.dataTransfer = (e).dataTransfer; } - } export interface IMouseWheelEvent extends MouseEvent { From f86beb18e8ce5383e60d90ed5bbab49e107307a9 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 3 Aug 2022 06:55:58 +0200 Subject: [PATCH 174/303] Increase timeout of web unit tests (#156894) * Windows: some Firefox web tests are timing out randomly (#155760) See if this is a fundamental issue or really Firefox is slower. * mention issue --- test/unit/browser/renderer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/browser/renderer.html b/test/unit/browser/renderer.html index 2bf6e3a2cab..5a2812ddd15 100644 --- a/test/unit/browser/renderer.html +++ b/test/unit/browser/renderer.html @@ -33,7 +33,7 @@ mocha.setup({ ui: 'tdd', - timeout: 5000 + timeout: 30000 // https://github.com/microsoft/vscode/issues/155760 }); From 7833aade5a73474ed2b40423942cc63edc1066c3 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 2 Aug 2022 22:03:10 -0700 Subject: [PATCH 175/303] Separate notebook kernel and api test (#156946) * Separate notebook kernel and api test. * no need to test reopen dirty document --- .../interactiveWindow.test.ts | 2 +- .../singlefolder-tests/notebook.api.test.ts | 369 ++++++++++++++++++ ...tebook.test.ts => notebook.kernel.test.ts} | 346 +--------------- .../test/browser/cellOperations.test.ts | 25 ++ 4 files changed, 397 insertions(+), 345 deletions(-) create mode 100644 extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts rename extensions/vscode-api-tests/src/singlefolder-tests/{notebook.test.ts => notebook.kernel.test.ts} (54%) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts index 89535dc5531..97f6da824cc 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import 'mocha'; import * as vscode from 'vscode'; import { disposeAll } from '../utils'; -import { Kernel, saveAllFilesAndCloseAll } from './notebook.test'; +import { Kernel, saveAllFilesAndCloseAll } from './notebook.api.test'; export type INativeInteractiveWindow = { notebookUri: vscode.Uri; inputUri: vscode.Uri; notebookEditor: vscode.NotebookEditor }; diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts new file mode 100644 index 00000000000..bd1bc363082 --- /dev/null +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts @@ -0,0 +1,369 @@ +/*--------------------------------------------------------------------------------------------- + * 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 'mocha'; +import { TextDecoder, TextEncoder } from 'util'; +import * as vscode from 'vscode'; +import { asPromise, assertNoRpc, closeAllEditors, createRandomFile, disposeAll, revertAllDirty, saveAllEditors } from '../utils'; + +async function createRandomNotebookFile() { + return createRandomFile('', undefined, '.vsctestnb'); +} + +async function openRandomNotebookDocument() { + const uri = await createRandomNotebookFile(); + return vscode.workspace.openNotebookDocument(uri); +} + +export async function saveAllFilesAndCloseAll() { + await saveAllEditors(); + await closeAllEditors(); +} + + +function sleep(ms: number): Promise { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); +} + +export class Kernel { + + readonly controller: vscode.NotebookController; + + readonly associatedNotebooks = new Set(); + + constructor(id: string, label: string, viewType: string = 'notebookCoreTest') { + this.controller = vscode.notebooks.createNotebookController(id, viewType, label); + this.controller.executeHandler = this._execute.bind(this); + this.controller.supportsExecutionOrder = true; + this.controller.supportedLanguages = ['typescript', 'javascript']; + this.controller.onDidChangeSelectedNotebooks(e => { + if (e.selected) { + this.associatedNotebooks.add(e.notebook.uri.toString()); + } else { + this.associatedNotebooks.delete(e.notebook.uri.toString()); + } + }); + } + + protected async _execute(cells: vscode.NotebookCell[]): Promise { + for (const cell of cells) { + await this._runCell(cell); + } + } + + protected async _runCell(cell: vscode.NotebookCell) { + // create a single output with exec order 1 and output is plain/text + // of either the cell itself or (iff empty) the cell's document's uri + const task = this.controller.createNotebookCellExecution(cell); + task.start(Date.now()); + task.executionOrder = 1; + await sleep(10); // Force to be take some time + await task.replaceOutput([new vscode.NotebookCellOutput([ + vscode.NotebookCellOutputItem.text(cell.document.getText() || cell.document.uri.toString(), 'text/plain') + ])]); + task.end(true); + } +} + + +function getFocusedCell(editor?: vscode.NotebookEditor) { + return editor ? editor.notebook.cellAt(editor.selections[0].start) : undefined; +} + +const apiTestContentProvider: vscode.NotebookContentProvider = { + openNotebook: async (resource: vscode.Uri): Promise => { + if (/.*empty\-.*\.vsctestnb$/.test(resource.path)) { + return { + metadata: {}, + cells: [] + }; + } + + const dto: vscode.NotebookData = { + metadata: { custom: { testMetadata: false } }, + cells: [ + { + value: 'test', + languageId: 'typescript', + kind: vscode.NotebookCellKind.Code, + outputs: [], + metadata: { custom: { testCellMetadata: 123 } }, + executionSummary: { timing: { startTime: 10, endTime: 20 } } + }, + { + value: 'test2', + languageId: 'typescript', + kind: vscode.NotebookCellKind.Code, + outputs: [ + new vscode.NotebookCellOutput([ + vscode.NotebookCellOutputItem.text('Hello World', 'text/plain') + ], + { + testOutputMetadata: true, + ['text/plain']: { testOutputItemMetadata: true } + }) + ], + executionSummary: { executionOrder: 5, success: true }, + metadata: { custom: { testCellMetadata: 456 } } + } + ] + }; + return dto; + }, + saveNotebook: async (_document: vscode.NotebookDocument, _cancellation: vscode.CancellationToken) => { + return; + }, + saveNotebookAs: async (_targetResource: vscode.Uri, _document: vscode.NotebookDocument, _cancellation: vscode.CancellationToken) => { + return; + }, + backupNotebook: async (_document: vscode.NotebookDocument, _context: vscode.NotebookDocumentBackupContext, _cancellation: vscode.CancellationToken) => { + return { + id: '1', + delete: () => { } + }; + } +}; + +(vscode.env.uiKind === vscode.UIKind.Web ? suite.skip : suite)('Notebook API tests', function () { + + const testDisposables: vscode.Disposable[] = []; + const suiteDisposables: vscode.Disposable[] = []; + + suiteTeardown(async function () { + + assertNoRpc(); + + await revertAllDirty(); + await closeAllEditors(); + + disposeAll(suiteDisposables); + suiteDisposables.length = 0; + }); + + suiteSetup(function () { + suiteDisposables.push(vscode.workspace.registerNotebookContentProvider('notebookCoreTest', apiTestContentProvider)); + }); + + let defaultKernel: Kernel; + + setup(async function () { + // there should be ONE default kernel in this suite + defaultKernel = new Kernel('mainKernel', 'Notebook Default Kernel'); + testDisposables.push(defaultKernel.controller); + await saveAllFilesAndCloseAll(); + }); + + teardown(async function () { + disposeAll(testDisposables); + testDisposables.length = 0; + await saveAllFilesAndCloseAll(); + }); + + test('edit API batch edits', async function () { + const notebook = await openRandomNotebookDocument(); + + const edit = new vscode.WorkspaceEdit(); + const metdataEdit = vscode.NotebookEdit.updateNotebookMetadata({ ...notebook.metadata, custom: { ...(notebook.metadata.custom || {}), extraNotebookMetadata: true } }); + edit.set(notebook.uri, [metdataEdit]); + const success = await vscode.workspace.applyEdit(edit); + assert.equal(success, true); + assert.ok(notebook.metadata.custom.extraNotebookMetadata, `Test metadata not found`); + }); + + test('notebook open', async function () { + const notebook = await openRandomNotebookDocument(); + const editor = await vscode.window.showNotebookDocument(notebook); + assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'test'); + assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript'); + + const secondCell = editor.notebook.cellAt(1); + assert.strictEqual(secondCell.outputs.length, 1); + assert.deepStrictEqual(secondCell.outputs[0].metadata, { testOutputMetadata: true, ['text/plain']: { testOutputItemMetadata: true } }); + assert.strictEqual(secondCell.outputs[0].items.length, 1); + assert.strictEqual(secondCell.outputs[0].items[0].mime, 'text/plain'); + assert.strictEqual(new TextDecoder().decode(secondCell.outputs[0].items[0].data), 'Hello World'); + assert.strictEqual(secondCell.executionSummary?.executionOrder, 5); + assert.strictEqual(secondCell.executionSummary?.success, true); + }); + + test('multiple tabs: different editors with same document', async function () { + const notebook = await openRandomNotebookDocument(); + const firstNotebookEditor = await vscode.window.showNotebookDocument(notebook, { viewColumn: vscode.ViewColumn.One }); + const secondNotebookEditor = await vscode.window.showNotebookDocument(notebook, { viewColumn: vscode.ViewColumn.Beside }); + assert.notStrictEqual(firstNotebookEditor, secondNotebookEditor); + assert.strictEqual(firstNotebookEditor?.notebook, secondNotebookEditor?.notebook, 'split notebook editors share the same document'); + }); + + test.skip('#106657. Opening a notebook from markers view is broken ', async function () { + + const document = await openRandomNotebookDocument(); + const [cell] = document.getCells(); + + assert.strictEqual(vscode.window.activeNotebookEditor, undefined); + + // opening a cell-uri opens a notebook editor + await vscode.window.showTextDocument(cell.document, { viewColumn: vscode.ViewColumn.Active }); + // await vscode.commands.executeCommand('vscode.open', cell.document.uri, vscode.ViewColumn.Active); + + assert.strictEqual(!!vscode.window.activeNotebookEditor, true); + assert.strictEqual(vscode.window.activeNotebookEditor!.notebook.uri.toString(), document.uri.toString()); + }); + + test('Cannot open notebook from cell-uri with vscode.open-command', async function () { + + const document = await openRandomNotebookDocument(); + const [cell] = document.getCells(); + + await saveAllFilesAndCloseAll(); + assert.strictEqual(vscode.window.activeNotebookEditor, undefined); + + // BUG is that the editor opener (https://github.com/microsoft/vscode/blob/8e7877bdc442f1e83a7fec51920d82b696139129/src/vs/editor/browser/services/openerService.ts#L69) + // removes the fragment if it matches something numeric. For notebooks that's not wanted... + // opening a cell-uri opens a notebook editor + await vscode.commands.executeCommand('vscode.open', cell.document.uri); + + assert.strictEqual(vscode.window.activeNotebookEditor!.notebook.uri.toString(), document.uri.toString()); + }); + + test('#97830, #97764. Support switch to other editor types', async function () { + const notebook = await openRandomNotebookDocument(); + const editor = await vscode.window.showNotebookDocument(notebook); + const edit = new vscode.WorkspaceEdit(); + const focusedCell = getFocusedCell(editor); + assert.ok(focusedCell); + edit.replace(focusedCell.document.uri, focusedCell.document.lineAt(0).range, 'var abc = 0;'); + await vscode.workspace.applyEdit(edit); + + assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'var abc = 0;'); + + // no kernel -> no default language + assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript'); + + await vscode.commands.executeCommand('vscode.openWith', notebook.uri, 'default'); + assert.strictEqual(vscode.window.activeTextEditor?.document.uri.path, notebook.uri.path); + }); + + test('#102411 - untitled notebook creation failed', async function () { + await vscode.commands.executeCommand('workbench.action.files.newUntitledFile', { viewType: 'notebookCoreTest' }); + assert.notStrictEqual(vscode.window.activeNotebookEditor, undefined, 'untitled notebook editor is not undefined'); + + await closeAllEditors(); + }); + + test('#115855 onDidSaveNotebookDocument', async function () { + const resource = await createRandomNotebookFile(); + const notebook = await vscode.workspace.openNotebookDocument(resource); + + const notebookEdit = new vscode.NotebookEdit(new vscode.NotebookRange(1, 1), [new vscode.NotebookCellData(vscode.NotebookCellKind.Code, 'test 2', 'javascript')]); + const edit = new vscode.WorkspaceEdit(); + edit.set(notebook.uri, [notebookEdit]); + await vscode.workspace.applyEdit(edit); + assert.strictEqual(notebook.isDirty, true); + + const saveEvent = asPromise(vscode.workspace.onDidSaveNotebookDocument); + await notebook.save(); + await saveEvent; + + assert.strictEqual(notebook.isDirty, false); + }); +}); + +(vscode.env.uiKind === vscode.UIKind.Web ? suite.skip : suite)('statusbar', () => { + const emitter = new vscode.EventEmitter(); + const onDidCallProvide = emitter.event; + const suiteDisposables: vscode.Disposable[] = []; + suiteTeardown(async function () { + assertNoRpc(); + + await revertAllDirty(); + await closeAllEditors(); + + disposeAll(suiteDisposables); + suiteDisposables.length = 0; + }); + + suiteSetup(() => { + suiteDisposables.push(vscode.notebooks.registerNotebookCellStatusBarItemProvider('notebookCoreTest', { + async provideCellStatusBarItems(cell: vscode.NotebookCell, _token: vscode.CancellationToken): Promise { + emitter.fire(cell); + return []; + } + })); + + suiteDisposables.push(vscode.workspace.registerNotebookContentProvider('notebookCoreTest', apiTestContentProvider)); + }); + + test.skip('provideCellStatusBarItems called on metadata change', async function () { // TODO@roblourens https://github.com/microsoft/vscode/issues/139324 + const provideCalled = asPromise(onDidCallProvide); + const notebook = await openRandomNotebookDocument(); + await vscode.window.showNotebookDocument(notebook); + await provideCalled; + + const edit = new vscode.WorkspaceEdit(); + edit.replaceNotebookCellMetadata(notebook.uri, 0, { inputCollapsed: true }); + vscode.workspace.applyEdit(edit); + await provideCalled; + }); +}); + +suite('Notebook & LiveShare', function () { + + const suiteDisposables: vscode.Disposable[] = []; + const notebookType = 'vsls-testing'; + + suiteTeardown(() => { + vscode.Disposable.from(...suiteDisposables).dispose(); + }); + + suiteSetup(function () { + + suiteDisposables.push(vscode.workspace.registerNotebookSerializer(notebookType, new class implements vscode.NotebookSerializer { + deserializeNotebook(content: Uint8Array, _token: vscode.CancellationToken): vscode.NotebookData | Thenable { + const value = new TextDecoder().decode(content); + const cell1 = new vscode.NotebookCellData(vscode.NotebookCellKind.Code, value, 'fooLang'); + cell1.outputs = [new vscode.NotebookCellOutput([vscode.NotebookCellOutputItem.stderr(value)])]; + return new vscode.NotebookData([cell1]); + } + serializeNotebook(data: vscode.NotebookData, _token: vscode.CancellationToken): Uint8Array | Thenable { + return new TextEncoder().encode(data.cells[0].value); + } + }, {}, { + displayName: 'LS', + filenamePattern: ['*'], + })); + }); + + test('command: vscode.resolveNotebookContentProviders', async function () { + + type Info = { viewType: string; displayName: string; filenamePattern: string[] }; + + const info = await vscode.commands.executeCommand('vscode.resolveNotebookContentProviders'); + assert.strictEqual(Array.isArray(info), true); + + const item = info.find(item => item.viewType === notebookType); + assert.ok(item); + assert.strictEqual(item?.viewType, notebookType); + }); + + test('command: vscode.executeDataToNotebook', async function () { + const value = 'dataToNotebook'; + const data = await vscode.commands.executeCommand('vscode.executeDataToNotebook', notebookType, new TextEncoder().encode(value)); + assert.ok(data instanceof vscode.NotebookData); + assert.strictEqual(data.cells.length, 1); + assert.strictEqual(data.cells[0].value, value); + assert.strictEqual(new TextDecoder().decode(data.cells[0].outputs![0].items[0].data), value); + }); + + test('command: vscode.executeNotebookToData', async function () { + const value = 'notebookToData'; + const notebook = new vscode.NotebookData([new vscode.NotebookCellData(vscode.NotebookCellKind.Code, value, 'fooLang')]); + const data = await vscode.commands.executeCommand('vscode.executeNotebookToData', notebookType, notebook); + assert.ok(data instanceof Uint8Array); + assert.deepStrictEqual(new TextDecoder().decode(data), value); + }); +}); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts similarity index 54% rename from extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts rename to extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts index 9582ed49c0c..0bc9384ccbd 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import 'mocha'; -import { TextDecoder, TextEncoder } from 'util'; +import { TextDecoder } from 'util'; import * as vscode from 'vscode'; import { asPromise, assertNoRpc, closeAllEditors, createRandomFile, disposeAll, revertAllDirty, saveAllEditors } from '../utils'; @@ -76,10 +76,6 @@ export class Kernel { } -function getFocusedCell(editor?: vscode.NotebookEditor) { - return editor ? editor.notebook.cellAt(editor.selections[0].start) : undefined; -} - async function assertKernel(kernel: Kernel, notebook: vscode.NotebookDocument): Promise { const success = await vscode.commands.executeCommand('notebook.selectKernel', { extension: 'vscode.vscode-api-tests', @@ -143,7 +139,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { } }; -(vscode.env.uiKind === vscode.UIKind.Web ? suite.skip : suite)('Notebook API tests', function () { +(vscode.env.uiKind === vscode.UIKind.Web ? suite.skip : suite)('Notebook Kernel API tests', function () { const testDisposables: vscode.Disposable[] = []; const suiteDisposables: vscode.Disposable[] = []; @@ -178,81 +174,6 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { await saveAllFilesAndCloseAll(); }); - test('edit API batch edits', async function () { - const notebook = await openRandomNotebookDocument(); - - const edit = new vscode.WorkspaceEdit(); - const metdataEdit = vscode.NotebookEdit.updateNotebookMetadata({ ...notebook.metadata, custom: { ...(notebook.metadata.custom || {}), extraNotebookMetadata: true } }); - edit.set(notebook.uri, [metdataEdit]); - const success = await vscode.workspace.applyEdit(edit); - assert.equal(success, true); - assert.ok(notebook.metadata.custom.extraNotebookMetadata, `Test metadata not found`); - }); - - test('notebook open', async function () { - const notebook = await openRandomNotebookDocument(); - const editor = await vscode.window.showNotebookDocument(notebook); - assert.strictEqual(vscode.window.activeNotebookEditor === editor, true, 'notebook first'); - assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'test'); - assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript'); - - const secondCell = editor.notebook.cellAt(1); - assert.strictEqual(secondCell.outputs.length, 1); - assert.deepStrictEqual(secondCell.outputs[0].metadata, { testOutputMetadata: true, ['text/plain']: { testOutputItemMetadata: true } }); - assert.strictEqual(secondCell.outputs[0].items.length, 1); - assert.strictEqual(secondCell.outputs[0].items[0].mime, 'text/plain'); - assert.strictEqual(new TextDecoder().decode(secondCell.outputs[0].items[0].data), 'Hello World'); - assert.strictEqual(secondCell.executionSummary?.executionOrder, 5); - assert.strictEqual(secondCell.executionSummary?.success, true); - }); - - test('notebook cell actions', async function () { - const notebook = await openRandomNotebookDocument(); - const editor = await vscode.window.showNotebookDocument(notebook); - assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first'); - assert.strictEqual(vscode.window.activeNotebookEditor === editor, true, 'notebook first'); - assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'test'); - assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript'); - - let activeCell = getFocusedCell(editor); - - // ---- focus top and then copy down ---- // - await vscode.commands.executeCommand('notebook.focusTop'); - activeCell = getFocusedCell(editor); - assert.strictEqual(editor.notebook.getCells().indexOf(activeCell!), 0); - - await vscode.commands.executeCommand('notebook.cell.copyDown'); - activeCell = getFocusedCell(editor); - assert.strictEqual(editor.notebook.getCells().indexOf(activeCell!), 1); - assert.strictEqual(activeCell?.document.getText(), 'test'); - - // delete focused cell - { - const focusedCell = getFocusedCell(editor); - assert.strictEqual(focusedCell !== undefined, true); - const edit = new vscode.WorkspaceEdit(); - edit.replaceNotebookCells(focusedCell!.notebook.uri, new vscode.NotebookRange(focusedCell!.index, focusedCell!.index + 1), []); - await vscode.workspace.applyEdit(edit); - } - - activeCell = getFocusedCell(editor); - assert.strictEqual(editor.notebook.getCells().indexOf(activeCell!), 1); - assert.strictEqual(activeCell?.document.getText(), 'test2'); - - // ---- focus top and then copy up ---- // - await vscode.commands.executeCommand('notebook.focusTop'); - await vscode.commands.executeCommand('notebook.cell.copyUp'); - assert.strictEqual(editor.notebook.cellCount, 3); - assert.strictEqual(editor.notebook.cellAt(0).document.getText(), 'test'); - assert.strictEqual(editor.notebook.cellAt(1).document.getText(), 'test'); - assert.strictEqual(editor.notebook.cellAt(2).document.getText(), 'test2'); - activeCell = getFocusedCell(editor); - assert.strictEqual(editor.notebook.getCells().indexOf(activeCell!), 0); - - await vscode.commands.executeCommand('workbench.action.files.save'); - await vscode.commands.executeCommand('workbench.action.closeActiveEditor'); - }); - // TODO@rebornix this is wrong, `await vscode.commands.executeCommand('notebook.execute');` doesn't wait until the workspace edit is applied test.skip('cell execute command takes arguments', async () => { const notebook = await openRandomNotebookDocument(); @@ -413,136 +334,6 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { listener.dispose(); }); - test('multiple tabs: different editors with same document', async function () { - - const notebook = await openRandomNotebookDocument(); - const firstNotebookEditor = await vscode.window.showNotebookDocument(notebook, { viewColumn: vscode.ViewColumn.One }); - assert.ok(firstNotebookEditor === vscode.window.activeNotebookEditor); - - assert.strictEqual(firstNotebookEditor !== undefined, true, 'notebook first'); - assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor!)?.document.getText(), 'test'); - assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor!)?.document.languageId, 'typescript'); - - const secondNotebookEditor = await vscode.window.showNotebookDocument(notebook, { viewColumn: vscode.ViewColumn.Beside }); - assert.strictEqual(secondNotebookEditor !== undefined, true, 'notebook first'); - assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor!)?.document.getText(), 'test'); - assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor!)?.document.languageId, 'typescript'); - - assert.notStrictEqual(firstNotebookEditor, secondNotebookEditor); - assert.strictEqual(firstNotebookEditor?.notebook, secondNotebookEditor?.notebook, 'split notebook editors share the same document'); - - }); - - test.skip('#106657. Opening a notebook from markers view is broken ', async function () { - - const document = await openRandomNotebookDocument(); - const [cell] = document.getCells(); - - assert.strictEqual(vscode.window.activeNotebookEditor, undefined); - - // opening a cell-uri opens a notebook editor - await vscode.window.showTextDocument(cell.document, { viewColumn: vscode.ViewColumn.Active }); - // await vscode.commands.executeCommand('vscode.open', cell.document.uri, vscode.ViewColumn.Active); - - assert.strictEqual(!!vscode.window.activeNotebookEditor, true); - assert.strictEqual(vscode.window.activeNotebookEditor!.notebook.uri.toString(), document.uri.toString()); - }); - - test('Cannot open notebook from cell-uri with vscode.open-command', async function () { - - const document = await openRandomNotebookDocument(); - const [cell] = document.getCells(); - - await saveAllFilesAndCloseAll(); - assert.strictEqual(vscode.window.activeNotebookEditor, undefined); - - // BUG is that the editor opener (https://github.com/microsoft/vscode/blob/8e7877bdc442f1e83a7fec51920d82b696139129/src/vs/editor/browser/services/openerService.ts#L69) - // removes the fragment if it matches something numeric. For notebooks that's not wanted... - await vscode.commands.executeCommand('vscode.open', cell.document.uri); - - assert.strictEqual(vscode.window.activeNotebookEditor!.notebook.uri.toString(), document.uri.toString()); - }); - - test('#97830, #97764. Support switch to other editor types', async function () { - const notebook = await openRandomNotebookDocument(); - const editor = await vscode.window.showNotebookDocument(notebook); - const edit = new vscode.WorkspaceEdit(); - const focusedCell = getFocusedCell(editor); - assert.ok(focusedCell); - edit.replace(focusedCell.document.uri, focusedCell.document.lineAt(0).range, 'var abc = 0;'); - await vscode.workspace.applyEdit(edit); - - assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'var abc = 0;'); - - // no kernel -> no default language - assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript'); - - await vscode.commands.executeCommand('vscode.openWith', notebook.uri, 'default'); - assert.strictEqual(vscode.window.activeTextEditor?.document.uri.path, notebook.uri.path); - }); - - // open text editor, pin, and then open a notebook - test('#96105 - dirty editors', async function () { - const resource = await createRandomNotebookFile(); - await vscode.commands.executeCommand('vscode.openWith', resource, 'default'); - const edit = new vscode.WorkspaceEdit(); - edit.insert(resource, new vscode.Position(0, 0), 'var abc = 0;'); - await vscode.workspace.applyEdit(edit); - - // now it's dirty, open the resource with notebook editor should open a new one - await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest'); - assert.notStrictEqual(vscode.window.activeNotebookEditor, undefined, 'notebook first'); - // assert.notStrictEqual(vscode.window.activeTextEditor, undefined); - - }); - - test('#102411 - untitled notebook creation failed', async function () { - await vscode.commands.executeCommand('workbench.action.files.newUntitledFile', { viewType: 'notebookCoreTest' }); - assert.notStrictEqual(vscode.window.activeNotebookEditor, undefined, 'untitled notebook editor is not undefined'); - - await closeAllEditors(); - }); - - test('#102423 - copy/paste shares the same text buffer', async function () { - const notebook = await openRandomNotebookDocument(); - await vscode.window.showNotebookDocument(notebook); - - let activeCell = getFocusedCell(vscode.window.activeNotebookEditor); - assert.strictEqual(activeCell?.document.getText(), 'test'); - - await vscode.commands.executeCommand('notebook.cell.copyDown'); - await vscode.commands.executeCommand('notebook.cell.edit'); - activeCell = getFocusedCell(vscode.window.activeNotebookEditor); - assert.strictEqual(vscode.window.activeNotebookEditor!.notebook.getCells().indexOf(activeCell!), 1); - assert.strictEqual(activeCell?.document.getText(), 'test'); - - const edit = new vscode.WorkspaceEdit(); - edit.insert(getFocusedCell(vscode.window.activeNotebookEditor)!.document.uri, new vscode.Position(0, 0), 'var abc = 0;'); - await vscode.workspace.applyEdit(edit); - - assert.strictEqual(vscode.window.activeNotebookEditor!.notebook.getCells().length, 3); - assert.notStrictEqual(vscode.window.activeNotebookEditor!.notebook.cellAt(0).document.getText(), vscode.window.activeNotebookEditor!.notebook.cellAt(1).document.getText()); - - await closeAllEditors(); - }); - - test('#115855 onDidSaveNotebookDocument', async function () { - const resource = await createRandomNotebookFile(); - const notebook = await vscode.workspace.openNotebookDocument(resource); - - const notebookEdit = new vscode.NotebookEdit(new vscode.NotebookRange(1, 1), [new vscode.NotebookCellData(vscode.NotebookCellKind.Code, 'test 2', 'javascript')]); - const edit = new vscode.WorkspaceEdit(); - edit.set(notebook.uri, [notebookEdit]); - await vscode.workspace.applyEdit(edit); - assert.strictEqual(notebook.isDirty, true); - - const saveEvent = asPromise(vscode.workspace.onDidSaveNotebookDocument); - await notebook.save(); - await saveEvent; - - assert.strictEqual(notebook.isDirty, false); - }); - test('Output changes are applied once the promise resolves', async function () { let called = false; @@ -710,136 +501,3 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { }); }); }); - -(vscode.env.uiKind === vscode.UIKind.Web ? suite.skip : suite)('statusbar', () => { - const emitter = new vscode.EventEmitter(); - const onDidCallProvide = emitter.event; - const suiteDisposables: vscode.Disposable[] = []; - suiteTeardown(async function () { - assertNoRpc(); - - await revertAllDirty(); - await closeAllEditors(); - - disposeAll(suiteDisposables); - suiteDisposables.length = 0; - }); - - suiteSetup(() => { - suiteDisposables.push(vscode.notebooks.registerNotebookCellStatusBarItemProvider('notebookCoreTest', { - async provideCellStatusBarItems(cell: vscode.NotebookCell, _token: vscode.CancellationToken): Promise { - emitter.fire(cell); - return []; - } - })); - - suiteDisposables.push(vscode.workspace.registerNotebookContentProvider('notebookCoreTest', apiTestContentProvider)); - }); - - test.skip('provideCellStatusBarItems called on metadata change', async function () { // TODO@roblourens https://github.com/microsoft/vscode/issues/139324 - const provideCalled = asPromise(onDidCallProvide); - const notebook = await openRandomNotebookDocument(); - await vscode.window.showNotebookDocument(notebook); - await provideCalled; - - const edit = new vscode.WorkspaceEdit(); - edit.replaceNotebookCellMetadata(notebook.uri, 0, { inputCollapsed: true }); - vscode.workspace.applyEdit(edit); - await provideCalled; - }); -}); - -(vscode.env.uiKind === vscode.UIKind.Web ? suite.skip : suite)('Notebook API tests (metadata)', function () { - const testDisposables: vscode.Disposable[] = []; - const suiteDisposables: vscode.Disposable[] = []; - - suiteTeardown(async function () { - assertNoRpc(); - - await revertAllDirty(); - await closeAllEditors(); - - disposeAll(suiteDisposables); - suiteDisposables.length = 0; - }); - - suiteSetup(function () { - suiteDisposables.push(vscode.workspace.registerNotebookContentProvider('notebookCoreTest', apiTestContentProvider)); - }); - - setup(async function () { - await saveAllFilesAndCloseAll(); - }); - - teardown(async function () { - disposeAll(testDisposables); - testDisposables.length = 0; - await saveAllFilesAndCloseAll(); - }); - - test('custom metadata should be supported', async function () { - const notebook = await openRandomNotebookDocument(); - const editor = await vscode.window.showNotebookDocument(notebook); - - assert.strictEqual(editor.notebook.metadata.custom?.testMetadata, false); - assert.strictEqual(getFocusedCell(editor)?.metadata.custom?.testCellMetadata, 123); - assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript'); - }); -}); - -suite('Notebook & LiveShare', function () { - - const suiteDisposables: vscode.Disposable[] = []; - const notebookType = 'vsls-testing'; - - suiteTeardown(() => { - vscode.Disposable.from(...suiteDisposables).dispose(); - }); - - suiteSetup(function () { - - suiteDisposables.push(vscode.workspace.registerNotebookSerializer(notebookType, new class implements vscode.NotebookSerializer { - deserializeNotebook(content: Uint8Array, _token: vscode.CancellationToken): vscode.NotebookData | Thenable { - const value = new TextDecoder().decode(content); - const cell1 = new vscode.NotebookCellData(vscode.NotebookCellKind.Code, value, 'fooLang'); - cell1.outputs = [new vscode.NotebookCellOutput([vscode.NotebookCellOutputItem.stderr(value)])]; - return new vscode.NotebookData([cell1]); - } - serializeNotebook(data: vscode.NotebookData, _token: vscode.CancellationToken): Uint8Array | Thenable { - return new TextEncoder().encode(data.cells[0].value); - } - }, {}, { - displayName: 'LS', - filenamePattern: ['*'], - })); - }); - - test('command: vscode.resolveNotebookContentProviders', async function () { - - type Info = { viewType: string; displayName: string; filenamePattern: string[] }; - - const info = await vscode.commands.executeCommand('vscode.resolveNotebookContentProviders'); - assert.strictEqual(Array.isArray(info), true); - - const item = info.find(item => item.viewType === notebookType); - assert.ok(item); - assert.strictEqual(item?.viewType, notebookType); - }); - - test('command: vscode.executeDataToNotebook', async function () { - const value = 'dataToNotebook'; - const data = await vscode.commands.executeCommand('vscode.executeDataToNotebook', notebookType, new TextEncoder().encode(value)); - assert.ok(data instanceof vscode.NotebookData); - assert.strictEqual(data.cells.length, 1); - assert.strictEqual(data.cells[0].value, value); - assert.strictEqual(new TextDecoder().decode(data.cells[0].outputs![0].items[0].data), value); - }); - - test('command: vscode.executeNotebookToData', async function () { - const value = 'notebookToData'; - const notebook = new vscode.NotebookData([new vscode.NotebookCellData(vscode.NotebookCellKind.Code, value, 'fooLang')]); - const data = await vscode.commands.executeCommand('vscode.executeNotebookToData', notebookType, notebook); - assert.ok(data instanceof Uint8Array); - assert.deepStrictEqual(new TextDecoder().decode(data), value); - }); -}); diff --git a/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts b/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts index c35be948647..2de6c8fcf3c 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/cellOperations.test.ts @@ -12,6 +12,7 @@ import { Range } from 'vs/editor/common/core/range'; import { ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits'; import { ILanguageService } from 'vs/editor/common/languages/language'; +import { ITextBuffer, ValidAnnotatedEditOperation } from 'vs/editor/common/model'; suite('CellOperations', () => { test('Move cells - single cell', async function () { @@ -162,6 +163,30 @@ suite('CellOperations', () => { }); }); + test('Copy/duplicate cells - should not share the same text buffer #102423', async function () { + await withTestNotebook( + [ + ['# header a', 'markdown', CellKind.Markup, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}] + ], + async (editor, viewModel) => { + viewModel.updateSelectionsState({ kind: SelectionStateType.Index, focus: { start: 1, end: 2 }, selections: [{ start: 1, end: 2 }] }); + await copyCellRange({ notebookEditor: editor, cell: viewModel.cellAt(1)! }, 'down'); + assert.strictEqual(viewModel.length, 3); + const cell1 = viewModel.cellAt(1); + const cell2 = viewModel.cellAt(2); + assert.ok(cell1); + assert.ok(cell2); + assert.strictEqual(cell1.getText(), 'var b = 1;'); + assert.strictEqual(viewModel.cellAt(2)?.getText(), 'var b = 1;'); + + (cell1.textBuffer as ITextBuffer).applyEdits([ + new ValidAnnotatedEditOperation(null, new Range(1, 1, 1, 4), '', false, false, false) + ], false, true); + assert.notStrictEqual(cell1.getText(), cell2.getText()); + }); + }); + test('Join cell with below - single cell', async function () { await withTestNotebook( [ From 784de603197348d570857adf3a306b3b92deea1f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 2 Aug 2022 22:03:33 -0700 Subject: [PATCH 176/303] Add `activeWebviewPanelId` context key (#156944) Fixes #156942 This context tracks the id of the active webviewPanel --- .../markdown-language-features/package.json | 16 ++++++++-------- .../src/preview/previewManager.ts | 8 -------- .../api/browser/mainThreadWebviewPanels.ts | 2 +- .../customEditor/browser/customEditorInput.ts | 2 +- .../browser/customEditorInputFactory.ts | 2 +- .../contrib/webview/browser/overlayWebview.ts | 6 +++--- .../contrib/webview/browser/webview.ts | 5 +++++ .../contrib/webview/browser/webviewElement.ts | 11 +++++------ .../webviewPanel/browser/webviewEditor.ts | 11 ++++++++++- .../browser/webviewEditorInputSerializer.ts | 2 +- .../browser/webviewWorkbenchService.ts | 17 +++++++++++++++-- .../webviewView/browser/webviewViewPane.ts | 2 +- 12 files changed, 51 insertions(+), 33 deletions(-) diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index cae88bf134f..ffa9336499b 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -187,22 +187,22 @@ }, { "command": "markdown.showSource", - "when": "markdownPreviewFocus", + "when": "activeWebviewPanelId == 'markdown.preview' || activeCustomEditorId == 'vscode.markdown.preview.editor'", "group": "navigation" }, { "command": "markdown.preview.refresh", - "when": "markdownPreviewFocus", + "when": "activeWebviewPanelId == 'markdown.preview' || activeCustomEditorId == 'vscode.markdown.preview.editor'", "group": "1_markdown" }, { "command": "markdown.preview.toggleLock", - "when": "markdownPreviewFocus", + "when": "activeWebviewPanelId == 'markdown.preview' || activeCustomEditorId == 'vscode.markdown.preview.editor'", "group": "1_markdown" }, { "command": "markdown.showPreviewSecuritySelector", - "when": "markdownPreviewFocus", + "when": "activeWebviewPanelId == 'markdown.preview' || activeCustomEditorId == 'vscode.markdown.preview.editor'", "group": "1_markdown" } ], @@ -247,7 +247,7 @@ }, { "command": "markdown.showSource", - "when": "markdownPreviewFocus", + "when": "activeWebviewPanelId == 'markdown.preview' || activeCustomEditorId == 'vscode.markdown.preview.editor'", "group": "navigation" }, { @@ -256,11 +256,11 @@ }, { "command": "markdown.showPreviewSecuritySelector", - "when": "markdownPreviewFocus" + "when": "activeWebviewPanelId == 'markdown.preview' || activeCustomEditorId == 'vscode.markdown.preview.editor'" }, { "command": "markdown.preview.toggleLock", - "when": "markdownPreviewFocus" + "when": "activeWebviewPanelId == 'markdown.preview' || activeCustomEditorId == 'vscode.markdown.preview.editor'" }, { "command": "markdown.preview.refresh", @@ -268,7 +268,7 @@ }, { "command": "markdown.preview.refresh", - "when": "markdownPreviewFocus" + "when": "activeWebviewPanelId == 'markdown.preview' || activeCustomEditorId == 'vscode.markdown.preview.editor'" }, { "command": "markdown.findAllFileReferences", diff --git a/extensions/markdown-language-features/src/preview/previewManager.ts b/extensions/markdown-language-features/src/preview/previewManager.ts index 134989ce181..3faa0f63b0f 100644 --- a/extensions/markdown-language-features/src/preview/previewManager.ts +++ b/extensions/markdown-language-features/src/preview/previewManager.ts @@ -58,8 +58,6 @@ class PreviewStore extends Disposable { export class MarkdownPreviewManager extends Disposable implements vscode.WebviewPanelSerializer, vscode.CustomTextEditorProvider { - private static readonly markdownPreviewActiveContextKey = 'markdownPreviewFocus'; - private readonly _topmostLineMonitor = new TopmostLineMonitor(); private readonly _previewConfigurations = new MarkdownPreviewConfigurationManager(); @@ -216,7 +214,6 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview this._contributions, this._tocProvider); - this.setPreviewActiveContext(true); this._activePreview = preview; return this.registerDynamicPreview(preview); } @@ -250,19 +247,14 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview private trackActive(preview: IManagedMarkdownPreview): void { preview.onDidChangeViewState(({ webviewPanel }) => { - this.setPreviewActiveContext(webviewPanel.active); this._activePreview = webviewPanel.active ? preview : undefined; }); preview.onDispose(() => { if (this._activePreview === preview) { - this.setPreviewActiveContext(false); this._activePreview = undefined; } }); } - private setPreviewActiveContext(value: boolean) { - vscode.commands.executeCommand('setContext', MarkdownPreviewManager.markdownPreviewActiveContextKey, value); - } } diff --git a/src/vs/workbench/api/browser/mainThreadWebviewPanels.ts b/src/vs/workbench/api/browser/mainThreadWebviewPanels.ts index c8dd0761ef1..79a0765ef3e 100644 --- a/src/vs/workbench/api/browser/mainThreadWebviewPanels.ts +++ b/src/vs/workbench/api/browser/mainThreadWebviewPanels.ts @@ -167,7 +167,7 @@ export class MainThreadWebviewPanels extends Disposable implements extHostProtoc const webview = this._webviewWorkbenchService.createWebview({ id: handle, - providedId: viewType, + providedViewType: viewType, options: reviveWebviewOptions(initData.panelOptions), contentOptions: reviveWebviewContentOptions(initData.webviewOptions), extension diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts index a514a41b857..f5f1a414b18 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts @@ -46,7 +46,7 @@ export class CustomEditorInput extends LazilyResolvedWebviewEditorInput { const id = generateUuid(); const webview = accessor.get(IWebviewService).createWebviewOverlay({ id, - providedId: viewType, + providedViewType: viewType, options: { customClasses: options?.customClasses }, contentOptions: {}, extension: undefined, diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditorInputFactory.ts b/src/vs/workbench/contrib/customEditor/browser/customEditorInputFactory.ts index 4277c67ab6a..e98fbb5a058 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditorInputFactory.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditorInputFactory.ts @@ -111,7 +111,7 @@ export class CustomEditorInputSerializer extends WebviewEditorInputSerializer { function reviveWebview(webviewService: IWebviewService, data: { id: string; origin: string | undefined; viewType: string; state: any; webviewOptions: WebviewOptions; contentOptions: WebviewContentOptions; extension?: WebviewExtensionDescription }) { const webview = webviewService.createWebviewOverlay({ id: data.id, - providedId: data.viewType, + providedViewType: data.viewType, origin: data.origin, options: { purpose: WebviewContentPurpose.CustomEditor, diff --git a/src/vs/workbench/contrib/webview/browser/overlayWebview.ts b/src/vs/workbench/contrib/webview/browser/overlayWebview.ts index 81499a931b6..3eeb445b292 100644 --- a/src/vs/workbench/contrib/webview/browser/overlayWebview.ts +++ b/src/vs/workbench/contrib/webview/browser/overlayWebview.ts @@ -44,7 +44,7 @@ export class OverlayWebview extends Disposable implements IOverlayWebview { private _findWidgetEnabled: IContextKey | undefined; public readonly id: string; - public readonly providedId?: string; + public readonly providedViewType?: string; public readonly origin: string; public constructor( @@ -56,7 +56,7 @@ export class OverlayWebview extends Disposable implements IOverlayWebview { super(); this.id = initInfo.id; - this.providedId = initInfo.providedId; + this.providedViewType = initInfo.providedViewType; this.origin = initInfo.origin ?? generateUuid(); this._extension = initInfo.extension; @@ -194,7 +194,7 @@ export class OverlayWebview extends Disposable implements IOverlayWebview { if (!this._webview.value) { const webview = this._webviewService.createWebviewElement({ id: this.id, - providedId: this.providedId, + providedViewType: this.providedViewType, origin: this.origin, options: this._options, contentOptions: this._contentOptions, diff --git a/src/vs/workbench/contrib/webview/browser/webview.ts b/src/vs/workbench/contrib/webview/browser/webview.ts index e9e90223d4e..83296c95ac4 100644 --- a/src/vs/workbench/contrib/webview/browser/webview.ts +++ b/src/vs/workbench/contrib/webview/browser/webview.ts @@ -161,6 +161,11 @@ export interface IWebview extends IDisposable { */ readonly origin: string; + /** + * The original view type of the webview. + */ + readonly providedViewType?: string; + html: string; contentOptions: WebviewContentOptions; localResourcesRoot: readonly URI[]; diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 465ab3b4681..73c6baaf38e 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -102,7 +102,7 @@ namespace WebviewState { export interface WebviewInitInfo { readonly id: string; - readonly providedId?: string; + readonly providedViewType?: string; readonly origin?: string; readonly options: WebviewOptions; @@ -123,11 +123,10 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD */ public readonly id: string; - /** * The provided identifier of this webview. */ - public readonly providedId?: string; + public readonly providedViewType?: string; /** * The origin this webview itself is loaded from. May not be unique @@ -210,7 +209,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD super(); this.id = initInfo.id; - this.providedId = initInfo.providedId; + this.providedViewType = initInfo.providedViewType; this.iframeId = generateUuid(); this.origin = initInfo.origin ?? this.iframeId; @@ -343,7 +342,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD getActions: () => { const contextKeyService = this._contextKeyService!.createOverlay([ ...Object.entries(data.context), - ['webview', this.providedId], + ['webview', this.providedViewType], ]); const result: IAction[] = []; @@ -352,7 +351,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD menu.dispose(); return result; }, - getActionsContext: (): WebviewActionContext => ({ ...data.context, webview: this.providedId }), + getActionsContext: (): WebviewActionContext => ({ ...data.context, webview: this.providedViewType }), getAnchor: () => ({ x: elementBox.x + data.clientX, y: elementBox.y + data.clientY diff --git a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts index 5b6a38cba23..d804ab85570 100644 --- a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts +++ b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts @@ -9,7 +9,8 @@ import { Emitter, Event } from 'vs/base/common/event'; import { DisposableStore, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { isWeb } from 'vs/base/common/platform'; import { generateUuid } from 'vs/base/common/uuid'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import * as nls from 'vs/nls'; +import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -26,6 +27,14 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService'; +/** + * Tracks the id of the actively focused webview. + */ +export const CONTEXT_ACTIVE_WEBVIEW_PANEL_ID = new RawContextKey('activeWebviewPanelId', '', { + type: 'string', + description: nls.localize('context.activeWebviewId', "The viewType of the currently active webview panel."), +}); + export class WebviewEditor extends EditorPane { public static readonly ID = 'WebviewEditor'; diff --git a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInputSerializer.ts b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInputSerializer.ts index 483a6b37bc9..9adca06119c 100644 --- a/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInputSerializer.ts +++ b/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInputSerializer.ts @@ -80,7 +80,7 @@ export class WebviewEditorInputSerializer implements IEditorSerializer { return this._webviewWorkbenchService.reviveWebview({ webviewInitInfo: { id: data.id, - providedId: data.providedId, + providedViewType: data.providedId, origin: data.origin, options: data.webviewOptions, contentOptions: data.contentOptions, diff --git a/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts b/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts index 00232b050e9..97e206c6ec9 100644 --- a/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts +++ b/src/vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService.ts @@ -10,6 +10,7 @@ import { isCancellationError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { Iterable } from 'vs/base/common/iterator'; import { combinedDisposable, Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { EditorActivation } from 'vs/platform/editor/common/editor'; import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { GroupIdentifier } from 'vs/workbench/common/editor'; @@ -17,6 +18,7 @@ import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { IOverlayWebview, IWebviewService } from 'vs/workbench/contrib/webview/browser/webview'; import { WebviewInitInfo } from 'vs/workbench/contrib/webview/browser/webviewElement'; +import { CONTEXT_ACTIVE_WEBVIEW_PANEL_ID } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditor'; import { WebviewIconManager, WebviewIcons } from 'vs/workbench/contrib/webviewPanel/browser/webviewIconManager'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import { ACTIVE_GROUP_TYPE, IEditorService, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService'; @@ -185,13 +187,18 @@ export class WebviewEditorService extends Disposable implements IWebviewWorkbenc private readonly _iconManager: WebviewIconManager; + private readonly _activeWebviewPanelIdContext: IContextKey; + constructor( + @IContextKeyService contextKeyService: IContextKeyService, @IEditorService private readonly _editorService: IEditorService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IWebviewService private readonly _webviewService: IWebviewService, ) { super(); + this._activeWebviewPanelIdContext = CONTEXT_ACTIVE_WEBVIEW_PANEL_ID.bindTo(contextKeyService); + this._iconManager = this._register(this._instantiationService.createInstance(WebviewIconManager)); this._register(_editorService.onDidActiveEditorChange(() => { @@ -229,6 +236,12 @@ export class WebviewEditorService extends Disposable implements IWebviewWorkbenc } } + if (newActiveWebview) { + this._activeWebviewPanelIdContext.set(newActiveWebview.webview.providedViewType ?? ''); + } else { + this._activeWebviewPanelIdContext.reset(); + } + if (newActiveWebview !== this._activeWebview) { this._activeWebview = newActiveWebview; this._onDidChangeActiveWebviewEditor.fire(newActiveWebview); @@ -242,7 +255,7 @@ export class WebviewEditorService extends Disposable implements IWebviewWorkbenc showOptions: ICreateWebViewShowOptions, ): WebviewInput { const webview = this._webviewService.createWebviewOverlay(webviewInitInfo); - const webviewInput = this._instantiationService.createInstance(WebviewInput, { id: webviewInitInfo.id, viewType, name: title, providedId: webviewInitInfo.providedId }, webview, this.iconManager); + const webviewInput = this._instantiationService.createInstance(WebviewInput, { id: webviewInitInfo.id, viewType, name: title, providedId: webviewInitInfo.providedViewType }, webview, this.iconManager); this._editorService.openEditor(webviewInput, { pinned: true, preserveFocus: showOptions.preserveFocus, @@ -293,7 +306,7 @@ export class WebviewEditorService extends Disposable implements IWebviewWorkbenc const webview = this._webviewService.createWebviewOverlay(options.webviewInitInfo); webview.state = options.state; - const webviewInput = this._instantiationService.createInstance(LazilyResolvedWebviewEditorInput, { id: options.webviewInitInfo.id, viewType: options.viewType, providedId: options.webviewInitInfo.providedId, name: options.title }, webview); + const webviewInput = this._instantiationService.createInstance(LazilyResolvedWebviewEditorInput, { id: options.webviewInitInfo.id, viewType: options.viewType, providedId: options.webviewInitInfo.providedViewType, name: options.title }, webview); webviewInput.iconPath = options.iconPath; if (typeof options.group === 'number') { diff --git a/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts b/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts index 9a149dca7ee..d72f98cb736 100644 --- a/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts +++ b/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts @@ -169,7 +169,7 @@ export class WebviewViewPane extends ViewPane { const webviewId = generateUuid(); const webview = this.webviewService.createWebviewOverlay({ id: webviewId, - providedId: this.id, + providedViewType: this.id, options: { purpose: WebviewContentPurpose.WebviewView }, contentOptions: {}, extension: this.extensionId ? { id: this.extensionId } : undefined From ccbe26bf2f34af2fbfc28fbe235e8aaade10f2d0 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Tue, 2 Aug 2022 22:04:24 -0700 Subject: [PATCH 177/303] use raceTimeout to detect when waiting to resolve takes too long.. and ignore focus out (#156916) --- .../base/parts/quickinput/test/browser/quickinput.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/base/parts/quickinput/test/browser/quickinput.test.ts b/src/vs/base/parts/quickinput/test/browser/quickinput.test.ts index 89f2f212dd4..dc99756b291 100644 --- a/src/vs/base/parts/quickinput/test/browser/quickinput.test.ts +++ b/src/vs/base/parts/quickinput/test/browser/quickinput.test.ts @@ -39,7 +39,7 @@ suite('QuickInput', () => { // https://github.com/microsoft/vscode/issues/147543 controller = new QuickInputController({ container: fixture, idPrefix: 'testQuickInput', - ignoreFocusOut() { return false; }, + ignoreFocusOut() { return true; }, isScreenReaderOptimized() { return false; }, returnFocus() { }, backKeybindingLabel() { return undefined; }, @@ -80,7 +80,7 @@ suite('QuickInput', () => { // https://github.com/microsoft/vscode/issues/147543 await wait; controller.accept(); - const pick = await pickPromise; + const pick = await raceTimeout(pickPromise, 2000); assert.strictEqual(pick, item); }); @@ -104,7 +104,7 @@ suite('QuickInput', () => { // https://github.com/microsoft/vscode/issues/147543 await wait; controller.accept(); - const value = await inputPromise; + const value = await raceTimeout(inputPromise, 2000); assert.strictEqual(value, 'foo'); }); From c62db61006118a9782ba6a93b957eac940154b45 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Tue, 2 Aug 2022 22:24:34 -0700 Subject: [PATCH 178/303] Support `ILocalizedString` in `openCommandActionDescriptor` `title`s (#156921) --- .../parts/activitybar/activitybarPart.ts | 2 +- .../workbench/browser/parts/panel/panelPart.ts | 2 +- .../browser/parts/views/viewsService.ts | 18 +++++++++++------- src/vs/workbench/common/views.ts | 5 +++-- .../debug/browser/debug.contribution.ts | 2 +- .../browser/extensions.contribution.ts | 2 +- .../contrib/files/browser/explorerViewlet.ts | 2 +- .../workbench/contrib/remote/browser/remote.ts | 2 +- .../search/browser/search.contribution.ts | 2 +- .../views/common/viewContainerModel.ts | 4 ++-- 10 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index fedd79ca5e7..6d850ae03eb 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -716,7 +716,7 @@ export class ActivitybarPart extends Part implements IPaneCompositeSelectorPart } private addComposite(viewContainer: ViewContainer): void { - this.compositeBar.addComposite({ id: viewContainer.id, name: viewContainer.title, order: viewContainer.order, requestedIndex: viewContainer.requestedIndex }); + this.compositeBar.addComposite({ id: viewContainer.id, name: typeof viewContainer.title === 'string' ? viewContainer.title : viewContainer.title.value, order: viewContainer.order, requestedIndex: viewContainer.requestedIndex }); } private hideComposite(compositeId: string): void { diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 5d299207fe5..895149abf1c 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -374,7 +374,7 @@ export abstract class BasePanelPart extends CompositePart impleme } if (viewContainerModel.activeViewDescriptors.length) { contextKey.set(true); - this.compositeBar.addComposite({ id: viewContainer.id, name: viewContainer.title, order: viewContainer.order, requestedIndex: viewContainer.requestedIndex }); + this.compositeBar.addComposite({ id: viewContainer.id, name: typeof viewContainer.title === 'string' ? viewContainer.title : viewContainer.title.value, order: viewContainer.order, requestedIndex: viewContainer.requestedIndex }); if (this.layoutService.isRestored() && this.layoutService.isVisible(this.partId)) { const activeComposite = this.getActiveComposite(); diff --git a/src/vs/workbench/browser/parts/views/viewsService.ts b/src/vs/workbench/browser/parts/views/viewsService.ts index f5b267eff35..066cdd6651f 100644 --- a/src/vs/workbench/browser/parts/views/viewsService.ts +++ b/src/vs/workbench/browser/parts/views/viewsService.ts @@ -337,8 +337,8 @@ export class ViewsService extends Disposable implements IViewsService { private registerOpenViewContainerAction(viewContainer: ViewContainer): IDisposable { const disposables = new DisposableStore(); if (viewContainer.openCommandActionDescriptor) { - let { id, title, mnemonicTitle, keybindings, order } = viewContainer.openCommandActionDescriptor ?? { id: viewContainer.id }; - title = title ?? viewContainer.title; + const { id, mnemonicTitle, keybindings, order } = viewContainer.openCommandActionDescriptor ?? { id: viewContainer.id }; + const title = viewContainer.openCommandActionDescriptor.title ?? viewContainer.title; const that = this; disposables.add(registerAction2(class OpenViewContainerAction extends Action2 { constructor() { @@ -346,10 +346,12 @@ export class ViewsService extends Disposable implements IViewsService { id, get title(): ICommandActionTitle { const viewContainerLocation = that.viewDescriptorService.getViewContainerLocation(viewContainer); + const localizedTitle = typeof title === 'string' ? title : title.value; + const originalTitle = typeof title === 'string' ? title : title.original; if (viewContainerLocation === ViewContainerLocation.Sidebar) { - return { value: localize('show view', "Show {0}", title), original: `Show ${title}` }; + return { value: localize('show view', "Show {0}", localizedTitle), original: `Show ${originalTitle}` }; } else { - return { value: localize('toggle view', "Toggle {0}", title), original: `Toggle ${title}` }; + return { value: localize('toggle view', "Toggle {0}", localizedTitle), original: `Toggle ${originalTitle}` }; } }, category: CATEGORIES.View, @@ -412,10 +414,12 @@ export class ViewsService extends Disposable implements IViewsService { id: commandId, get title(): ICommandActionTitle { const viewContainerLocation = that.viewDescriptorService.getViewLocationById(viewDescriptor.id); + const localizedTitle = typeof title === 'string' ? title : title.value; + const originalTitle = typeof title === 'string' ? title : title.original; if (viewContainerLocation === ViewContainerLocation.Sidebar) { - return { value: localize('show view', "Show {0}", title), original: `Show ${title}` }; + return { value: localize('show view', "Show {0}", localizedTitle), original: `Show ${originalTitle}` }; } else { - return { value: localize('toggle view', "Toggle {0}", title), original: `Toggle ${title}` }; + return { value: localize('toggle view', "Toggle {0}", localizedTitle), original: `Toggle ${originalTitle}` }; } }, category: CATEGORIES.View, @@ -589,7 +593,7 @@ export class ViewsService extends Disposable implements IViewsService { Registry.as(getPaneCompositeExtension(viewContainerLocation)).registerPaneComposite(PaneCompositeDescriptor.create( PaneContainer, viewContainer.id, - viewContainer.title, + typeof viewContainer.title === 'string' ? viewContainer.title : viewContainer.title.value, isString(viewContainer.icon) ? viewContainer.icon : undefined, viewContainer.order, viewContainer.requestedIndex, diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index ac9b39c0c21..e7897261291 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -28,6 +28,7 @@ import { Codicon } from 'vs/base/common/codicons'; import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; import { CancellationToken } from 'vs/base/common/cancellation'; import { VSDataTransfer } from 'vs/base/common/dataTransfer'; +import { ILocalizedString } from 'vs/platform/action/common/action'; export const defaultViewIcon = registerIcon('default-view-icon', Codicon.window, localize('defaultViewIcon', 'Default view icon.')); @@ -54,7 +55,7 @@ export function ViewContainerLocationToString(viewContainerLocation: ViewContain type OpenCommandActionDescriptor = { readonly id: string; - readonly title?: string; + readonly title?: ILocalizedString | string; readonly mnemonicTitle?: string; readonly order?: number; readonly keybindings?: IKeybindings & { when?: ContextKeyExpression }; @@ -74,7 +75,7 @@ export interface IViewContainerDescriptor { /** * The title of the view container */ - readonly title: string; + readonly title: ILocalizedString | string; /** * Icon representation of the View container diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index ebedc061c54..0f3c3ada7ec 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -394,7 +394,7 @@ Registry.as(ViewExtensions.ViewsRegistry).registerViews([{ const viewContainer = Registry.as(ViewExtensions.ViewContainersRegistry).registerViewContainer({ id: VIEWLET_ID, - title: nls.localize('run and debug', "Run and Debug"), + title: { value: nls.localize('run and debug', "Run and Debug"), original: 'Run and Debug' }, openCommandActionDescriptor: { id: VIEWLET_ID, mnemonicTitle: nls.localize({ key: 'miViewRun', comment: ['&& denotes a mnemonic'] }, "&&Run"), diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 6c9c087bb9b..42582c84189 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -110,7 +110,7 @@ Registry.as(EditorExtensions.EditorPane).registerEditorPane Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer( { id: VIEWLET_ID, - title: localize('extensions', "Extensions"), + title: { value: localize('extensions', "Extensions"), original: 'Extensions' }, openCommandActionDescriptor: { id: VIEWLET_ID, mnemonicTitle: localize({ key: 'miViewExtensions', comment: ['&& denotes a mnemonic'] }, "E&&xtensions"), diff --git a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts index 6188a5bcb86..13d8f79d604 100644 --- a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts +++ b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts @@ -272,7 +272,7 @@ export const VIEW_CONTAINER: ViewContainer = viewContainerRegistry.registerViewC order: 0, openCommandActionDescriptor: { id: VIEWLET_ID, - title: localize('explore', "Explorer"), + title: { value: localize('explore', "Explorer"), original: 'Explorer' }, mnemonicTitle: localize({ key: 'miViewExplorer', comment: ['&& denotes a mnemonic'] }, "&&Explorer"), keybindings: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyE }, order: 0 diff --git a/src/vs/workbench/contrib/remote/browser/remote.ts b/src/vs/workbench/contrib/remote/browser/remote.ts index 8d3bf427980..c8aa533f654 100644 --- a/src/vs/workbench/contrib/remote/browser/remote.ts +++ b/src/vs/workbench/contrib/remote/browser/remote.ts @@ -549,7 +549,7 @@ registerAction2(SwitchRemoteAction); Registry.as(Extensions.ViewContainersRegistry).registerViewContainer( { id: VIEWLET_ID, - title: nls.localize('remote.explorer', "Remote Explorer"), + title: { value: nls.localize('remote.explorer', "Remote Explorer"), original: 'Remote Explorer' }, ctorDescriptor: new SyncDescriptor(RemoteViewPaneContainer), hideIfEmpty: true, viewOrderDelegate: { diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 9a7057668d8..97fddaac66e 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -638,7 +638,7 @@ const SEARCH_MODE_CONFIG = 'search.mode'; const viewContainer = Registry.as(ViewExtensions.ViewContainersRegistry).registerViewContainer({ id: VIEWLET_ID, - title: nls.localize('name', "Search"), + title: { value: nls.localize('name', "Search"), original: 'Search' }, ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [VIEWLET_ID, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }]), hideIfEmpty: true, icon: searchViewIcon, diff --git a/src/vs/workbench/services/views/common/viewContainerModel.ts b/src/vs/workbench/services/views/common/viewContainerModel.ts index 3df7d12368f..0418f5ee6cd 100644 --- a/src/vs/workbench/services/views/common/viewContainerModel.ts +++ b/src/vs/workbench/services/views/common/viewContainerModel.ts @@ -352,7 +352,7 @@ export class ViewContainerModel extends Disposable implements IViewContainerMode super(); this._register(Event.filter(contextKeyService.onDidChangeContext, e => e.affectsSome(this.contextKeys))(() => this.onDidChangeContext())); - this.viewDescriptorsState = this._register(instantiationService.createInstance(ViewDescriptorsState, viewContainer.storageId || `${viewContainer.id}.state`, viewContainer.title)); + this.viewDescriptorsState = this._register(instantiationService.createInstance(ViewDescriptorsState, viewContainer.storageId || `${viewContainer.id}.state`, typeof viewContainer.title === 'string' ? viewContainer.title : viewContainer.title.original)); this._register(this.viewDescriptorsState.onDidChangeStoredState(items => this.updateVisibility(items))); this._register(Event.any( @@ -370,7 +370,7 @@ export class ViewContainerModel extends Disposable implements IViewContainerMode private updateContainerInfo(): void { /* Use default container info if one of the visible view descriptors belongs to the current container by default */ const useDefaultContainerInfo = this.viewContainer.alwaysUseContainerInfo || this.visibleViewDescriptors.length === 0 || this.visibleViewDescriptors.some(v => Registry.as(ViewExtensions.ViewsRegistry).getViewContainer(v.id) === this.viewContainer); - const title = useDefaultContainerInfo ? this.viewContainer.title : this.visibleViewDescriptors[0]?.containerTitle || this.visibleViewDescriptors[0]?.name || ''; + const title = useDefaultContainerInfo ? (typeof this.viewContainer.title === 'string' ? this.viewContainer.title : this.viewContainer.title.value) : this.visibleViewDescriptors[0]?.containerTitle || this.visibleViewDescriptors[0]?.name || ''; let titleChanged: boolean = false; if (this._title !== title) { this._title = title; From bc137bb7452fad93433506e6fb6d369ecdb68ed1 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 3 Aug 2022 08:50:02 +0200 Subject: [PATCH 179/303] Fix #154072 (#156968) * Fix #154072 * fix compilation errors --- .../platform/sharedProcess/node/sharedProcess.ts | 2 +- .../userDataProfile/common/userDataProfile.ts | 4 ++-- .../electron-sandbox/userDataProfile.ts | 2 +- src/vs/platform/window/common/window.ts | 2 +- .../userDataProfile/browser/userDataProfile.ts | 3 ++- .../common/userDataProfileActions.ts | 15 +++++++++------ 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/vs/platform/sharedProcess/node/sharedProcess.ts b/src/vs/platform/sharedProcess/node/sharedProcess.ts index dafb357ea16..97c71c41b91 100644 --- a/src/vs/platform/sharedProcess/node/sharedProcess.ts +++ b/src/vs/platform/sharedProcess/node/sharedProcess.ts @@ -29,7 +29,7 @@ export interface ISharedProcessConfiguration extends ISandboxConfiguration { readonly backupWorkspacesPath: string; - readonly profiles: UriDto[]; + readonly profiles: readonly UriDto[]; readonly policiesData?: IStringDictionary<{ definition: PolicyDefinition; value: PolicyValue }>; } diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index b2064a7698f..1d3cc902349 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -69,7 +69,7 @@ export const PROFILES_ENABLEMENT_CONFIG = 'workbench.experimental.settingsProfil export type EmptyWindowWorkspaceIdentifier = 'empty-window'; export type WorkspaceIdentifier = ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier | EmptyWindowWorkspaceIdentifier; -export type DidChangeProfilesEvent = { readonly added: IUserDataProfile[]; readonly removed: IUserDataProfile[]; readonly updated: IUserDataProfile[]; readonly all: IUserDataProfile[] }; +export type DidChangeProfilesEvent = { readonly added: readonly IUserDataProfile[]; readonly removed: readonly IUserDataProfile[]; readonly updated: readonly IUserDataProfile[]; readonly all: readonly IUserDataProfile[] }; export type WillCreateProfileEvent = { profile: IUserDataProfile; @@ -89,7 +89,7 @@ export interface IUserDataProfilesService { readonly defaultProfile: IUserDataProfile; readonly onDidChangeProfiles: Event; - readonly profiles: IUserDataProfile[]; + readonly profiles: readonly IUserDataProfile[]; readonly onDidResetWorkspaces: Event; diff --git a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts index 113012688aa..f1fd6c1afa9 100644 --- a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts @@ -32,7 +32,7 @@ export class UserDataProfilesNativeService extends Disposable implements IUserDa readonly onDidResetWorkspaces: Event; constructor( - profiles: UriDto[], + profiles: readonly UriDto[], @IMainProcessService mainProcessService: IMainProcessService, @IEnvironmentService environmentService: IEnvironmentService, ) { diff --git a/src/vs/platform/window/common/window.ts b/src/vs/platform/window/common/window.ts index 237d73c3888..5aa516550f0 100644 --- a/src/vs/platform/window/common/window.ts +++ b/src/vs/platform/window/common/window.ts @@ -289,7 +289,7 @@ export interface INativeWindowConfiguration extends IWindowConfiguration, Native backupPath?: string; profiles: { - all: UriDto[]; + all: readonly UriDto[]; current: UriDto; }; diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index 324069eb10a..cfe0b76ee07 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -20,6 +20,7 @@ import { IUserDataProfile, IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; +import { SwitchProfileAction } from 'vs/workbench/contrib/userDataProfile/common/userDataProfileActions'; import { IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from 'vs/workbench/services/statusbar/browser/statusbar'; import { CURRENT_PROFILE_CONTEXT, HAS_PROFILES_CONTEXT, IUserDataProfileManagementService, IUserDataProfileService, ManageProfilesSubMenu, PROFILES_CATEGORY, PROFILES_ENABLEMENT_CONTEXT, PROFILES_TTILE } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; @@ -143,7 +144,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements if (this.userDataProfilesService.profiles.length > 1) { const statusBarEntry: IStatusbarEntry = { name: PROFILES_CATEGORY, - command: 'workbench.profiles.actions.switchProfile', + command: SwitchProfileAction.ID, ariaLabel: localize('currentProfile', "Current Settings Profile is {0}", this.userDataProfileService.currentProfile.name), text: `$(${userDataProfilesIcon.id}) ${this.userDataProfileService.currentProfile.name!}`, tooltip: localize('profileTooltip', "{0}: {1}", PROFILES_CATEGORY, this.userDataProfileService.currentProfile.name), diff --git a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts index 92696e458c8..10d756100ee 100644 --- a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts +++ b/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts @@ -21,6 +21,8 @@ import { CATEGORIES } from 'vs/workbench/common/actions'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ICommandService } from 'vs/platform/commands/common/commands'; +import { compare } from 'vs/base/common/strings'; +import { Codicon } from 'vs/base/common/codicons'; class CreateFromCurrentProfileAction extends Action2 { static readonly ID = 'workbench.profiles.actions.createFromCurrentProfile'; @@ -260,10 +262,11 @@ registerAction2(class DeleteProfileAction extends Action2 { } }); -registerAction2(class SwitchProfileAction extends Action2 { +export class SwitchProfileAction extends Action2 { + static readonly ID = 'workbench.profiles.actions.switchProfile'; constructor() { super({ - id: 'workbench.profiles.actions.switchProfile', + id: SwitchProfileAction.ID, title: { value: localize('switch profile', "Switch..."), original: 'Switch...' @@ -280,11 +283,10 @@ registerAction2(class SwitchProfileAction extends Action2 { const userDataProfilesService = accessor.get(IUserDataProfilesService); const userDataProfileManagementService = accessor.get(IUserDataProfileManagementService); - const profiles = userDataProfilesService.profiles; + const profiles = userDataProfilesService.profiles.slice(0).sort((a, b) => compare(a.name, b.name)); if (profiles.length) { const picks: Array = profiles.map(profile => ({ - label: profile.name!, - description: profile.name === userDataProfileService.currentProfile.name ? localize('current', "Current") : undefined, + label: `${profile.name}${profile.id === userDataProfileService.currentProfile.id ? ` $(${Codicon.check.id})` : ''}`, profile })); const pick = await quickInputService.pick(picks, { placeHolder: localize('pick profile', "Select Settings Profile") }); @@ -293,7 +295,8 @@ registerAction2(class SwitchProfileAction extends Action2 { } } } -}); +} +registerAction2(SwitchProfileAction); registerAction2(class ExportProfileAction extends Action2 { constructor() { From 88c5ba1a8a372bc3dcf85397453d8eed0348245a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 3 Aug 2022 08:57:19 +0200 Subject: [PATCH 180/303] use last active profile in web (#156966) * use last active profile in web * :lipstick: Co-authored-by: Benjamin Pasero --- .../userDataProfile/common/userDataProfile.ts | 4 +++ src/vs/workbench/browser/web.main.ts | 4 ++- .../environment/browser/environmentService.ts | 3 +++ .../host/browser/browserHostService.ts | 25 ++++++++++++------- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 1d3cc902349..9df1359aed6 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -225,6 +225,10 @@ export class UserDataProfilesService extends Disposable implements IUserDataProf } getProfile(workspaceIdentifier: WorkspaceIdentifier, profileToUseIfNotSet: IUserDataProfile): IUserDataProfile { + if (!this.enabled) { + return this.defaultProfile; + } + const workspace = this.getWorkspace(workspaceIdentifier); let profile = URI.isUri(workspace) ? this.profilesObject.workspaces.get(workspace) : this.profilesObject.emptyWindow; if (!profile) { diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index b36b008adce..2e744b847fa 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -269,7 +269,9 @@ export class BrowserMain extends Disposable { // User Data Profiles const userDataProfilesService = new BrowserUserDataProfilesService(environmentService, fileService, uriIdentityService, logService); serviceCollection.set(IUserDataProfilesService, userDataProfilesService); - const userDataProfileService = new UserDataProfileService(userDataProfilesService.getProfile(isWorkspaceIdentifier(payload) || isSingleFolderWorkspaceIdentifier(payload) ? payload : 'empty-window', userDataProfilesService.defaultProfile), userDataProfilesService); + const lastActiveProfile = environmentService.lastActiveProfile ? userDataProfilesService.profiles.find(p => p.id === environmentService.lastActiveProfile) : undefined; + const currentProfile = userDataProfilesService.getProfile(isWorkspaceIdentifier(payload) || isSingleFolderWorkspaceIdentifier(payload) ? payload : 'empty-window', lastActiveProfile ?? userDataProfilesService.defaultProfile); + const userDataProfileService = new UserDataProfileService(currentProfile, userDataProfilesService); serviceCollection.set(IUserDataProfileService, userDataProfileService); // Long running services (workspace, config, storage) diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index 122eba1dec7..1ed00644937 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -208,6 +208,9 @@ export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvi @memoize get disableWorkspaceTrust(): boolean { return !this.options.enableWorkspaceTrust; } + @memoize + get lastActiveProfile(): string | undefined { return this.payload?.get('lastActiveProfile'); } + editSessionId: string | undefined = this.options.editSessionId; private payload: Map | undefined; diff --git a/src/vs/workbench/services/host/browser/browserHostService.ts b/src/vs/workbench/services/host/browser/browserHostService.ts index 25fca6a0136..efba94ca42a 100644 --- a/src/vs/workbench/services/host/browser/browserHostService.ts +++ b/src/vs/workbench/services/host/browser/browserHostService.ts @@ -35,6 +35,7 @@ import { isTemporaryWorkspace, IWorkspaceContextService } from 'vs/platform/work import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { Schemas } from 'vs/base/common/network'; import { ITextEditorOptions } from 'vs/platform/editor/common/editor'; +import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; /** * A workspace to open in the workbench can either be: @@ -112,7 +113,8 @@ export class BrowserHostService extends Disposable implements IHostService { @ILifecycleService private readonly lifecycleService: BrowserLifecycleService, @ILogService private readonly logService: ILogService, @IDialogService private readonly dialogService: IDialogService, - @IWorkspaceContextService private readonly contextService: IWorkspaceContextService + @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, + @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, ) { super(); @@ -214,7 +216,7 @@ export class BrowserHostService extends Disposable implements IHostService { } private async doOpenWindow(toOpen: IWindowOpenable[], options?: IOpenWindowOptions): Promise { - const payload = this.preservePayload(); + const payload = this.preservePayload(false /* not an empty window */); const fileOpenables: IFileToOpen[] = []; const foldersToAdd: IWorkspaceFolderCreationData[] = []; @@ -371,13 +373,11 @@ export class BrowserHostService extends Disposable implements IHostService { this.instantiationService.invokeFunction(accessor => fn(accessor)); } - private preservePayload(): Array | undefined { + private preservePayload(isEmptyWindow: boolean): Array | undefined { // Selectively copy payload: for now only extension debugging properties are considered - let newPayload: Array | undefined = undefined; - if (this.environmentService.extensionDevelopmentLocationURI) { - newPayload = new Array(); - + const newPayload: Array = new Array(); + if (!isEmptyWindow && this.environmentService.extensionDevelopmentLocationURI) { newPayload.push(['extensionDevelopmentPath', this.environmentService.extensionDevelopmentLocationURI.toString()]); if (this.environmentService.debugExtensionHost.debugId) { @@ -389,7 +389,11 @@ export class BrowserHostService extends Disposable implements IHostService { } } - return newPayload; + if (!this.userDataProfileService.currentProfile.isDefault) { + newPayload.push(['lastActiveProfile', this.userDataProfileService.currentProfile.id]); + } + + return newPayload.length ? newPayload : undefined; } private getRecentLabel(openable: IWindowOpenable): string { @@ -421,7 +425,10 @@ export class BrowserHostService extends Disposable implements IHostService { } private async doOpenEmptyWindow(options?: IOpenEmptyWindowOptions): Promise { - return this.doOpen(undefined, { reuse: options?.forceReuseWindow }); + return this.doOpen(undefined, { + reuse: options?.forceReuseWindow, + payload: this.preservePayload(true /* empty window */) + }); } private async doOpen(workspace: IWorkspace, options?: { reuse?: boolean; payload?: object }): Promise { From 8125126a0324c115c06ca0b4390e1a58604831f3 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 3 Aug 2022 09:07:00 +0200 Subject: [PATCH 181/303] `window` => `windowImpl` (#156970) --- .../platform/windows/electron-main/{window.ts => windowImpl.ts} | 0 src/vs/platform/windows/electron-main/windowsMainService.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/vs/platform/windows/electron-main/{window.ts => windowImpl.ts} (100%) diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/windowImpl.ts similarity index 100% rename from src/vs/platform/windows/electron-main/window.ts rename to src/vs/platform/windows/electron-main/windowImpl.ts diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index b287f30732d..7aa556e2c7a 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -39,7 +39,7 @@ import { IProtocolMainService } from 'vs/platform/protocol/electron-main/protoco import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; import { IStateMainService } from 'vs/platform/state/electron-main/state'; import { IAddFoldersRequest, INativeOpenFileRequest, INativeWindowConfiguration, IOpenEmptyWindowOptions, IPath, IPathsToWaitFor, isFileToOpen, isFolderToOpen, isWorkspaceToOpen, IWindowOpenable, IWindowSettings } from 'vs/platform/window/common/window'; -import { CodeWindow } from 'vs/platform/windows/electron-main/window'; +import { CodeWindow } from 'vs/platform/windows/electron-main/windowImpl'; import { IOpenConfiguration, IOpenEmptyConfiguration, IWindowsCountChangedEvent, IWindowsMainService, OpenContext } from 'vs/platform/windows/electron-main/windows'; import { findWindowOnExtensionDevelopmentPath, findWindowOnFile, findWindowOnWorkspaceOrFolder } from 'vs/platform/windows/electron-main/windowsFinder'; import { IWindowState, WindowsStateHandler } from 'vs/platform/windows/electron-main/windowsStateHandler'; From f8ae10c8d05cf92f55c19b4937f0a5c5c0498778 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 3 Aug 2022 09:41:12 +0200 Subject: [PATCH 182/303] Piping into Code fails if data writes delayed (fix #155341) (#156973) --- src/vs/code/node/cli.ts | 2 +- src/vs/platform/environment/node/stdin.ts | 15 +++++++++++---- src/vs/server/node/server.cli.ts | 9 +++++---- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 3a006e635a3..0c2429c97e0 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -179,7 +179,7 @@ export async function main(argv: string[]): Promise { // returns a file path where stdin input is written into (write in progress). try { - readFromStdin(stdinFilePath, !!verbose); // throws error if file can not be written + await readFromStdin(stdinFilePath, !!verbose); // throws error if file can not be written // Make sure to open tmp file addArg(argv, stdinFilePath); diff --git a/src/vs/platform/environment/node/stdin.ts b/src/vs/platform/environment/node/stdin.ts index 27c30eb1e20..9bceca5ec47 100644 --- a/src/vs/platform/environment/node/stdin.ts +++ b/src/vs/platform/environment/node/stdin.ts @@ -39,26 +39,33 @@ export function getStdinFilePath(): string { } export async function readFromStdin(targetPath: string, verbose: boolean): Promise { - let encoding = await resolveTerminalEncoding(verbose); - const iconv = await import('@vscode/iconv-lite-umd'); + let [encoding, iconv] = await Promise.all([ + resolveTerminalEncoding(verbose), // respect terminal encoding when piping into file + import('@vscode/iconv-lite-umd'), // lazy load encoding module for usage + Promises.appendFile(targetPath, '') // make sure file exists right away (https://github.com/microsoft/vscode/issues/155341) + ]); + if (!iconv.encodingExists(encoding)) { console.log(`Unsupported terminal encoding: ${encoding}, falling back to UTF-8.`); encoding = 'utf8'; } - // Pipe into tmp file using terminals encoding // Use a `Queue` to be able to use `appendFile` // which helps file watchers to be aware of the // changes because each append closes the underlying // file descriptor. // (https://github.com/microsoft/vscode/issues/148952) - const decoder = iconv.getDecoder(encoding); + const appendFileQueue = new Queue(); + + const decoder = iconv.getDecoder(encoding); + process.stdin.on('data', chunk => { const chunkStr = decoder.write(chunk); appendFileQueue.queue(() => Promises.appendFile(targetPath, chunkStr)); }); + process.stdin.on('end', () => { const end = decoder.end(); if (typeof end === 'string') { diff --git a/src/vs/server/node/server.cli.ts b/src/vs/server/node/server.cli.ts index 837b0b500d4..650552d798d 100644 --- a/src/vs/server/node/server.cli.ts +++ b/src/vs/server/node/server.cli.ts @@ -87,7 +87,7 @@ const cliRemoteAuthority = process.env['VSCODE_CLI_AUTHORITY'] as string; const cliStdInFilePath = process.env['VSCODE_STDIN_FILE_PATH'] as string; -export function main(desc: ProductDescription, args: string[]): void { +export async function main(desc: ProductDescription, args: string[]): Promise { if (!cliPipe && !cliCommand) { console.log('Command is only available in WSL or inside a Visual Studio Code terminal.'); return; @@ -184,7 +184,7 @@ export function main(desc: ProductDescription, args: string[]): void { let stdinFilePath = cliStdInFilePath; if (!stdinFilePath) { stdinFilePath = getStdinFilePath(); - readFromStdin(stdinFilePath, verbose); // throws error if file can not be written + await readFromStdin(stdinFilePath, verbose); // throws error if file can not be written } // Make sure to open tmp file @@ -460,5 +460,6 @@ function mapFileToRemoteUri(uri: string): string { } const [, , productName, version, commit, executableName, ...remainingArgs] = process.argv; -main({ productName, version, commit, executableName }, remainingArgs); - +main({ productName, version, commit, executableName }, remainingArgs).then(null, err => { + console.error(err.message || err.stack || err); +}); From dd2e6f4175a50b35604bb4c8bda20be41f2041b3 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 3 Aug 2022 09:46:29 +0200 Subject: [PATCH 183/303] Fix #154077 (#156975) * Fix #154077 * dispose --- .../browser/userDataProfile.contribution.ts | 2 +- .../browser/userDataProfile.ts | 4 +- .../userDataProfileActions.ts | 59 ++++++++++++++++--- 3 files changed, 55 insertions(+), 10 deletions(-) rename src/vs/workbench/contrib/userDataProfile/{common => browser}/userDataProfileActions.ts (90%) diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.contribution.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.contribution.ts index ae8e9bbaf5d..b069dea82cd 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.contribution.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.contribution.ts @@ -7,7 +7,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchContributionsRegistry, Extensions } from 'vs/workbench/common/contributions'; import { UserDataProfilesWorkbenchContribution } from 'vs/workbench/contrib/userDataProfile/browser/userDataProfile'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; -import '../common/userDataProfileActions'; +import './userDataProfileActions'; const workbenchRegistry = Registry.as(Extensions.Workbench); workbenchRegistry.registerWorkbenchContribution(UserDataProfilesWorkbenchContribution, LifecyclePhase.Ready); diff --git a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts index cfe0b76ee07..cb4ef584daf 100644 --- a/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts @@ -20,7 +20,7 @@ import { IUserDataProfile, IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { SwitchProfileAction } from 'vs/workbench/contrib/userDataProfile/common/userDataProfileActions'; +import { MangeSettingsProfileAction } from 'vs/workbench/contrib/userDataProfile/browser/userDataProfileActions'; import { IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from 'vs/workbench/services/statusbar/browser/statusbar'; import { CURRENT_PROFILE_CONTEXT, HAS_PROFILES_CONTEXT, IUserDataProfileManagementService, IUserDataProfileService, ManageProfilesSubMenu, PROFILES_CATEGORY, PROFILES_ENABLEMENT_CONTEXT, PROFILES_TTILE } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; @@ -144,7 +144,7 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements if (this.userDataProfilesService.profiles.length > 1) { const statusBarEntry: IStatusbarEntry = { name: PROFILES_CATEGORY, - command: SwitchProfileAction.ID, + command: MangeSettingsProfileAction.ID, ariaLabel: localize('currentProfile', "Current Settings Profile is {0}", this.userDataProfileService.currentProfile.name), text: `$(${userDataProfilesIcon.id}) ${this.userDataProfileService.currentProfile.name!}`, tooltip: localize('profileTooltip', "{0}: {1}", PROFILES_CATEGORY, this.userDataProfileService.currentProfile.name), diff --git a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfileActions.ts similarity index 90% rename from src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts rename to src/vs/workbench/contrib/userDataProfile/browser/userDataProfileActions.ts index 10d756100ee..22d3d0992c8 100644 --- a/src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts +++ b/src/vs/workbench/contrib/userDataProfile/browser/userDataProfileActions.ts @@ -7,12 +7,12 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { joinPath } from 'vs/base/common/resources'; import { localize } from 'vs/nls'; -import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; +import { Action2, IMenuService, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IFileService } from 'vs/platform/files/common/files'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { asJson, asText, IRequestService } from 'vs/platform/request/common/request'; import { IUserDataProfileTemplate, isUserDataProfileTemplate, IUserDataProfileManagementService, IUserDataProfileImportExportService, PROFILES_CATEGORY, PROFILE_EXTENSION, PROFILE_FILTER, ManageProfilesSubMenu, IUserDataProfileService, PROFILES_ENABLEMENT_CONTEXT, HAS_PROFILES_CONTEXT } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; @@ -23,6 +23,8 @@ import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/commo import { ICommandService } from 'vs/platform/commands/common/commands'; import { compare } from 'vs/base/common/strings'; import { Codicon } from 'vs/base/common/codicons'; +import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; +import { IAction, Separator } from 'vs/base/common/actions'; class CreateFromCurrentProfileAction extends Action2 { static readonly ID = 'workbench.profiles.actions.createFromCurrentProfile'; @@ -262,11 +264,55 @@ registerAction2(class DeleteProfileAction extends Action2 { } }); -export class SwitchProfileAction extends Action2 { - static readonly ID = 'workbench.profiles.actions.switchProfile'; +export class MangeSettingsProfileAction extends Action2 { + static readonly ID = 'workbench.profiles.actions.manage'; constructor() { super({ - id: SwitchProfileAction.ID, + id: MangeSettingsProfileAction.ID, + title: { + value: localize('mange', "Manage..."), + original: 'Manage...' + }, + category: PROFILES_CATEGORY, + precondition: ContextKeyExpr.and(PROFILES_ENABLEMENT_CONTEXT, HAS_PROFILES_CONTEXT), + }); + } + + async run(accessor: ServicesAccessor) { + const quickInputService = accessor.get(IQuickInputService); + const menuService = accessor.get(IMenuService); + const contextKeyService = accessor.get(IContextKeyService); + const commandService = accessor.get(ICommandService); + + const disposables = new DisposableStore(); + const menu = disposables.add(menuService.createMenu(ManageProfilesSubMenu, contextKeyService)); + const actions: IAction[] = []; + disposables.add(createAndFillInActionBarActions(menu, undefined, actions)); + disposables.dispose(); + + if (actions.length) { + const picks: (IQuickPickItem | IQuickPickSeparator)[] = actions.map(action => { + if (action instanceof Separator) { + return { type: 'separator' }; + } + return { + id: action.id, + label: `${action.label}${action.checked ? ` $(${Codicon.check.id})` : ''}`, + }; + }); + const pick = await quickInputService.pick(picks, { canPickMany: false }); + if (pick?.id) { + await commandService.executeCommand(pick.id); + } + } + } +} +registerAction2(MangeSettingsProfileAction); + +registerAction2(class SwitchProfileAction extends Action2 { + constructor() { + super({ + id: 'workbench.profiles.actions.switchProfile', title: { value: localize('switch profile', "Switch..."), original: 'Switch...' @@ -295,8 +341,7 @@ export class SwitchProfileAction extends Action2 { } } } -} -registerAction2(SwitchProfileAction); +}); registerAction2(class ExportProfileAction extends Action2 { constructor() { From d6392016e6ab4a2d9a891ccea927fe088a022bba Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 3 Aug 2022 03:02:29 -0700 Subject: [PATCH 184/303] Add smooth scrolling setting Fixes #125950 --- src/vs/platform/terminal/common/terminal.ts | 3 ++- .../contrib/terminal/browser/xterm/xtermTerminal.ts | 5 ++++- src/vs/workbench/contrib/terminal/common/terminal.ts | 1 + .../contrib/terminal/common/terminalConfiguration.ts | 5 +++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 3f56c931175..ad7c40b1c3c 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -112,7 +112,8 @@ export const enum TerminalSettingId { ShellIntegrationDecorationIcon = 'terminal.integrated.shellIntegration.decorationIcon', ShellIntegrationDecorationIconError = 'terminal.integrated.shellIntegration.decorationIconError', ShellIntegrationDecorationIconSuccess = 'terminal.integrated.shellIntegration.decorationIconSuccess', - ShellIntegrationCommandHistory = 'terminal.integrated.shellIntegration.history' + ShellIntegrationCommandHistory = 'terminal.integrated.shellIntegration.history', + SmoothScrolling = 'terminal.integrated.smoothScrolling' } export const enum TerminalLogConstants { diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index f4cc3403c1a..4abe696bc03 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -42,6 +42,7 @@ import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProc // which suggests the fallback DOM-based renderer const SLOW_CANVAS_RENDER_THRESHOLD = 50; const NUMBER_OF_FRAMES_TO_MEASURE = 20; +const SMOOTH_SCROLL_DURATION = 125; let CanvasAddon: typeof CanvasAddonType; let SearchAddon: typeof SearchAddonType; @@ -144,7 +145,8 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II fastScrollSensitivity: config.fastScrollSensitivity, scrollSensitivity: config.mouseWheelScrollSensitivity, wordSeparator: config.wordSeparators, - overviewRulerWidth: 10 + overviewRulerWidth: 10, + smoothScrollDuration: config.smoothScrolling ? SMOOTH_SCROLL_DURATION : 0 })); this._core = (this.raw as any)._core as IXtermCore; @@ -242,6 +244,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II this.raw.options.rightClickSelectsWord = config.rightClickBehavior === 'selectWord'; this.raw.options.wordSeparator = config.wordSeparators; this.raw.options.customGlyphs = config.customGlyphs; + this.raw.options.smoothScrollDuration = config.smoothScrolling ? SMOOTH_SCROLL_DURATION : 0; if (this._shouldLoadWebgl()) { this._enableWebglRenderer(); } else { diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index e935775fcd3..4552c855bc6 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -302,6 +302,7 @@ export interface ITerminalConfiguration { enabled: boolean; decorationsEnabled: boolean; }; + smoothScrolling: boolean; } export const DEFAULT_LOCAL_ECHO_EXCLUDE: ReadonlyArray = ['vim', 'vi', 'nano', 'tmux']; diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index c5b6caee4af..d03469379e1 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -569,6 +569,11 @@ const terminalConfiguration: IConfigurationNode = { type: 'number', default: 100 }, + [TerminalSettingId.SmoothScrolling]: { + markdownDescription: localize('terminal.integrated.smoothScrolling', "Controls whether the terminal will scroll using an animation."), + type: 'boolean', + default: false + }, } }; From 67a1aa5cad1c711b054e7990da0191ac9938d8a1 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 3 Aug 2022 03:17:22 -0700 Subject: [PATCH 185/303] Support inactive selection background in terminal Fixes #156985 --- .../contrib/terminal/browser/xterm/xtermTerminal.ts | 4 +++- .../contrib/terminal/common/terminalColorRegistry.ts | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index 4abe696bc03..8a1ace0221c 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -28,7 +28,7 @@ import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeServic import { IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views'; import { editorBackground } from 'vs/platform/theme/common/colorRegistry'; import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; -import { TERMINAL_FOREGROUND_COLOR, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, ansiColorIdentifiers, TERMINAL_SELECTION_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_HIGHLIGHT_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_BORDER_COLOR, TERMINAL_OVERVIEW_RULER_FIND_MATCH_FOREGROUND_COLOR, TERMINAL_FIND_MATCH_HIGHLIGHT_BORDER_COLOR, TERMINAL_OVERVIEW_RULER_CURSOR_FOREGROUND_COLOR, TERMINAL_SELECTION_FOREGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; +import { TERMINAL_FOREGROUND_COLOR, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, ansiColorIdentifiers, TERMINAL_SELECTION_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_HIGHLIGHT_BACKGROUND_COLOR, TERMINAL_FIND_MATCH_BORDER_COLOR, TERMINAL_OVERVIEW_RULER_FIND_MATCH_FOREGROUND_COLOR, TERMINAL_FIND_MATCH_HIGHLIGHT_BORDER_COLOR, TERMINAL_OVERVIEW_RULER_CURSOR_FOREGROUND_COLOR, TERMINAL_SELECTION_FOREGROUND_COLOR, TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { Color } from 'vs/base/common/color'; import { ShellIntegrationAddon } from 'vs/platform/terminal/common/xterm/shellIntegrationAddon'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -624,6 +624,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II const cursorColor = theme.getColor(TERMINAL_CURSOR_FOREGROUND_COLOR) || foregroundColor; const cursorAccentColor = theme.getColor(TERMINAL_CURSOR_BACKGROUND_COLOR) || backgroundColor; const selectionBackgroundColor = theme.getColor(TERMINAL_SELECTION_BACKGROUND_COLOR); + const selectionInactiveBackgroundColor = theme.getColor(TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR); const selectionForegroundColor = theme.getColor(TERMINAL_SELECTION_FOREGROUND_COLOR) || undefined; return { @@ -632,6 +633,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II cursor: cursorColor?.toString(), cursorAccent: cursorAccentColor?.toString(), selectionBackground: selectionBackgroundColor?.toString(), + selectionInactiveBackground: selectionInactiveBackgroundColor?.toString(), selectionForeground: selectionForegroundColor?.toString(), black: theme.getColor(ansiColorIdentifiers[0])?.toString(), red: theme.getColor(ansiColorIdentifiers[1])?.toString(), diff --git a/src/vs/workbench/contrib/terminal/common/terminalColorRegistry.ts b/src/vs/workbench/contrib/terminal/common/terminalColorRegistry.ts index 44061cca143..b0c5917b454 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalColorRegistry.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalColorRegistry.ts @@ -5,7 +5,7 @@ import * as nls from 'vs/nls'; -import { registerColor, ColorIdentifier, ColorDefaults, editorFindMatch, editorFindMatchHighlight, overviewRulerFindMatchForeground, editorSelectionBackground } from 'vs/platform/theme/common/colorRegistry'; +import { registerColor, ColorIdentifier, ColorDefaults, editorFindMatch, editorFindMatchHighlight, overviewRulerFindMatchForeground, editorSelectionBackground, transparent } from 'vs/platform/theme/common/colorRegistry'; import { EDITOR_DRAG_AND_DROP_BACKGROUND, PANEL_BORDER, TAB_ACTIVE_BORDER } from 'vs/workbench/common/theme'; /** @@ -29,6 +29,12 @@ export const TERMINAL_SELECTION_BACKGROUND_COLOR = registerColor('terminal.selec hcDark: editorSelectionBackground, hcLight: editorSelectionBackground }, nls.localize('terminal.selectionBackground', 'The selection background color of the terminal.')); +export const TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR = registerColor('terminal.inactiveSelectionBackground', { + light: transparent(TERMINAL_SELECTION_BACKGROUND_COLOR, 0.5), + dark: transparent(TERMINAL_SELECTION_BACKGROUND_COLOR, 0.5), + hcDark: transparent(TERMINAL_SELECTION_BACKGROUND_COLOR, 0.7), + hcLight: transparent(TERMINAL_SELECTION_BACKGROUND_COLOR, 0.5) +}, nls.localize('terminal.inactiveSelectionBackground', 'The selection background color of the terminal when it does not have focus.')); export const TERMINAL_SELECTION_FOREGROUND_COLOR = registerColor('terminal.selectionForeground', { light: null, dark: null, From b0d46d6ea7ed67b1a510d256f49b22941ef5f813 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 3 Aug 2022 12:21:15 +0200 Subject: [PATCH 186/303] editors - do not throw from `createTextEditor` (#156980) --- .../services/textfile/common/textEditorService.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/services/textfile/common/textEditorService.ts b/src/vs/workbench/services/textfile/common/textEditorService.ts index 886acda45d2..28cd548aad3 100644 --- a/src/vs/workbench/services/textfile/common/textEditorService.ts +++ b/src/vs/workbench/services/textfile/common/textEditorService.ts @@ -87,23 +87,23 @@ export class TextEditorService extends Disposable implements ITextEditorService createTextEditor(input: IUntypedFileEditorInput): IFileEditorInput; createTextEditor(input: IUntypedEditorInput | IUntypedFileEditorInput): EditorInput | IFileEditorInput { - // Merge Editor is Unsupported from here + // Merge Editor Not Supported (we fallback to showing the result only) if (isResourceMergeEditorInput(input)) { - throw new Error('Unsupported input'); + return this.createTextEditor(input.result); } // Diff Editor Support if (isResourceDiffEditorInput(input)) { - const original = this.createTextEditor({ ...input.original }); - const modified = this.createTextEditor({ ...input.modified }); + const original = this.createTextEditor(input.original); + const modified = this.createTextEditor(input.modified); return this.instantiationService.createInstance(DiffEditorInput, input.label, input.description, original, modified, undefined); } // Side by Side Editor Support if (isResourceSideBySideEditorInput(input)) { - const primary = this.createTextEditor({ ...input.primary }); - const secondary = this.createTextEditor({ ...input.secondary }); + const primary = this.createTextEditor(input.primary); + const secondary = this.createTextEditor(input.secondary); return this.instantiationService.createInstance(SideBySideEditorInput, input.label, input.description, secondary, primary); } From 4bace4b5745698f1d8fb351b92de31c6074fa5dc Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 3 Aug 2022 03:27:18 -0700 Subject: [PATCH 187/303] Ignore bad canvas addon versions --- scripts/update-xterm.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/update-xterm.js b/scripts/update-xterm.js index ac11b9e3217..bc574935902 100644 --- a/scripts/update-xterm.js +++ b/scripts/update-xterm.js @@ -31,7 +31,17 @@ function getLatestModuleVersion(moduleName) { if (err) { reject(err); } - const versions = JSON.parse(stdout); + let versions = JSON.parse(stdout); + // HACK: Some bad versions were published as v5 which cannot be unpublished, ignore these + if (moduleName === 'xterm-addon-canvas') { + versions = versions.filter(e => ![ + '0.12.0', + '5.0.0-beta.1', + '5.0.0-beta.2', + '5.0.0-beta.3', + '5.0.0-beta.4', + ].includes(e)); + } resolve(versions[versions.length - 1]); }); }); From 501216b18c01fd86985e7134634a9466655288f3 Mon Sep 17 00:00:00 2001 From: aiday-mar Date: Wed, 3 Aug 2022 12:35:42 +0200 Subject: [PATCH 188/303] Adapt sticky scroll to lineNumbers option. Fixing #156744 --- .../contrib/stickyScroll/browser/stickyScroll.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index e31b5b3030d..a5f72f30716 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -11,7 +11,7 @@ import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeat import { OutlineModel, OutlineElement } from 'vs/editor/contrib/documentSymbols/browser/outlineModel'; import { CancellationToken, CancellationTokenSource, } from 'vs/base/common/cancellation'; import * as dom from 'vs/base/browser/dom'; -import { EditorLayoutInfo, EditorOption } from 'vs/editor/common/config/editorOptions'; +import { EditorLayoutInfo, EditorOption, RenderLineNumbersType } from 'vs/editor/common/config/editorOptions'; import { createStringBuilder } from 'vs/editor/common/core/stringBuilder'; import { RenderLineInput, renderViewLine } from 'vs/editor/common/viewLayout/viewLineRenderer'; import { SymbolKind } from 'vs/editor/common/languages'; @@ -68,6 +68,10 @@ class StickyScrollController extends Disposable implements IEditorContribution { this._sessionStore.add(this._editor.onDidLayoutChange(() => this._onDidResize())); this._sessionStore.add(this._editor.onDidChangeModelContent(() => this._updateSoon.schedule())); this._sessionStore.add(this._languageFeaturesService.documentSymbolProvider.onDidChange(() => this._update(true))); + const lineNumberOption = this._editor.getOption(EditorOption.lineNumbers); + if (lineNumberOption.renderType === RenderLineNumbersType.Relative) { + this._sessionStore.add(this._editor.onDidChangeCursorPosition(() => this._update(false))); + } this._update(true); } } @@ -310,7 +314,12 @@ class StickyScrollCodeLine extends Disposable { } const innerLineNumberHTML = document.createElement('span'); - innerLineNumberHTML.innerText = this._lineNumber.toString(); + const lineNumberOption = this._editor.getOption(EditorOption.lineNumbers); + if (lineNumberOption.renderType === RenderLineNumbersType.On || lineNumberOption.renderType === RenderLineNumbersType.Interval && this._lineNumber % 10 === 0) { + innerLineNumberHTML.innerText = this._lineNumber.toString(); + } else if (lineNumberOption.renderType === RenderLineNumbersType.Relative) { + innerLineNumberHTML.innerText = Math.abs(this._lineNumber - this._editor.getPosition().lineNumber).toString(); + } innerLineNumberHTML.className = 'sticky-line-number'; innerLineNumberHTML.style.lineHeight = `${lineHeight}px`; innerLineNumberHTML.style.width = `${layoutInfo.lineNumbersWidth}px`; From 3db62b7ad10e6b5123b5a28975764c38a136ac20 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 3 Aug 2022 03:38:10 -0700 Subject: [PATCH 189/303] Clean up --- .../terminal/browser/xterm/xtermTerminal.ts | 25 +++-------- .../test/browser/xterm/xtermTerminal.test.ts | 45 +++++++++++++------ 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index 8a1ace0221c..42b76ec101c 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -220,7 +220,6 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II this._enableWebglRenderer(); } else if (this._shouldLoadCanvas()) { this._enableCanvasRenderer(); - // rendererType: this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType), } // Screen must be created at this point as xterm.open is called return this._container.querySelector('.xterm-screen')!; @@ -283,13 +282,12 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II // This is to fix an issue where dragging the windpow to the top of the screen to // maximize on Windows/Linux would fire an event saying that the terminal was not // visible. - // TODO: Fix renderer - // if (this.raw.getOption('rendererType') === 'canvas') { - // this._core._renderService?._onIntersectionChange({ intersectionRatio: 1 }); - // // HACK: Force a refresh of the screen to ensure links are refresh corrected. - // // This can probably be removed when the above hack is fixed in Chromium. - // this.raw.refresh(0, this.raw.rows - 1); - // } + if (!!this._canvasAddon) { + this._core._renderService?._onIntersectionChange({ intersectionRatio: 1 }); + // HACK: Force a refresh of the screen to ensure links are refresh corrected. + // This can probably be removed when the above hack is fixed in Chromium. + this.raw.refresh(0, this.raw.rows - 1); + } } async findNext(term: string, searchOptions: ISearchOptions): Promise { @@ -436,15 +434,6 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II } } - // TODO: Fix renderer - // private _getBuiltInXtermRenderer(gpuAcceleration: string, suggestedRendererType?: string): RendererType { - // let rendererType: RendererType = 'canvas'; - // if (gpuAcceleration === 'off' || (gpuAcceleration === 'auto' && suggestedRendererType === 'dom')) { - // rendererType = 'dom'; - // } - // return rendererType; - // } - private async _enableWebglRenderer(): Promise { if (!this.raw.element || this._webglAddon) { return; @@ -458,8 +447,6 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II this._webglAddon.onContextLoss(() => { this._logService.info(`Webgl lost context, disposing of webgl renderer`); this._disposeOfWebglRenderer(); - // TODO: Fix renderer - // this.raw.options.rendererType = 'dom'; }); // Uncomment to add the texture atlas to the DOM // setTimeout(() => { diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts index 57ec65285bd..b7584045545 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts @@ -27,6 +27,7 @@ import { TerminalLocation } from 'vs/platform/terminal/common/terminal'; import { TerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; +import { CanvasAddon } from 'xterm-addon-canvas'; class TestWebglAddon { static shouldThrow = false; @@ -45,10 +46,29 @@ class TestWebglAddon { clearTextureAtlas() { } } +class TestCanvasAddon { + static shouldThrow = false; + static isEnabled = false; + activate() { + TestCanvasAddon.isEnabled = !TestCanvasAddon.shouldThrow; + if (TestCanvasAddon.shouldThrow) { + throw new Error('Test canvas set to throw'); + } + } + dispose() { + TestCanvasAddon.isEnabled = false; + } + clearTextureAtlas() { } +} + class TestXtermTerminal extends XtermTerminal { webglAddonPromise: Promise = Promise.resolve(TestWebglAddon); + canvasAddonPromise: Promise = Promise.resolve(TestCanvasAddon); + // Force synchronous to avoid async when activating the addon + protected override _getCanvasAddonConstructor() { + return this.canvasAddonPromise; + } protected override _getWebglAddonConstructor() { - // Force synchronous to avoid async when activating the addon return this.webglAddonPromise; } } @@ -259,22 +279,21 @@ suite('XtermTerminal', () => { } else { strictEqual(TestWebglAddon.isEnabled, true); } + strictEqual(TestCanvasAddon.isEnabled, false); // Turn off to reset state - // TODO: Fix renderer - // await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'off' } }); - // configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); - // await xterm.webglAddonPromise; // await addon activate - // strictEqual(xterm.raw.options.rendererType, 'dom'); - // strictEqual(TestWebglAddon.isEnabled, false); + await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'off' } }); + configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); + await xterm.canvasAddonPromise; // await addon activate + strictEqual(TestWebglAddon.isEnabled, false); + strictEqual(TestCanvasAddon.isEnabled, true); // // Set to auto again but throw when activating the webgl addon - // TestWebglAddon.shouldThrow = true; - // await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'auto' } }); - // configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); - // await xterm.webglAddonPromise; // await addon activate - // strictEqual(xterm.raw.options.rendererType, 'canvas'); - // strictEqual(TestWebglAddon.isEnabled, false); + TestWebglAddon.shouldThrow = true; + await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'auto' } }); + configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); + strictEqual(TestWebglAddon.isEnabled, false); + strictEqual(TestCanvasAddon.isEnabled, false); }); }); }); From 16ecdd2b42802d53af7cd55d8ee4c556ccd0cedb Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 3 Aug 2022 03:50:25 -0700 Subject: [PATCH 190/303] Fix tests by allowing xterm proposed api --- .../commandDetectionCapability.test.ts | 2 +- .../partialCommandDetectionCapability.test.ts | 2 +- .../browser/links/terminalLinkManager.test.ts | 2 +- .../browser/links/terminalLinkOpeners.test.ts | 2 +- .../links/terminalLocalLinkDetector.test.ts | 2 +- .../links/terminalUriLinkDetector.test.ts | 2 +- .../links/terminalWordLinkDetector.test.ts | 2 +- .../browser/xterm/decorationAddon.test.ts | 1 + .../browser/xterm/lineDataEventAddon.test.ts | 4 +- .../xterm/shellIntegrationAddon.test.ts | 5 +-- .../test/browser/xterm/xtermTerminal.test.ts | 42 ++++++------------- 11 files changed, 22 insertions(+), 44 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/test/browser/capabilities/commandDetectionCapability.test.ts b/src/vs/workbench/contrib/terminal/test/browser/capabilities/commandDetectionCapability.test.ts index c2e7d77cfa9..00dfbccf937 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/capabilities/commandDetectionCapability.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/capabilities/commandDetectionCapability.test.ts @@ -63,7 +63,7 @@ suite('CommandDetectionCapability', () => { } setup(() => { - xterm = new Terminal({ cols: 80 }); + xterm = new Terminal({ allowProposedApi: true, cols: 80 }); capability = new TestCommandDetectionCapability(xterm, new NullLogService()); addEvents = []; capability.onCommandFinished(e => addEvents.push(e)); diff --git a/src/vs/workbench/contrib/terminal/test/browser/capabilities/partialCommandDetectionCapability.test.ts b/src/vs/workbench/contrib/terminal/test/browser/capabilities/partialCommandDetectionCapability.test.ts index 9475f8a1828..162559dd410 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/capabilities/partialCommandDetectionCapability.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/capabilities/partialCommandDetectionCapability.test.ts @@ -35,7 +35,7 @@ suite('PartialCommandDetectionCapability', () => { } setup(() => { - xterm = new Terminal({ cols: 80 }) as TestTerminal; + xterm = new Terminal({ allowProposedApi: true, cols: 80 }) as TestTerminal; capability = new PartialCommandDetectionCapability(xterm); addEvents = []; capability.onCommandFinished(e => addEvents.push(e)); diff --git a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkManager.test.ts b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkManager.test.ts index a7559d081f0..cbb412b8bbe 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkManager.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkManager.test.ts @@ -80,7 +80,7 @@ suite('TerminalLinkManager', () => { instantiationService.stub(IThemeService, themeService); instantiationService.stub(IViewDescriptorService, viewDescriptorService); - xterm = new Terminal({ cols: 80, rows: 30 }); + xterm = new Terminal({ allowProposedApi: true, cols: 80, rows: 30 }); linkManager = instantiationService.createInstance(TestLinkManager, xterm, upcastPartial({ async getInitialCwd() { return ''; diff --git a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts index aa801c53f36..0861f699a70 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLinkOpeners.test.ts @@ -87,7 +87,7 @@ suite('Workbench - TerminalLinkOpeners', () => { } } as Partial); // /*editorServiceSpy = */instantiationService.spy(IEditorService, 'openEditor'); - xterm = new Terminal(); + xterm = new Terminal({ allowProposedApi: true }); }); suite('TerminalSearchLinkOpener', () => { diff --git a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts index 93ff1ce3687..203ae923f2f 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/links/terminalLocalLinkDetector.test.ts @@ -98,7 +98,7 @@ suite('Workbench - TerminalLocalLinkDetector', () => { configurationService = new TestConfigurationService(); instantiationService.stub(IConfigurationService, configurationService); - xterm = new Terminal({ cols: 80, rows: 30 }); + xterm = new Terminal({ allowProposedApi: true, cols: 80, rows: 30 }); }); suite('platform independent', () => { diff --git a/src/vs/workbench/contrib/terminal/test/browser/links/terminalUriLinkDetector.test.ts b/src/vs/workbench/contrib/terminal/test/browser/links/terminalUriLinkDetector.test.ts index e7a39a54056..a3a9e6399f7 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/links/terminalUriLinkDetector.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/links/terminalUriLinkDetector.test.ts @@ -22,7 +22,7 @@ suite('Workbench - TerminalUriLinkDetector', () => { instantiationService.stub(IConfigurationService, configurationService); - xterm = new Terminal({ cols: 80, rows: 30 }); + xterm = new Terminal({ allowProposedApi: true, cols: 80, rows: 30 }); detector = instantiationService.createInstance(TerminalUriLinkDetector, xterm, resolveLinkForTest); }); diff --git a/src/vs/workbench/contrib/terminal/test/browser/links/terminalWordLinkDetector.test.ts b/src/vs/workbench/contrib/terminal/test/browser/links/terminalWordLinkDetector.test.ts index 63c04b0b285..4c2de33692a 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/links/terminalWordLinkDetector.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/links/terminalWordLinkDetector.test.ts @@ -22,7 +22,7 @@ suite('Workbench - TerminalWordLinkDetector', () => { instantiationService.stub(IConfigurationService, configurationService); - xterm = new Terminal({ cols: 80, rows: 30 }); + xterm = new Terminal({ allowProposedApi: true, cols: 80, rows: 30 }); detector = instantiationService.createInstance(TerminalWordLinkDetector, xterm); }); diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts index ddcbd66e3b2..660f447a4ec 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/decorationAddon.test.ts @@ -49,6 +49,7 @@ suite('DecorationAddon', () => { }); instantiationService.stub(IThemeService, new TestThemeService()); xterm = new TestTerminal({ + allowProposedApi: true, cols: 80, rows: 30 }); diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/lineDataEventAddon.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/lineDataEventAddon.test.ts index 5f2bad78612..0b8da74d55c 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/lineDataEventAddon.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/lineDataEventAddon.test.ts @@ -28,9 +28,7 @@ suite('LineDataEventAddon', () => { let events: string[]; setup(() => { - xterm = new Terminal({ - cols: 4 - }); + xterm = new Terminal({ allowProposedApi: true, cols: 4 }); lineDataEventAddon = new LineDataEventAddon(); xterm.loadAddon(lineDataEventAddon); diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/shellIntegrationAddon.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/shellIntegrationAddon.test.ts index bafbd5e65a8..f85909ac8c6 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/shellIntegrationAddon.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/shellIntegrationAddon.test.ts @@ -42,10 +42,7 @@ suite('ShellIntegrationAddon', () => { let capabilities: ITerminalCapabilityStore; setup(() => { - xterm = new Terminal({ - cols: 80, - rows: 30 - }); + xterm = new Terminal({ allowProposedApi: true, cols: 80, rows: 30 }); const instantiationService = new TestInstantiationService(); instantiationService.stub(ILogService, NullLogService); shellIntegrationAddon = instantiationService.createInstance(TestShellIntegrationAddon, undefined, undefined); diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts index b7584045545..3e211d85b3b 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts @@ -16,7 +16,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IViewDescriptor, IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { Emitter } from 'vs/base/common/event'; -import { TERMINAL_BACKGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR, TERMINAL_SELECTION_FOREGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; +import { TERMINAL_BACKGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR, TERMINAL_SELECTION_FOREGROUND_COLOR, TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; import { WebglAddon } from 'xterm-addon-webgl'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; @@ -27,7 +27,6 @@ import { TerminalLocation } from 'vs/platform/terminal/common/terminal'; import { TerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; -import { CanvasAddon } from 'xterm-addon-canvas'; class TestWebglAddon { static shouldThrow = false; @@ -46,28 +45,9 @@ class TestWebglAddon { clearTextureAtlas() { } } -class TestCanvasAddon { - static shouldThrow = false; - static isEnabled = false; - activate() { - TestCanvasAddon.isEnabled = !TestCanvasAddon.shouldThrow; - if (TestCanvasAddon.shouldThrow) { - throw new Error('Test canvas set to throw'); - } - } - dispose() { - TestCanvasAddon.isEnabled = false; - } - clearTextureAtlas() { } -} - class TestXtermTerminal extends XtermTerminal { webglAddonPromise: Promise = Promise.resolve(TestWebglAddon); - canvasAddonPromise: Promise = Promise.resolve(TestCanvasAddon); // Force synchronous to avoid async when activating the addon - protected override _getCanvasAddonConstructor() { - return this.canvasAddonPromise; - } protected override _getWebglAddonConstructor() { return this.webglAddonPromise; } @@ -167,6 +147,7 @@ suite('XtermTerminal', () => { [TERMINAL_CURSOR_FOREGROUND_COLOR]: '#000300', [TERMINAL_CURSOR_BACKGROUND_COLOR]: '#000400', [TERMINAL_SELECTION_BACKGROUND_COLOR]: '#000500', + [TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR]: '#000600', [TERMINAL_SELECTION_FOREGROUND_COLOR]: undefined, 'terminal.ansiBlack': '#010000', 'terminal.ansiRed': '#020000', @@ -191,7 +172,8 @@ suite('XtermTerminal', () => { foreground: '#000200', cursor: '#000300', cursorAccent: '#000400', - selection: '#000500', + selectionBackground: '#000500', + selectionInactiveBackground: '#000600', selectionForeground: undefined, black: '#010000', green: '#030000', @@ -216,7 +198,8 @@ suite('XtermTerminal', () => { [TERMINAL_CURSOR_FOREGROUND_COLOR]: '#00030f', [TERMINAL_CURSOR_BACKGROUND_COLOR]: '#00040f', [TERMINAL_SELECTION_BACKGROUND_COLOR]: '#00050f', - [TERMINAL_SELECTION_FOREGROUND_COLOR]: '#00060f', + [TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR]: '#00060f', + [TERMINAL_SELECTION_FOREGROUND_COLOR]: '#00070f', 'terminal.ansiBlack': '#01000f', 'terminal.ansiRed': '#02000f', 'terminal.ansiGreen': '#03000f', @@ -239,8 +222,9 @@ suite('XtermTerminal', () => { foreground: '#00020f', cursor: '#00030f', cursorAccent: '#00040f', - selection: '#00050f', - selectionForeground: '#00060f', + selectionBackground: '#00050f', + selectionInactiveBackground: '#00060f', + selectionForeground: '#00070f', black: '#01000f', green: '#03000f', red: '#02000f', @@ -279,21 +263,19 @@ suite('XtermTerminal', () => { } else { strictEqual(TestWebglAddon.isEnabled, true); } - strictEqual(TestCanvasAddon.isEnabled, false); // Turn off to reset state await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'off' } }); configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); - await xterm.canvasAddonPromise; // await addon activate + await xterm.webglAddonPromise; // await addon activate strictEqual(TestWebglAddon.isEnabled, false); - strictEqual(TestCanvasAddon.isEnabled, true); - // // Set to auto again but throw when activating the webgl addon + // Set to auto again but throw when activating the webgl addon TestWebglAddon.shouldThrow = true; await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'auto' } }); configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); + await xterm.webglAddonPromise; // await addon activate strictEqual(TestWebglAddon.isEnabled, false); - strictEqual(TestCanvasAddon.isEnabled, false); }); }); }); From 1196da0c50f87633ea3f36fd41091133b00a5033 Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Wed, 3 Aug 2022 13:02:08 +0200 Subject: [PATCH 191/303] Add more logging when a protocol timeout occurs (#156991) Add more logging when a protocol timeout occurs (#147328) --- src/vs/base/parts/ipc/common/ipc.net.ts | 26 ++++++++++++++++--- .../remote/common/remoteAgentConnection.ts | 4 +-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/vs/base/parts/ipc/common/ipc.net.ts b/src/vs/base/parts/ipc/common/ipc.net.ts index 5d464d87e87..badadce84f4 100644 --- a/src/vs/base/parts/ipc/common/ipc.net.ts +++ b/src/vs/base/parts/ipc/common/ipc.net.ts @@ -136,6 +136,12 @@ export interface WebSocketCloseEvent { export type SocketCloseEvent = NodeSocketCloseEvent | WebSocketCloseEvent | undefined; +export interface SocketTimeoutEvent { + readonly unacknowledgedMsgCount: number; + readonly timeSinceOldestUnacknowledgedMsg: number; + readonly timeSinceLastReceivedSomeData: number; +} + export interface ISocket extends IDisposable { onData(listener: (e: VSBuffer) => void): IDisposable; onClose(listener: (e: SocketCloseEvent) => void): IDisposable; @@ -667,6 +673,16 @@ class Queue { this._last = null; } + public length(): number { + let result = 0; + let current = this._first; + while (current) { + current = current.next; + result++; + } + return result; + } + public peek(): T | null { if (!this._first) { return null; @@ -800,8 +816,8 @@ export class PersistentProtocol implements IMessagePassingProtocol { private readonly _onSocketClose = new BufferedEmitter(); readonly onSocketClose: Event = this._onSocketClose.event; - private readonly _onSocketTimeout = new BufferedEmitter(); - readonly onSocketTimeout: Event = this._onSocketTimeout.event; + private readonly _onSocketTimeout = new BufferedEmitter(); + readonly onSocketTimeout: Event = this._onSocketTimeout.event; public get unacknowledgedCount(): number { return this._outgoingMsgId - this._outgoingAckId; @@ -1081,7 +1097,11 @@ export class PersistentProtocol implements IMessagePassingProtocol { if (!this._loadEstimator.hasHighLoad()) { // Trash the socket this._lastSocketTimeoutTime = Date.now(); - this._onSocketTimeout.fire(undefined); + this._onSocketTimeout.fire({ + unacknowledgedMsgCount: this._outgoingUnackMsg.length(), + timeSinceOldestUnacknowledgedMsg, + timeSinceLastReceivedSomeData + }); return; } } diff --git a/src/vs/platform/remote/common/remoteAgentConnection.ts b/src/vs/platform/remote/common/remoteAgentConnection.ts index d6883c9f3d9..e3e72781d7e 100644 --- a/src/vs/platform/remote/common/remoteAgentConnection.ts +++ b/src/vs/platform/remote/common/remoteAgentConnection.ts @@ -595,9 +595,9 @@ export abstract class PersistentConnection extends Disposable { } this._beginReconnecting(); })); - this._register(protocol.onSocketTimeout(() => { + this._register(protocol.onSocketTimeout((e) => { const logPrefix = commonLogPrefix(this._connectionType, this.reconnectionToken, true); - this._options.logService.info(`${logPrefix} received socket timeout event.`); + this._options.logService.info(`${logPrefix} received socket timeout event (unacknowledgedMsgCount: ${e.unacknowledgedMsgCount}, timeSinceOldestUnacknowledgedMsg: ${e.timeSinceOldestUnacknowledgedMsg}, timeSinceLastReceivedSomeData: ${e.timeSinceLastReceivedSomeData}).`); this._beginReconnecting(); })); From b39e5d436abb928a0296682fec44a4ebf59d5331 Mon Sep 17 00:00:00 2001 From: aiday-mar Date: Wed, 3 Aug 2022 13:04:51 +0200 Subject: [PATCH 192/303] Removing the splice in the render function. Correct ranges constructed in the updateOutlineModel function. Fixes 156881. --- .../stickyScroll/browser/stickyScroll.ts | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index a5f72f30716..b6bf6b833e8 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -182,8 +182,7 @@ class StickyScrollController extends Disposable implements IEditorContribution { }); let previous: number[] = []; for (const [index, arr] of this._ranges.entries()) { - const [start, end, _depth] = arr; - if (previous[0] === start && previous[1] === end) { + if (previous[0] === arr[0]) { this._ranges.splice(index, 1); } else { previous = arr; @@ -206,9 +205,8 @@ class StickyScrollController extends Disposable implements IEditorContribution { const scrollTop = this._editor.getScrollTop(); this.stickyScrollWidget.emptyRootNode(); - const beginningLinesConsidered: Set = new Set(); - for (const [index, arr] of this._ranges.entries()) { + for (const arr of this._ranges) { const [start, end, depth] = arr; if (end - start > 0) { const topOfElementAtDepth = (depth - 1) * lineHeight; @@ -218,18 +216,12 @@ class StickyScrollController extends Disposable implements IEditorContribution { const topOfEndLine = this._editor.getTopForLineNumber(end) - scrollTop; const bottomOfEndLine = this._editor.getBottomForLineNumber(end) - scrollTop; - if (!beginningLinesConsidered.has(start)) { - if (topOfElementAtDepth >= topOfEndLine - 1 && topOfElementAtDepth < bottomOfEndLine - 2) { - beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, depth, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth)); - break; - } - else if (bottomOfElementAtDepth > bottomOfBeginningLine && bottomOfElementAtDepth < bottomOfEndLine - 1) { - beginningLinesConsidered.add(start); - this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, depth, this._editor, 0, 0)); - } - } else { - this._ranges.splice(index, 1); + if (topOfElementAtDepth >= topOfEndLine - 1 && topOfElementAtDepth < bottomOfEndLine - 2) { + this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, depth, this._editor, -1, bottomOfEndLine - bottomOfElementAtDepth)); + break; + } + else if (bottomOfElementAtDepth > bottomOfBeginningLine && bottomOfElementAtDepth < bottomOfEndLine - 1) { + this.stickyScrollWidget.pushCodeLine(new StickyScrollCodeLine(start, depth, this._editor, 0, 0)); } } } From e614dac55cc4367a57f0ac4cda5757fa94d9282e Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 3 Aug 2022 06:32:35 -0700 Subject: [PATCH 193/303] Pass progress type along in notification updates Fixes #155955 --- src/vs/platform/progress/common/progress.ts | 1 + .../browser/parts/statusbar/statusbarItem.ts | 4 ++-- .../services/progress/browser/progressService.ts | 11 +++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/progress/common/progress.ts b/src/vs/platform/progress/common/progress.ts index adee9697946..1926498d466 100644 --- a/src/vs/platform/progress/common/progress.ts +++ b/src/vs/platform/progress/common/progress.ts @@ -64,6 +64,7 @@ export interface IProgressNotificationOptions extends IProgressOptions { readonly secondaryActions?: readonly IAction[]; readonly delay?: number; readonly silent?: boolean; + readonly type?: 'syncing' | 'loading'; } export interface IProgressDialogOptions extends IProgressOptions { diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts b/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts index acad14f1802..2305c0fc522 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts @@ -248,7 +248,7 @@ class StatusBarCodiconLabel extends SimpleIconLabel { private progressCodicon = renderIcon(syncing); private currentText = ''; - private currentShowProgress = false; + private currentShowProgress: boolean | 'syncing' | 'loading' = false; constructor( private readonly container: HTMLElement @@ -258,7 +258,7 @@ class StatusBarCodiconLabel extends SimpleIconLabel { set showProgress(showProgress: boolean | 'syncing' | 'loading') { if (this.currentShowProgress !== showProgress) { - this.currentShowProgress = !!showProgress; + this.currentShowProgress = showProgress; this.progressCodicon = renderIcon(showProgress === 'loading' ? spinningLoading : syncing); this.text = this.currentText; } diff --git a/src/vs/workbench/services/progress/browser/progressService.ts b/src/vs/workbench/services/progress/browser/progressService.ts index faca26a6b76..5d95e1984f7 100644 --- a/src/vs/workbench/services/progress/browser/progressService.ts +++ b/src/vs/workbench/services/progress/browser/progressService.ts @@ -71,15 +71,17 @@ export class ProgressService extends Disposable implements IProgressService { switch (location) { case ProgressLocation.Notification: return this.withNotificationProgress({ ...options, location, silent: this.notificationService.doNotDisturbMode }, task, onDidCancel); - case ProgressLocation.Window: + case ProgressLocation.Window: { + const type = (options as IProgressWindowOptions).type; if ((options as IProgressWindowOptions).command) { // Window progress with command get's shown in the status bar - return this.withWindowProgress({ ...options, location }, task); + return this.withWindowProgress({ ...options, location, type }, task); } // Window progress without command can be shown as silent notification // which will first appear in the status bar and can then be brought to // the front when clicking. - return this.withNotificationProgress({ delay: 150 /* default for ProgressLocation.Window */, ...options, silent: true, location: ProgressLocation.Notification }, task, onDidCancel); + return this.withNotificationProgress({ delay: 150 /* default for ProgressLocation.Window */, ...options, silent: true, location: ProgressLocation.Notification, type }, task, onDidCancel); + } case ProgressLocation.Explorer: return this.withPaneCompositeProgress('workbench.view.explorer', ViewContainerLocation.Sidebar, task, { ...options, location }); case ProgressLocation.Scm: @@ -235,7 +237,8 @@ export class ProgressService extends Disposable implements IProgressService { this.withWindowProgress({ location: ProgressLocation.Window, title: options.title ? parseLinkedText(options.title).toString() : undefined, // convert markdown links => string - command: 'notifications.showList' + command: 'notifications.showList', + type: options.type }, progress => { function reportProgress(step: IProgressStep) { From 4ea6a27637094a99e0551331c44a2446bcbf7273 Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Wed, 3 Aug 2022 15:41:26 +0200 Subject: [PATCH 194/303] Fix duplicated intersected label highlight (#157000) --- src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts b/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts index 3b69763252e..18c2d093f00 100644 --- a/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts +++ b/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts @@ -96,10 +96,10 @@ export class HighlightedLabel { if (pos < highlight.start) { const substring = this.text.substring(pos, highlight.start); children.push(dom.$('span', undefined, ...this.supportIcons ? renderLabelWithIcons(substring) : [substring])); - pos = highlight.end; + pos = highlight.start; } - const substring = this.text.substring(highlight.start, highlight.end); + const substring = this.text.substring(pos, highlight.end); const element = dom.$('span.highlight', undefined, ...this.supportIcons ? renderLabelWithIcons(substring) : [substring]); if (highlight.extraClasses) { From bcabf7ce3358305a7d1ff940a347b857c7d869ad Mon Sep 17 00:00:00 2001 From: Tomer Chachamu Date: Wed, 3 Aug 2022 16:24:42 +0100 Subject: [PATCH 195/303] Inherit more settings during extension development (#151872) Closes #143601 --- src/vs/platform/windows/electron-main/windowsMainService.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index 7aa556e2c7a..d46e9821bdc 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -1417,12 +1417,15 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic const currentWindowConfig = window.config; if (!configuration.extensionDevelopmentPath && currentWindowConfig && !!currentWindowConfig.extensionDevelopmentPath) { configuration.extensionDevelopmentPath = currentWindowConfig.extensionDevelopmentPath; + configuration.extensionDevelopmentKind = currentWindowConfig.extensionDevelopmentKind; + configuration['enable-proposed-api'] = currentWindowConfig['enable-proposed-api']; configuration.verbose = currentWindowConfig.verbose; + configuration['inspect-extensions'] = currentWindowConfig['inspect-extensions']; configuration['inspect-brk-extensions'] = currentWindowConfig['inspect-brk-extensions']; configuration.debugId = currentWindowConfig.debugId; configuration.extensionEnvironment = currentWindowConfig.extensionEnvironment; - configuration['inspect-extensions'] = currentWindowConfig['inspect-extensions']; configuration['extensions-dir'] = currentWindowConfig['extensions-dir']; + configuration['disable-extensions'] = currentWindowConfig['disable-extensions']; } } From 36244a045772fcf9ea9217b83f902a2d098d8c8d Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Wed, 3 Aug 2022 11:33:29 -0400 Subject: [PATCH 196/303] Remove the resolvers ability to work with typed editors (#157010) --- .../browser/parts/editor/editorCommands.ts | 8 ++- .../editor/browser/editorResolverService.ts | 27 +-------- .../services/editor/browser/editorService.ts | 10 ++-- .../editor/common/editorResolverService.ts | 4 +- .../editor/test/browser/editorService.test.ts | 55 +++++++++++-------- 5 files changed, 49 insertions(+), 55 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index 264ba8fba9b..5215338e573 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -951,8 +951,14 @@ function registerCloseEditorCommands() { if (!editor) { return; } + const untypedEditor = editor.toUntyped(); - const resolvedEditor = await editorResolverService.resolveEditor({ editor, options: { ...editorService.activeEditorPane?.options, override: EditorResolution.PICK } }, group); + // Resolver can only resolve untyped editors + if (!untypedEditor) { + return; + } + untypedEditor.options = { ...editorService.activeEditorPane?.options, override: EditorResolution.PICK }; + const resolvedEditor = await editorResolverService.resolveEditor(untypedEditor, group); if (!isEditorInputWithOptionsAndGroup(resolvedEditor)) { return; } diff --git a/src/vs/workbench/services/editor/browser/editorResolverService.ts b/src/vs/workbench/services/editor/browser/editorResolverService.ts index 853daff7507..2508f39f28e 100644 --- a/src/vs/workbench/services/editor/browser/editorResolverService.ts +++ b/src/vs/workbench/services/editor/browser/editorResolverService.ts @@ -83,37 +83,16 @@ export class EditorResolverService extends Disposable implements IEditorResolver }); } - private resolveUntypedInputAndGroup(editor: EditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): [IUntypedEditorInput, IEditorGroup, EditorActivation | undefined] | undefined { - let untypedEditor: IUntypedEditorInput | undefined = undefined; + private resolveUntypedInputAndGroup(editor: IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): [IUntypedEditorInput, IEditorGroup, EditorActivation | undefined] | undefined { + const untypedEditor = editor; - // Typed: convert to untyped to be able to resolve the editor as the service only uses untyped - if (isEditorInputWithOptions(editor)) { - untypedEditor = editor.editor.toUntyped(); - - if (untypedEditor) { - // Preserve original options: specifically it is - // possible that a `override` was defined from - // the outside and we do not want to lose it. - untypedEditor.options = { ...untypedEditor.options, ...editor.options }; - } - } - - // Untyped: take as is - else { - untypedEditor = editor; - } - - // Typed editors that cannot convert to untyped will be returned as undefined - if (!untypedEditor) { - return undefined; - } // Use the untyped editor to find a group const [group, activation] = this.instantiationService.invokeFunction(findGroup, untypedEditor, preferredGroup); return [untypedEditor, group, activation]; } - async resolveEditor(editor: EditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise { + async resolveEditor(editor: IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise { // Update the flattened editors this._flattenedEditors = this._flattenEditorsMap(); diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 4a2b8ea5e9d..81dd80a4cc6 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -501,8 +501,8 @@ export class EditorService extends Disposable implements EditorServiceImpl { } // Resolve override unless disabled - if (options?.override !== EditorResolution.DISABLED) { - const resolvedEditor = await this.editorResolverService.resolveEditor(isEditorInput(editor) ? { editor, options } : editor, preferredGroup); + if (options?.override !== EditorResolution.DISABLED && !isEditorInput(editor)) { + const resolvedEditor = await this.editorResolverService.resolveEditor(editor, preferredGroup); if (resolvedEditor === ResolvedStatus.ABORT) { return; // skip editor if override is aborted @@ -561,7 +561,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { let group: IEditorGroup | undefined = undefined; // Resolve override unless disabled - if (editor.options?.override !== EditorResolution.DISABLED) { + if (editor.options?.override !== EditorResolution.DISABLED && !isEditorInputWithOptions(editor)) { const resolvedEditor = await this.editorResolverService.resolveEditor(editor, preferredGroup); if (resolvedEditor === ResolvedStatus.ABORT) { @@ -860,9 +860,9 @@ export class EditorService extends Disposable implements EditorServiceImpl { } // Resolve override unless disabled - if (override !== EditorResolution.DISABLED) { + if (override !== EditorResolution.DISABLED && !isEditorInput(replacement.replacement)) { const resolvedEditor = await this.editorResolverService.resolveEditor( - isEditorReplacement(replacement) ? { editor: replacement.replacement, options: replacement.options } : replacement.replacement, + replacement.replacement, targetGroup ); diff --git a/src/vs/workbench/services/editor/common/editorResolverService.ts b/src/vs/workbench/services/editor/common/editorResolverService.ts index 9de7b992657..416f743d7bc 100644 --- a/src/vs/workbench/services/editor/common/editorResolverService.ts +++ b/src/vs/workbench/services/editor/common/editorResolverService.ts @@ -156,12 +156,12 @@ export interface IEditorResolverService { ): IDisposable; /** - * Given an editor resolves it to the suitable EditorInputWithOptionsAndGroup based on user extensions, settings, and built-in editors + * Given an editor resolves it to the suitable ResolvedEitor based on user extensions, settings, and built-in editors * @param editor The editor to resolve * @param preferredGroup The group you want to open the editor in * @returns An EditorInputWithOptionsAndGroup if there is an available editor or a status of how to proceed */ - resolveEditor(editor: EditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise; + resolveEditor(editor: IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise; /** * Given a resource returns all the editor ids that match that resource. If there is exclusive editor we return an empty array diff --git a/src/vs/workbench/services/editor/test/browser/editorService.test.ts b/src/vs/workbench/services/editor/test/browser/editorService.test.ts index e0c3b499650..151f1049b93 100644 --- a/src/vs/workbench/services/editor/test/browser/editorService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorService.test.ts @@ -851,11 +851,12 @@ suite('EditorService', () => { assert.ok(typedInput instanceof TestFileEditorInput); assert.strictEqual(typedInput.resource.toString(), typedEditor.resource.toString()); - assert.strictEqual(editorFactoryCalled, 1); + // It's a typed editor input so the resolver should not have been called + assert.strictEqual(editorFactoryCalled, 0); assert.strictEqual(untitledEditorFactoryCalled, 0); assert.strictEqual(diffEditorFactoryCalled, 0); - assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedEditor.resource.toString()); + assert.ok(!lastEditorFactoryEditor); assert.ok(!lastUntitledEditorFactoryEditor); assert.ok(!lastDiffEditorFactoryEditor); @@ -876,11 +877,11 @@ suite('EditorService', () => { assert.ok(typedInput instanceof TestFileEditorInput); assert.strictEqual(typedInput.resource.toString(), typedEditorReplacement.resource.toString()); - assert.strictEqual(editorFactoryCalled, 2); + assert.strictEqual(editorFactoryCalled, 0); assert.strictEqual(untitledEditorFactoryCalled, 0); assert.strictEqual(diffEditorFactoryCalled, 0); - assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedInput.resource.toString()); + assert.ok(!lastEditorFactoryEditor); assert.ok(!lastUntitledEditorFactoryEditor); assert.ok(!lastDiffEditorFactoryEditor); @@ -941,7 +942,8 @@ suite('EditorService', () => { const pane = await openEditor({ editor: typedEditor, options: { override: DEFAULT_EDITOR_ASSOCIATION.id } }); assert.strictEqual(pane?.group, rootGroup); - assert.ok(pane.input instanceof FileEditorInput); + // We shouldn't have resolved because it is a typed editor, even though we have an override specified + assert.ok(pane.input instanceof TestFileEditorInput); assert.strictEqual(pane.input.resource.toString(), typedEditor.resource.toString()); assert.strictEqual(editorFactoryCalled, 0); @@ -964,11 +966,11 @@ suite('EditorService', () => { assert.ok(pane.input instanceof TestFileEditorInput); assert.strictEqual(pane.input.resource.toString(), typedEditor.resource.toString()); - assert.strictEqual(editorFactoryCalled, 1); + assert.strictEqual(editorFactoryCalled, 0); assert.strictEqual(untitledEditorFactoryCalled, 0); assert.strictEqual(diffEditorFactoryCalled, 0); - assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedEditor.resource.toString()); + assert.ok(!lastEditorFactoryEditor); assert.ok(!lastUntitledEditorFactoryEditor); assert.ok(!lastDiffEditorFactoryEditor); @@ -985,12 +987,11 @@ suite('EditorService', () => { assert.strictEqual(pane.input.resource.toString(), typedEditor.resource.toString()); assert.strictEqual(pane.group.isSticky(pane.input), true); - assert.strictEqual(editorFactoryCalled, 1); + assert.strictEqual(editorFactoryCalled, 0); assert.strictEqual(untitledEditorFactoryCalled, 0); assert.strictEqual(diffEditorFactoryCalled, 0); - assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedEditor.resource.toString()); - assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).options?.preserveFocus, true); + assert.ok(!lastEditorFactoryEditor); assert.ok(!lastUntitledEditorFactoryEditor); assert.ok(!lastDiffEditorFactoryEditor); @@ -1008,12 +1009,11 @@ suite('EditorService', () => { assert.strictEqual(pane.input.resource.toString(), typedEditor.resource.toString()); assert.strictEqual(pane.group.isSticky(pane.input), true); - assert.strictEqual(editorFactoryCalled, 1); + assert.strictEqual(editorFactoryCalled, 0); assert.strictEqual(untitledEditorFactoryCalled, 0); assert.strictEqual(diffEditorFactoryCalled, 0); - assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedEditor.resource.toString()); - assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).options?.preserveFocus, true); + assert.ok(!lastEditorFactoryEditor); assert.ok(!lastUntitledEditorFactoryEditor); assert.ok(!lastDiffEditorFactoryEditor); @@ -1031,11 +1031,11 @@ suite('EditorService', () => { assert.ok(pane?.input instanceof TestFileEditorInput); assert.strictEqual(pane?.input.resource.toString(), typedEditor.resource.toString()); - assert.strictEqual(editorFactoryCalled, 1); + assert.strictEqual(editorFactoryCalled, 0); assert.strictEqual(untitledEditorFactoryCalled, 0); assert.strictEqual(diffEditorFactoryCalled, 0); - assert.strictEqual((lastEditorFactoryEditor as IResourceEditorInput).resource.toString(), typedEditor.resource.toString()); + assert.ok(!lastEditorFactoryEditor); assert.ok(!lastUntitledEditorFactoryEditor); assert.ok(!lastDiffEditorFactoryEditor); @@ -1342,7 +1342,8 @@ suite('EditorService', () => { assert.strictEqual(pane?.group, rootGroup); assert.strictEqual(pane?.group.count, 5); - assert.strictEqual(editorFactoryCalled, 3); + // Only the untyped editors should have had factories called (and 1 is disabled so 3 untyped - 1 disabled = 2) + assert.strictEqual(editorFactoryCalled, 2); assert.strictEqual(untitledEditorFactoryCalled, 0); assert.strictEqual(diffEditorFactoryCalled, 0); @@ -2334,13 +2335,19 @@ suite('EditorService', () => { ); assert.strictEqual(editorCount, 0); - const input1 = new TestFileEditorInput(URI.parse('file://test/path/resource1.txt'), TEST_EDITOR_INPUT_ID); - const input2 = new TestFileEditorInput(URI.parse('file://test/path/resource2.txt'), TEST_EDITOR_INPUT_ID); - const input3 = new TestFileEditorInput(URI.parse('file://test/path/resource3.md'), TEST_EDITOR_INPUT_ID); - const input4 = new TestFileEditorInput(URI.parse('file://test/path/resource4.md'), TEST_EDITOR_INPUT_ID); + const input1 = new TestFileEditorInput(URI.parse('file://test/path/resource1.txt'), TEST_EDITOR_INPUT_ID).toUntyped(); + const input2 = new TestFileEditorInput(URI.parse('file://test/path/resource2.txt'), TEST_EDITOR_INPUT_ID).toUntyped(); + const input3 = new TestFileEditorInput(URI.parse('file://test/path/resource3.md'), TEST_EDITOR_INPUT_ID).toUntyped(); + const input4 = new TestFileEditorInput(URI.parse('file://test/path/resource4.md'), TEST_EDITOR_INPUT_ID).toUntyped(); - // Open editor input 1 and it shouln't trigger override as the glob doesn't match - await service.openEditors([{ editor: input1 }, { editor: input2 }, { editor: input3 }, { editor: input4 }]); + assert.ok(input1); + assert.ok(input2); + assert.ok(input3); + assert.ok(input4); + + // Open editor inputs + await service.openEditors([input1, input2, input3, input4]); + // Only two matched the factory glob assert.strictEqual(editorCount, 2); registrationDisposable.dispose(); @@ -2374,6 +2381,8 @@ suite('EditorService', () => { assert.strictEqual(editorCount, 0); const input1 = new TestFileEditorInput(URI.parse('file://test/path/resource2.md'), TEST_EDITOR_INPUT_ID); + const untypedInput1 = input1.toUntyped(); + assert.ok(untypedInput1); // Open editor input 1 and it shouldn't trigger because I've disabled the override logic await service.openEditor(input1, { override: EditorResolution.DISABLED }); @@ -2381,7 +2390,7 @@ suite('EditorService', () => { await service.replaceEditors([{ editor: input1, - replacement: input1, + replacement: untypedInput1, }], part.activeGroup); assert.strictEqual(editorCount, 1); From 57599a9ecd4e605966547a6e40364246a550a1c2 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 3 Aug 2022 08:38:52 -0700 Subject: [PATCH 197/303] Bump api notebook milestone (#157011) --- .vscode/notebooks/api.github-issues | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/notebooks/api.github-issues b/.vscode/notebooks/api.github-issues index 6ba33aa8ae8..d02651f621e 100644 --- a/.vscode/notebooks/api.github-issues +++ b/.vscode/notebooks/api.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"July 2022\"" + "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"August 2022\"" }, { "kind": 1, From 61e8687fa3ee8e4d90ff8254d39e6fc167945728 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Wed, 3 Aug 2022 09:46:12 -0700 Subject: [PATCH 198/303] Notebook Cells re-render upon changes to metadata (#156917) * dataflow support for updated metadata * update cellAttachmentRenderer.ts to reflect metadata being a getter() inside MarkupCell * update condition to re-render cells, now includes metadata changes * notebook cells now re-render upon metadata changes * fix missing metadata update Co-authored-by: Peng Lyu --- .../ipynb/src/cellAttachmentRenderer.ts | 2 +- extensions/ipynb/src/common.ts | 2 +- .../view/renderers/backLayerWebView.ts | 26 +++++++------- .../browser/view/renderers/webviewMessages.ts | 1 + .../browser/view/renderers/webviewPreloads.ts | 35 ++++++++++--------- .../browser/viewModel/markupCellViewModel.ts | 6 ++-- 6 files changed, 40 insertions(+), 32 deletions(-) diff --git a/extensions/ipynb/src/cellAttachmentRenderer.ts b/extensions/ipynb/src/cellAttachmentRenderer.ts index 69e294d57b9..4f3626d5a18 100644 --- a/extensions/ipynb/src/cellAttachmentRenderer.ts +++ b/extensions/ipynb/src/cellAttachmentRenderer.ts @@ -22,7 +22,7 @@ export async function activate(ctx: RendererContext) { md.renderer.rules.image = (tokens: MarkdownItToken[], idx: number, options, env, self) => { const token = tokens[idx]; const src = token.attrGet('src'); - const attachments: Record> = env.outputItem.metadata?.custom?.attachments; // this stores attachment entries for every image in the cell + const attachments: Record> = env.outputItem.metadata().custom?.attachments; if (attachments && src) { const imageAttachment = attachments[src.replace('attachment:', '')]; if (imageAttachment) { diff --git a/extensions/ipynb/src/common.ts b/extensions/ipynb/src/common.ts index de72fbbbfc3..047814ecfc1 100644 --- a/extensions/ipynb/src/common.ts +++ b/extensions/ipynb/src/common.ts @@ -44,7 +44,7 @@ export interface CellOutputMetadata { /** * Metadata we store in VS Code cells. - * This contains the original metadata from the Jupyuter cells. + * This contains the original metadata from the Jupyter cells. */ export interface CellMetadata { /** diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index eed6f5eb480..c3b91419cef 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1025,31 +1025,33 @@ var requirejs = (function() { }); } - async showMarkupPreview(initialization: IMarkupCellInitialization) { + async showMarkupPreview(newContent: IMarkupCellInitialization) { if (this._disposed) { return; } - const entry = this.markupPreviewMapping.get(initialization.cellId); + const entry = this.markupPreviewMapping.get(newContent.cellId); if (!entry) { - return this.createMarkupPreview(initialization); + return this.createMarkupPreview(newContent); } - const sameContent = initialization.content === entry.content; - if (!sameContent || !entry.visible) { + const sameContent = newContent.content === entry.content; + const sameMetadata = newContent.metadata === entry.metadata; + if (!sameContent || !sameMetadata || !entry.visible) { this._sendMessageToWebview({ type: 'showMarkupCell', - id: initialization.cellId, - handle: initialization.cellHandle, + id: newContent.cellId, + handle: newContent.cellHandle, // If the content has not changed, we still want to make sure the // preview is visible but don't need to send anything over - content: sameContent ? undefined : initialization.content, - top: initialization.offset + content: sameContent ? undefined : newContent.content, + top: newContent.offset, + metadata: sameMetadata ? undefined : newContent.metadata }); } - - entry.content = initialization.content; - entry.offset = initialization.offset; + entry.metadata = newContent.metadata; + entry.content = newContent.content; + entry.offset = newContent.offset; entry.visible = true; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts index 08b8489dcb3..f8cb6f80e31 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts @@ -316,6 +316,7 @@ export interface IShowMarkupCellMessage { readonly handle: number; readonly content: string | undefined; readonly top: number; + readonly metadata: NotebookCellMetadata | undefined; } export interface IUpdateSelectedMarkupCellsMessage { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index dea460bd27d..3e86223876e 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -1035,7 +1035,7 @@ async function webviewPreloads(ctx: PreloadContext) { break; case 'showMarkupCell': - viewModel.showMarkupCell(event.data.id, event.data.top, event.data.content); + viewModel.showMarkupCell(event.data.id, event.data.top, event.data.content, event.data.metadata); break; case 'hideMarkupCells': @@ -1448,7 +1448,7 @@ async function webviewPreloads(ctx: PreloadContext) { let cell = this._markupCells.get(info.cellId); if (cell) { cell.element.style.visibility = info.visible ? 'visible' : 'hidden'; - await cell.updateContentAndRender(info.content); + await cell.updateContentAndRender(info.content, info.metadata); } else { cell = await this.createMarkupCell(info, info.offset, info.visible); } @@ -1462,14 +1462,14 @@ async function webviewPreloads(ctx: PreloadContext) { } } - public async updateMarkupContent(id: string, newContent: string): Promise { + public async updateMarkupContent(id: string, newContent: string, metadata: NotebookCellMetadata): Promise { const cell = this.getExpectedMarkupCell(id); - await cell?.updateContentAndRender(newContent); + await cell?.updateContentAndRender(newContent, metadata); } - public showMarkupCell(id: string, top: number, newContent: string | undefined): void { + public showMarkupCell(id: string, top: number, newContent: string | undefined, metadata: NotebookCellMetadata | undefined): void { const cell = this.getExpectedMarkupCell(id); - cell?.show(top, newContent); + cell?.show(top, newContent, metadata); } public hideMarkupCell(id: string): void { @@ -1633,11 +1633,11 @@ async function webviewPreloads(ctx: PreloadContext) { private readonly outputItem: rendererApi.OutputItem; /// Internal field that holds text content - private _content: { readonly value: string; readonly version: number }; + private _content: { readonly value: string; readonly version: number; readonly metadata: NotebookCellMetadata }; constructor(id: string, mime: string, content: string, top: number, metadata: NotebookCellMetadata) { this.id = id; - this._content = { value: content, version: 0 }; + this._content = { value: content, version: 0, metadata: metadata }; let resolveReady: () => void; this.ready = new Promise(r => resolveReady = r); @@ -1646,7 +1646,10 @@ async function webviewPreloads(ctx: PreloadContext) { this.outputItem = Object.freeze({ id, mime, - metadata, + + metadata: (): NotebookCellMetadata => { + return this._content.metadata; + }, text: (): string => { return this._content.value; @@ -1688,7 +1691,7 @@ async function webviewPreloads(ctx: PreloadContext) { this.addEventListeners(); - this.updateContentAndRender(this._content.value).then(() => { + this.updateContentAndRender(this._content.value, this._content.metadata).then(() => { resizeObserver.observe(this.element, this.id, false, this.id); resolveReady(); }); @@ -1738,8 +1741,8 @@ async function webviewPreloads(ctx: PreloadContext) { }); } - public async updateContentAndRender(newContent: string): Promise { - this._content = { value: newContent, version: this._content.version + 1 }; + public async updateContentAndRender(newContent: string, metadata: NotebookCellMetadata): Promise { + this._content = { value: newContent, version: this._content.version + 1, metadata }; await renderers.render(this.outputItem, this.element); @@ -1772,11 +1775,11 @@ async function webviewPreloads(ctx: PreloadContext) { }); } - public show(top: number, newContent: string | undefined): void { + public show(top: number, newContent: string | undefined, metadata: NotebookCellMetadata | undefined): void { this.element.style.visibility = 'visible'; this.element.style.top = `${top}px`; - if (typeof newContent === 'string') { - this.updateContentAndRender(newContent); + if (typeof newContent === 'string' || metadata) { + this.updateContentAndRender(newContent ?? this._content.value, metadata ?? this._content.metadata); } else { this.updateMarkupDimensions(); } @@ -1792,7 +1795,7 @@ async function webviewPreloads(ctx: PreloadContext) { } public rerender() { - this.updateContentAndRender(this._content.value); + this.updateContentAndRender(this._content.value, this._content.metadata); } public remove() { diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts index b6adb4b5a59..d603fa80208 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts @@ -29,8 +29,10 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM public get renderedHtml(): string | undefined { return this._renderedHtml; } public set renderedHtml(value: string | undefined) { - this._renderedHtml = value; - this._onDidChangeState.fire({ contentChanged: true }); + if (this._renderedHtml !== value) { + this._renderedHtml = value; + this._onDidChangeState.fire({ contentChanged: true }); + } } get layoutInfo() { From 82314b9ed5e9a02d559857bae91b3a20bae211ad Mon Sep 17 00:00:00 2001 From: rebornix Date: Wed, 3 Aug 2022 10:08:02 -0700 Subject: [PATCH 199/303] remove outdated test --- .../singlefolder-tests/notebook.api.test.ts | 11 ------- .../notebook.document.test.ts | 12 +++++++ .../notebook.editor.test.ts | 33 ------------------- 3 files changed, 12 insertions(+), 44 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts index bd1bc363082..4d273ee5931 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts @@ -164,17 +164,6 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { await saveAllFilesAndCloseAll(); }); - test('edit API batch edits', async function () { - const notebook = await openRandomNotebookDocument(); - - const edit = new vscode.WorkspaceEdit(); - const metdataEdit = vscode.NotebookEdit.updateNotebookMetadata({ ...notebook.metadata, custom: { ...(notebook.metadata.custom || {}), extraNotebookMetadata: true } }); - edit.set(notebook.uri, [metdataEdit]); - const success = await vscode.workspace.applyEdit(edit); - assert.equal(success, true); - assert.ok(notebook.metadata.custom.extraNotebookMetadata, `Test metadata not found`); - }); - test('notebook open', async function () { const notebook = await openRandomNotebookDocument(); const editor = await vscode.window.showNotebookDocument(notebook); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts index 8a92bb7324e..1f34fc7998f 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts @@ -315,6 +315,18 @@ suite('Notebook Document', function () { assert.strictEqual(data.cellChanges[0].cell.index, 0); }); + test('workspace edit API (notebookMetadata)', async function () { + const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest'); + const document = await vscode.workspace.openNotebookDocument(uri); + + const edit = new vscode.WorkspaceEdit(); + const metdataEdit = vscode.NotebookEdit.updateNotebookMetadata({ ...document.metadata, custom: { ...(document.metadata.custom || {}), extraNotebookMetadata: true } }); + edit.set(document.uri, [metdataEdit]); + const success = await vscode.workspace.applyEdit(edit); + assert.equal(success, true); + assert.ok(document.metadata.custom.extraNotebookMetadata, `Test metadata not found`); + }); + test('document save API', async function () { const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest'); const notebook = await vscode.workspace.openNotebookDocument(uri); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.editor.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.editor.test.ts index 12b79163769..e14c48fdd17 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.editor.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.editor.test.ts @@ -65,39 +65,6 @@ import * as utils from '../utils'; testDisposables.length = 0; }); - test.skip('showNotebookDocument', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/139078 - - const notebookDocumentsFromOnDidOpen = new Set(); - const sub = vscode.workspace.onDidOpenNotebookDocument(e => { - notebookDocumentsFromOnDidOpen.add(e); - }); - - const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest'); - - const editor = await vscode.window.showNotebookDocument(uri); - assert.strictEqual(uri.toString(), editor.notebook.uri.toString()); - - assert.strictEqual(notebookDocumentsFromOnDidOpen.has(editor.notebook), true); - - const includes = vscode.workspace.notebookDocuments.includes(editor.notebook); - assert.strictEqual(true, includes); - - sub.dispose(); - }); - - // TODO@rebornix deal with getting started - test.skip('notebook editor has viewColumn', async function () { - - const uri1 = await utils.createRandomFile(undefined, undefined, '.nbdtest'); - const editor1 = await vscode.window.showNotebookDocument(uri1); - - assert.strictEqual(editor1.viewColumn, vscode.ViewColumn.One); - - const uri2 = await utils.createRandomFile(undefined, undefined, '.nbdtest'); - const editor2 = await vscode.window.showNotebookDocument(uri2, { viewColumn: vscode.ViewColumn.Beside }); - assert.strictEqual(editor2.viewColumn, vscode.ViewColumn.Two); - }); - // #138683 test('Opening a notebook should fire activeNotebook event changed only once', async function () { const openedEditor = onDidOpenNotebookEditor(); From 336373dfc5088b5a679d3353b6c81e697526cae7 Mon Sep 17 00:00:00 2001 From: rebornix Date: Wed, 3 Aug 2022 10:14:45 -0700 Subject: [PATCH 200/303] bring back kernel execute test --- .../singlefolder-tests/notebook.api.test.ts | 4 ++-- .../notebook.kernel.test.ts | 24 ++++++------------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts index 4d273ee5931..233f3ee6177 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.api.test.ts @@ -287,7 +287,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { suiteDisposables.push(vscode.workspace.registerNotebookContentProvider('notebookCoreTest', apiTestContentProvider)); }); - test.skip('provideCellStatusBarItems called on metadata change', async function () { // TODO@roblourens https://github.com/microsoft/vscode/issues/139324 + test('provideCellStatusBarItems called on metadata change', async function () { const provideCalled = asPromise(onDidCallProvide); const notebook = await openRandomNotebookDocument(); await vscode.window.showNotebookDocument(notebook); @@ -295,7 +295,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { const edit = new vscode.WorkspaceEdit(); edit.replaceNotebookCellMetadata(notebook.uri, 0, { inputCollapsed: true }); - vscode.workspace.applyEdit(edit); + await vscode.workspace.applyEdit(edit); await provideCalled; }); }); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts index 0bc9384ccbd..d41129e04f4 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts @@ -174,19 +174,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { await saveAllFilesAndCloseAll(); }); - // TODO@rebornix this is wrong, `await vscode.commands.executeCommand('notebook.execute');` doesn't wait until the workspace edit is applied - test.skip('cell execute command takes arguments', async () => { - const notebook = await openRandomNotebookDocument(); - await vscode.window.showNotebookDocument(notebook); - assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first'); - const editor = vscode.window.activeNotebookEditor!; - const cell = editor.notebook.cellAt(0); - - await vscode.commands.executeCommand('notebook.execute'); - assert.strictEqual(cell.outputs.length, 0, 'should not execute'); // not runnable, didn't work - }); - - test('cell execute command takes arguments 2', async () => { + test('cell execute command takes arguments', async () => { const notebook = await openRandomNotebookDocument(); await vscode.window.showNotebookDocument(notebook); assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first'); @@ -217,11 +205,10 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { }); // #126371 - test.skip('cell execute command takes arguments ICellRange[]', async () => { + test('cell execute command takes arguments', async () => { const notebook = await openRandomNotebookDocument(); await vscode.window.showNotebookDocument(notebook); - vscode.commands.executeCommand('notebook.cell.execute', { ranges: [{ start: 0, end: 1 }, { start: 1, end: 2 }] }); let firstCellExecuted = false; let secondCellExecuted = false; let resolve: () => void; @@ -242,6 +229,8 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { } }); + vscode.commands.executeCommand('notebook.cell.execute', { document: notebook.uri, ranges: [{ start: 0, end: 1 }, { start: 1, end: 2 }] }); + await p; listener.dispose(); await saveAllFilesAndCloseAll(); @@ -306,12 +295,11 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { }); }); - test.skip('onDidChangeCellExecutionState is fired', async () => { // TODO@rebornix https://github.com/microsoft/vscode/issues/139350 + test('onDidChangeCellExecutionState is fired', async () => { const notebook = await openRandomNotebookDocument(); const editor = await vscode.window.showNotebookDocument(notebook); const cell = editor.notebook.cellAt(0); - vscode.commands.executeCommand('notebook.cell.execute'); let eventCount = 0; let resolve: () => void; const p = new Promise(r => resolve = r); @@ -330,6 +318,8 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { eventCount++; }); + vscode.commands.executeCommand('notebook.cell.execute', { document: notebook.uri, ranges: [{ start: 0, end: 1 }] }); + await p; listener.dispose(); }); From 743b756d572df42796a741920b49280f71b6c90e Mon Sep 17 00:00:00 2001 From: Justin Chen <54879025+justschen@users.noreply.github.com> Date: Wed, 3 Aug 2022 10:25:23 -0700 Subject: [PATCH 201/303] Bugfix for code action clicking #157017 * added disabled hover * code cleanup on disabled option hovers * removed comments * widget enabled by default * code cleanup and fix on build * clean up on css removed unused importants * small patch for css rules * minor refactor on codeactionitems * fix on disabled option click * fix on disabled option click --- .../contrib/codeAction/browser/codeActionMenu.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts index 9a583b49409..74581bc44ae 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts @@ -117,7 +117,6 @@ class CodeMenuRenderer implements IListRenderer): void { + if (e.element) { + if (!e.element.isEnabled) { + this.currSelectedItem = undefined; + this.codeActionList.value?.setFocus([]); + } + } + } + private renderCodeActionMenuList(element: HTMLElement, inputArray: IAction[]): IDisposable { const renderDisposables = new DisposableStore(); const renderMenu = document.createElement('div'); @@ -275,12 +283,12 @@ export class CodeActionMenu extends Disposable implements IEditorContribution { }, [this.listRenderer], { keyboardSupport: false } ); + renderDisposables.add(this.codeActionList.value.onMouseClick(e => this._onListClick(e))); renderDisposables.add(this.codeActionList.value.onMouseOver(e => this._onListHover(e))); renderDisposables.add(this.codeActionList.value.onDidChangeFocus(e => this.codeActionList.value?.domFocus())); renderDisposables.add(this.codeActionList.value.onDidChangeSelection(e => this._onListSelection(e))); renderDisposables.add(this._editor.onDidLayoutChange(e => this.hideCodeActionWidget())); - // Populating the list widget and tracking enabled options. inputArray.forEach((item, index) => { From f62d30f9ea2598dc82ffe644e6de41e613ad6be5 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 3 Aug 2022 10:28:26 -0700 Subject: [PATCH 202/303] focus `No` option of task dialogue box by default (#157020) fix 156287 --- src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts index 335e13df336..4979605bef7 100644 --- a/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts +++ b/src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts @@ -209,7 +209,8 @@ export class TaskQuickPick extends Disposable { const changeSettingResult = await this._dialogService.show(Severity.Warning, nls.localize('TaskQuickPick.changeSettingDetails', "Task detection for {0} tasks causes files in any workspace you open to be run as code. Enabling {0} task detection is a user setting and will apply to any workspace you open. \n\n Do you want to enable {0} task detection for all workspaces?", selectedType), - [noButton, yesButton] + [noButton, yesButton], + { cancelId: 1 } ); if (changeSettingResult.choice === 1) { await this._configurationService.updateValue(`${selectedType}.autoDetect`, 'on'); From 33a4cffb6aacabbc63dba507389151dd3f4c10ed Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 3 Aug 2022 10:43:04 -0700 Subject: [PATCH 203/303] Don't register duplicate view container command --- .../contrib/editSessions/browser/editSessions.contribution.ts | 4 ++-- .../contrib/editSessions/browser/editSessionsViews.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts index 46eed6e6a06..3c79379d4fe 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -158,11 +158,11 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo title: EDIT_SESSIONS_TITLE, ctorDescriptor: new SyncDescriptor( ViewPaneContainer, - [EDIT_SESSIONS_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true }] + [EDIT_SESSIONS_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }] ), icon: EDIT_SESSIONS_VIEW_ICON, hideIfEmpty: true - }, ViewContainerLocation.Sidebar + }, ViewContainerLocation.Sidebar, { donotRegisterOpenCommand: true } ); this._register(this.instantiationService.createInstance(EditSessionsDataViews, container)); } diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts index 28dfa2257e4..307224d2a90 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts @@ -31,7 +31,7 @@ export class EditSessionsDataViews extends Disposable { private registerViews(container: ViewContainer): void { const viewId = EDIT_SESSIONS_DATA_VIEW_ID; - const name = localize('edit sessions data', 'All Sessions'); + const name = EDIT_SESSIONS_TITLE; const treeView = this.instantiationService.createInstance(TreeView, viewId, name); treeView.showCollapseAllAction = true; treeView.showRefreshAction = true; From 431e087e4822c710f4b35f0802d7e13e52facc2a Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 3 Aug 2022 10:53:54 -0700 Subject: [PATCH 204/303] Use a better icon and tree node label --- .../contrib/editSessions/browser/editSessionsViews.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts index 307224d2a90..50dfef3c360 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts @@ -59,7 +59,7 @@ export class EditSessionsDataViews extends Disposable { super({ id: 'workbench.editSessions.actions.resume', title: localize('workbench.editSessions.actions.resume', "Resume Edit Session"), - icon: Codicon.repoPull, + icon: Codicon.desktopDownload, menu: { id: MenuId.ViewItemContext, when: ContextKeyExpr.and(ContextKeyExpr.equals('view', viewId), ContextKeyExpr.regex('viewItem', /edit-session/i)), @@ -136,8 +136,8 @@ class EditSessionDataViewDataProvider implements ITreeViewDataProvider { return { handle: resource.toString(), collapsibleState: TreeItemCollapsibleState.Collapsed, - label: { label: session.ref }, - description: fromNow(session.created, true), + label: { label: fromNow(session.created, true) }, + description: session.ref, themeIcon: Codicon.repo, contextValue: `edit-session` }; From 918454bf993400b683456bb261e8c315bd771387 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 3 Aug 2022 11:00:59 -0700 Subject: [PATCH 205/303] Enable edit sessions by default --- .../contrib/editSessions/browser/editSessions.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts index 3c79379d4fe..1842935caa9 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -596,7 +596,7 @@ Registry.as(Extensions.Configuration).registerConfigurat 'workbench.experimental.editSessions.enabled': { 'type': 'boolean', 'tags': ['experimental', 'usesOnlineServices'], - 'default': false, + 'default': true, 'markdownDescription': localize('editSessionsEnabled', "Controls whether to display cloud-enabled actions to store and resume uncommitted changes when switching between web, desktop, or devices."), }, } From 67e0e8f12fb5ef1a8acfb83511e44c2670500cbe Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Wed, 3 Aug 2022 14:39:46 -0400 Subject: [PATCH 206/303] Telemetry extraction should fail build (#157006) --- package.json | 2 +- yarn.lock | 59 +++++++++++++++++++++++++++------------------------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index 61109d3f320..b3a17d88784 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "@types/yazl": "^2.4.2", "@typescript-eslint/eslint-plugin": "^5.10.0", "@typescript-eslint/parser": "^5.10.0", - "@vscode/telemetry-extractor": "^1.9.6", + "@vscode/telemetry-extractor": "^1.9.8", "@vscode/test-web": "^0.0.29", "ansi-colors": "^3.2.3", "asar": "^3.0.3", diff --git a/yarn.lock b/yarn.lock index adf3db9cf5f..69392c854ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -591,13 +591,13 @@ resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== -"@ts-morph/common@~0.12.3": - version "0.12.3" - resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.12.3.tgz#a96e250217cd30e480ab22ec6a0ebbe65fd784ff" - integrity sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w== +"@ts-morph/common@~0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.16.0.tgz#57e27d4b3fd65a4cd72cb36679ed08acb40fa3ba" + integrity sha512-SgJpzkTgZKLKqQniCjLaE3c2L2sdL7UShvmTmPBejAKd2OKV/yfMpQ2IWpAuA+VY5wy7PkSUaEObIqEK6afFuw== dependencies: - fast-glob "^3.2.7" - minimatch "^3.0.4" + fast-glob "^3.2.11" + minimatch "^5.1.0" mkdirp "^1.0.4" path-browserify "^1.0.1" @@ -1021,14 +1021,14 @@ resolved "https://registry.yarnpkg.com/@vscode/sudo-prompt/-/sudo-prompt-9.3.1.tgz#c562334bc6647733649fd42afc96c0eea8de3b65" integrity sha512-9ORTwwS74VaTn38tNbQhsA5U44zkJfcb0BdTSyyG6frP4e8KMtHuTXYmwefe5dpL8XB1aGSIVTaLjD3BbWb5iA== -"@vscode/telemetry-extractor@^1.9.6": - version "1.9.6" - resolved "https://registry.yarnpkg.com/@vscode/telemetry-extractor/-/telemetry-extractor-1.9.6.tgz#1b8d31c2ea841b33e5aa4e9c69a01f011cfc3add" - integrity sha512-G5m3NRNXW5ePsm4dft64EiOOopYin/3vQ6mBwWKkgnRkD8LivVvtDBjDMwZGsN5lF0w4t+ugb+IE4bXfMhZMcg== +"@vscode/telemetry-extractor@^1.9.8": + version "1.9.8" + resolved "https://registry.yarnpkg.com/@vscode/telemetry-extractor/-/telemetry-extractor-1.9.8.tgz#ffc000720ea2b9cd3421ba8a7bd172972c398b06" + integrity sha512-L27/fgC/gM7AY6AXriFGrznnX1M4Nc7VmHabYinDPoJDQYLjbSEDDVjjlSS6BiVkzc3OrFQStqXpHBhImis2eQ== dependencies: "@vscode/ripgrep" "^1.14.2" command-line-args "^5.2.1" - ts-morph "^13.0.3" + ts-morph "^15.1.0" "@vscode/test-web@^0.0.29": version "0.0.29" @@ -1979,6 +1979,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^2.3.1, braces@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -4248,18 +4255,7 @@ fast-glob@^3.1.1, fast-glob@^3.2.4: micromatch "^4.0.2" picomatch "^2.2.1" -fast-glob@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-glob@^3.2.9: +fast-glob@^3.2.11, fast-glob@^3.2.9: version "3.2.11" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== @@ -7018,6 +7014,13 @@ minimatch@4.2.1: dependencies: brace-expansion "^1.1.7" +minimatch@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" + integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" @@ -10313,12 +10316,12 @@ ts-loader@^9.2.7: micromatch "^4.0.0" semver "^7.3.4" -ts-morph@^13.0.3: - version "13.0.3" - resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-13.0.3.tgz#c0c51d1273ae2edb46d76f65161eb9d763444c1d" - integrity sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw== +ts-morph@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-15.1.0.tgz#53deea5296d967ff6eba8f15f99d378aa7074a4e" + integrity sha512-RBsGE2sDzUXFTnv8Ba22QfeuKbgvAGJFuTN7HfmIRUkgT/NaVLfDM/8OFm2NlFkGlWEXdpW5OaFIp1jvqdDuOg== dependencies: - "@ts-morph/common" "~0.12.3" + "@ts-morph/common" "~0.16.0" code-block-writer "^11.0.0" tsec@0.1.4: From 60ede6b6e3566c0675acc2adf4384de7d24cd0ad Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 3 Aug 2022 14:30:39 -0700 Subject: [PATCH 207/303] Add a welcome view when there are no edit sessions --- .../editSessions/browser/editSessionsViews.ts | 52 +++++++++++++++++-- .../browser/editSessionsWorkbenchService.ts | 24 ++++++++- .../editSessions/common/editSessions.ts | 2 +- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts index 50dfef3c360..7b96959f190 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts @@ -10,16 +10,19 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati import { Registry } from 'vs/platform/registry/common/platform'; import { TreeView, TreeViewPane } from 'vs/workbench/browser/parts/views/treeView'; import { Extensions, ITreeItem, ITreeViewDataProvider, ITreeViewDescriptor, IViewsRegistry, TreeItemCollapsibleState, TreeViewItemHandleArg, ViewContainer } from 'vs/workbench/common/views'; -import { EDIT_SESSIONS_DATA_VIEW_ID, EDIT_SESSIONS_SCHEME, EDIT_SESSIONS_SHOW_VIEW, EDIT_SESSIONS_SIGNED_IN, EDIT_SESSIONS_TITLE, IEditSessionsWorkbenchService } from 'vs/workbench/contrib/editSessions/common/editSessions'; +import { EDIT_SESSIONS_DATA_VIEW_ID, EDIT_SESSIONS_SCHEME, EDIT_SESSIONS_SHOW_VIEW, EDIT_SESSIONS_SIGNED_IN, EDIT_SESSIONS_SIGNED_IN_KEY, EDIT_SESSIONS_TITLE, IEditSessionsWorkbenchService } from 'vs/workbench/contrib/editSessions/common/editSessions'; import { URI } from 'vs/base/common/uri'; import { fromNow } from 'vs/base/common/date'; import { Codicon } from 'vs/base/common/codicons'; import { API_OPEN_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands'; import { registerAction2, Action2, MenuId } from 'vs/platform/actions/common/actions'; -import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { ContextKeyExpr, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +const EDIT_SESSIONS_COUNT_KEY = 'editSessionsCount'; +const EDIT_SESSIONS_COUNT_CONTEXT_KEY = new RawContextKey(EDIT_SESSIONS_COUNT_KEY, 0); + export class EditSessionsDataViews extends Disposable { constructor( container: ViewContainer, @@ -41,7 +44,9 @@ export class EditSessionsDataViews extends Disposable { treeView.dataProvider = this.instantiationService.createInstance(EditSessionDataViewDataProvider); } }); - Registry.as(Extensions.ViewsRegistry).registerViews([{ + + const viewsRegistry = Registry.as(Extensions.ViewsRegistry); + viewsRegistry.registerViews([{ id: viewId, name, ctorDescriptor: new SyncDescriptor(TreeViewPane), @@ -54,6 +59,20 @@ export class EditSessionsDataViews extends Disposable { hideByDefault: true, }], container); + viewsRegistry.registerViewWelcomeContent(viewId, { + content: localize( + 'noEditSessions', + 'You have no stored edit sessions to display.\n{0}', + localize( + { key: 'storeEditSessionCommand', comment: ['Please do not translate the word "command", it is part of our internal syntax which must not change'] }, + '[{0}](command:workbench.editSessions.actions.store)', + localize('storeEditSessionTitle', 'Store Edit Session') + ) + ), + when: ContextKeyExpr.and(ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, true), ContextKeyExpr.equals(EDIT_SESSIONS_COUNT_KEY, 0)), + order: 1 + }); + registerAction2(class extends Action2 { constructor() { super({ @@ -76,6 +95,22 @@ export class EditSessionsDataViews extends Disposable { } }); + registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.editSessions.actions.store', + title: localize('workbench.editSessions.actions.store', "Store Edit Session"), + icon: Codicon.cloudUpload, + }); + } + + async run(accessor: ServicesAccessor, handle: TreeViewItemHandleArg): Promise { + const commandService = accessor.get(ICommandService); + await commandService.executeCommand('workbench.experimental.editSessions.actions.storeCurrent'); + await treeView.refresh(); + } + }); + registerAction2(class extends Action2 { constructor() { super({ @@ -109,9 +144,15 @@ export class EditSessionsDataViews extends Disposable { } class EditSessionDataViewDataProvider implements ITreeViewDataProvider { + + private editSessionsCount; + constructor( - @IEditSessionsWorkbenchService private readonly editSessionsWorkbenchService: IEditSessionsWorkbenchService - ) { } + @IEditSessionsWorkbenchService private readonly editSessionsWorkbenchService: IEditSessionsWorkbenchService, + @IContextKeyService private readonly contextKeyService: IContextKeyService + ) { + this.editSessionsCount = EDIT_SESSIONS_COUNT_CONTEXT_KEY.bindTo(this.contextKeyService); + } async getChildren(element?: ITreeItem): Promise { if (!element) { @@ -131,6 +172,7 @@ class EditSessionDataViewDataProvider implements ITreeViewDataProvider { private async getAllEditSessions(): Promise { const allEditSessions = await this.editSessionsWorkbenchService.list(); + this.editSessionsCount.set(allEditSessions.length); return allEditSessions.map((session) => { const resource = URI.from({ scheme: EDIT_SESSIONS_SCHEME, authority: 'remote-session-content', path: `/${session.ref}` }); return { diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts index 36f51b145a0..c8c9b8f437f 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts @@ -59,6 +59,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes // If another window changes the preferred session storage, reset our cached auth state in memory this._register(this.storageService.onDidChangeValue(e => this.onDidChangeStorage(e))); + this.registerSignInAction(); this.registerResetAuthenticationAction(); this.signedInContext = EDIT_SESSIONS_SIGNED_IN.bindTo(this.contextKeyService); @@ -109,7 +110,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes return (content !== undefined && content !== null && ref !== undefined) ? { ref: ref, editSession: JSON.parse(content) } : undefined; } - async delete(ref: string) { + async delete(ref: string | null) { await this.initialize(); if (!this.initialized) { throw new Error(`Unable to delete edit session with ref ${ref}.`); @@ -349,6 +350,27 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes } } + private registerSignInAction() { + const that = this; + this._register(registerAction2(class ResetEditSessionAuthenticationAction extends Action2 { + constructor() { + super({ + id: 'workbench.editSessions.actions.signIn', + title: localize('sign in', 'Sign In'), + category: EDIT_SESSION_SYNC_CATEGORY, + precondition: ContextKeyExpr.equals(EDIT_SESSIONS_SIGNED_IN_KEY, false), + menu: [{ + id: MenuId.CommandPalette, + }] + }); + } + + async run() { + await that.initialize(); + } + })); + } + private registerResetAuthenticationAction() { const that = this; this._register(registerAction2(class ResetEditSessionAuthenticationAction extends Action2 { diff --git a/src/vs/workbench/contrib/editSessions/common/editSessions.ts b/src/vs/workbench/contrib/editSessions/common/editSessions.ts index c4a2801d9ff..447225b211a 100644 --- a/src/vs/workbench/contrib/editSessions/common/editSessions.ts +++ b/src/vs/workbench/contrib/editSessions/common/editSessions.ts @@ -23,7 +23,7 @@ export interface IEditSessionsWorkbenchService { read(ref: string | undefined): Promise<{ ref: string; editSession: EditSession } | undefined>; write(editSession: EditSession): Promise; - delete(ref: string): Promise; + delete(ref: string | null): Promise; list(): Promise; } From 1249eb2410656d70d2a85caf160e72d927f7a113 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 3 Aug 2022 14:32:03 -0700 Subject: [PATCH 208/303] Add an action to delete all edit sessions --- .../editSessions/browser/editSessionsViews.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts index 7b96959f190..1607260baa8 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts @@ -140,6 +140,34 @@ export class EditSessionsDataViews extends Disposable { } } }); + + registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.editSessions.actions.deleteAll', + title: localize('workbench.editSessions.actions.deleteAll', "Delete All Edit Sessions"), + icon: Codicon.trash, + menu: { + id: MenuId.ViewTitle, + when: ContextKeyExpr.and(ContextKeyExpr.equals('view', viewId), ContextKeyExpr.greater(EDIT_SESSIONS_COUNT_KEY, 0)), + } + }); + } + + async run(accessor: ServicesAccessor): Promise { + const dialogService = accessor.get(IDialogService); + const editSessionWorkbenchService = accessor.get(IEditSessionsWorkbenchService); + const result = await dialogService.confirm({ + message: localize('confirm delete all', 'Are you sure you want to permanently delete all edit sessions? You cannot undo this action.'), + type: 'warning', + title: EDIT_SESSIONS_TITLE + }); + if (result.confirmed) { + await editSessionWorkbenchService.delete(null); + await treeView.refresh(); + } + } + }); } } From c0d3e7cf4c9a7d90e352b345b882fc134180d69a Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 3 Aug 2022 14:43:33 -0700 Subject: [PATCH 209/303] Update Codicons (#157036) --- .../browser/ui/codicons/codicon/codicon.ttf | Bin 72504 -> 72488 bytes src/vs/base/common/codicons.ts | 22 +++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf index 5abfa748fb56c712c19d127f550727acc3fabe59..e4a30a34bc39894ac6b3a378add06a4a8bd67dbd 100644 GIT binary patch delta 359 zcmdn7jb+6)mI;Q;+ngs%H1W003c19!0eNoSW&=qjIoh{ff2}OP{>QnO`ZI0 zrxybwlL%1kM?rpZiSlg?T?R%L9tH++nTdOJSayeq@o#){n1k7h!F=;3&VEKli^)#h zKN&4I+wg?5@>(%4yxI%FK=}oN@tlkno1|~EGFnc)qp+5F8PBfGJ&OCJC(p9IKiSnb zU~{G2t;6*^3^ELiKnE}|uraVRXh7Lq3@QxzP&PM%Fhei{GteQNKoLHMG$@-1$S#4h znStykD4PYyo&aUDGDtAYgRh&`@p$HAbH4x0o2!m<$c3Gcq%F wGaE7(Oz&l8tliGb!uWudhbK9+C^;upHz%0Ed}NzW@LL delta 374 zcmZ3njb+C+mI;Q;JDmF_n)q7Bggj$lP?TU`VD`yPtSDeQ#@NWfzzF0sDC8yPre2PE z!otAFBmxxsT998{;_y1!nt_pphk-#{XW||m7N+JXzm0DWb1<7TSZv8CD8E23o|DmXlk{y?Myttp6xK4&;5oOsM{%F@WIa3Y$*#6f zHdor+I$Y1qAj7~2bN~Yb8v{FoI+V@Dpu(UBWpgtKGXya(10BK%6yak?g|eA|>|!XJ z8OUygvRQ!aekhxjL5yK8l+6Yd-wb7QF?cW>1hF}QhH^8gF>+47#l)z_XgQsUnXwy4 zO<-oMWny61&cnj^kX2bEIkPA^Csj8mu_!%NH@~zbCo?aV4=M=ZPXEctsJ~sGi}9xb E0O{^hP5=M^ diff --git a/src/vs/base/common/codicons.ts b/src/vs/base/common/codicons.ts index da581de1cc6..fc803a10ef6 100644 --- a/src/vs/base/common/codicons.ts +++ b/src/vs/base/common/codicons.ts @@ -94,11 +94,12 @@ export class Codicon implements CSSIcon { public static readonly eyeUnwatch = new Codicon('eye-unwatch', { fontCharacter: '\\ea70' }); public static readonly eyeWatch = new Codicon('eye-watch', { fontCharacter: '\\ea70' }); public static readonly circleFilled = new Codicon('circle-filled', { fontCharacter: '\\ea71' }); - public static readonly primitiveDot = new Codicon('primitive-dot', { fontCharacter: '\\ea71' }); - public static readonly closeDirty = new Codicon('close-dirty', { fontCharacter: '\\ea71' }); - public static readonly debugBreakpoint = new Codicon('debug-breakpoint', { fontCharacter: '\\ea71' }); - public static readonly debugBreakpointDisabled = new Codicon('debug-breakpoint-disabled', { fontCharacter: '\\ea71' }); - public static readonly debugHint = new Codicon('debug-hint', { fontCharacter: '\\ea71' }); + public static readonly primitiveDot = new Codicon('primitive-dot', Codicon.circleFilled.definition); + public static readonly closeDirty = new Codicon('close-dirty', Codicon.circleFilled.definition); + public static readonly terminalDecorationSuccess = new Codicon('terminal-decoration-success', Codicon.circleFilled.definition); + public static readonly debugBreakpoint = new Codicon('debug-breakpoint', Codicon.circleFilled.definition); + public static readonly debugBreakpointDisabled = new Codicon('debug-breakpoint-disabled', Codicon.circleFilled.definition); + public static readonly debugHint = new Codicon('debug-hint', Codicon.circleFilled.definition); public static readonly primitiveSquare = new Codicon('primitive-square', { fontCharacter: '\\ea72' }); public static readonly edit = new Codicon('edit', { fontCharacter: '\\ea73' }); public static readonly pencil = new Codicon('pencil', { fontCharacter: '\\ea73' }); @@ -218,8 +219,10 @@ export class Codicon implements CSSIcon { public static readonly chromeMaximize = new Codicon('chrome-maximize', { fontCharacter: '\\eab9' }); public static readonly chromeMinimize = new Codicon('chrome-minimize', { fontCharacter: '\\eaba' }); public static readonly chromeRestore = new Codicon('chrome-restore', { fontCharacter: '\\eabb' }); - public static readonly circleOutline = new Codicon('circle-outline', { fontCharacter: '\\eabc' }); - public static readonly debugBreakpointUnverified = new Codicon('debug-breakpoint-unverified', { fontCharacter: '\\eabc' }); + public static readonly circle = new Codicon('circle', { fontCharacter: '\\eabc' }); + public static readonly circleOutline = new Codicon('circle-outline', Codicon.circle.definition); + public static readonly terminalDecorationIncomplete = new Codicon('terminal-decoration-incomplete', Codicon.circle.definition); + public static readonly debugBreakpointUnverified = new Codicon('debug-breakpoint-unverified', Codicon.circle.definition); public static readonly circleSlash = new Codicon('circle-slash', { fontCharacter: '\\eabd' }); public static readonly circuitBoard = new Codicon('circuit-board', { fontCharacter: '\\eabe' }); public static readonly clearAll = new Codicon('clear-all', { fontCharacter: '\\eabf' }); @@ -430,6 +433,7 @@ export class Codicon implements CSSIcon { public static readonly debugStackframeActive = new Codicon('debug-stackframe-active', { fontCharacter: '\\eb89' }); public static readonly circleSmallFilled = new Codicon('circle-small-filled', { fontCharacter: '\\eb8a' }); public static readonly debugStackframeDot = new Codicon('debug-stackframe-dot', Codicon.circleSmallFilled.definition); + public static readonly terminalDecorationMark = new Codicon('terminal-decoration-mark', Codicon.circleSmallFilled.definition); public static readonly debugStackframe = new Codicon('debug-stackframe', { fontCharacter: '\\eb8b' }); public static readonly debugStackframeFocused = new Codicon('debug-stackframe-focused', { fontCharacter: '\\eb8b' }); public static readonly debugBreakpointUnsupported = new Codicon('debug-breakpoint-unsupported', { fontCharacter: '\\eb8c' }); @@ -473,7 +477,8 @@ export class Codicon implements CSSIcon { public static readonly pinnedDirty = new Codicon('pinned-dirty', { fontCharacter: '\\ebb2' }); public static readonly passFilled = new Codicon('pass-filled', { fontCharacter: '\\ebb3' }); public static readonly circleLargeFilled = new Codicon('circle-large-filled', { fontCharacter: '\\ebb4' }); - public static readonly circleLargeOutline = new Codicon('circle-large-outline', { fontCharacter: '\\ebb5' }); + public static readonly circleLarge = new Codicon('circle-large', { fontCharacter: '\\ebb5' }); + public static readonly circleLargeOutline = new Codicon('circle-large-outline', Codicon.circleLarge.definition); public static readonly combine = new Codicon('combine', { fontCharacter: '\\ebb6' }); public static readonly gather = new Codicon('gather', { fontCharacter: '\\ebb6' }); public static readonly table = new Codicon('table', { fontCharacter: '\\ebb7' }); @@ -549,6 +554,7 @@ export class Codicon implements CSSIcon { public static readonly indent = new Codicon('indent', { fontCharacter: '\\ebf9' }); public static readonly recordSmall = new Codicon('record-small', { fontCharacter: '\\ebfa' }); public static readonly errorSmall = new Codicon('error-small', { fontCharacter: '\\ebfb' }); + public static readonly terminalDecorationError = new Codicon('terminal-decoration-error', Codicon.errorSmall.definition); public static readonly arrowCircleDown = new Codicon('arrow-circle-down', { fontCharacter: '\\ebfc' }); public static readonly arrowCircleLeft = new Codicon('arrow-circle-left', { fontCharacter: '\\ebfd' }); public static readonly arrowCircleRight = new Codicon('arrow-circle-right', { fontCharacter: '\\ebfe' }); From 43d0df37afac741e700a787d5bec36e6d078d728 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 3 Aug 2022 15:57:55 -0700 Subject: [PATCH 210/303] improve task setting description (#157039) fix #156728 --- src/vs/workbench/contrib/tasks/browser/task.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts index 7671ffb7db8..0f9f957a33c 100644 --- a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts +++ b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts @@ -510,7 +510,7 @@ configurationRegistry.registerConfiguration({ }, [TaskSettingId.ShowDecorations]: { type: 'boolean', - description: nls.localize('task.showDecorations', "Shows decorations at points of interest in the terminal buffer such as the first problem found via a watch task. Note that this will only take effect for future tasks."), + markdownDescription: nls.localize('task.showDecorations', "Shows decorations at points of interest in the terminal buffer such as the first problem found via a watch task. Note that this will only take effect for future tasks. {0} will take precedence over this setting", '`#terminal.integrated.shellIntegration.decorationsEnabled#`'), default: true }, [TaskSettingId.Reconnection]: { From 1c02bdda63eaa3889a8d3469b07fff9c50c4b6da Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 3 Aug 2022 15:58:10 -0700 Subject: [PATCH 211/303] `task & reconnectionOwner` -> `reconnectionProperties` (#156926) --- src/vs/platform/terminal/common/terminal.ts | 21 ++++++++++--------- .../terminal/common/terminalProcess.ts | 5 ++--- src/vs/platform/terminal/node/ptyService.ts | 3 +-- .../tasks/browser/terminalTaskSystem.ts | 9 ++++---- .../contrib/terminal/browser/terminal.ts | 7 +++---- .../browser/terminalEditorSerializer.ts | 3 +-- .../terminal/browser/terminalInstance.ts | 8 +++---- .../browser/terminalProcessManager.ts | 12 +++++------ .../terminal/browser/terminalService.ts | 6 +++--- 9 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index ad7c40b1c3c..a59e831fc7d 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -168,14 +168,20 @@ export interface IPtyHostAttachTarget { icon: TerminalIcon | undefined; fixedDimensions: IFixedTerminalDimensions | undefined; environmentVariableCollections: ISerializableEnvironmentVariableCollections | undefined; - reconnectionOwner?: string; - task?: { label: string; id: string; lastTask: string; group?: string }; + reconnectionProperties?: IReconnectionProperties; waitOnExit?: WaitOnExitValue; hideFromUser?: boolean; isFeatureTerminal?: boolean; type?: TerminalType; } +export interface IReconnectionProperties { + ownerId: string; + data?: unknown; +} + +export interface IReconnectionTaskData { label: string; id: string; lastTask: string; group?: string } + export type TerminalType = 'Task' | 'Local' | undefined; export enum TitleEventSource { @@ -448,9 +454,9 @@ export interface IShellLaunchConfig { ignoreConfigurationCwd?: boolean; /** - * The owner of this terminal for reconnection. + * The reconnection properties for this terminal */ - reconnectionOwner?: string; + reconnectionProperties?: IReconnectionProperties; /** Whether to wait for a key press before closing the terminal. */ waitOnExit?: WaitOnExitValue; @@ -477,7 +483,7 @@ export interface IShellLaunchConfig { * This is a terminal that attaches to an already running terminal. */ attachPersistentProcess?: { - id: number; findRevivedId?: boolean; pid: number; title: string; titleSource: TitleEventSource; cwd: string; icon?: TerminalIcon; color?: string; hasChildProcesses?: boolean; fixedDimensions?: IFixedTerminalDimensions; environmentVariableCollections?: ISerializableEnvironmentVariableCollections; reconnectionOwner?: string; task?: { label: string; id: string; lastTask: string; group?: string }; type?: TerminalType; waitOnExit?: WaitOnExitValue; hideFromUser?: boolean; isFeatureTerminal?: boolean; + id: number; findRevivedId?: boolean; pid: number; title: string; titleSource: TitleEventSource; cwd: string; icon?: TerminalIcon; color?: string; hasChildProcesses?: boolean; fixedDimensions?: IFixedTerminalDimensions; environmentVariableCollections?: ISerializableEnvironmentVariableCollections; reconnectionProperties?: IReconnectionProperties; type?: TerminalType; waitOnExit?: WaitOnExitValue; hideFromUser?: boolean; isFeatureTerminal?: boolean; }; /** @@ -549,11 +555,6 @@ export interface IShellLaunchConfig { * Create a terminal without shell integration even when it's enabled */ ignoreShellIntegration?: boolean; - - /** - * The task associated with this terminal - */ - task?: { label: string; id: string; lastTask: string; group?: string }; } export type WaitOnExitValue = boolean | string | ((exitCode: number) => string); diff --git a/src/vs/platform/terminal/common/terminalProcess.ts b/src/vs/platform/terminal/common/terminalProcess.ts index dc360427a6b..212deef3e1b 100644 --- a/src/vs/platform/terminal/common/terminalProcess.ts +++ b/src/vs/platform/terminal/common/terminalProcess.ts @@ -5,7 +5,7 @@ import { UriComponents } from 'vs/base/common/uri'; import { ISerializableEnvironmentVariableCollection, ISerializableEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariable'; -import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon, TerminalType, TitleEventSource, WaitOnExitValue } from 'vs/platform/terminal/common/terminal'; +import { IFixedTerminalDimensions, IRawTerminalTabLayoutInfo, IReconnectionProperties, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon, TerminalType, TitleEventSource, WaitOnExitValue } from 'vs/platform/terminal/common/terminal'; export interface ISingleTerminalConfiguration { userValue: T | undefined; @@ -60,8 +60,7 @@ export interface IProcessDetails { color: string | undefined; fixedDimensions: IFixedTerminalDimensions | undefined; environmentVariableCollections: ISerializableEnvironmentVariableCollections | undefined; - reconnectionOwner?: string; - task?: { label: string; id: string; lastTask: string; group?: string }; + reconnectionProperties?: IReconnectionProperties; waitOnExit?: WaitOnExitValue; hideFromUser?: boolean; isFeatureTerminal?: boolean; diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index cb23737373f..615de9d6b5a 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -410,8 +410,7 @@ export class PtyService extends Disposable implements IPtyService { color: persistentProcess.color, fixedDimensions: persistentProcess.fixedDimensions, environmentVariableCollections: persistentProcess.processLaunchOptions.options.environmentVariableCollections, - reconnectionOwner: persistentProcess.shellLaunchConfig.reconnectionOwner, - task: persistentProcess.shellLaunchConfig.task, + reconnectionProperties: persistentProcess.shellLaunchConfig.reconnectionProperties, waitOnExit: persistentProcess.shellLaunchConfig.waitOnExit, hideFromUser: persistentProcess.shellLaunchConfig.hideFromUser, isFeatureTerminal: persistentProcess.shellLaunchConfig.isFeatureTerminal, diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index eed6a1d6cf2..9b2924e896d 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -30,7 +30,7 @@ import { URI } from 'vs/base/common/uri'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IShellLaunchConfig, TerminalLocation, TerminalSettingId, WaitOnExitValue } from 'vs/platform/terminal/common/terminal'; +import { IReconnectionTaskData, IShellLaunchConfig, TerminalLocation, TerminalSettingId, WaitOnExitValue } from 'vs/platform/terminal/common/terminal'; import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { IViewDescriptorService, IViewsService, ViewContainerLocation } from 'vs/workbench/common/views'; @@ -1271,7 +1271,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { private async _reconnectToTerminal(task: Task): Promise { for (let i = 0; i < this._reconnectTerminals.length; i++) { const terminal = this._reconnectTerminals[i]; - const taskForTerminal = terminal.shellLaunchConfig.attachPersistentProcess?.task; + const taskForTerminal = terminal.shellLaunchConfig.attachPersistentProcess?.reconnectionProperties?.data as IReconnectionTaskData; if (taskForTerminal?.id && task.getRecentlyUsedKey() === taskForTerminal.lastTask) { this._reconnectTerminals.splice(i, 1); return terminal; @@ -1318,7 +1318,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { return; } for (const terminal of terminals) { - const task = terminal.shellLaunchConfig.attachPersistentProcess?.task; + const task = terminal.shellLaunchConfig.attachPersistentProcess?.reconnectionProperties?.data as IReconnectionTaskData; if (!task) { continue; } @@ -1428,8 +1428,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { this._terminalCreationQueue = this._terminalCreationQueue.then(() => this._doCreateTerminal(task, group, launchConfigs!)); const terminal: ITerminalInstance = (await this._terminalCreationQueue)!; - terminal.shellLaunchConfig.task = { lastTask: task.getRecentlyUsedKey()!, group, label: task._label, id: task._id }; - terminal.shellLaunchConfig.reconnectionOwner = ReconnectionType; + terminal.shellLaunchConfig.reconnectionProperties = { ownerId: ReconnectionType, data: { lastTask: taskKey, group, label: task._label, id: task._id } }; const terminalKey = terminal.instanceId.toString(); const terminalData = { terminal: terminal, lastTask: taskKey, group }; terminal.onDisposed(() => this._deleteTaskAndTerminal(terminal, terminalData)); diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index f340fd0bea8..2eb9043b540 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -11,7 +11,7 @@ import { FindReplaceState } from 'vs/editor/contrib/find/browser/findState'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IKeyMods } from 'vs/platform/quickinput/common/quickInput'; import { ITerminalCapabilityStore, ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities'; -import { IExtensionTerminalProfile, IProcessPropertyMap, IShellIntegration, IShellLaunchConfig, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, ProcessPropertyType, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalShellType, TerminalType, TitleEventSource, WaitOnExitValue } from 'vs/platform/terminal/common/terminal'; +import { IExtensionTerminalProfile, IProcessPropertyMap, IReconnectionProperties, IShellIntegration, IShellLaunchConfig, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, ProcessPropertyType, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalShellType, TerminalType, TitleEventSource, WaitOnExitValue } from 'vs/platform/terminal/common/terminal'; import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProcess'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; @@ -257,11 +257,10 @@ interface ITerminalEditorInputObject { readonly icon: TerminalIcon | undefined; readonly color: string | undefined; readonly hasChildProcesses?: boolean; - readonly task?: { label: string; id: string; lastTask: string; group?: string; waitOnExit?: WaitOnExitValue }; readonly type?: TerminalType; readonly isFeatureTerminal?: boolean; readonly hideFromUser?: boolean; - readonly reconnectionOwner?: string; + readonly reconnectionProperties?: IReconnectionProperties; } export interface ISerializedTerminalEditorInput extends ITerminalEditorInputObject { @@ -450,7 +449,7 @@ export interface ITerminalInstance { readonly fixedRows?: number; readonly icon?: TerminalIcon; readonly color?: string; - readonly reconnectionOwner?: string; + readonly reconnectionProperties?: IReconnectionProperties; readonly processName: string; readonly sequence?: string; readonly staticTitle?: string; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorSerializer.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorSerializer.ts index 853b4eb98e7..ec2244d2a66 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorSerializer.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorSerializer.ts @@ -44,10 +44,9 @@ export class TerminalInputSerializer implements IEditorSerializer { color: instance.color, resource: instance.resource.toString(), hasChildProcesses: instance.hasChildProcesses, - task: instance.shellLaunchConfig.task, - type: instance.shellLaunchConfig.type, isFeatureTerminal: instance.shellLaunchConfig.isFeatureTerminal, hideFromUser: instance.shellLaunchConfig.hideFromUser, + reconnectionProperties: instance.shellLaunchConfig.reconnectionProperties }; } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 1ba61b1d3d7..fd737c5b019 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -46,7 +46,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { TerminalCapabilityStoreMultiplexer } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; -import { IProcessDataEvent, IProcessPropertyMap, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, ShellIntegrationStatus, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IProcessPropertyMap, IReconnectionProperties, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, ShellIntegrationStatus, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal'; import { escapeNonWindowsPath, collapseTildePath } from 'vs/platform/terminal/common/terminalEnvironment'; import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry'; import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService'; @@ -282,7 +282,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // TODO: Should this be an event as it can fire twice? get processReady(): Promise { return this._processManager.ptyProcessReady; } get hasChildProcesses(): boolean { return this.shellLaunchConfig.attachPersistentProcess?.hasChildProcesses || this._processManager.hasChildProcesses; } - get reconnectionOwner(): string | undefined { return this.shellLaunchConfig.attachPersistentProcess?.reconnectionOwner || this.shellLaunchConfig.reconnectionOwner; } + get reconnectionProperties(): IReconnectionProperties | undefined { return this.shellLaunchConfig.attachPersistentProcess?.reconnectionProperties || this.shellLaunchConfig.reconnectionProperties; } get areLinksReady(): boolean { return this._areLinksReady; } get initialDataEvents(): string[] | undefined { return this._initialDataEvents; } get exitCode(): number | undefined { return this._exitCode; } @@ -696,7 +696,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._shutdownPersistentProcessId = shutdownPersistentProcessId; } get persistentProcessId(): number | undefined { return this._processManager.persistentProcessId ?? this._shutdownPersistentProcessId; } - get shouldPersist(): boolean { return (this._processManager.shouldPersist || this._shutdownPersistentProcessId !== undefined) && !this.shellLaunchConfig.isTransient && (!this.reconnectionOwner || this._configurationService.getValue(TaskSettingId.Reconnection) === true); } + get shouldPersist(): boolean { return (this._processManager.shouldPersist || this._shutdownPersistentProcessId !== undefined) && !this.shellLaunchConfig.isTransient && (!this.reconnectionProperties || this._configurationService.getValue(TaskSettingId.Reconnection) === true); } /** * Create xterm.js instance and attach data listeners. @@ -2392,7 +2392,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { info.requiresAction && this._configHelper.config.environmentChangesRelaunch && !this._processManager.hasWrittenData && - (!this._shellLaunchConfig.isFeatureTerminal || (this.reconnectionOwner && this._configurationService.getValue(TaskSettingId.Reconnection) === true)) && + (!this._shellLaunchConfig.isFeatureTerminal || (this.reconnectionProperties && this._configurationService.getValue(TaskSettingId.Reconnection) === true)) && !this._shellLaunchConfig.customPtyImplementation && !this._shellLaunchConfig.isExtensionOwnedTerminal && !this._shellLaunchConfig.attachPersistentProcess diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index a82ae60c449..a2f8a5be7c7 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -20,7 +20,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { NaiveCwdDetectionCapability } from 'vs/platform/terminal/common/capabilities/naiveCwdDetectionCapability'; import { TerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; -import { FlowControlConstants, IProcessDataEvent, IProcessProperty, IProcessPropertyMap, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalEnvironment, ITerminalLaunchError, ITerminalProcessOptions, ProcessPropertyType, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; +import { FlowControlConstants, IProcessDataEvent, IProcessProperty, IProcessPropertyMap, IProcessReadyEvent, IReconnectionProperties, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalEnvironment, ITerminalLaunchError, ITerminalProcessOptions, ProcessPropertyType, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { ISerializedCommandDetectionCapability } from 'vs/platform/terminal/common/terminalProcess'; import { TerminalRecorder } from 'vs/platform/terminal/common/terminalRecorder'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -114,10 +114,10 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce readonly onRestoreCommands = this._onRestoreCommands.event; get persistentProcessId(): number | undefined { return this._process?.id; } - get shouldPersist(): boolean { return !!this.reconnectionOwner || (this._process ? this._process.shouldPersist : false); } + get shouldPersist(): boolean { return !!this.reconnectionProperties || (this._process ? this._process.shouldPersist : false); } get hasWrittenData(): boolean { return this._hasWrittenData; } get hasChildProcesses(): boolean { return this._hasChildProcesses; } - get reconnectionOwner(): string | undefined { return this._shellLaunchConfig?.attachPersistentProcess?.reconnectionOwner || this._shellLaunchConfig?.reconnectionOwner || undefined; } + get reconnectionProperties(): IReconnectionProperties | undefined { return this._shellLaunchConfig?.attachPersistentProcess?.reconnectionProperties || this._shellLaunchConfig?.reconnectionProperties || undefined; } constructor( private readonly _instanceId: number, @@ -246,7 +246,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce // this is a copy of what the merged environment collection is on the remote side const env = await this._resolveEnvironment(backend, variableResolver, shellLaunchConfig); - const shouldPersist = ((this._configurationService.getValue(TaskSettingId.Reconnection) && shellLaunchConfig.reconnectionOwner) || !shellLaunchConfig.isFeatureTerminal) && this._configHelper.config.enablePersistentSessions && !shellLaunchConfig.isTransient; + const shouldPersist = ((this._configurationService.getValue(TaskSettingId.Reconnection) && shellLaunchConfig.reconnectionProperties) || !shellLaunchConfig.isFeatureTerminal) && this._configHelper.config.enablePersistentSessions && !shellLaunchConfig.isTransient; if (shellLaunchConfig.attachPersistentProcess) { const result = await backend.attachToProcess(shellLaunchConfig.attachPersistentProcess.id); if (result) { @@ -460,7 +460,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce windowsEnableConpty: this._configHelper.config.windowsEnableConpty && !isScreenReaderModeEnabled, environmentVariableCollections: this._extEnvironmentVariableCollection ? serializeEnvironmentVariableCollections(this._extEnvironmentVariableCollection.collections) : undefined }; - const shouldPersist = ((this._configurationService.getValue(TaskSettingId.Reconnection) && shellLaunchConfig.reconnectionOwner) || !shellLaunchConfig.isFeatureTerminal) && this._configHelper.config.enablePersistentSessions && !shellLaunchConfig.isTransient; + const shouldPersist = ((this._configurationService.getValue(TaskSettingId.Reconnection) && shellLaunchConfig.reconnectionProperties) || !shellLaunchConfig.isFeatureTerminal) && this._configHelper.config.enablePersistentSessions && !shellLaunchConfig.isTransient; return await backend.createProcess(shellLaunchConfig, initialCwd, cols, rows, this._configHelper.config.unicodeVersion, env, options, shouldPersist); } @@ -493,7 +493,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce this._ptyResponsiveListener?.dispose(); this._ptyResponsiveListener = undefined; if (this._shellLaunchConfig) { - if (this._shellLaunchConfig.isFeatureTerminal && !this.reconnectionOwner) { + if (this._shellLaunchConfig.isFeatureTerminal && !this.reconnectionProperties) { // Indicate the process is exited (and gone forever) only for feature terminals // so they can react to the exit, this is particularly important for tasks so // that it knows that the process is not still active. Note that this is not diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 1d504f3334c..6b923e75969 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -1049,12 +1049,12 @@ export class TerminalService implements ITerminalService { } private _addToReconnected(instance: ITerminalInstance): void { - if (instance.reconnectionOwner) { - const reconnectedTerminals = this._reconnectedTerminals.get(instance.reconnectionOwner); + if (instance.reconnectionProperties) { + const reconnectedTerminals = this._reconnectedTerminals.get(instance.reconnectionProperties.ownerId); if (reconnectedTerminals) { reconnectedTerminals.push(instance); } else { - this._reconnectedTerminals.set(instance.reconnectionOwner, [instance]); + this._reconnectedTerminals.set(instance.reconnectionProperties.ownerId, [instance]); } } } From 357d14621c86f79dbd740e1720b06d46b55e1b6c Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Wed, 3 Aug 2022 19:16:33 -0400 Subject: [PATCH 212/303] RPM packaging: Use standard macros (#153247) * RPM spec: Use standard macros for paths/name - Once `@@NAME@@` is replaced into the spec file as the `Name:`, it can be referenced with the RPM macro `%{name}` - The installation directories corresponding to `/usr/bin/` and `/usr/share/` are defined in the RPM macros `%{_bindir}` and `%{_datadir}` Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Co-authored-by: Robo --- resources/linux/rpm/code.spec.template | 60 ++++++++++++++------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/resources/linux/rpm/code.spec.template b/resources/linux/rpm/code.spec.template index 00ddb6fdf08..61659d25837 100644 --- a/resources/linux/rpm/code.spec.template +++ b/resources/linux/rpm/code.spec.template @@ -11,7 +11,7 @@ Icon: @@NAME@@.xpm Requires: @@DEPENDENCIES@@ AutoReq: 0 -%global __provides_exclude_from ^%{_datadir}/@@NAME@@/.*\\.so.*$ +%global __provides_exclude_from ^%{_datadir}/%{name}/.*\\.so.*$ %description Visual Studio Code is a new choice of tool that combines the simplicity of a code editor with what developers need for the core edit-build-debug cycle. See https://code.visualstudio.com/docs/setup/linux for installation instructions and FAQ. @@ -21,25 +21,29 @@ Visual Studio Code is a new choice of tool that combines the simplicity of a cod %define _build_id_links none %install -mkdir -p %{buildroot}/usr/bin -mkdir -p %{buildroot}/usr/share/@@NAME@@ -mkdir -p %{buildroot}/usr/share/applications -mkdir -p %{buildroot}/usr/share/pixmaps -mkdir -p %{buildroot}/usr/share/bash-completion/completions -mkdir -p %{buildroot}/usr/share/zsh/site-functions -mkdir -p %{buildroot}/usr/share/mime/packages -cp -r usr/share/@@NAME@@/* %{buildroot}/usr/share/@@NAME@@ -cp -r usr/share/applications/@@NAME@@.desktop %{buildroot}/usr/share/applications -cp -r usr/share/applications/@@NAME@@-url-handler.desktop %{buildroot}/usr/share/applications -cp -r usr/share/mime/packages/@@NAME@@-workspace.xml %{buildroot}/usr/share/mime/packages/@@NAME@@-workspace.xml -cp -r usr/share/pixmaps/@@ICON@@.png %{buildroot}/usr/share/pixmaps -cp usr/share/bash-completion/completions/@@NAME@@ %{buildroot}/usr/share/bash-completion/completions/@@NAME@@ -cp usr/share/zsh/site-functions/_@@NAME@@ %{buildroot}/usr/share/zsh/site-functions/_@@NAME@@ -ln -s ../share/@@NAME@@/bin/@@NAME@@ %{buildroot}/usr/bin/@@NAME@@ +# Destination directories +mkdir -p %{buildroot}%{_bindir} +mkdir -p %{buildroot}%{_datadir}/%{name} +mkdir -p %{buildroot}%{_datadir}/applications +mkdir -p %{buildroot}%{_datadir}/mime/packages +mkdir -p %{buildroot}%{_datadir}/pixmaps +mkdir -p %{buildroot}%{_datadir}/bash-completion/completions +mkdir -p %{buildroot}%{_datadir}/zsh/site-functions +# Application +cp -r usr/share/%{name}/* %{buildroot}%{_datadir}/%{name} +ln -s %{_datadir}/%{name}/bin/%{name} %{buildroot}%{_bindir}/%{name} +# Support files +cp -r usr/share/applications/%{name}.desktop %{buildroot}%{_datadir}/applications +cp -r usr/share/applications/%{name}-url-handler.desktop %{buildroot}%{_datadir}/applications +cp -r usr/share/mime/packages/%{name}-workspace.xml %{buildroot}%{_datadir}/mime/packages/%{name}-workspace.xml +cp -r usr/share/pixmaps/@@ICON@@.png %{buildroot}%{_datadir}/pixmaps +# Shell completions +cp usr/share/bash-completion/completions/%{name} %{buildroot}%{_datadir}/bash-completion/completions/%{name} +cp usr/share/zsh/site-functions/_%{name} %{buildroot}%{_datadir}/zsh/site-functions/_%{name} %post # Remove the legacy bin command if this is the stable build -if [ "@@NAME@@" = "code" ]; then +if [ "%{name}" = "code" ]; then rm -f /usr/local/bin/code fi @@ -54,21 +58,21 @@ fi #fi # Update mimetype database to pickup workspace mimetype -update-mime-database /usr/share/mime &> /dev/null || : +update-mime-database %{_datadir}/mime &> /dev/null || : %postun # Update mimetype database for removed workspace mimetype -update-mime-database /usr/share/mime &> /dev/null || : +update-mime-database %{_datadir}/mime &> /dev/null || : %files %defattr(-,root,root) -%attr(4755, root, root) /usr/share/@@NAME@@/chrome-sandbox +%attr(4755, root, root) %{_datadir}/%{name}/chrome-sandbox -/usr/bin/@@NAME@@ -/usr/share/@@NAME@@/ -/usr/share/applications/@@NAME@@.desktop -/usr/share/applications/@@NAME@@-url-handler.desktop -/usr/share/mime/packages/@@NAME@@-workspace.xml -/usr/share/pixmaps/@@ICON@@.png -/usr/share/bash-completion/completions/@@NAME@@ -/usr/share/zsh/site-functions/_@@NAME@@ +%{_bindir}/%{name} +%{_datadir}/%{name}/ +%{_datadir}/applications/%{name}.desktop +%{_datadir}/applications/%{name}-url-handler.desktop +%{_datadir}/mime/packages/%{name}-workspace.xml +%{_datadir}/pixmaps/@@ICON@@.png +%{_datadir}/bash-completion/completions/%{name} +%{_datadir}/zsh/site-functions/_%{name} From 9f80085795235a542238b1350759d3521031f2ab Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Wed, 3 Aug 2022 16:31:19 -0700 Subject: [PATCH 213/303] Fix language-specific tab expansion and polish (#157035) * Fix language-specific tab expansion and polish Fixes #156075 * Add back check --- extensions/emmet/package.json | 2 +- extensions/emmet/src/abbreviationActions.ts | 60 +++++++++---------- .../emmet/src/defaultCompletionProvider.ts | 4 +- extensions/emmet/src/selectItemHTML.ts | 2 +- .../contrib/emmet/browser/emmetActions.ts | 10 +++- 5 files changed, 42 insertions(+), 36 deletions(-) diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json index 9cbe3bf74a6..2c1bbda1ad7 100644 --- a/extensions/emmet/package.json +++ b/extensions/emmet/package.json @@ -65,7 +65,7 @@ "emmet.showAbbreviationSuggestions": { "type": "boolean", "default": true, - "scope": "language-overridable", + "scope": "resource", "markdownDescription": "%emmetShowAbbreviationSuggestions%" }, "emmet.includeLanguages": { diff --git a/extensions/emmet/src/abbreviationActions.ts b/extensions/emmet/src/abbreviationActions.ts index 45a9510acd5..3a930feea2d 100644 --- a/extensions/emmet/src/abbreviationActions.ts +++ b/extensions/emmet/src/abbreviationActions.ts @@ -264,47 +264,47 @@ export async function wrapWithAbbreviation(args: any): Promise { } export function expandEmmetAbbreviation(args: any): Thenable { - if (!validate() || !vscode.window.activeTextEditor) { - return fallbackTab(); + if (!validate()) { + return Promise.resolve(undefined); } + const editor = vscode.window.activeTextEditor!; + + args = args || {}; + if (!args['language']) { + args['language'] = editor.document.languageId; + } else { + const excludedLanguages = vscode.workspace.getConfiguration('emmet')['excludeLanguages'] ?? []; + if (excludedLanguages.includes(args['language'])) { + return fallbackTab(args['language']); + } + } + const languageId: string = args['language']; + /** * Short circuit the parsing. If previous character is space, do not expand. */ - if (vscode.window.activeTextEditor.selections.length === 1 && - vscode.window.activeTextEditor.selection.isEmpty + if (editor.selections.length === 1 && editor.selection.isEmpty ) { - const anchor = vscode.window.activeTextEditor.selection.anchor; + const anchor = editor.selection.anchor; if (anchor.character === 0) { - return fallbackTab(); + return fallbackTab(languageId); } const prevPositionAnchor = anchor.translate(0, -1); - const prevText = vscode.window.activeTextEditor.document.getText(new vscode.Range(prevPositionAnchor, anchor)); + const prevText = editor.document.getText(new vscode.Range(prevPositionAnchor, anchor)); if (prevText === ' ' || prevText === '\t') { - return fallbackTab(); + return fallbackTab(languageId); } } - args = args || {}; - if (!args['language']) { - args['language'] = vscode.window.activeTextEditor.document.languageId; - } else { - const excludedLanguages = vscode.workspace.getConfiguration('emmet')['excludeLanguages'] ? vscode.workspace.getConfiguration('emmet')['excludeLanguages'] : []; - if (excludedLanguages.indexOf(vscode.window.activeTextEditor.document.languageId) > -1) { - return fallbackTab(); - } - } const syntax = getSyntaxFromArgs(args); if (!syntax) { - return fallbackTab(); + return fallbackTab(languageId); } - - const editor = vscode.window.activeTextEditor; - // When tabbed on a non empty selection, do not treat it as an emmet abbreviation, and fallback to tab instead - if (vscode.workspace.getConfiguration('emmet')['triggerExpansionOnTab'] === true && editor.selections.find(x => !x.isEmpty)) { - return fallbackTab(); + if (vscode.workspace.getConfiguration('emmet', { languageId })['triggerExpansionOnTab'] === true && editor.selections.find(x => !x.isEmpty)) { + return fallbackTab(languageId); } const abbreviationList: ExpandAbbreviationInput[] = []; @@ -325,7 +325,7 @@ export function expandEmmetAbbreviation(args: any): Thenable
explicitly // else we will end up with <
@@ -415,12 +415,12 @@ export function expandEmmetAbbreviation(args: any): Thenable { - return success ? Promise.resolve(undefined) : fallbackTab(); + return success ? Promise.resolve(undefined) : fallbackTab(languageId); }); } -function fallbackTab(): Thenable { - if (vscode.workspace.getConfiguration('emmet')['triggerExpansionOnTab'] === true) { +function fallbackTab(languageId: string): Thenable { + if (vscode.workspace.getConfiguration('emmet', { languageId })['triggerExpansionOnTab'] === true) { return vscode.commands.executeCommand('tab'); } return Promise.resolve(true); @@ -470,13 +470,13 @@ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocumen && propertyNode.separator && offset >= propertyNode.separatorToken.end && offset <= propertyNode.terminatorToken.start - && abbreviation.indexOf(':') === -1) { + && !abbreviation.includes(':')) { return hexColorRegex.test(abbreviation) || abbreviation === '!'; } if (!propertyNode.terminatorToken && propertyNode.separator && offset >= propertyNode.separatorToken.end - && abbreviation.indexOf(':') === -1) { + && !abbreviation.includes(':')) { return hexColorRegex.test(abbreviation) || abbreviation === '!'; } if (hexColorRegex.test(abbreviation) || abbreviation === '!') { @@ -529,7 +529,7 @@ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocumen const typeAttribute = (currentHtmlNode.attributes || []).filter(x => x.name.toString() === 'type')[0]; const typeValue = typeAttribute ? typeAttribute.value.toString() : ''; - if (allowedMimeTypesInScriptTag.indexOf(typeValue) > -1) { + if (allowedMimeTypesInScriptTag.includes(typeValue)) { return true; } diff --git a/extensions/emmet/src/defaultCompletionProvider.ts b/extensions/emmet/src/defaultCompletionProvider.ts index c8a6f657d75..96ed024d593 100644 --- a/extensions/emmet/src/defaultCompletionProvider.ts +++ b/extensions/emmet/src/defaultCompletionProvider.ts @@ -31,7 +31,7 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi if (expandedText.startsWith('<')) { this.lastCompletionType = 'html'; - } else if (expandedText.indexOf(':') > 0 && expandedText.endsWith(';')) { + } else if (expandedText.includes(':') && expandedText.endsWith(';')) { this.lastCompletionType = 'css'; } else { this.lastCompletionType = undefined; @@ -43,7 +43,7 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi private provideCompletionItemsInternal(document: vscode.TextDocument, position: vscode.Position, context: vscode.CompletionContext): Thenable | undefined { const emmetConfig = vscode.workspace.getConfiguration('emmet'); const excludedLanguages = emmetConfig['excludeLanguages'] ? emmetConfig['excludeLanguages'] : []; - if (excludedLanguages.indexOf(document.languageId) > -1) { + if (excludedLanguages.includes(document.languageId)) { return; } diff --git a/extensions/emmet/src/selectItemHTML.ts b/extensions/emmet/src/selectItemHTML.ts index 6400913396c..2465d3da652 100644 --- a/extensions/emmet/src/selectItemHTML.ts +++ b/extensions/emmet/src/selectItemHTML.ts @@ -140,7 +140,7 @@ function getNextAttribute(document: vscode.TextDocument, selectionStart: number, } // Fetch the next word in the attr value - if (attr.value.toString().indexOf(' ') === -1) { + if (!attr.value.toString().includes(' ')) { // attr value does not have space, so no next word to find continue; } diff --git a/src/vs/workbench/contrib/emmet/browser/emmetActions.ts b/src/vs/workbench/contrib/emmet/browser/emmetActions.ts index 95bbfe3d823..9dac525abcc 100644 --- a/src/vs/workbench/contrib/emmet/browser/emmetActions.ts +++ b/src/vs/workbench/contrib/emmet/browser/emmetActions.ts @@ -8,6 +8,7 @@ import { grammarsExtPoint, ITMSyntaxExtensionPoint } from 'vs/workbench/services import { IExtensionService, ExtensionPointContribution } from 'vs/workbench/services/extensions/common/extensions'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; interface ModeScopeMap { [key: string]: string; @@ -70,13 +71,18 @@ export abstract class EmmetEditorAction extends EditorAction { } public run(accessor: ServicesAccessor, editor: ICodeEditor): Promise { - const extensionService = accessor.get(IExtensionService); const commandService = accessor.get(ICommandService); + const configurationService = accessor.get(IConfigurationService); + const extensionService = accessor.get(IExtensionService); return this._withGrammarContributions(extensionService).then((grammarContributions) => { if (this.id === 'editor.emmet.action.expandAbbreviation' && grammarContributions) { - return commandService.executeCommand('emmet.expandAbbreviation', EmmetEditorAction.getLanguage(editor, grammarContributions)); + const languageInfo = EmmetEditorAction.getLanguage(editor, grammarContributions); + const languageId = languageInfo?.language; + if (configurationService.getValue('emmet.triggerExpansionOnTab', { overrideIdentifier: languageId }) === true) { + return commandService.executeCommand('emmet.expandAbbreviation', languageInfo); + } } return undefined; From 012cfb2795b4874c7e520ef0b43f92d0b0866dcf Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 3 Aug 2022 16:36:32 -0700 Subject: [PATCH 214/303] Fixes #155309 (#157048) --- .../workbench/contrib/notebook/browser/view/cellParts/cellDnd.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellDnd.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellDnd.ts index 86e0a69074a..a5b951d33c9 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellDnd.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellDnd.ts @@ -95,7 +95,6 @@ export class CellDragAndDropController extends Disposable { return; } event.browserEvent.preventDefault(); - event.browserEvent.stopImmediatePropagation(); this.onCellDragover(event); }, true); addCellDragListener(DOM.EventType.DROP, event => { From da066ffcc97381ae079890f888756ddf792579df Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Wed, 3 Aug 2022 17:37:29 -0700 Subject: [PATCH 215/303] Clear queries if setting search failed (#157046) * Clear queries if setting search failed Fixes #153582 * Add clarity --- .../preferences/browser/settingsEditor2.ts | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index 25bb124f3c0..11a3c258f19 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -642,6 +642,7 @@ export class SettingsEditor2 extends EditorPane { private onDidClickSetting(evt: ISettingLinkClickEvent, recursed?: boolean): void { const targetElement = this.currentSettingsModel.getElementsByName(evt.targetKey)?.[0]; + let revealFailed = false; if (targetElement) { let sourceTop = 0.5; try { @@ -661,23 +662,34 @@ export class SettingsEditor2 extends EditorPane { if (this.viewState.filterToCategory && evt.source.displayCategory !== targetElement.displayCategory) { this.tocTree.setFocus([]); } - this.settingsTree.reveal(targetElement, sourceTop); + try { + this.settingsTree.reveal(targetElement, sourceTop); + } catch (_) { + // The listwidget couldn't find the setting to reveal, + // even though it's in the model, meaning there might be a filter + // preventing it from showing up. + revealFailed = true; + } - // We need to shift focus from the setting that contains the link to the setting that's - // linked. Clicking on the link sets focus on the setting that contains the link, - // which is why we need the setTimeout. - setTimeout(() => { - this.settingsTree.setFocus([targetElement]); - }, 50); + if (!revealFailed) { + // We need to shift focus from the setting that contains the link to the setting that's + // linked. Clicking on the link sets focus on the setting that contains the link, + // which is why we need the setTimeout. + setTimeout(() => { + this.settingsTree.setFocus([targetElement]); + }, 50); - const domElements = this.settingRenderers.getDOMElementsForSettingKey(this.settingsTree.getHTMLElement(), evt.targetKey); - if (domElements && domElements[0]) { - const control = domElements[0].querySelector(AbstractSettingRenderer.CONTROL_SELECTOR); - if (control) { - (control).focus(); + const domElements = this.settingRenderers.getDOMElementsForSettingKey(this.settingsTree.getHTMLElement(), evt.targetKey); + if (domElements && domElements[0]) { + const control = domElements[0].querySelector(AbstractSettingRenderer.CONTROL_SELECTOR); + if (control) { + (control).focus(); + } } } - } else if (!recursed) { + } + + if (!recursed && revealFailed) { // We'll call this event handler again after clearing the search query, // so that more settings show up in the list. const p = this.triggerSearch(''); From d07eb95444b73922d28596e8479277e50a060d3a Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 3 Aug 2022 19:46:15 -0500 Subject: [PATCH 216/303] Fix getting initial configs from debug adapter (#157051) Fixes #156943 --- .../contrib/debug/browser/debugConfigurationManager.ts | 6 +++--- src/vs/workbench/contrib/debug/browser/debugQuickAccess.ts | 2 +- src/vs/workbench/contrib/debug/common/debug.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts index a00d75ef26a..5ccaf7933c3 100644 --- a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts @@ -215,7 +215,7 @@ export class ConfigurationManager implements IConfigurationManager { disposables.add(input.onDidTriggerItemButton(async (context) => { resolve(undefined); const { launch, config } = context.item; - await launch.openConfigFile({ preserveFocus: false, type: config.type }); + await launch.openConfigFile({ preserveFocus: false, type: config.type, suppressInitialConfigs: true }); // Only Launch have a pin trigger button await (launch as Launch).writeConfiguration(config); await this.selectConfiguration(launch, config.name); @@ -564,7 +564,7 @@ class Launch extends AbstractLaunch implements ILaunch { return this.configurationService.inspect('launch', { resource: this.workspace.uri }).workspaceFolderValue; } - async openConfigFile({ preserveFocus, type, useInitialConfigs }: { preserveFocus: boolean; type?: string; useInitialConfigs?: boolean }, token?: CancellationToken): Promise<{ editor: IEditorPane | null; created: boolean }> { + async openConfigFile({ preserveFocus, type, suppressInitialConfigs }: { preserveFocus: boolean; type?: string; suppressInitialConfigs?: boolean }, token?: CancellationToken): Promise<{ editor: IEditorPane | null; created: boolean }> { const resource = this.uri; let created = false; let content = ''; @@ -573,7 +573,7 @@ class Launch extends AbstractLaunch implements ILaunch { content = fileContent.value.toString(); } catch { // launch.json not found: create one by collecting launch configs from debugConfigProviders - content = await this.getInitialConfigurationContent(this.workspace.uri, type, useInitialConfigs, token); + content = await this.getInitialConfigurationContent(this.workspace.uri, type, !suppressInitialConfigs, token); if (!content) { // Cancelled return { editor: null, created: false }; diff --git a/src/vs/workbench/contrib/debug/browser/debugQuickAccess.ts b/src/vs/workbench/contrib/debug/browser/debugQuickAccess.ts index 6cd33d34f5c..9e338934aad 100644 --- a/src/vs/workbench/contrib/debug/browser/debugQuickAccess.ts +++ b/src/vs/workbench/contrib/debug/browser/debugQuickAccess.ts @@ -63,7 +63,7 @@ export class StartDebugQuickAccessProvider extends PickerQuickAccessProvider { - config.launch.openConfigFile({ preserveFocus: false, useInitialConfigs: false }); + config.launch.openConfigFile({ preserveFocus: false }); return TriggerAction.CLOSE_PICKER; }, diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index ca1c5e318d2..44fec50c3d1 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -927,7 +927,7 @@ export interface ILaunch { /** * Opens the launch.json file. Creates if it does not exist. */ - openConfigFile(options: { preserveFocus: boolean; type?: string; useInitialConfigs?: boolean }, token?: CancellationToken): Promise<{ editor: IEditorPane | null; created: boolean }>; + openConfigFile(options: { preserveFocus: boolean; type?: string; suppressInitialConfigs?: boolean }, token?: CancellationToken): Promise<{ editor: IEditorPane | null; created: boolean }>; } // Debug service interfaces From cebad239e88e15b3738844e77cf26955d6b4d1a7 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 3 Aug 2022 19:48:22 -0500 Subject: [PATCH 217/303] Don't prompt to open launch.json when failing to start a dynamic launch config (#157049) Fixes #156351 --- src/vs/workbench/contrib/debug/browser/debugService.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index ffdaa1c43eb..6ecdf57aa2f 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -840,17 +840,19 @@ export class DebugService implements IDebugService { try { return await dbg.substituteVariables(folder, config); } catch (err) { - this.showError(err.message); + this.showError(err.message, undefined, !!launch?.getConfiguration(config.name)); return undefined; // bail out } } return Promise.resolve(config); } - private async showError(message: string, errorActions: ReadonlyArray = []): Promise { + private async showError(message: string, errorActions: ReadonlyArray = [], promptLaunchJson = true): Promise { const configureAction = new Action(DEBUG_CONFIGURE_COMMAND_ID, DEBUG_CONFIGURE_LABEL, undefined, true, () => this.commandService.executeCommand(DEBUG_CONFIGURE_COMMAND_ID)); // Don't append the standard command if id of any provided action indicates it is a command - const actions = errorActions.filter((action) => action.id.endsWith('.command')).length > 0 ? errorActions : [...errorActions, configureAction]; + const actions = errorActions.filter((action) => action.id.endsWith('.command')).length > 0 ? + errorActions : + [...errorActions, ...(promptLaunchJson ? [configureAction] : [])]; const { choice } = await this.dialogService.show(severity.Error, message, actions.map(a => a.label).concat(nls.localize('cancel', "Cancel")), { cancelId: actions.length }); if (choice < actions.length) { await actions[choice].run(); From ff92ad573f4341eb2b01cb07d7c8cf0e4edfabeb Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Thu, 4 Aug 2022 14:53:10 +0900 Subject: [PATCH 218/303] chore: bump electron@19.0.11 --- .yarnrc | 2 +- cgmanifest.json | 4 ++-- package.json | 2 +- yarn.lock | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.yarnrc b/.yarnrc index 7b6a179b254..818a30bbcd1 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,4 +1,4 @@ disturl "https://electronjs.org/headers" -target "19.0.10" +target "19.0.11" runtime "electron" build_from_source "true" diff --git a/cgmanifest.json b/cgmanifest.json index 78d331b3612..2e877eb9912 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -60,12 +60,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "7e1099a8e4b04709e3d5068403c77eb0feb7371f" + "commitHash": "a5cafd174d2027529d0b251e5b8e58da2b364e5b" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "19.0.10" + "version": "19.0.11" }, { "component": { diff --git a/package.json b/package.json index d98532339c0..2b35222fe71 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,7 @@ "cssnano": "^4.1.11", "debounce": "^1.0.0", "deemon": "^1.4.0", - "electron": "19.0.10", + "electron": "19.0.11", "eslint": "8.7.0", "eslint-plugin-header": "3.1.1", "eslint-plugin-jsdoc": "^39.3.2", diff --git a/yarn.lock b/yarn.lock index bee4429a8b3..8e979f354bb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3578,10 +3578,10 @@ electron-to-chromium@^1.3.723: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.737.tgz#196f2e9656f4f3c31930750e1899c091b72d36b5" integrity sha512-P/B84AgUSQXaum7a8m11HUsYL8tj9h/Pt5f7Hg7Ty6bm5DxlFq+e5+ouHUoNQMsKDJ7u4yGfI8mOErCmSH9wyg== -electron@19.0.10: - version "19.0.10" - resolved "https://registry.yarnpkg.com/electron/-/electron-19.0.10.tgz#4d2f03f307fbb70a295ff419112130b75661eda9" - integrity sha512-EiWtPWdD7CzkRkp1cw7t0N9W2qhI5XZOudHX7daOh5wI076nsdV2dtlAf/XyTHhPNoKR5qhTWrSnYL9PY6D1vg== +electron@19.0.11: + version "19.0.11" + resolved "https://registry.yarnpkg.com/electron/-/electron-19.0.11.tgz#0c0a52abc08694fd38916d9270baf45bb7752a27" + integrity sha512-GPM6C1Ze17/gR4koTE171MxrI5unYfFRgXQdkMdpWM2Cd55LMUrVa0QHCsfKpsaloufv9T65lsOn0uZuzCw5UA== dependencies: "@electron/get" "^1.14.1" "@types/node" "^16.11.26" From 45245af3e93eed908fed12622d6a3e7c19b30e7f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 4 Aug 2022 11:16:54 +0200 Subject: [PATCH 219/303] smoke - disable opening devtools on error (#157080) --- src/vs/code/electron-sandbox/workbench/workbench.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/code/electron-sandbox/workbench/workbench.js b/src/vs/code/electron-sandbox/workbench/workbench.js index 0af36c6e1ac..c8e4431d6db 100644 --- a/src/vs/code/electron-sandbox/workbench/workbench.js +++ b/src/vs/code/electron-sandbox/workbench/workbench.js @@ -36,7 +36,7 @@ return { // disable automated devtools opening on error when running extension tests // as this can lead to nondeterministic test execution (devtools steals focus) - forceDisableShowDevtoolsOnError: typeof windowConfig.extensionTestsPath === 'string', + forceDisableShowDevtoolsOnError: typeof windowConfig.extensionTestsPath === 'string' || windowConfig['enable-smoke-test-driver'] === true, // enable devtools keybindings in extension development window forceEnableDeveloperKeybindings: Array.isArray(windowConfig.extensionDevelopmentPath) && windowConfig.extensionDevelopmentPath.length > 0, removeDeveloperKeybindingsAfterLoad: true From 0ccc4d94791bfa33faa8bb66eed4f60477ea70da Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 4 Aug 2022 02:45:21 -0700 Subject: [PATCH 220/303] Fix #149457. Duplicate Action getter (#157063) --- .../browser/ui/actionbar/actionViewItems.ts | 22 ++++++++----------- .../ui/dropdown/dropdownActionViewItem.ts | 10 ++++----- src/vs/base/browser/ui/menu/menu.ts | 10 ++++----- .../parts/quickinput/browser/quickInput.ts | 4 ++-- .../browser/parts/compositeBarActions.ts | 14 ++++++------ .../comments/browser/reactionsAction.ts | 2 +- .../markers/browser/markersViewActions.ts | 2 +- .../preferences/browser/preferencesWidgets.ts | 6 ++--- src/vs/workbench/contrib/scm/browser/util.ts | 2 +- 9 files changed, 34 insertions(+), 38 deletions(-) diff --git a/src/vs/base/browser/ui/actionbar/actionViewItems.ts b/src/vs/base/browser/ui/actionbar/actionViewItems.ts index 6883fb11764..fea999ce34f 100644 --- a/src/vs/base/browser/ui/actionbar/actionViewItems.ts +++ b/src/vs/base/browser/ui/actionbar/actionViewItems.ts @@ -95,10 +95,6 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem { this._actionRunner = actionRunner; } - getAction(): IAction { - return this._action; - } - isEnabled(): boolean { return this._action.enabled; } @@ -214,7 +210,7 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem { } protected getTooltip(): string | undefined { - return this.getAction().tooltip; + return this.action.tooltip; } protected updateTooltip(): void { @@ -333,18 +329,18 @@ export class ActionViewItem extends BaseActionViewItem { override updateLabel(): void { if (this.options.label && this.label) { - this.label.textContent = this.getAction().label; + this.label.textContent = this.action.label; } } override getTooltip() { let title: string | null = null; - if (this.getAction().tooltip) { - title = this.getAction().tooltip; + if (this.action.tooltip) { + title = this.action.tooltip; - } else if (!this.options.label && this.getAction().label && this.options.icon) { - title = this.getAction().label; + } else if (!this.options.label && this.action.label && this.options.icon) { + title = this.action.label; if (this.options.keybinding) { title = nls.localize({ key: 'titleLabel', comment: ['action title', 'action keybinding'] }, "{0} ({1})", title, this.options.keybinding); @@ -359,7 +355,7 @@ export class ActionViewItem extends BaseActionViewItem { } if (this.options.icon) { - this.cssClass = this.getAction().class; + this.cssClass = this.action.class; if (this.label) { this.label.classList.add('codicon'); @@ -375,7 +371,7 @@ export class ActionViewItem extends BaseActionViewItem { } override updateEnabled(): void { - if (this.getAction().enabled) { + if (this.action.enabled) { if (this.label) { this.label.removeAttribute('aria-disabled'); this.label.classList.remove('disabled'); @@ -394,7 +390,7 @@ export class ActionViewItem extends BaseActionViewItem { override updateChecked(): void { if (this.label) { - if (this.getAction().checked) { + if (this.action.checked) { this.label.classList.add('checked'); } else { this.label.classList.remove('checked'); diff --git a/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts b/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts index 00da36a947b..c0aa2b92063 100644 --- a/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts +++ b/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts @@ -133,10 +133,10 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem { override getTooltip(): string | undefined { let title: string | null = null; - if (this.getAction().tooltip) { - title = this.getAction().tooltip; - } else if (this.getAction().label) { - title = this.getAction().label; + if (this.action.tooltip) { + title = this.action.tooltip; + } else if (this.action.label) { + title = this.action.label; } return title ?? undefined; @@ -159,7 +159,7 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem { } protected override updateEnabled(): void { - const disabled = !this.getAction().enabled; + const disabled = !this.action.enabled; this.actionItem?.classList.toggle('disabled', disabled); this.element?.classList.toggle('disabled', disabled); } diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 5e4410b5005..e4f1e20ffd9 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -446,7 +446,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem { // Set mnemonic if (this.options.label && options.enableMnemonics) { - const label = this.getAction().label; + const label = this.action.label; if (label) { const matches = MENU_MNEMONIC_REGEX.exec(label); if (matches) { @@ -572,7 +572,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem { if (this.options.label) { clearNode(this.label); - let label = stripIcons(this.getAction().label); + let label = stripIcons(this.action.label); if (label) { const cleanLabel = cleanMnemonic(label); if (!this.options.enableMnemonics) { @@ -624,7 +624,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem { this.item.classList.remove(...this.cssClass.split(' ')); } if (this.options.icon && this.label) { - this.cssClass = this.getAction().class || ''; + this.cssClass = this.action.class || ''; this.label.classList.add('icon'); if (this.cssClass) { this.label.classList.add(...this.cssClass.split(' ')); @@ -636,7 +636,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem { } override updateEnabled(): void { - if (this.getAction().enabled) { + if (this.action.enabled) { if (this.element) { this.element.classList.remove('disabled'); this.element.removeAttribute('aria-disabled'); @@ -665,7 +665,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem { return; } - const checked = this.getAction().checked; + const checked = this.action.checked; this.item.classList.toggle('checked', !!checked); if (checked !== undefined) { this.item.setAttribute('role', 'menuitemcheckbox'); diff --git a/src/vs/base/parts/quickinput/browser/quickInput.ts b/src/vs/base/parts/quickinput/browser/quickInput.ts index 2b906e565f4..e2d0526b38b 100644 --- a/src/vs/base/parts/quickinput/browser/quickInput.ts +++ b/src/vs/base/parts/quickinput/browser/quickInput.ts @@ -1684,10 +1684,10 @@ export class QuickInputController extends Disposable { if (enabled !== this.enabled) { this.enabled = enabled; for (const item of this.getUI().leftActionBar.viewItems) { - (item as ActionViewItem).getAction().enabled = enabled; + (item as ActionViewItem).action.enabled = enabled; } for (const item of this.getUI().rightActionBar.viewItems) { - (item as ActionViewItem).getAction().enabled = enabled; + (item as ActionViewItem).action.enabled = enabled; } this.getUI().checkAll.disabled = !enabled; // this.getUI().inputBox.enabled = enabled; Avoid loosing focus. diff --git a/src/vs/workbench/browser/parts/compositeBarActions.ts b/src/vs/workbench/browser/parts/compositeBarActions.ts index df8b6bc78d0..cbfde51fcb3 100644 --- a/src/vs/workbench/browser/parts/compositeBarActions.ts +++ b/src/vs/workbench/browser/parts/compositeBarActions.ts @@ -277,7 +277,7 @@ export class ActivityActionViewItem extends BaseActionViewItem { } protected updateBadge(): void { - const action = this.getAction(); + const action = this.action; if (!this.badge || !this.badgeContent || !(action instanceof ActivityAction)) { return; } @@ -351,7 +351,7 @@ export class ActivityActionViewItem extends BaseActionViewItem { } if (!this.options.icon) { - this.label.textContent = this.getAction().label; + this.label.textContent = this.action.label; } } @@ -370,7 +370,7 @@ export class ActivityActionViewItem extends BaseActionViewItem { private computeTitle(): string { this.keybindingLabel = this.computeKeybindingLabel(); let title = this.keybindingLabel ? localize('titleKeybinding', "{0} ({1})", this.activity.name, this.keybindingLabel) : this.activity.name; - const badge = (this.getAction() as ActivityAction).getBadge(); + const badge = (this.action as ActivityAction).getBadge(); if (badge?.getDescription()) { title = localize('badgeTitle', "{0} - {1}", title, badge.getDescription()); } @@ -605,8 +605,8 @@ export class CompositeActionViewItem extends ActivityActionViewItem { // Activate on drag over to reveal targets [this.badge, this.label].forEach(b => this._register(new DelayedDragHandler(b, () => { - if (!this.getAction().checked) { - this.getAction().run(); + if (!this.action.checked) { + this.action.run(); } }))); @@ -692,7 +692,7 @@ export class CompositeActionViewItem extends ActivityActionViewItem { } protected override updateChecked(): void { - if (this.getAction().checked) { + if (this.action.checked) { this.container.classList.add('checked'); this.container.setAttribute('aria-label', this.container.title); this.container.setAttribute('aria-expanded', 'true'); @@ -711,7 +711,7 @@ export class CompositeActionViewItem extends ActivityActionViewItem { return; } - if (this.getAction().enabled) { + if (this.action.enabled) { this.element.classList.remove('disabled'); } else { this.element.classList.add('disabled'); diff --git a/src/vs/workbench/contrib/comments/browser/reactionsAction.ts b/src/vs/workbench/contrib/comments/browser/reactionsAction.ts index 11f33528a56..692b5d24037 100644 --- a/src/vs/workbench/contrib/comments/browser/reactionsAction.ts +++ b/src/vs/workbench/contrib/comments/browser/reactionsAction.ts @@ -37,7 +37,7 @@ export class ReactionActionViewItem extends ActionViewItem { return; } - const action = this.getAction() as ReactionAction; + const action = this.action as ReactionAction; if (action.class) { this.label.classList.add(action.class); } diff --git a/src/vs/workbench/contrib/markers/browser/markersViewActions.ts b/src/vs/workbench/contrib/markers/browser/markersViewActions.ts index d1d3e232cf8..66531dffc3b 100644 --- a/src/vs/workbench/contrib/markers/browser/markersViewActions.ts +++ b/src/vs/workbench/contrib/markers/browser/markersViewActions.ts @@ -498,7 +498,7 @@ export class QuickFixActionViewItem extends ActionViewItem { return; } const elementPosition = DOM.getDomNodePagePosition(this.element); - const quickFixes = (this.getAction()).quickFixes; + const quickFixes = (this.action).quickFixes; if (quickFixes.length) { this.contextMenuService.showContextMenu({ getAnchor: () => ({ x: elementPosition.left + 10, y: elementPosition.top + elementPosition.height + 4 }), diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts index 596899b518b..0edfbe7a9b7 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts @@ -300,10 +300,10 @@ export class SettingsTargetsWidget extends Widget { this.userRemoteSettings.checked = ConfigurationTarget.USER_REMOTE === this.settingsTarget; this.workspaceSettings.checked = ConfigurationTarget.WORKSPACE === this.settingsTarget; if (this.settingsTarget instanceof URI) { - this.folderSettings.getAction().checked = true; + this.folderSettings.action.checked = true; this.folderSettings.folder = this.contextService.getWorkspaceFolder(this.settingsTarget as URI); } else { - this.folderSettings.getAction().checked = false; + this.folderSettings.action.checked = false; } this.inUserTab.set(this.userLocalSettings.checked); } @@ -368,7 +368,7 @@ export class SettingsTargetsWidget extends Widget { this.settingsSwitcherBar.domNode.classList.toggle('empty-workbench', this.contextService.getWorkbenchState() === WorkbenchState.EMPTY); this.userRemoteSettings.enabled = !!(this.options.enableRemoteSettings && this.environmentService.remoteAuthority); this.workspaceSettings.enabled = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY; - this.folderSettings.getAction().enabled = this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE && this.contextService.getWorkspace().folders.length > 0; + this.folderSettings.action.enabled = this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE && this.contextService.getWorkspace().folders.length > 0; this.workspaceSettings.tooltip = (await this.preferencesService.getEditableSettingsURI(ConfigurationTarget.WORKSPACE))?.fsPath || ''; } diff --git a/src/vs/workbench/contrib/scm/browser/util.ts b/src/vs/workbench/contrib/scm/browser/util.ts index c8f4524d017..a5b56e467ae 100644 --- a/src/vs/workbench/contrib/scm/browser/util.ts +++ b/src/vs/workbench/contrib/scm/browser/util.ts @@ -107,7 +107,7 @@ class StatusBarActionViewItem extends ActionViewItem { override updateLabel(): void { if (this.options.label && this.label) { - reset(this.label, ...renderLabelWithIcons(this.getAction().label)); + reset(this.label, ...renderLabelWithIcons(this.action.label)); } } } From 12300dac0c8efa3ccb3ee96d41ba0a710c6c5e65 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 4 Aug 2022 11:45:54 +0200 Subject: [PATCH 221/303] Windows: some Firefox web tests are timing out randomly (#155760) (#157066) --- .../azure-pipelines/darwin/product-build-darwin-test.yml | 8 ++++---- build/azure-pipelines/win32/product-build-win32-test.yml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin-test.yml b/build/azure-pipelines/darwin/product-build-darwin-test.yml index 1094b41ca21..aeea69d5601 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-test.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-test.yml @@ -31,8 +31,8 @@ steps: - script: | set -e - DEBUG=*browser* yarn test-browser-no-install --sequential --browser chromium --browser webkit --tfs "Browser Unit Tests" - displayName: Run unit tests (Browser, Chromium & Webkit) + DEBUG=*browser* yarn test-browser-no-install --sequential --browser chromium --browser webkit --browser firefox --tfs "Browser Unit Tests" + displayName: Run unit tests (Browser, Chromium & Webkit & Firefox) timeoutInMinutes: 30 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: @@ -50,8 +50,8 @@ steps: - script: | set -e - DEBUG=*browser* yarn test-browser-no-install --sequential --build --browser chromium --browser webkit --tfs "Browser Unit Tests" - displayName: Run unit tests (Browser, Chromium & Webkit) + DEBUG=*browser* yarn test-browser-no-install --sequential --build --browser chromium --browser webkit --browser firefox --tfs "Browser Unit Tests" + displayName: Run unit tests (Browser, Chromium & Webkit & Firefox) timeoutInMinutes: 30 - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: diff --git a/build/azure-pipelines/win32/product-build-win32-test.yml b/build/azure-pipelines/win32/product-build-win32-test.yml index 59c91cd2b13..23c2d43a1cc 100644 --- a/build/azure-pipelines/win32/product-build-win32-test.yml +++ b/build/azure-pipelines/win32/product-build-win32-test.yml @@ -36,8 +36,8 @@ steps: - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" - exec { node test/unit/browser/index.js --sequential --browser chromium --browser firefox --tfs "Browser Unit Tests" } - displayName: Run unit tests (Browser, Chromium & Firefox) + exec { node test/unit/browser/index.js --sequential --browser chromium --tfs "Browser Unit Tests" } + displayName: Run unit tests (Browser, Chromium) timeoutInMinutes: 20 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: @@ -59,8 +59,8 @@ steps: - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" - exec { yarn test-browser-no-install --sequential --build --browser chromium --browser firefox --tfs "Browser Unit Tests" } - displayName: Run unit tests (Browser, Chromium & Firefox) + exec { yarn test-browser-no-install --sequential --build --browser chromium --tfs "Browser Unit Tests" } + displayName: Run unit tests (Browser, Chromium) timeoutInMinutes: 20 - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: From 0a7226e9adee77c9c482e2dc5ae0dc41e4f83404 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 4 Aug 2022 11:52:56 +0200 Subject: [PATCH 222/303] Revert "Increase timeout of web unit tests" (#157065) Revert "Increase timeout of web unit tests (#156894)" This reverts commit f86beb18e8ce5383e60d90ed5bbab49e107307a9. --- test/unit/browser/renderer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/browser/renderer.html b/test/unit/browser/renderer.html index 5a2812ddd15..2bf6e3a2cab 100644 --- a/test/unit/browser/renderer.html +++ b/test/unit/browser/renderer.html @@ -33,7 +33,7 @@ mocha.setup({ ui: 'tdd', - timeout: 30000 // https://github.com/microsoft/vscode/issues/155760 + timeout: 5000 }); From 35819b2481ddfea0d75dd332962d5c4adbea4475 Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Thu, 4 Aug 2022 03:37:56 -0700 Subject: [PATCH 223/303] update traffic lights on macos when title bar zooms (#155906) * update traffic lights on macos when title bar zooms fixes #155557 * address PR feedback - update api name - cached window controls information * address feedback Co-authored-by: Benjamin Pasero --- src/vs/platform/native/common/native.ts | 7 +- .../electron-main/nativeHostMainService.ts | 10 +-- src/vs/platform/state/node/stateService.ts | 1 - .../platform/window/electron-main/window.ts | 2 + .../windows/electron-main/windowImpl.ts | 80 +++++++++---------- .../test/electron-main/windowsFinder.test.ts | 1 + .../parts/titlebar/titlebarPart.ts | 11 +-- .../electron-browser/workbenchTestServices.ts | 2 +- 8 files changed, 56 insertions(+), 58 deletions(-) diff --git a/src/vs/platform/native/common/native.ts b/src/vs/platform/native/common/native.ts index 569f00ad4f9..7d5bec764da 100644 --- a/src/vs/platform/native/common/native.ts +++ b/src/vs/platform/native/common/native.ts @@ -74,7 +74,12 @@ export interface ICommonNativeHostService { unmaximizeWindow(): Promise; minimizeWindow(): Promise; - updateTitleBarOverlay(options: { height?: number; backgroundColor?: string; foregroundColor?: string }): Promise; + /** + * Only supported on Windows and macOS. Updates the window controls to match the title bar size. + * + * @param options `backgroundColor` and `foregroundColor` are only supported on Windows + */ + updateWindowControls(options: { height?: number; backgroundColor?: string; foregroundColor?: string }): Promise; setMinimumSize(width: number | undefined, height: number | undefined): Promise; diff --git a/src/vs/platform/native/electron-main/nativeHostMainService.ts b/src/vs/platform/native/electron-main/nativeHostMainService.ts index a8fa55f59bf..3a7d4b38bc4 100644 --- a/src/vs/platform/native/electron-main/nativeHostMainService.ts +++ b/src/vs/platform/native/electron-main/nativeHostMainService.ts @@ -211,14 +211,10 @@ export class NativeHostMainService extends Disposable implements INativeHostMain } } - async updateTitleBarOverlay(windowId: number | undefined, options: { height?: number; backgroundColor?: string; foregroundColor?: string }): Promise { + async updateWindowControls(windowId: number | undefined, options: { height?: number; backgroundColor?: string; foregroundColor?: string }): Promise { const window = this.windowById(windowId); - if (window?.win) { - window.win.setTitleBarOverlay({ - color: options.backgroundColor?.trim() === '' ? undefined : options.backgroundColor, - symbolColor: options.foregroundColor?.trim() === '' ? undefined : options.foregroundColor, - height: options.height ? options.height - 1 : undefined // account for window border - }); + if (window) { + window.updateWindowControls(options); } } diff --git a/src/vs/platform/state/node/stateService.ts b/src/vs/platform/state/node/stateService.ts index 09e49209fb5..6d1e52f957a 100644 --- a/src/vs/platform/state/node/stateService.ts +++ b/src/vs/platform/state/node/stateService.ts @@ -167,5 +167,4 @@ export class StateService implements IStateService { getItem(key: string, defaultValue?: T): T | undefined { return this.fileStorage.getItem(key, defaultValue); } - } diff --git a/src/vs/platform/window/electron-main/window.ts b/src/vs/platform/window/electron-main/window.ts index 0f80ee03903..4b5303de633 100644 --- a/src/vs/platform/window/electron-main/window.ts +++ b/src/vs/platform/window/electron-main/window.ts @@ -73,6 +73,8 @@ export interface ICodeWindow extends IDisposable { updateTouchBar(items: ISerializableCommandAction[][]): void; serializeWindowState(): IWindowState; + + updateWindowControls(options: { height?: number; backgroundColor?: string; foregroundColor?: string }): void; } export const enum LoadReason { diff --git a/src/vs/platform/windows/electron-main/windowImpl.ts b/src/vs/platform/windows/electron-main/windowImpl.ts index e11613b3ca9..b684d4f0ac5 100644 --- a/src/vs/platform/windows/electron-main/windowImpl.ts +++ b/src/vs/platform/windows/electron-main/windowImpl.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { app, BrowserWindow, BrowserWindowConstructorOptions, Display, Event, nativeImage, NativeImage, Point, Rectangle, screen, SegmentedControlSegment, systemPreferences, TouchBar, TouchBarSegmentedControl } from 'electron'; +import { app, BrowserWindow, BrowserWindowConstructorOptions, Display, Event, nativeImage, NativeImage, Rectangle, screen, SegmentedControlSegment, systemPreferences, TouchBar, TouchBarSegmentedControl } from 'electron'; import { RunOnceScheduler } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import { toErrorMessage } from 'vs/base/common/errorMessage'; @@ -42,6 +42,7 @@ import { Color } from 'vs/base/common/color'; import { IPolicyService } from 'vs/platform/policy/common/policy'; import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { revive } from 'vs/base/common/marshalling'; +import { IStateMainService } from 'vs/platform/state/electron-main/state'; import product from 'vs/platform/product/common/product'; export interface IWindowCreationOptions { @@ -83,6 +84,8 @@ const enum ReadyState { export class CodeWindow extends Disposable implements ICodeWindow { + private static readonly windowControlHeightStateStorageKey = 'windowControlHeight'; + //#region Events private readonly _onWillLoad = this._register(new Emitter()); @@ -140,9 +143,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { private representedFilename: string | undefined; private documentEdited: boolean | undefined; - private customTrafficLightPosition: boolean | undefined; - private defaultTrafficLightPosition: Point | undefined; - private readonly whenReadyCallbacks: { (window: ICodeWindow): void }[] = []; private readonly touchBarGroups: TouchBarSegmentedControl[] = []; @@ -172,7 +172,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { @ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService, @IProductService private readonly productService: IProductService, @IProtocolMainService private readonly protocolMainService: IProtocolMainService, - @IWindowsMainService private readonly windowsMainService: IWindowsMainService + @IWindowsMainService private readonly windowsMainService: IWindowsMainService, + @IStateMainService private readonly stateMainService: IStateMainService ) { super(); @@ -290,11 +291,15 @@ export class CodeWindow extends Disposable implements ICodeWindow { this._id = this._win.id; if (isMacintosh && useCustomTitleStyle) { - this.updateTrafficLightPosition(); // adjust traffic light position depending on command center + this._win.setSheetOffset(22); // offset dialogs by the height of the custom title bar if we have any } - if (isMacintosh && useCustomTitleStyle) { - this._win.setSheetOffset(22); // offset dialogs by the height of the custom title bar if we have any + // Update the window controls immediately based on cached values + if ((isWindows || isMacintosh) && useCustomTitleStyle) { + const cachedWindowControlHeight = this.stateMainService.getItem((CodeWindow.windowControlHeightStateStorageKey)); + if (cachedWindowControlHeight) { + this.updateWindowControls({ height: cachedWindowControlHeight }); + } } // Windows Custom System Context Menu @@ -401,7 +406,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { } setRepresentedFilename(filename: string): void { - if (isMacintosh && !this.customTrafficLightPosition) { // TODO@electron https://github.com/electron/electron/issues/34822 + if (isMacintosh) { this._win.setRepresentedFilename(filename); } else { this.representedFilename = filename; @@ -409,7 +414,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { } getRepresentedFilename(): string | undefined { - if (isMacintosh && !this.customTrafficLightPosition) { // TODO@electron https://github.com/electron/electron/issues/34822 + if (isMacintosh) { return this._win.getRepresentedFilename(); } @@ -786,9 +791,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { this.setMenuBarVisibility(newMenuBarVisibility); } - // Traffic Lights - this.updateTrafficLightPosition(e); - // Proxy let newHttpProxy = (this.configurationService.getValue('http.proxy') || '').trim() || (process.env['https_proxy'] || process.env['HTTPS_PROXY'] || process.env['http_proxy'] || process.env['HTTP_PROXY'] || '').trim() // Not standardized. @@ -1062,6 +1064,28 @@ export class CodeWindow extends Disposable implements ICodeWindow { return state; } + updateWindowControls(options: { height?: number; backgroundColor?: string; foregroundColor?: string }): void { + + // Cache the height for speeds lookups on startup + if (options.height) { + this.stateMainService.setItem((CodeWindow.windowControlHeightStateStorageKey), options.height); + } + + // Windows: window control overlay (WCO) + if (isWindows) { + this._win.setTitleBarOverlay({ + color: options.backgroundColor?.trim() === '' ? undefined : options.backgroundColor, + symbolColor: options.foregroundColor?.trim() === '' ? undefined : options.foregroundColor, + height: options.height ? options.height - 1 : undefined // account for window border + }); + } + + // macOS: traffic lights + else if (isMacintosh && options.height !== undefined) { + this._win.setTrafficLightPosition({ x: 7, y: (options.height - 15) / 2 }); // 15px is the height of the traffic lights + } + } + private restoreWindowState(state?: IWindowState): [IWindowState, boolean? /* has multiple displays */] { mark('code/willRestoreCodeWindowState'); @@ -1346,36 +1370,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { } } - private updateTrafficLightPosition(e?: IConfigurationChangeEvent): void { - if (!isMacintosh) { - return; // only applies to macOS - } - - const commandCenterSettingKey = 'window.commandCenter'; - if (e && !e.affectsConfiguration(commandCenterSettingKey)) { - return; - } - - const useCustomTitleStyle = getTitleBarStyle(this.configurationService) === 'custom'; - if (!useCustomTitleStyle) { - return; // only applies with custom title bar - } - - const useCustomTrafficLightPosition = this.configurationService.getValue(commandCenterSettingKey); - if (useCustomTrafficLightPosition) { - if (!this.defaultTrafficLightPosition) { - this.defaultTrafficLightPosition = this._win.getTrafficLightPosition(); // remember default to restore later - } - this._win.setTrafficLightPosition({ x: 7, y: 10 }); - } else { - if (this.defaultTrafficLightPosition) { - this._win.setTrafficLightPosition(this.defaultTrafficLightPosition); - } - } - - this.customTrafficLightPosition = useCustomTrafficLightPosition; - } - handleTitleDoubleClick(): void { // Respect system settings on mac with regards to title click on windows title diff --git a/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts b/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts index 3fba62c1b4d..9410d67711e 100644 --- a/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts +++ b/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts @@ -70,6 +70,7 @@ suite('WindowsFinder', () => { handleTitleDoubleClick(): void { throw new Error('Method not implemented.'); } updateTouchBar(items: UriDto[][]): void { throw new Error('Method not implemented.'); } serializeWindowState(): IWindowState { throw new Error('Method not implemented'); } + updateWindowControls(options: { height?: number | undefined; backgroundColor?: string | undefined; foregroundColor?: string | undefined }): void { throw new Error('Method not implemented.'); } dispose(): void { } }; } diff --git a/src/vs/workbench/electron-sandbox/parts/titlebar/titlebarPart.ts b/src/vs/workbench/electron-sandbox/parts/titlebar/titlebarPart.ts index 4720f73a32a..aaf65505c81 100644 --- a/src/vs/workbench/electron-sandbox/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/electron-sandbox/parts/titlebar/titlebarPart.ts @@ -10,7 +10,7 @@ import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/co import { IStorageService } from 'vs/platform/storage/common/storage'; import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService'; import { IHostService } from 'vs/workbench/services/host/browser/host'; -import { isMacintosh, isWindows, isLinux } from 'vs/base/common/platform'; +import { isMacintosh, isWindows, isLinux, isNative } from 'vs/base/common/platform'; import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { TitlebarPart as BrowserTitleBarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; @@ -222,7 +222,7 @@ export class TitlebarPart extends BrowserTitleBarPart { if (!this.cachedWindowControlStyles || this.cachedWindowControlStyles.bgColor !== this.element.style.backgroundColor || this.cachedWindowControlStyles.fgColor !== this.element.style.color) { - this.nativeHostService.updateTitleBarOverlay({ backgroundColor: this.element.style.backgroundColor, foregroundColor: this.element.style.color }); + this.nativeHostService.updateWindowControls({ backgroundColor: this.element.style.backgroundColor, foregroundColor: this.element.style.color }); } } } @@ -230,11 +230,12 @@ export class TitlebarPart extends BrowserTitleBarPart { override layout(width: number, height: number): void { super.layout(width, height); - if (useWindowControlsOverlay(this.configurationService, this.environmentService)) { - const newHeight = Math.trunc(this.element.clientHeight * getZoomFactor()); + if (useWindowControlsOverlay(this.configurationService, this.environmentService) || + (isMacintosh && isNative && getTitleBarStyle(this.configurationService) === 'custom')) { + const newHeight = Math.round(height * getZoomFactor()); if (newHeight !== this.cachedWindowControlHeight) { this.cachedWindowControlHeight = newHeight; - this.nativeHostService.updateTitleBarOverlay({ height: newHeight }); + this.nativeHostService.updateWindowControls({ height: newHeight }); } } } diff --git a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts index 16a83da3eac..55416f15f53 100644 --- a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts @@ -226,7 +226,7 @@ export class TestNativeHostService implements INativeHostService { async maximizeWindow(): Promise { } async unmaximizeWindow(): Promise { } async minimizeWindow(): Promise { } - async updateTitleBarOverlay(options: { height?: number; backgroundColor?: string; foregroundColor?: string }): Promise { } + async updateWindowControls(options: { height?: number; backgroundColor?: string; foregroundColor?: string }): Promise { } async setMinimumSize(width: number | undefined, height: number | undefined): Promise { } async saveWindowSplash(value: IPartsSplash): Promise { } async focusWindow(options?: { windowId?: number | undefined } | undefined): Promise { } From 9158abdcbe14005f3cc28779d2217ef59b46237e Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 4 Aug 2022 05:34:07 -0700 Subject: [PATCH 224/303] Move IReconnectionTaskData into contrib/tasks Part of #155234 --- src/vs/platform/terminal/common/terminal.ts | 2 -- .../contrib/tasks/browser/terminalTaskSystem.ts | 9 ++++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index a59e831fc7d..6721816d4ec 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -180,8 +180,6 @@ export interface IReconnectionProperties { data?: unknown; } -export interface IReconnectionTaskData { label: string; id: string; lastTask: string; group?: string } - export type TerminalType = 'Task' | 'Local' | undefined; export enum TitleEventSource { diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 9b2924e896d..e26e2e290d2 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -30,7 +30,7 @@ import { URI } from 'vs/base/common/uri'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IReconnectionTaskData, IShellLaunchConfig, TerminalLocation, TerminalSettingId, WaitOnExitValue } from 'vs/platform/terminal/common/terminal'; +import { IShellLaunchConfig, TerminalLocation, TerminalSettingId, WaitOnExitValue } from 'vs/platform/terminal/common/terminal'; import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { IViewDescriptorService, IViewsService, ViewContainerLocation } from 'vs/workbench/common/views'; @@ -63,6 +63,13 @@ interface IActiveTerminalData { state?: TaskEventKind; } +interface IReconnectionTaskData { + label: string; + id: string; + lastTask: string; + group?: string; +} + const ReconnectionType = 'Task'; class InstanceManager { From 458d86084ff7c850cefbce3880e9f3afe910c410 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 4 Aug 2022 14:54:21 +0200 Subject: [PATCH 225/303] Comments panel title is not localized (#157090) Fixes #156953 --- src/vs/workbench/api/browser/mainThreadComments.ts | 4 ++-- .../workbench/contrib/comments/browser/commentsTreeViewer.ts | 3 ++- src/vs/workbench/contrib/comments/browser/commentsView.ts | 4 ---- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadComments.ts b/src/vs/workbench/api/browser/mainThreadComments.ts index 7184b593f3a..df492c1919b 100644 --- a/src/vs/workbench/api/browser/mainThreadComments.ts +++ b/src/vs/workbench/api/browser/mainThreadComments.ts @@ -16,7 +16,7 @@ import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/ext import { ICommentInfo, ICommentService, INotebookCommentInfo } from 'vs/workbench/contrib/comments/browser/commentService'; import { CommentsPanel } from 'vs/workbench/contrib/comments/browser/commentsView'; import { CommentProviderFeatures, ExtHostCommentsShape, ExtHostContext, MainContext, MainThreadCommentsShape, CommentThreadChanges } from '../common/extHost.protocol'; -import { COMMENTS_VIEW_ID, COMMENTS_VIEW_TITLE } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer'; +import { COMMENTS_VIEW_ID, COMMENTS_VIEW_STORAGE_ID, COMMENTS_VIEW_TITLE } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer'; import { ViewContainer, IViewContainersRegistry, Extensions as ViewExtensions, ViewContainerLocation, IViewsRegistry, IViewsService, IViewDescriptorService } from 'vs/workbench/common/views'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; @@ -583,7 +583,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments id: COMMENTS_VIEW_ID, title: COMMENTS_VIEW_TITLE, ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [COMMENTS_VIEW_ID, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }]), - storageId: COMMENTS_VIEW_TITLE, + storageId: COMMENTS_VIEW_STORAGE_ID, hideIfEmpty: true, icon: commentsViewIcon, order: 10, diff --git a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts index 3d8c19fce39..e702e5edce4 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts @@ -27,7 +27,8 @@ import { CommentThreadState } from 'vs/editor/common/languages'; import { Color } from 'vs/base/common/color'; export const COMMENTS_VIEW_ID = 'workbench.panel.comments'; -export const COMMENTS_VIEW_TITLE = 'Comments'; +export const COMMENTS_VIEW_STORAGE_ID = 'Comments'; +export const COMMENTS_VIEW_TITLE = nls.localize('comments.view.title', "Comments"); export class CommentsAsyncDataSource implements IAsyncDataSource { hasChildren(element: any): boolean { diff --git a/src/vs/workbench/contrib/comments/browser/commentsView.ts b/src/vs/workbench/contrib/comments/browser/commentsView.ts index 4c38db0a895..9630fb50242 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsView.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsView.ts @@ -156,10 +156,6 @@ export class CommentsPanel extends ViewPane { this.tree.layout(height, width); } - public getTitle(): string { - return COMMENTS_VIEW_TITLE; - } - private createMessageBox(parent: HTMLElement): void { this.messageBoxContainer = dom.append(parent, dom.$('.message-box-container')); this.messageBoxContainer.setAttribute('tabIndex', '0'); From 1d4f22aea824367fdc93c9dae84ec698a59b9abe Mon Sep 17 00:00:00 2001 From: aiday-mar Date: Thu, 4 Aug 2022 15:29:16 +0200 Subject: [PATCH 226/303] Removing duplicate lines by using filter instead of splice. Fixes #157054. --- .../stickyScroll/browser/stickyScroll.ts | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index b6bf6b833e8..9116b35a334 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -171,7 +171,7 @@ class StickyScrollController extends Disposable implements IEditorContribution { this._findLineRanges(outline, 0); } } - this._ranges = this._ranges.sort(function (a, b) { + this._ranges.sort(function (a, b) { if (a[0] !== b[0]) { return a[0] - b[0]; } else if (a[1] !== b[1]) { @@ -180,18 +180,29 @@ class StickyScrollController extends Disposable implements IEditorContribution { return a[2] - b[2]; } }); - let previous: number[] = []; - for (const [index, arr] of this._ranges.entries()) { - if (previous[0] === arr[0]) { - this._ranges.splice(index, 1); + + const startLinesConsidered: Set = new Set(); + this._ranges = this._ranges.filter(arr => { + if (!this._containsArray(startLinesConsidered, arr)) { + startLinesConsidered.add(arr); + return true; } else { - previous = arr; + return false; } - } + }); } } } + private _containsArray(set: Set, array: number[]) { + for (const arr of set) { + if (arr.toString() === array.toString()) { + return true; + } + } + return false; + } + private _renderStickyScroll() { if (!(this._editor.hasModel())) { return; From 0b5cef4f76cf8217d64123adb5b68fbff0873410 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 4 Aug 2022 06:59:43 -0700 Subject: [PATCH 227/303] Remove shell decoration icon settings Fixes #156503 --- src/vs/platform/terminal/common/terminal.ts | 3 --- .../terminal/browser/xterm/decorationAddon.ts | 26 +++++-------------- .../terminal/common/terminalConfiguration.ts | 15 ----------- 3 files changed, 7 insertions(+), 37 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 6721816d4ec..80633905e94 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -109,9 +109,6 @@ export const enum TerminalSettingId { ShellIntegrationEnabled = 'terminal.integrated.shellIntegration.enabled', ShellIntegrationShowWelcome = 'terminal.integrated.shellIntegration.showWelcome', ShellIntegrationDecorationsEnabled = 'terminal.integrated.shellIntegration.decorationsEnabled', - ShellIntegrationDecorationIcon = 'terminal.integrated.shellIntegration.decorationIcon', - ShellIntegrationDecorationIconError = 'terminal.integrated.shellIntegration.decorationIconError', - ShellIntegrationDecorationIconSuccess = 'terminal.integrated.shellIntegration.decorationIconSuccess', ShellIntegrationCommandHistory = 'terminal.integrated.shellIntegration.history', SmoothScrolling = 'terminal.integrated.smoothScrolling' } diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts index dedbc805e9b..901cb67a0dc 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/decorationAddon.ts @@ -37,7 +37,6 @@ const enum DecorationSelector { Default = 'default', Codicon = 'codicon', XtermDecoration = 'xterm-decoration', - GenericMarkerIcon = 'codicon-circle-small-filled', OverviewRuler = '.xterm-decoration-overview-ruler' } @@ -79,11 +78,7 @@ export class DecorationAddon extends Disposable implements ITerminalAddon { this._hoverDelayer = this._register(new Delayer(this._configurationService.getValue('workbench.hover.delay'))); this._register(this._configurationService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration(TerminalSettingId.ShellIntegrationDecorationIcon) || - e.affectsConfiguration(TerminalSettingId.ShellIntegrationDecorationIconSuccess) || - e.affectsConfiguration(TerminalSettingId.ShellIntegrationDecorationIconError)) { - this._refreshStyles(); - } else if (e.affectsConfiguration(TerminalSettingId.FontSize) || e.affectsConfiguration(TerminalSettingId.LineHeight)) { + if (e.affectsConfiguration(TerminalSettingId.FontSize) || e.affectsConfiguration(TerminalSettingId.LineHeight)) { this.refreshLayouts(); } else if (e.affectsConfiguration('workbench.colorCustomizations')) { this._refreshStyles(true); @@ -338,7 +333,7 @@ export class DecorationAddon extends Disposable implements ITerminalAddon { element.classList.add(DecorationSelector.CommandDecoration, DecorationSelector.Codicon, DecorationSelector.XtermDecoration); if (genericMarkProperties) { - element.classList.add(DecorationSelector.DefaultColor, DecorationSelector.GenericMarkerIcon); + element.classList.add(DecorationSelector.DefaultColor, ...Codicon.terminalDecorationMark.classNamesArray); if (!genericMarkProperties.hoverMessage) { //disable the mouse pointer element.classList.add(DecorationSelector.Default); @@ -348,12 +343,12 @@ export class DecorationAddon extends Disposable implements ITerminalAddon { this._updateCommandDecorationVisibility(element); if (exitCode === undefined) { element.classList.add(DecorationSelector.DefaultColor, DecorationSelector.Default); - element.classList.add(`codicon-${this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationIcon)}`); + element.classList.add(...Codicon.terminalDecorationIncomplete.classNamesArray); } else if (exitCode) { element.classList.add(DecorationSelector.ErrorColor); - element.classList.add(`codicon-${this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationIconError)}`); + element.classList.add(...Codicon.terminalDecorationError.classNamesArray); } else { - element.classList.add(`codicon-${this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationIconSuccess)}`); + element.classList.add(...Codicon.terminalDecorationSuccess.classNamesArray); } } } @@ -453,11 +448,7 @@ export class DecorationAddon extends Disposable implements ITerminalAddon { private async _showConfigureCommandDecorationsQuickPick() { const quickPick = this._quickInputService.createQuickPick(); quickPick.items = [ - { id: 'a', label: localize('changeDefaultIcon', 'Change default icon') }, - { id: 'b', label: localize('changeSuccessIcon', 'Change success icon') }, - { id: 'c', label: localize('changeErrorIcon', 'Change error icon') }, - { type: 'separator' }, - { id: 'd', label: localize('toggleVisibility', 'Toggle visibility') }, + { id: 'a', label: localize('toggleVisibility', 'Toggle visibility') }, ]; quickPick.canSelectMany = false; quickPick.onDidAccept(async e => { @@ -465,10 +456,7 @@ export class DecorationAddon extends Disposable implements ITerminalAddon { const result = quickPick.activeItems[0]; let iconSetting: string | undefined; switch (result.id) { - case 'a': iconSetting = TerminalSettingId.ShellIntegrationDecorationIcon; break; - case 'b': iconSetting = TerminalSettingId.ShellIntegrationDecorationIconSuccess; break; - case 'c': iconSetting = TerminalSettingId.ShellIntegrationDecorationIconError; break; - case 'd': this._showToggleVisibilityQuickPick(); break; + case 'a': this._showToggleVisibilityQuickPick(); break; } if (iconSetting) { this._showChangeIconQuickPick(iconSetting); diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 30fe86a21d0..790e1777020 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -116,21 +116,6 @@ const terminalConfiguration: IConfigurationNode = { default: 'view', description: localize('terminal.integrated.defaultLocation', "Controls where newly created terminals will appear.") }, - [TerminalSettingId.ShellIntegrationDecorationIconSuccess]: { - type: 'string', - default: 'primitive-dot', - markdownDescription: localize('terminal.integrated.shellIntegration.decorationIconSuccess', "Controls the icon that will be used for each command in terminals with shell integration enabled that do not have an associated exit code. Set to {0} to hide the icon or disable decorations with {1}.", '`\"\"`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`') - }, - [TerminalSettingId.ShellIntegrationDecorationIconError]: { - type: 'string', - default: 'error-small', - markdownDescription: localize('terminal.integrated.shellIntegration.decorationIconError', "Controls the icon that will be used for each command in terminals with shell integration enabled that do have an associated exit code. Set to {0} to hide the icon or disable decorations with {1}.", '`\"\"`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`') - }, - [TerminalSettingId.ShellIntegrationDecorationIcon]: { - type: 'string', - default: 'circle-outline', - markdownDescription: localize('terminal.integrated.shellIntegration.decorationIcon', "Controls the icon that will be used for skipped/empty commands. Set to {0} to hide the icon or disable decorations with {1}.", '`\"\"`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`') - }, [TerminalSettingId.TabsFocusMode]: { type: 'string', enum: ['singleClick', 'doubleClick'], From 739c8ab0f59352359a253a80ea283726a1f5358d Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 4 Aug 2022 16:12:39 +0200 Subject: [PATCH 228/303] Mark showIfCollapsed as public API (#157093) --- src/vs/editor/common/model.ts | 1 - src/vs/monaco.d.ts | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index 82eb82d558b..bf2cc58e639 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -106,7 +106,6 @@ export interface IModelDecorationOptions { isWholeLine?: boolean; /** * Always render the decoration (even when the range it encompasses is collapsed). - * @internal */ showIfCollapsed?: boolean; /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index f218c073d38..ca6486a7eec 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1496,6 +1496,10 @@ declare namespace monaco.editor { * Should the decoration expand to encompass a whole line. */ isWholeLine?: boolean; + /** + * Always render the decoration (even when the range it encompasses is collapsed). + */ + showIfCollapsed?: boolean; /** * Specifies the stack order of a decoration. * A decoration with greater stack order is always in front of a decoration with From 3220a9159e0279b27de6215b62e71ef9724363e0 Mon Sep 17 00:00:00 2001 From: aiday-mar Date: Thu, 4 Aug 2022 17:15:48 +0200 Subject: [PATCH 229/303] Make sticky scroll disappear on the line before the end of the scope. Fixes #156999. --- package.json | 2 +- .../editor/contrib/stickyScroll/browser/stickyScroll.ts | 8 +++++++- yarn.lock | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2b35222fe71..3110343d2fc 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "native-keymap": "3.3.0", "native-watchdog": "1.4.0", "node-pty": "0.11.0-beta11", - "spdlog": "^0.13.0", + "spdlog": "^0.13.6", "tas-client-umd": "0.1.6", "v8-inspect-profiler": "^0.1.0", "vscode-oniguruma": "1.6.1", diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index 9116b35a334..aa6ff72904a 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -130,6 +130,7 @@ class StickyScrollController extends Disposable implements IEditorContribution { } else { this._addOutlineRanges(outlineElement, depth); } + console.log('ranges : ', this._ranges); } private _addOutlineRanges(outlineElement: OutlineElement, depth: number) { @@ -141,7 +142,12 @@ class StickyScrollController extends Disposable implements IEditorContribution { if (kind === SymbolKind.Class || kind === SymbolKind.Constructor || kind === SymbolKind.Function || kind === SymbolKind.Interface || kind === SymbolKind.Method || kind === SymbolKind.Module) { currentStartLine = outlineElement?.symbol.range.startLineNumber as number; currentEndLine = outlineElement?.symbol.range.endLineNumber as number; - this._ranges.push([currentStartLine, currentEndLine, depth]); + // this._ranges.push([currentStartLine, currentEndLine, depth]); + if (currentEndLine > currentStartLine) { + this._ranges.push([currentStartLine, currentEndLine - 1, depth]); + } else { + this._ranges.push([currentStartLine, currentEndLine, depth]); + } depth--; } if (outlineElement.parent instanceof OutlineElement) { diff --git a/yarn.lock b/yarn.lock index 8e979f354bb..8e28e6eeb84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9496,7 +9496,7 @@ sparkles@^1.0.0: resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== -spdlog@^0.13.0: +spdlog@^0.13.6: version "0.13.6" resolved "https://registry.yarnpkg.com/spdlog/-/spdlog-0.13.6.tgz#26b2e13d46cbf8f2334c12ba2a8cc82de5a28f02" integrity sha512-iGqDoA88G3Rv3lkbVQglTulp3nv12FzND6LDC7cOZ+OoFvWnXVb3+Ebhed60oZ6+IWWGwDtjXK6ympwr7C1XmQ== From 28c2fe134fa116b5fea4e3156680f14b33977899 Mon Sep 17 00:00:00 2001 From: aiday-mar Date: Thu, 4 Aug 2022 17:25:42 +0200 Subject: [PATCH 230/303] updating spdlog --- remote/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/remote/package.json b/remote/package.json index 68e36b12bc9..6cd24e3be5e 100644 --- a/remote/package.json +++ b/remote/package.json @@ -18,7 +18,7 @@ "minimist": "^1.2.6", "native-watchdog": "1.4.0", "node-pty": "0.11.0-beta11", - "spdlog": "^0.13.0", + "spdlog": "^0.13.6", "tas-client-umd": "0.1.6", "vscode-oniguruma": "1.6.1", "vscode-proxy-agent": "^0.12.0", From a951adfd4facdc9244c5608a159d9c7b7cd6b95e Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 08:44:54 -0700 Subject: [PATCH 231/303] Fix sorting of preferred refactorings above quick fixes (#157047) Fixes #156343 --- src/vs/editor/contrib/codeAction/browser/codeAction.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeAction.ts b/src/vs/editor/contrib/codeAction/browser/codeAction.ts index ff3e5abdb7b..1131773f70d 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeAction.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeAction.ts @@ -60,23 +60,27 @@ export interface CodeActionSet extends IDisposable { class ManagedCodeActionSet extends Disposable implements CodeActionSet { - private static codeActionsComparator({ action: a }: CodeActionItem, { action: b }: CodeActionItem): number { + private static codeActionsPreferredComparator(a: languages.CodeAction, b: languages.CodeAction): number { if (a.isPreferred && !b.isPreferred) { return -1; } else if (!a.isPreferred && b.isPreferred) { return 1; + } else { + return 0; } + } + private static codeActionsComparator({ action: a }: CodeActionItem, { action: b }: CodeActionItem): number { if (isNonEmptyArray(a.diagnostics)) { if (isNonEmptyArray(b.diagnostics)) { - return a.diagnostics[0].message.localeCompare(b.diagnostics[0].message); + return ManagedCodeActionSet.codeActionsPreferredComparator(a, b) || a.diagnostics[0].message.localeCompare(b.diagnostics[0].message); } else { return -1; } } else if (isNonEmptyArray(b.diagnostics)) { return 1; } else { - return 0; // both have no diagnostics + return ManagedCodeActionSet.codeActionsPreferredComparator(a, b); // both have no diagnostics } } From 962c94e0472b94f90bdbbd2fcea85962a2fb12ff Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Thu, 4 Aug 2022 09:11:55 -0700 Subject: [PATCH 232/303] find start pattern instead of getting all buffer lines (#157042) --- .../contrib/tasks/browser/terminalTaskSystem.ts | 13 +++++++++++-- .../contrib/tasks/common/problemCollectors.ts | 3 ++- .../workbench/contrib/terminal/browser/terminal.ts | 10 +++++----- .../contrib/terminal/browser/xterm/xtermTerminal.ts | 13 ++++--------- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index e26e2e290d2..94352dcce88 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -950,8 +950,17 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { }); }); if (trigger === Triggers.reconnect && !!terminal.xterm) { - const bufferLines = terminal.xterm.bufferLines; - for (let i = 0; i < bufferLines.length; i++) { + const bufferLines = []; + + const bufferReverseIterator = terminal.xterm.getBufferReverseIterator(); + const startRegex = new RegExp(watchingProblemMatcher.beginPatterns.map(pattern => pattern.source).join('|')); + for (const nextLine of bufferReverseIterator) { + bufferLines.push(nextLine); + if (startRegex.test(nextLine)) { + break; + } + } + for (let i = bufferLines.length - 1; i >= 0; i--) { watchingProblemMatcher.processLine(bufferLines[i]); } if (!delayer) { diff --git a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts index 7bf4c6ae71f..0087529e25f 100644 --- a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts +++ b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts @@ -413,7 +413,7 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement private currentResource: string | undefined; private lines: string[] = []; - + public beginPatterns: RegExp[] = []; constructor(problemMatchers: ProblemMatcher[], markerService: IMarkerService, modelService: IModelService, fileService?: IFileService) { super(problemMatchers, markerService, modelService, fileService); this.resetCurrentResource(); @@ -428,6 +428,7 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement begin: matcher.watching.beginsPattern, end: matcher.watching.endsPattern }); + this.beginPatterns.push(matcher.watching.beginsPattern.regexp); } }); diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 2eb9043b540..ec47ea30031 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -916,11 +916,6 @@ export interface IXtermTerminal { */ readonly shellIntegration: IShellIntegration; - /** - * An array representing the buffer lines as strings - */ - readonly bufferLines: string[]; - readonly onDidChangeSelection: Event; /** @@ -978,6 +973,11 @@ export interface IXtermTerminal { * @param properties */ addDecoration(marker: IMarker, properties: IGenericMarkProperties): void; + + /** + * Returns a reverse iterator of buffer lines as strings + */ + getBufferReverseIterator(): IterableIterator; } export interface IInternalXtermTerminal { diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index c1a9d2cd629..d05f15bbe10 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -57,19 +57,14 @@ let WebglAddon: typeof WebglAddonType; export class XtermTerminal extends DisposableStore implements IXtermTerminal, IInternalXtermTerminal { /** The raw xterm.js instance */ readonly raw: RawXtermTerminal; - private _bufferLines: string[] = []; - get bufferLines(): string[] { - if (this.raw.buffer.active.length === this._bufferLines.length) { - return this._bufferLines; - } - for (let i = this._bufferLines.length; i < this.raw.buffer.active.length; i++) { - const line = this.raw.buffer.active.getLine(i)?.translateToString(); + *getBufferReverseIterator(): IterableIterator { + for (let i = this.raw.buffer.active.length; i >= 0; i--) { + const line = this.raw.buffer.active.getLine(i)?.translateToString().trim(); if (line) { - this._bufferLines.push(line); + yield line; } } - return this._bufferLines; } private _core: IXtermCore; private static _suggestedRendererType: 'canvas' | 'dom' | undefined = undefined; From 0cca0bae89e06bef30d02c807153c5de24103032 Mon Sep 17 00:00:00 2001 From: aiday-mar Date: Thu, 4 Aug 2022 18:21:46 +0200 Subject: [PATCH 233/303] Downgrading spdlog and removing console statement. --- package.json | 2 +- remote/package.json | 2 +- src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts | 3 --- yarn.lock | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 3110343d2fc..2b35222fe71 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "native-keymap": "3.3.0", "native-watchdog": "1.4.0", "node-pty": "0.11.0-beta11", - "spdlog": "^0.13.6", + "spdlog": "^0.13.0", "tas-client-umd": "0.1.6", "v8-inspect-profiler": "^0.1.0", "vscode-oniguruma": "1.6.1", diff --git a/remote/package.json b/remote/package.json index 6cd24e3be5e..68e36b12bc9 100644 --- a/remote/package.json +++ b/remote/package.json @@ -18,7 +18,7 @@ "minimist": "^1.2.6", "native-watchdog": "1.4.0", "node-pty": "0.11.0-beta11", - "spdlog": "^0.13.6", + "spdlog": "^0.13.0", "tas-client-umd": "0.1.6", "vscode-oniguruma": "1.6.1", "vscode-proxy-agent": "^0.12.0", diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts index aa6ff72904a..67b68da1f2d 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts @@ -130,7 +130,6 @@ class StickyScrollController extends Disposable implements IEditorContribution { } else { this._addOutlineRanges(outlineElement, depth); } - console.log('ranges : ', this._ranges); } private _addOutlineRanges(outlineElement: OutlineElement, depth: number) { @@ -142,7 +141,6 @@ class StickyScrollController extends Disposable implements IEditorContribution { if (kind === SymbolKind.Class || kind === SymbolKind.Constructor || kind === SymbolKind.Function || kind === SymbolKind.Interface || kind === SymbolKind.Method || kind === SymbolKind.Module) { currentStartLine = outlineElement?.symbol.range.startLineNumber as number; currentEndLine = outlineElement?.symbol.range.endLineNumber as number; - // this._ranges.push([currentStartLine, currentEndLine, depth]); if (currentEndLine > currentStartLine) { this._ranges.push([currentStartLine, currentEndLine - 1, depth]); } else { @@ -220,7 +218,6 @@ class StickyScrollController extends Disposable implements IEditorContribution { return; } const scrollTop = this._editor.getScrollTop(); - this.stickyScrollWidget.emptyRootNode(); for (const arr of this._ranges) { diff --git a/yarn.lock b/yarn.lock index 8e28e6eeb84..8e979f354bb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9496,7 +9496,7 @@ sparkles@^1.0.0: resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== -spdlog@^0.13.6: +spdlog@^0.13.0: version "0.13.6" resolved "https://registry.yarnpkg.com/spdlog/-/spdlog-0.13.6.tgz#26b2e13d46cbf8f2334c12ba2a8cc82de5a28f02" integrity sha512-iGqDoA88G3Rv3lkbVQglTulp3nv12FzND6LDC7cOZ+OoFvWnXVb3+Ebhed60oZ6+IWWGwDtjXK6ympwr7C1XmQ== From f8b87c37ce662a18c0a488e8e634006c65e1f6e5 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Thu, 4 Aug 2022 12:25:01 -0400 Subject: [PATCH 234/303] Have timeline excluded sources use storage service (#157099) * Use storage service for exclude sources * Deprecate old setting --- .../timeline/browser/timeline.contribution.ts | 30 ------------- .../contrib/timeline/browser/timelinePane.ts | 45 +++++++++++++------ 2 files changed, 32 insertions(+), 43 deletions(-) diff --git a/src/vs/workbench/contrib/timeline/browser/timeline.contribution.ts b/src/vs/workbench/contrib/timeline/browser/timeline.contribution.ts index adf11e1f50e..5bdb2b4dc03 100644 --- a/src/vs/workbench/contrib/timeline/browser/timeline.contribution.ts +++ b/src/vs/workbench/contrib/timeline/browser/timeline.contribution.ts @@ -12,7 +12,6 @@ import { VIEW_CONTAINER } from 'vs/workbench/contrib/files/browser/explorerViewl import { ITimelineService, TimelinePaneId } from 'vs/workbench/contrib/timeline/common/timeline'; import { TimelineHasProviderContext, TimelineService } from 'vs/workbench/contrib/timeline/common/timelineService'; import { TimelinePane } from './timelinePane'; -import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ISubmenuItem, MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands'; @@ -40,35 +39,6 @@ export class TimelinePaneDescriptor implements IViewDescriptor { focusCommand = { id: 'timeline.focus' }; } -// Configuration -const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); -configurationRegistry.registerConfiguration({ - id: 'timeline', - order: 1001, - title: localize('timelineConfigurationTitle', "Timeline"), - type: 'object', - properties: { - 'timeline.excludeSources': { - type: [ - 'array', - 'null' - ], - default: null, - description: localize('timeline.excludeSources', "An array of Timeline sources that should be excluded from the Timeline view."), - }, - 'timeline.pageSize': { - type: ['number', 'null'], - default: null, - markdownDescription: localize('timeline.pageSize', "The number of items to show in the Timeline view by default and when loading more items. Setting to `null` (the default) will automatically choose a page size based on the visible area of the Timeline view."), - }, - 'timeline.pageOnScroll': { - type: 'boolean', - default: false, - description: localize('timeline.pageOnScroll', "Experimental. Controls whether the Timeline view will load the next page of items when you scroll to the end of the list."), - }, - } -}); - Registry.as(ViewExtensions.ViewsRegistry).registerViews([new TimelinePaneDescriptor()], VIEW_CONTAINER); namespace OpenTimelineAction { diff --git a/src/vs/workbench/contrib/timeline/browser/timelinePane.ts b/src/vs/workbench/contrib/timeline/browser/timelinePane.ts index 68635d45e61..1fd81d272ef 100644 --- a/src/vs/workbench/contrib/timeline/browser/timelinePane.ts +++ b/src/vs/workbench/contrib/timeline/browser/timelinePane.ts @@ -52,6 +52,7 @@ import { IHoverService } from 'vs/workbench/services/hover/browser/hover'; import { IHoverDelegate, IHoverDelegateOptions } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { IStorageService, IStorageValueChangeEvent, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; const ItemHeight = 22; @@ -226,6 +227,7 @@ class LoadMoreCommand { } export const TimelineFollowActiveEditorContext = new RawContextKey('timelineFollowActiveEditor', true, true); +export const TimelineExcludeSources = new RawContextKey('timelineExcludeSources', '[]', true); export class TimelinePane extends ViewPane { static readonly TITLE = localize('timeline', "Timeline"); @@ -239,6 +241,7 @@ export class TimelinePane extends ViewPane { private visibilityDisposables: DisposableStore | undefined; private followActiveEditorContext: IContextKey; + private timelineExcludeSourcesContext: IContextKey; private excludedSources: Set; private pendingRequests = new Map(); @@ -252,6 +255,7 @@ export class TimelinePane extends ViewPane { @IContextMenuService contextMenuService: IContextMenuService, @IContextKeyService contextKeyService: IContextKeyService, @IConfigurationService configurationService: IConfigurationService, + @IStorageService private readonly storageService: IStorageService, @IViewDescriptorService viewDescriptorService: IViewDescriptorService, @IInstantiationService instantiationService: IInstantiationService, @IEditorService protected editorService: IEditorService, @@ -270,9 +274,20 @@ export class TimelinePane extends ViewPane { this.commands = this._register(this.instantiationService.createInstance(TimelinePaneCommands, this)); this.followActiveEditorContext = TimelineFollowActiveEditorContext.bindTo(this.contextKeyService); + this.timelineExcludeSourcesContext = TimelineExcludeSources.bindTo(this.contextKeyService); - this.excludedSources = new Set(configurationService.getValue('timeline.excludeSources')); + // TOOD @lramos15 remove after a few iterations of deprecated setting + const oldExcludedSourcesSetting: string[] = configurationService.getValue('timeline.excludeSources'); + if (oldExcludedSourcesSetting) { + configurationService.updateValue('timeline.excludeSources', undefined); + const oldSettingString = JSON.stringify(oldExcludedSourcesSetting); + this.timelineExcludeSourcesContext.set(oldSettingString); + // Update the storage service with the setting + storageService.store('timeline.excludeSources', oldSettingString, StorageScope.PROFILE, StorageTarget.USER); + } + this.excludedSources = new Set(JSON.parse(storageService.get('timeline.excludeSources', StorageScope.PROFILE, '[]'))); + this._register(storageService.onDidChangeValue(this.onStorageServiceChanged, this)); this._register(configurationService.onDidChangeConfiguration(this.onConfigurationChanged, this)); this._register(timelineService.onDidChangeProviders(this.onProvidersChanged, this)); this._register(timelineService.onDidChangeTimeline(this.onTimelineChanged, this)); @@ -335,13 +350,11 @@ export class TimelinePane extends ViewPane { this.loadTimeline(true); } - private onConfigurationChanged(e: IConfigurationChangeEvent) { - if (e.affectsConfiguration('timeline.pageOnScroll')) { - this._pageOnScroll = undefined; - } - - if (e.affectsConfiguration('timeline.excludeSources')) { - this.excludedSources = new Set(this.configurationService.getValue('timeline.excludeSources')); + private onStorageServiceChanged(e: IStorageValueChangeEvent) { + if (e.key === 'timeline.excludeSources') { + const excludedSourcesString = this.storageService.get('timeline.excludeSources', StorageScope.PROFILE, '[]'); + this.timelineExcludeSourcesContext.set(excludedSourcesString); + this.excludedSources = new Set(JSON.parse(excludedSourcesString)); const missing = this.timelineService.getSources() .filter(({ id }) => !this.excludedSources.has(id) && !this.timelinesBySource.has(id)); @@ -353,6 +366,12 @@ export class TimelinePane extends ViewPane { } } + private onConfigurationChanged(e: IConfigurationChangeEvent) { + if (e.affectsConfiguration('timeline.pageOnScroll')) { + this._pageOnScroll = undefined; + } + } + private onActiveEditorChanged() { if (!this.followActiveEditor || !this.isExpanded()) { return; @@ -1207,7 +1226,7 @@ class TimelinePaneCommands extends Disposable { constructor( private readonly pane: TimelinePane, @ITimelineService private readonly timelineService: ITimelineService, - @IConfigurationService private readonly configurationService: IConfigurationService, + @IStorageService private readonly storageService: IStorageService, @IContextKeyService private readonly contextKeyService: IContextKeyService, @IMenuService private readonly menuService: IMenuService, ) { @@ -1294,7 +1313,7 @@ class TimelinePaneCommands extends Disposable { private updateTimelineSourceFilters() { this.sourceDisposables.clear(); - const excluded = new Set(this.configurationService.getValue('timeline.excludeSources') ?? []); + const excluded = new Set(JSON.parse(this.storageService.get('timeline.excludeSources', StorageScope.PROFILE, '[]'))); for (const source of this.timelineService.getSources()) { this.sourceDisposables.add(registerAction2(class extends Action2 { constructor() { @@ -1305,7 +1324,7 @@ class TimelinePaneCommands extends Disposable { id: MenuId.TimelineFilterSubMenu, group: 'navigation', }, - toggled: ContextKeyExpr.regex(`config.timeline.excludeSources`, new RegExp(`\\b${escapeRegExpCharacters(source.id)}\\b`)).negate() + toggled: ContextKeyExpr.regex(`timelineExcludeSources`, new RegExp(`\\b${escapeRegExpCharacters(source.id)}\\b`)).negate() }); } run(accessor: ServicesAccessor, ...args: any[]) { @@ -1315,8 +1334,8 @@ class TimelinePaneCommands extends Disposable { excluded.add(source.id); } - const configurationService = accessor.get(IConfigurationService); - configurationService.updateValue('timeline.excludeSources', [...excluded.keys()]); + const storageService = accessor.get(IStorageService); + storageService.store('timeline.excludeSources', JSON.stringify([...excluded.keys()]), StorageScope.PROFILE, StorageTarget.USER); } })); } From 1811f30775477ecafcf3f87309cf05988364409d Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Thu, 4 Aug 2022 12:25:37 -0400 Subject: [PATCH 235/303] Escape bolding in name error message (#157108) --- src/vs/workbench/contrib/files/browser/fileActions.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index b90da455004..f84179c32dc 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -658,8 +658,10 @@ export function validateFileName(pathService: IPathService, item: ExplorerItem, // Check for invalid file name. if (names.some(folderName => !pathService.hasValidBasename(item.resource, os, folderName))) { + // Escape * characters + const escapedName = name.replace(/\*/g, '\\*'); return { - content: nls.localize('invalidFileNameError', "The name **{0}** is not valid as a file or folder name. Please choose a different name.", trimLongName(name)), + content: nls.localize('invalidFileNameError', "The name **{0}** is not valid as a file or folder name. Please choose a different name.", trimLongName(escapedName)), severity: Severity.Error }; } From 740ba5c3d43286f0419ddb8290e1264a8606e4ed Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 4 Aug 2022 09:49:21 -0700 Subject: [PATCH 236/303] Fix tests after codicon changes --- test/automation/src/terminal.ts | 6 +++--- .../areas/terminal/terminal-shellIntegration.test.ts | 12 ------------ 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/test/automation/src/terminal.ts b/test/automation/src/terminal.ts index d088f849520..56b6f46ddb4 100644 --- a/test/automation/src/terminal.ts +++ b/test/automation/src/terminal.ts @@ -10,9 +10,9 @@ import { IElement } from './driver'; export enum Selector { TerminalView = `#terminal`, - CommandDecorationPlaceholder = `.terminal-command-decoration.codicon-circle-outline`, - CommandDecorationSuccess = `.terminal-command-decoration.codicon-primitive-dot`, - CommandDecorationError = `.terminal-command-decoration.codicon-error-small`, + CommandDecorationPlaceholder = `.terminal-command-decoration.codicon-terminal-decoration-incomplete`, + CommandDecorationSuccess = `.terminal-command-decoration.codicon-terminal-decoration-success`, + CommandDecorationError = `.terminal-command-decoration.codicon-terminal-decoration-error`, Xterm = `#terminal .terminal-wrapper`, XtermEditor = `.editor-instance .terminal-wrapper`, TabsEntry = '.terminal-tabs-entry', diff --git a/test/smoke/src/areas/terminal/terminal-shellIntegration.test.ts b/test/smoke/src/areas/terminal/terminal-shellIntegration.test.ts index 23fb97dda74..823f61f4e31 100644 --- a/test/smoke/src/areas/terminal/terminal-shellIntegration.test.ts +++ b/test/smoke/src/areas/terminal/terminal-shellIntegration.test.ts @@ -51,18 +51,6 @@ export function setup() { await terminal.assertCommandDecorations({ placeholder: 1, success: 0, error: 1 }); }); }); - describe('Custom configuration', function () { - it('Should update and show custom icons', async () => { - await createShellIntegrationProfile(); - await terminal.assertCommandDecorations({ placeholder: 1, success: 0, error: 0 }); - await terminal.runCommandInTerminal(`echo "foo"`); - await terminal.runCommandInTerminal(`bar`); - await settingsEditor.addUserSetting('terminal.integrated.shellIntegration.decorationIcon', '"zap"'); - await settingsEditor.addUserSetting('terminal.integrated.shellIntegration.decorationIconSuccess', '"zap"'); - await settingsEditor.addUserSetting('terminal.integrated.shellIntegration.decorationIconError', '"zap"'); - await terminal.assertCommandDecorations(undefined, { updatedIcon: "zap", count: 3 }); - }); - }); describe('terminal.integrated.shellIntegration.decorationsEnabled should determine gutter and overview ruler decoration visibility', function () { beforeEach(async () => { await settingsEditor.clearUserSettings(); From 411b38306637a7e88f0951d07362fc6d522b8718 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Thu, 4 Aug 2022 13:06:57 -0400 Subject: [PATCH 237/303] Fix too many timeline settings removed (#157110) Fix too many settings removed --- .../timeline/browser/timeline.contribution.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/vs/workbench/contrib/timeline/browser/timeline.contribution.ts b/src/vs/workbench/contrib/timeline/browser/timeline.contribution.ts index 5bdb2b4dc03..8aae19bc264 100644 --- a/src/vs/workbench/contrib/timeline/browser/timeline.contribution.ts +++ b/src/vs/workbench/contrib/timeline/browser/timeline.contribution.ts @@ -12,6 +12,7 @@ import { VIEW_CONTAINER } from 'vs/workbench/contrib/files/browser/explorerViewl import { ITimelineService, TimelinePaneId } from 'vs/workbench/contrib/timeline/common/timeline'; import { TimelineHasProviderContext, TimelineService } from 'vs/workbench/contrib/timeline/common/timelineService'; import { TimelinePane } from './timelinePane'; +import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ISubmenuItem, MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands'; @@ -39,6 +40,27 @@ export class TimelinePaneDescriptor implements IViewDescriptor { focusCommand = { id: 'timeline.focus' }; } +// Configuration +const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); +configurationRegistry.registerConfiguration({ + id: 'timeline', + order: 1001, + title: localize('timelineConfigurationTitle', "Timeline"), + type: 'object', + properties: { + 'timeline.pageSize': { + type: ['number', 'null'], + default: null, + markdownDescription: localize('timeline.pageSize', "The number of items to show in the Timeline view by default and when loading more items. Setting to `null` (the default) will automatically choose a page size based on the visible area of the Timeline view."), + }, + 'timeline.pageOnScroll': { + type: 'boolean', + default: false, + description: localize('timeline.pageOnScroll', "Experimental. Controls whether the Timeline view will load the next page of items when you scroll to the end of the list."), + }, + } +}); + Registry.as(ViewExtensions.ViewsRegistry).registerViews([new TimelinePaneDescriptor()], VIEW_CONTAINER); namespace OpenTimelineAction { From d9c6f61294f6e21a258673ee19b3e7aef01c5cfb Mon Sep 17 00:00:00 2001 From: Leonardo Montini Date: Thu, 4 Aug 2022 19:20:58 +0200 Subject: [PATCH 238/303] Added cursor pointer in monaco select box for consistency (#152976) --- src/vs/base/browser/ui/selectBox/selectBox.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/base/browser/ui/selectBox/selectBox.css b/src/vs/base/browser/ui/selectBox/selectBox.css index d296d1ff0a0..c0a54d83b27 100644 --- a/src/vs/base/browser/ui/selectBox/selectBox.css +++ b/src/vs/base/browser/ui/selectBox/selectBox.css @@ -5,6 +5,7 @@ .monaco-select-box { width: 100%; + cursor: pointer; } .monaco-select-box-dropdown-container { From 0c78644c6e8d4cec044de25b71d7af61dd342054 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 10:46:56 -0700 Subject: [PATCH 239/303] Use tabs to figure out when to report JS/TS diagnostics (#157117) Fixes #101885 We currently only want to report diagnostics for opened JS/TS files --- .../src/tsServer/bufferSyncSupport.ts | 126 +++++++++++++++++- 1 file changed, 124 insertions(+), 2 deletions(-) diff --git a/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts b/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts index ed6af73fcf4..27b41948f75 100644 --- a/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts @@ -11,6 +11,7 @@ import { coalesce } from '../utils/arrays'; import { Delayer, setImmediate } from '../utils/async'; import { nulToken } from '../utils/cancellation'; import { Disposable } from '../utils/dispose'; +import { vscodeNotebookCell } from '../utils/fileSchemes'; import * as languageModeIds from '../utils/languageIds'; import { ResourceMap } from '../utils/resourceMap'; import * as typeConverters from '../utils/typeConverters'; @@ -361,6 +362,98 @@ class GetErrRequest { } } +class TabResourceTracker extends Disposable { + + private readonly _onDidChange = this._register(new vscode.EventEmitter<{ + readonly closed: Iterable; + readonly opened: Iterable; + }>()); + public readonly onDidChange = this._onDidChange.event; + + private readonly _tabResources: ResourceMap<{ readonly tabs: Set }>; + + constructor( + normalizePath: (resource: vscode.Uri) => string | undefined, + config: { + readonly onCaseInsensitiveFileSystem: boolean; + }, + ) { + super(); + + this._tabResources = new ResourceMap<{ readonly tabs: Set }>(normalizePath, config); + + for (const tabGroup of vscode.window.tabGroups.all) { + for (const tab of tabGroup.tabs) { + this.add(tab); + } + } + + this._register(vscode.window.tabGroups.onDidChangeTabs(e => { + const closed = e.closed.flatMap(tab => this.delete(tab)); + const opened = e.opened.flatMap(tab => this.add(tab)); + if (closed.length || opened.length) { + this._onDidChange.fire({ closed, opened }); + } + })); + } + + public has(resource: vscode.Uri): boolean { + if (resource.scheme === vscodeNotebookCell) { + const notebook = vscode.workspace.notebookDocuments.find(doc => + doc.getCells().some(cell => cell.document.uri.toString() === resource.toString())); + + return !!notebook && this.has(notebook.uri); + } + + const entry = this._tabResources.get(resource); + return !!entry && entry.tabs.size > 0; + } + + private add(tab: vscode.Tab): vscode.Uri[] { + const addedResources: vscode.Uri[] = []; + for (const uri of this.getResourcesForTab(tab)) { + const entry = this._tabResources.get(uri); + if (entry) { + entry.tabs.add(tab); + } else { + this._tabResources.set(uri, { tabs: new Set([tab]) }); + addedResources.push(uri); + } + } + return addedResources; + } + + private delete(tab: vscode.Tab): vscode.Uri[] { + const closedResources: vscode.Uri[] = []; + for (const uri of this.getResourcesForTab(tab)) { + const entry = this._tabResources.get(uri); + if (!entry) { + continue; + } + + entry.tabs.delete(tab); + if (entry.tabs.size === 0) { + this._tabResources.delete(uri); + closedResources.push(uri); + } + } + return closedResources; + } + + private getResourcesForTab(tab: vscode.Tab): vscode.Uri[] { + if (tab.input instanceof vscode.TabInputText) { + return [tab.input.uri]; + } else if (tab.input instanceof vscode.TabInputTextDiff) { + return [tab.input.original, tab.input.modified]; + } else if (tab.input instanceof vscode.TabInputNotebook) { + return [tab.input.uri]; + } else { + return []; + } + } +} + + export default class BufferSyncSupport extends Disposable { private readonly client: ITypeScriptServiceClient; @@ -375,6 +468,8 @@ export default class BufferSyncSupport extends Disposable { private listening: boolean = false; private readonly synchronizer: BufferSynchronizer; + private readonly _tabResources: TabResourceTracker; + constructor( client: ITypeScriptServiceClient, modeIds: readonly string[], @@ -391,6 +486,28 @@ export default class BufferSyncSupport extends Disposable { this.pendingDiagnostics = new PendingDiagnostics(pathNormalizer, { onCaseInsensitiveFileSystem }); this.synchronizer = new BufferSynchronizer(client, pathNormalizer, onCaseInsensitiveFileSystem); + this._tabResources = this._register(new TabResourceTracker(pathNormalizer, { onCaseInsensitiveFileSystem })); + this._register(this._tabResources.onDidChange(e => { + if (this.client.configuration.enableProjectDiagnostics) { + return; + } + + for (const closed of e.closed) { + const syncedBuffer = this.syncedBuffers.get(closed); + if (syncedBuffer) { + this.pendingDiagnostics.delete(closed); + this.pendingGetErr?.files.delete(closed); + } + } + + for (const opened of e.opened) { + const syncedBuffer = this.syncedBuffers.get(opened); + if (syncedBuffer) { + this.requestDiagnostic(syncedBuffer); + } + } + })); + this.updateConfiguration(); vscode.workspace.onDidChangeConfiguration(this.updateConfiguration, this, this._disposables); } @@ -494,6 +611,7 @@ export default class BufferSyncSupport extends Disposable { if (!syncedBuffer) { return; } + this.pendingDiagnostics.delete(resource); this.pendingGetErr?.files.delete(resource); this.syncedBuffers.delete(resource); @@ -506,7 +624,7 @@ export default class BufferSyncSupport extends Disposable { public interruptGetErr(f: () => R): R { if (!this.pendingGetErr - || this.client.configuration.enableProjectDiagnostics // `geterr` happens on seperate server so no need to cancel it. + || this.client.configuration.enableProjectDiagnostics // `geterr` happens on separate server so no need to cancel it. ) { return f(); } @@ -628,7 +746,11 @@ export default class BufferSyncSupport extends Disposable { this._validateTypeScript = tsConfig.get('validate.enable', true); } - private shouldValidate(buffer: SyncedBuffer) { + private shouldValidate(buffer: SyncedBuffer): boolean { + if (!this.client.configuration.enableProjectDiagnostics && !this._tabResources.has(buffer.resource)) { // Only validate resources that are showing to the user + return false; + } + switch (buffer.kind) { case BufferKind.JavaScript: return this._validateJavaScript; From cd9d43bebda91234d325956381e678026f5a1aa3 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Thu, 4 Aug 2022 13:55:22 -0400 Subject: [PATCH 240/303] Fix search editor title not updating (#156011) * Fix search editor title not updating * Share old name with resolveModels * Tweak name Co-authored-by: Rob Lourens --- .../contrib/searchEditor/browser/searchEditorInput.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts index cb9c0e342b5..5d7d63b8f5e 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts @@ -72,6 +72,8 @@ export class SearchEditorInput extends EditorInput { private dirty: boolean = false; + private lastLabel: string | undefined; + private readonly _onDidChangeContent = this._register(new Emitter()); readonly onDidChangeContent: Event = this._onDidChangeContent.event; @@ -158,9 +160,9 @@ export class SearchEditorInput extends EditorInput { this.configChangeListenerDisposable?.dispose(); if (!this.isDisposed()) { this.configChangeListenerDisposable = model.onConfigDidUpdate(() => { - const oldName = this.getName(); - if (oldName !== this.getName()) { + if (this.lastLabel !== this.getName()) { this._onDidChangeLabel.fire(); + this.lastLabel = this.getName(); } this.memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE).searchConfig = model.config; }); @@ -170,11 +172,11 @@ export class SearchEditorInput extends EditorInput { async resolveModels() { return this.model.resolve().then(data => { - const oldName = this.getName(); this._cachedResultsModel = data.resultsModel; this._cachedConfigurationModel = data.configurationModel; - if (oldName !== this.getName()) { + if (this.lastLabel !== this.getName()) { this._onDidChangeLabel.fire(); + this.lastLabel = this.getName(); } this.registerConfigChangeListeners(data.configurationModel); return data; From ff7e53a5758d79825b986713abed333883dc6c47 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 11:06:57 -0700 Subject: [PATCH 241/303] Respect original ordering of quick fixes (#157104) Fixes #126393 --- src/vs/editor/contrib/codeAction/browser/codeAction.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/codeAction.ts b/src/vs/editor/contrib/codeAction/browser/codeAction.ts index 1131773f70d..009f7b05ca8 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeAction.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeAction.ts @@ -72,15 +72,11 @@ class ManagedCodeActionSet extends Disposable implements CodeActionSet { private static codeActionsComparator({ action: a }: CodeActionItem, { action: b }: CodeActionItem): number { if (isNonEmptyArray(a.diagnostics)) { - if (isNonEmptyArray(b.diagnostics)) { - return ManagedCodeActionSet.codeActionsPreferredComparator(a, b) || a.diagnostics[0].message.localeCompare(b.diagnostics[0].message); - } else { - return -1; - } + return -1; } else if (isNonEmptyArray(b.diagnostics)) { return 1; } else { - return ManagedCodeActionSet.codeActionsPreferredComparator(a, b); // both have no diagnostics + return ManagedCodeActionSet.codeActionsPreferredComparator(a, b); // both have no diagnostics } } From f2e1518df9f758bef38ee1a8afe6803e94c9a1eb Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 4 Aug 2022 11:11:48 -0700 Subject: [PATCH 242/303] product: bump version number (#157120) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b35222fe71..b447b323ee4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "code-oss-dev", - "version": "1.70.0", + "version": "1.71.0", "distro": "7dc7a14b0f0031128c799f96c856bd3290c3ebee", "author": { "name": "Microsoft Corporation" From ede1cd6a388a52e08d2dd64c73e590f96436c480 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 4 Aug 2022 20:41:00 +0200 Subject: [PATCH 243/303] Windows: some Firefox web tests are timing out randomly (fix #155760) (#157125) --- .../azure-pipelines/darwin/product-build-darwin-test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin-test.yml b/build/azure-pipelines/darwin/product-build-darwin-test.yml index aeea69d5601..1094b41ca21 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-test.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-test.yml @@ -31,8 +31,8 @@ steps: - script: | set -e - DEBUG=*browser* yarn test-browser-no-install --sequential --browser chromium --browser webkit --browser firefox --tfs "Browser Unit Tests" - displayName: Run unit tests (Browser, Chromium & Webkit & Firefox) + DEBUG=*browser* yarn test-browser-no-install --sequential --browser chromium --browser webkit --tfs "Browser Unit Tests" + displayName: Run unit tests (Browser, Chromium & Webkit) timeoutInMinutes: 30 - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: @@ -50,8 +50,8 @@ steps: - script: | set -e - DEBUG=*browser* yarn test-browser-no-install --sequential --build --browser chromium --browser webkit --browser firefox --tfs "Browser Unit Tests" - displayName: Run unit tests (Browser, Chromium & Webkit & Firefox) + DEBUG=*browser* yarn test-browser-no-install --sequential --build --browser chromium --browser webkit --tfs "Browser Unit Tests" + displayName: Run unit tests (Browser, Chromium & Webkit) timeoutInMinutes: 30 - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: From 321a0317f01eecb3e6703995b4e0253b62f5b526 Mon Sep 17 00:00:00 2001 From: David Dossett Date: Thu, 4 Aug 2022 12:19:36 -0700 Subject: [PATCH 244/303] Fix panel tab outline offset (Fix #146856) (#157132) Fix panel tab high contrast outline offset (Fix #146856) --- src/vs/workbench/browser/parts/panel/panelPart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 895149abf1c..6d2a4e69561 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -1082,7 +1082,7 @@ registerThemingParticipant((theme, collector) => { outline-width: 1px; outline-style: solid; border-bottom: none; - outline-offset: -2px; + outline-offset: -1px; } .monaco-workbench .part.basepanel > .title > .panel-switcher-container > .monaco-action-bar .action-item:not(.checked):hover .action-label { From 21f7df634a8ac45d1198cb414fe90366f782bcee Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Thu, 4 Aug 2022 12:46:35 -0700 Subject: [PATCH 245/303] [fix oss] no call into update window controls when disabled (#157138) no call into update window controls when disabled --- src/vs/platform/windows/electron-main/windowImpl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/windows/electron-main/windowImpl.ts b/src/vs/platform/windows/electron-main/windowImpl.ts index b684d4f0ac5..7406f930694 100644 --- a/src/vs/platform/windows/electron-main/windowImpl.ts +++ b/src/vs/platform/windows/electron-main/windowImpl.ts @@ -295,7 +295,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { } // Update the window controls immediately based on cached values - if ((isWindows || isMacintosh) && useCustomTitleStyle) { + if (useCustomTitleStyle && ((isWindows && useWindowControlsOverlay(this.configurationService, this.environmentMainService)) || isMacintosh)) { const cachedWindowControlHeight = this.stateMainService.getItem((CodeWindow.windowControlHeightStateStorageKey)); if (cachedWindowControlHeight) { this.updateWindowControls({ height: cachedWindowControlHeight }); From c28357289742974f2400af33099c459e0b755d29 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 4 Aug 2022 14:40:32 -0700 Subject: [PATCH 246/303] Fix #154358. Avoid dom update in resize observer handler (#157147) --- .../browser/view/renderers/webviewPreloads.ts | 62 ++++++++++++++----- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 3e86223876e..16fec06c8ba 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -226,6 +226,14 @@ async function webviewPreloads(ctx: PreloadContext) { activate(ctx: KernelPreloadContext): Promise | void; } + interface IObservedElement { + id: string; + output: boolean; + lastKnownPadding: number; + lastKnownHeight: number; + cellId: string; + } + function createKernelContext(): KernelPreloadContext { return { onDidReceiveKernelMessage: onDidReceiveKernelMessage.event, @@ -300,7 +308,7 @@ async function webviewPreloads(ctx: PreloadContext) { private readonly _observer: ResizeObserver; - private readonly _observedElements = new WeakMap(); + private readonly _observedElements = new WeakMap(); private _outputResizeTimer: any; constructor() { @@ -317,33 +325,57 @@ async function webviewPreloads(ctx: PreloadContext) { this.postResizeMessage(observedElementInfo.cellId); - if (entry.target.id === observedElementInfo.id && entry.contentRect) { - if (observedElementInfo.output) { - if (entry.contentRect.height !== 0) { + if (entry.target.id !== observedElementInfo.id) { + continue; + } + + if (!entry.contentRect) { + continue; + } + + if (!observedElementInfo.output) { + // markup, update directly + this.updateHeight(observedElementInfo, entry.target.offsetHeight); + continue; + } + + const newHeight = entry.contentRect.height; + const shouldUpdatePadding = + (newHeight !== 0 && observedElementInfo.lastKnownPadding === 0) || + (newHeight === 0 && observedElementInfo.lastKnownPadding !== 0); + + if (shouldUpdatePadding) { + // Do not update dimension in resize observer + window.requestAnimationFrame(() => { + if (newHeight !== 0) { entry.target.style.padding = `${ctx.style.outputNodePadding}px ${ctx.style.outputNodePadding}px ${ctx.style.outputNodePadding}px ${ctx.style.outputNodeLeftPadding}px`; } else { entry.target.style.padding = `0px`; } - } - - const offsetHeight = entry.target.offsetHeight; - if (observedElementInfo.lastKnownHeight !== offsetHeight) { - observedElementInfo.lastKnownHeight = offsetHeight; - dimensionUpdater.updateHeight(observedElementInfo.id, offsetHeight, { - isOutput: observedElementInfo.output - }); - } + this.updateHeight(observedElementInfo, entry.target.offsetHeight); + }); + } else { + this.updateHeight(observedElementInfo, entry.target.offsetHeight); } } }); } + private updateHeight(observedElementInfo: IObservedElement, offsetHeight: number) { + if (observedElementInfo.lastKnownHeight !== offsetHeight) { + observedElementInfo.lastKnownHeight = offsetHeight; + dimensionUpdater.updateHeight(observedElementInfo.id, offsetHeight, { + isOutput: observedElementInfo.output + }); + } + } + public observe(container: Element, id: string, output: boolean, cellId: string) { if (this._observedElements.has(container)) { return; } - this._observedElements.set(container, { id, output, lastKnownHeight: -1, cellId }); + this._observedElements.set(container, { id, output, lastKnownPadding: ctx.style.outputNodePadding, lastKnownHeight: -1, cellId }); this._observer.observe(container); } @@ -1988,7 +2020,7 @@ async function webviewPreloads(ctx: PreloadContext) { this.element.style.position = 'absolute'; this.element.style.top = `0px`; this.element.style.left = left + 'px'; - this.element.style.padding = '0px'; + this.element.style.padding = `${ctx.style.outputNodePadding}px ${ctx.style.outputNodePadding}px ${ctx.style.outputNodePadding}px ${ctx.style.outputNodeLeftPadding}`; addMouseoverListeners(this.element, outputId); } From 44c38244ef80cd8feaea85f89953b9b2da48d8b8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 14:46:02 -0700 Subject: [PATCH 247/303] Move non-types stuff out of types.ts (#157145) - Moves object related methods to `objects.ts` - Moves assertion to `asserts.ts` - Move URI stuff to `uri.ts` --- src/vs/base/common/assert.ts | 4 ++ src/vs/base/common/objects.ts | 35 +++++++++++++ src/vs/base/common/types.ts | 50 ------------------- src/vs/base/common/uri.ts | 7 +++ src/vs/base/common/worker/simpleWorker.ts | 8 +-- src/vs/editor/browser/services/webWorker.ts | 6 +-- .../editor/common/modelLineProjectionData.ts | 2 +- .../common/services/editorSimpleWorker.ts | 8 +-- .../services/unicodeTextModelHighlighter.ts | 2 +- .../browser/inlineCompletionsModel.ts | 2 +- src/vs/platform/action/common/action.ts | 3 +- .../browser/indexedDBFileSystemProvider.ts | 4 +- .../sharedProcess/node/sharedProcess.ts | 2 +- src/vs/platform/storage/common/storageIpc.ts | 2 +- src/vs/platform/theme/common/colorRegistry.ts | 2 +- .../browser/userDataProfile.ts | 2 +- .../userDataProfile/common/userDataProfile.ts | 4 +- .../electron-sandbox/userDataProfile.ts | 3 +- .../userDataProfile/node/userDataProfile.ts | 2 +- src/vs/platform/window/common/window.ts | 3 +- .../test/electron-main/windowsFinder.test.ts | 3 +- .../contrib/debug/browser/debugMemory.ts | 2 +- .../testing/common/testItemCollection.ts | 2 +- 23 files changed, 75 insertions(+), 83 deletions(-) diff --git a/src/vs/base/common/assert.ts b/src/vs/base/common/assert.ts index 9e2510b4d0b..04d57c2ff87 100644 --- a/src/vs/base/common/assert.ts +++ b/src/vs/base/common/assert.ts @@ -11,3 +11,7 @@ export function ok(value?: unknown, message?: string) { throw new Error(message ? `Assertion failed (${message})` : 'Assertion Failed'); } } + +export function assertNever(value: never, message = 'Unreachable'): never { + throw new Error(message); +} diff --git a/src/vs/base/common/objects.ts b/src/vs/base/common/objects.ts index 52d27bc3080..9e59345c09c 100644 --- a/src/vs/base/common/objects.ts +++ b/src/vs/base/common/objects.ts @@ -232,3 +232,38 @@ export function filter(obj: obj, predicate: (key: string, value: any) => boolean } return result; } + +export function getAllPropertyNames(obj: object): string[] { + let res: string[] = []; + let proto = Object.getPrototypeOf(obj); + while (Object.prototype !== proto) { + res = res.concat(Object.getOwnPropertyNames(proto)); + proto = Object.getPrototypeOf(proto); + } + return res; +} + +export function getAllMethodNames(obj: object): string[] { + const methods: string[] = []; + for (const prop of getAllPropertyNames(obj)) { + if (typeof (obj as any)[prop] === 'function') { + methods.push(prop); + } + } + return methods; +} + +export function createProxyObject(methodNames: string[], invoke: (method: string, args: unknown[]) => unknown): T { + const createProxyMethod = (method: string): () => unknown => { + return function () { + const args = Array.prototype.slice.call(arguments, 0); + return invoke(method, args); + }; + }; + + const result = {} as T; + for (const methodName of methodNames) { + (result)[methodName] = createProxyMethod(methodName); + } + return result; +} diff --git a/src/vs/base/common/types.ts b/src/vs/base/common/types.ts index 36e532e5695..08063ae38d1 100644 --- a/src/vs/base/common/types.ts +++ b/src/vs/base/common/types.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { URI, UriComponents } from 'vs/base/common/uri'; - /** * @returns whether the provided parameter is a JavaScript String or not. */ @@ -20,7 +18,6 @@ export function isStringArray(value: unknown): value is string[] { } /** - * * @returns whether the provided parameter is of type `object` but **not** * `null`, an `array`, a `regexp`, nor a `date`. */ @@ -36,7 +33,6 @@ export function isObject(obj: unknown): obj is Object { } /** - * * @returns whether the provided parameter is of type `Buffer` or Uint8Array dervived type */ export function isTypedArray(obj: unknown): obj is Object { @@ -194,41 +190,6 @@ export function validateConstraint(arg: unknown, constraint: TypeConstraint | un } } -export function getAllPropertyNames(obj: object): string[] { - let res: string[] = []; - let proto = Object.getPrototypeOf(obj); - while (Object.prototype !== proto) { - res = res.concat(Object.getOwnPropertyNames(proto)); - proto = Object.getPrototypeOf(proto); - } - return res; -} - -export function getAllMethodNames(obj: object): string[] { - const methods: string[] = []; - for (const prop of getAllPropertyNames(obj)) { - if (typeof (obj as any)[prop] === 'function') { - methods.push(prop); - } - } - return methods; -} - -export function createProxyObject(methodNames: string[], invoke: (method: string, args: unknown[]) => unknown): T { - const createProxyMethod = (method: string): () => unknown => { - return function () { - const args = Array.prototype.slice.call(arguments, 0); - return invoke(method, args); - }; - }; - - const result = {} as T; - for (const methodName of methodNames) { - (result)[methodName] = createProxyMethod(methodName); - } - return result; -} - /** * Converts null to undefined, passes all other values through. */ @@ -258,17 +219,6 @@ export type AddFirstParameterToFunctions; }; -/** - * Mapped-type that replaces all occurrences of URI with UriComponents - */ -export type UriDto = { [K in keyof T]: T[K] extends URI - ? UriComponents - : UriDto }; - -export function assertNever(value: never, message = 'Unreachable'): never { - throw new Error(message); -} - /** * Given an object with all optional properties, requires at least one to be defined. * i.e. AtLeastOne; diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 4aa3825cb4e..744afa00f0c 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -701,3 +701,10 @@ function percentDecode(str: string): string { } return str.replace(_rEncodedAsHex, (match) => decodeURIComponentGraceful(match)); } + +/** + * Mapped-type that replaces all occurrences of URI with UriComponents + */ +export type UriDto = { [K in keyof T]: T[K] extends URI + ? UriComponents + : UriDto }; diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index 5e9df9db7dd..17ecac8ff27 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -6,8 +6,8 @@ import { transformErrorForSerialization } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { getAllMethodNames } from 'vs/base/common/objects'; import { globals, isWeb } from 'vs/base/common/platform'; -import * as types from 'vs/base/common/types'; import * as strings from 'vs/base/common/strings'; const INITIALIZE = '$initialize'; @@ -332,7 +332,7 @@ export class SimpleWorkerClient extends Disp loaderConfiguration = globals.requirejs.s.contexts._.config; } - const hostMethods = types.getAllMethodNames(host); + const hostMethods = getAllMethodNames(host); // Send initialize message this._onModuleLoaded = this._protocol.sendMessage(INITIALIZE, [ @@ -507,7 +507,7 @@ export class SimpleWorkerServer { if (this._requestHandlerFactory) { // static request handler this._requestHandler = this._requestHandlerFactory(hostProxy); - return Promise.resolve(types.getAllMethodNames(this._requestHandler)); + return Promise.resolve(getAllMethodNames(this._requestHandler)); } if (loaderConfig) { @@ -548,7 +548,7 @@ export class SimpleWorkerServer { return; } - resolve(types.getAllMethodNames(this._requestHandler)); + resolve(getAllMethodNames(this._requestHandler)); }, reject); }); } diff --git a/src/vs/editor/browser/services/webWorker.ts b/src/vs/editor/browser/services/webWorker.ts index c853e3220ec..b5757c58865 100644 --- a/src/vs/editor/browser/services/webWorker.ts +++ b/src/vs/editor/browser/services/webWorker.ts @@ -3,11 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { getAllMethodNames } from 'vs/base/common/objects'; import { URI } from 'vs/base/common/uri'; import { EditorWorkerClient } from 'vs/editor/browser/services/editorWorkerService'; -import { IModelService } from 'vs/editor/common/services/model'; -import * as types from 'vs/base/common/types'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; +import { IModelService } from 'vs/editor/common/services/model'; /** * Create a new web worker that has model syncing capabilities built in. @@ -92,7 +92,7 @@ class MonacoWebWorkerImpl extends EditorWorkerClient implement private _getForeignProxy(): Promise { if (!this._foreignProxy) { this._foreignProxy = this._getProxy().then((proxy) => { - const foreignHostMethods = this._foreignModuleHost ? types.getAllMethodNames(this._foreignModuleHost) : []; + const foreignHostMethods = this._foreignModuleHost ? getAllMethodNames(this._foreignModuleHost) : []; return proxy.loadForeignModule(this._foreignModuleId, this._foreignModuleCreateData, foreignHostMethods).then((foreignMethods) => { this._foreignModuleCreateData = null; diff --git a/src/vs/editor/common/modelLineProjectionData.ts b/src/vs/editor/common/modelLineProjectionData.ts index 8a6fbd6ca4b..e1f87378985 100644 --- a/src/vs/editor/common/modelLineProjectionData.ts +++ b/src/vs/editor/common/modelLineProjectionData.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { assertNever } from 'vs/base/common/types'; +import { assertNever } from 'vs/base/common/assert'; import { WrappingIndent } from 'vs/editor/common/config/editorOptions'; import { FontInfo } from 'vs/editor/common/config/fontInfo'; import { Position } from 'vs/editor/common/core/position'; diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index d68936dbda4..8961cde0dce 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -19,10 +19,10 @@ import { ILinkComputerTarget, computeLinks } from 'vs/editor/common/languages/li import { BasicInplaceReplace } from 'vs/editor/common/languages/supports/inplaceReplaceSupport'; import { IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker'; import { createMonacoBaseAPI } from 'vs/editor/common/services/editorBaseApi'; -import * as types from 'vs/base/common/types'; import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost'; import { StopWatch } from 'vs/base/common/stopwatch'; import { UnicodeTextModelHighlighter, UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter'; +import { createProxyObject, getAllMethodNames } from 'vs/base/common/objects'; export interface IMirrorModel extends IMirrorTextModel { readonly uri: URI; @@ -634,7 +634,7 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable { return this._host.fhr(method, args); }; - const foreignHost = types.createProxyObject(foreignHostMethods, proxyMethodRequest); + const foreignHost = createProxyObject(foreignHostMethods, proxyMethodRequest); const ctx: IWorkerContext = { host: foreignHost, @@ -646,14 +646,14 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable { if (this._foreignModuleFactory) { this._foreignModule = this._foreignModuleFactory(ctx, createData); // static foreing module - return Promise.resolve(types.getAllMethodNames(this._foreignModule)); + return Promise.resolve(getAllMethodNames(this._foreignModule)); } // ESM-comment-begin return new Promise((resolve, reject) => { require([moduleId], (foreignModule: { create: IForeignModuleFactory }) => { this._foreignModule = foreignModule.create(ctx, createData); - resolve(types.getAllMethodNames(this._foreignModule)); + resolve(getAllMethodNames(this._foreignModule)); }, reject); }); diff --git a/src/vs/editor/common/services/unicodeTextModelHighlighter.ts b/src/vs/editor/common/services/unicodeTextModelHighlighter.ts index 9ef1f337e5a..e4d5b6effcc 100644 --- a/src/vs/editor/common/services/unicodeTextModelHighlighter.ts +++ b/src/vs/editor/common/services/unicodeTextModelHighlighter.ts @@ -7,7 +7,7 @@ import { IRange, Range } from 'vs/editor/common/core/range'; import { Searcher } from 'vs/editor/common/model/textModelSearch'; import * as strings from 'vs/base/common/strings'; import { IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorker'; -import { assertNever } from 'vs/base/common/types'; +import { assertNever } from 'vs/base/common/assert'; import { DEFAULT_WORD_REGEXP, getWordAtText } from 'vs/editor/common/core/wordHelper'; export class UnicodeTextModelHighlighter { diff --git a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts index 02104cfe890..e6f2c1190d5 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel.ts @@ -28,7 +28,7 @@ import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeat import { IFeatureDebounceInformation, ILanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce'; import { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser'; import { SnippetController2 } from 'vs/editor/contrib/snippet/browser/snippetController2'; -import { assertNever } from 'vs/base/common/types'; +import { assertNever } from 'vs/base/common/assert'; import { matchesSubString } from 'vs/base/common/filters'; import { getReadonlyEmptyArray } from 'vs/editor/contrib/inlineCompletions/browser/utils'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; diff --git a/src/vs/platform/action/common/action.ts b/src/vs/platform/action/common/action.ts index ceccd0a3508..4b3f1b5f0ff 100644 --- a/src/vs/platform/action/common/action.ts +++ b/src/vs/platform/action/common/action.ts @@ -3,8 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { UriDto } from 'vs/base/common/types'; -import { URI } from 'vs/base/common/uri'; +import { URI, UriDto } from 'vs/base/common/uri'; import { ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; diff --git a/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts b/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts index 660dd5cdcc1..c3c62689805 100644 --- a/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts +++ b/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts @@ -8,8 +8,8 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { ExtUri } from 'vs/base/common/resources'; -import { isString, UriDto } from 'vs/base/common/types'; -import { URI } from 'vs/base/common/uri'; +import { isString } from 'vs/base/common/types'; +import { URI, UriDto } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { createFileSystemProviderError, FileChangeType, IFileDeleteOptions, IFileOverwriteOptions, FileSystemProviderCapabilities, FileSystemProviderError, FileSystemProviderErrorCode, FileType, IFileWriteOptions, IFileChange, IFileSystemProviderWithFileReadWriteCapability, IStat, IWatchOptions } from 'vs/platform/files/common/files'; import { DBClosedError, IndexedDB } from 'vs/base/browser/indexedDB'; diff --git a/src/vs/platform/sharedProcess/node/sharedProcess.ts b/src/vs/platform/sharedProcess/node/sharedProcess.ts index 97c71c41b91..a67f68f3434 100644 --- a/src/vs/platform/sharedProcess/node/sharedProcess.ts +++ b/src/vs/platform/sharedProcess/node/sharedProcess.ts @@ -9,7 +9,7 @@ import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; import { LogLevel } from 'vs/platform/log/common/log'; import { IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; import { PolicyDefinition, PolicyValue } from 'vs/platform/policy/common/policy'; -import { UriDto } from 'vs/base/common/types'; +import { UriDto } from 'vs/base/common/uri'; export interface ISharedProcess { diff --git a/src/vs/platform/storage/common/storageIpc.ts b/src/vs/platform/storage/common/storageIpc.ts index d5be460c5da..dfde3c2d0a9 100644 --- a/src/vs/platform/storage/common/storageIpc.ts +++ b/src/vs/platform/storage/common/storageIpc.ts @@ -5,7 +5,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; -import { UriDto } from 'vs/base/common/types'; +import { UriDto } from 'vs/base/common/uri'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { IStorageDatabase, IStorageItemsChangeEvent, IUpdateRequest } from 'vs/base/parts/storage/common/storage'; import { IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile'; diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index c1f226c3601..01f9f4743ad 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -7,7 +7,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { Color, RGBA } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; -import { assertNever } from 'vs/base/common/types'; +import { assertNever } from 'vs/base/common/assert'; import * as nls from 'vs/nls'; import { Extensions as JSONExtensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import * as platform from 'vs/platform/registry/common/platform'; diff --git a/src/vs/platform/userDataProfile/browser/userDataProfile.ts b/src/vs/platform/userDataProfile/browser/userDataProfile.ts index 782a627770f..82f44361941 100644 --- a/src/vs/platform/userDataProfile/browser/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/browser/userDataProfile.ts @@ -5,7 +5,7 @@ import { BroadcastDataChannel } from 'vs/base/browser/broadcast'; import { revive } from 'vs/base/common/marshalling'; -import { UriDto } from 'vs/base/common/types'; +import { UriDto } from 'vs/base/common/uri'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; diff --git a/src/vs/platform/userDataProfile/common/userDataProfile.ts b/src/vs/platform/userDataProfile/common/userDataProfile.ts index 9df1359aed6..e6d19a5196f 100644 --- a/src/vs/platform/userDataProfile/common/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/common/userDataProfile.ts @@ -7,8 +7,8 @@ import { hash } from 'vs/base/common/hash'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { joinPath } from 'vs/base/common/resources'; -import { isUndefined, UriDto } from 'vs/base/common/types'; -import { URI } from 'vs/base/common/uri'; +import { isUndefined } from 'vs/base/common/types'; +import { URI, UriDto } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; diff --git a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts index f1fd6c1afa9..bcd15aa8096 100644 --- a/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts @@ -6,8 +6,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { joinPath } from 'vs/base/common/resources'; -import { UriDto } from 'vs/base/common/types'; -import { URI } from 'vs/base/common/uri'; +import { URI, UriDto } from 'vs/base/common/uri'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services'; diff --git a/src/vs/platform/userDataProfile/node/userDataProfile.ts b/src/vs/platform/userDataProfile/node/userDataProfile.ts index 1405ca08e76..b36da2b327a 100644 --- a/src/vs/platform/userDataProfile/node/userDataProfile.ts +++ b/src/vs/platform/userDataProfile/node/userDataProfile.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { revive } from 'vs/base/common/marshalling'; -import { UriDto } from 'vs/base/common/types'; +import { UriDto } from 'vs/base/common/uri'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { ILogService } from 'vs/platform/log/common/log'; diff --git a/src/vs/platform/window/common/window.ts b/src/vs/platform/window/common/window.ts index 5aa516550f0..e25a1573fed 100644 --- a/src/vs/platform/window/common/window.ts +++ b/src/vs/platform/window/common/window.ts @@ -6,8 +6,7 @@ import { IStringDictionary } from 'vs/base/common/collections'; import { PerformanceMark } from 'vs/base/common/performance'; import { isLinux, isMacintosh, isNative, isWeb, isWindows } from 'vs/base/common/platform'; -import { UriDto } from 'vs/base/common/types'; -import { URI, UriComponents } from 'vs/base/common/uri'; +import { URI, UriComponents, UriDto } from 'vs/base/common/uri'; import { ISandboxConfiguration } from 'vs/base/parts/sandbox/common/sandboxTypes'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; diff --git a/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts b/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts index 9410d67711e..f211c37ae0a 100644 --- a/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts +++ b/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts @@ -8,8 +8,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Event } from 'vs/base/common/event'; import { join } from 'vs/base/common/path'; import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources'; -import { UriDto } from 'vs/base/common/types'; -import { URI } from 'vs/base/common/uri'; +import { URI, UriDto } from 'vs/base/common/uri'; import { getPathFromAmdModule } from 'vs/base/test/node/testUtils'; import { ICommandAction } from 'vs/platform/action/common/action'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; diff --git a/src/vs/workbench/contrib/debug/browser/debugMemory.ts b/src/vs/workbench/contrib/debug/browser/debugMemory.ts index b724227781e..b869672f5e7 100644 --- a/src/vs/workbench/contrib/debug/browser/debugMemory.ts +++ b/src/vs/workbench/contrib/debug/browser/debugMemory.ts @@ -7,7 +7,7 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { clamp } from 'vs/base/common/numbers'; -import { assertNever } from 'vs/base/common/types'; +import { assertNever } from 'vs/base/common/assert'; import { URI } from 'vs/base/common/uri'; import { FileChangeType, IFileOpenOptions, FilePermission, FileSystemProviderCapabilities, FileSystemProviderError, FileSystemProviderErrorCode, FileType, IFileChange, IFileSystemProvider, IStat, IWatchOptions } from 'vs/platform/files/common/files'; import { DEBUG_MEMORY_SCHEME, IDebugService, IDebugSession, IMemoryInvalidationEvent, IMemoryRegion, MemoryRange, MemoryRangeType, State } from 'vs/workbench/contrib/debug/common/debug'; diff --git a/src/vs/workbench/contrib/testing/common/testItemCollection.ts b/src/vs/workbench/contrib/testing/common/testItemCollection.ts index 9a72a25c1ac..bc5cfa13207 100644 --- a/src/vs/workbench/contrib/testing/common/testItemCollection.ts +++ b/src/vs/workbench/contrib/testing/common/testItemCollection.ts @@ -6,7 +6,7 @@ import { Barrier, isThenable, RunOnceScheduler } from 'vs/base/common/async'; import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; -import { assertNever } from 'vs/base/common/types'; +import { assertNever } from 'vs/base/common/assert'; import { applyTestItemUpdate, ITestItem, ITestTag, namespaceTestTag, TestDiffOpType, TestItemExpandState, TestsDiff, TestsDiffOp } from 'vs/workbench/contrib/testing/common/testTypes'; import { TestId } from 'vs/workbench/contrib/testing/common/testId'; From 68912bd84455af48bbee698d358c17a7d4ebad44 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 14:46:53 -0700 Subject: [PATCH 248/303] Use 'import type' for '@jupyterlab/nbformat' (#157153) This is a type only dev dep so we should prevent referencing it as a value --- extensions/ipynb/src/cellIdService.ts | 2 +- extensions/ipynb/src/common.ts | 2 +- extensions/ipynb/src/deserializers.ts | 2 +- extensions/ipynb/src/notebookSerializer.ts | 2 +- extensions/ipynb/src/serializers.ts | 2 +- extensions/ipynb/src/test/serializers.test.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/extensions/ipynb/src/cellIdService.ts b/extensions/ipynb/src/cellIdService.ts index ddda0a9fd5f..2eccb586ef4 100644 --- a/extensions/ipynb/src/cellIdService.ts +++ b/extensions/ipynb/src/cellIdService.ts @@ -8,7 +8,7 @@ import { v4 as uuid } from 'uuid'; import { getCellMetadata } from './serializers'; import { CellMetadata } from './common'; import { getNotebookMetadata } from './notebookSerializer'; -import * as nbformat from '@jupyterlab/nbformat'; +import type * as nbformat from '@jupyterlab/nbformat'; /** * Ensure all new cells in notebooks with nbformat >= 4.5 have an id. diff --git a/extensions/ipynb/src/common.ts b/extensions/ipynb/src/common.ts index 047814ecfc1..d5ff5f86069 100644 --- a/extensions/ipynb/src/common.ts +++ b/extensions/ipynb/src/common.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nbformat from '@jupyterlab/nbformat'; +import type * as nbformat from '@jupyterlab/nbformat'; /** * Metadata we store in VS Code cell output items. diff --git a/extensions/ipynb/src/deserializers.ts b/extensions/ipynb/src/deserializers.ts index 50a3a1271b0..92cd20bb33a 100644 --- a/extensions/ipynb/src/deserializers.ts +++ b/extensions/ipynb/src/deserializers.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nbformat from '@jupyterlab/nbformat'; +import type * as nbformat from '@jupyterlab/nbformat'; import { extensions, NotebookCellData, NotebookCellExecutionSummary, NotebookCellKind, NotebookCellOutput, NotebookCellOutputItem, NotebookData } from 'vscode'; import { CellMetadata, CellOutputMetadata } from './common'; diff --git a/extensions/ipynb/src/notebookSerializer.ts b/extensions/ipynb/src/notebookSerializer.ts index 37eee49b1be..0c3ccd09723 100644 --- a/extensions/ipynb/src/notebookSerializer.ts +++ b/extensions/ipynb/src/notebookSerializer.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nbformat from '@jupyterlab/nbformat'; +import type * as nbformat from '@jupyterlab/nbformat'; import * as detectIndent from 'detect-indent'; import * as vscode from 'vscode'; import { defaultNotebookFormat } from './constants'; diff --git a/extensions/ipynb/src/serializers.ts b/extensions/ipynb/src/serializers.ts index 078bb408cc5..455fb0d2745 100644 --- a/extensions/ipynb/src/serializers.ts +++ b/extensions/ipynb/src/serializers.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nbformat from '@jupyterlab/nbformat'; +import type * as nbformat from '@jupyterlab/nbformat'; import { NotebookCell, NotebookCellData, NotebookCellKind, NotebookCellOutput } from 'vscode'; import { CellMetadata, CellOutputMetadata } from './common'; import { textMimeTypes } from './deserializers'; diff --git a/extensions/ipynb/src/test/serializers.test.ts b/extensions/ipynb/src/test/serializers.test.ts index 15ef1185f94..2a59c73532e 100644 --- a/extensions/ipynb/src/test/serializers.test.ts +++ b/extensions/ipynb/src/test/serializers.test.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nbformat from '@jupyterlab/nbformat'; +import type * as nbformat from '@jupyterlab/nbformat'; import * as assert from 'assert'; import * as vscode from 'vscode'; import { jupyterCellOutputToCellOutput, jupyterNotebookModelToNotebookData } from '../deserializers'; From 24e585963c0648b0ec0b67ef22ee303de4585d71 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 14:48:55 -0700 Subject: [PATCH 249/303] Remove SimpleSequence (#157149) This class doesn't appear to be used anywhere --- src/vs/base/common/sequence.ts | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/vs/base/common/sequence.ts b/src/vs/base/common/sequence.ts index ac3593d8990..2559c069be8 100644 --- a/src/vs/base/common/sequence.ts +++ b/src/vs/base/common/sequence.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { Emitter, Event } from 'vs/base/common/event'; -import { IDisposable } from 'vs/base/common/lifecycle'; export interface ISplice { readonly start: number; @@ -33,26 +32,3 @@ export class Sequence implements ISequence, ISpliceable { this._onDidSplice.fire({ start, deleteCount, toInsert }); } } - -export class SimpleSequence implements ISequence { - - private _elements: T[]; - get elements(): T[] { return this._elements; } - - readonly onDidSplice: Event>; - private disposable: IDisposable; - - constructor(elements: T[], onDidAdd: Event, onDidRemove: Event) { - this._elements = [...elements]; - this.onDidSplice = Event.any( - Event.map(onDidAdd, e => ({ start: this.elements.length, deleteCount: 0, toInsert: [e] })), - Event.map(Event.filter(Event.map(onDidRemove, e => this.elements.indexOf(e)), i => i > -1), i => ({ start: i, deleteCount: 1, toInsert: [] })) - ); - - this.disposable = this.onDidSplice(({ start, deleteCount, toInsert }) => this._elements.splice(start, deleteCount, ...toInsert)); - } - - dispose(): void { - this.disposable.dispose(); - } -} From c5f857f0cf0b8b6cb12bc98f12a8b9833de150c0 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 14:49:05 -0700 Subject: [PATCH 250/303] Remove skipped webview tests (#157155) Fixes #153066 It's unclear what is causing these to occasionally fail in CI but keeping around these skipped tests is not useful --- .../src/singlefolder-tests/webview.test.ts | 578 ------------------ 1 file changed, 578 deletions(-) delete mode 100644 extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts deleted file mode 100644 index d9c199ea50e..00000000000 --- a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts +++ /dev/null @@ -1,578 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; -import 'mocha'; -import * as os from 'os'; -import * as vscode from 'vscode'; -import { assertNoRpc, closeAllEditors, delay, disposeAll } from '../utils'; - -const webviewId = 'myWebview'; - -function workspaceFile(...segments: string[]) { - return vscode.Uri.joinPath(vscode.workspace.workspaceFolders![0].uri, ...segments); -} - -suite.skip('vscode API - webview', () => { // TODO@mjbvz https://github.com/microsoft/vscode/issues/153066 - const disposables: vscode.Disposable[] = []; - - function _register(disposable: T) { - disposables.push(disposable); - return disposable; - } - - teardown(async () => { - assertNoRpc(); - await closeAllEditors(); - disposeAll(disposables); - }); - - test.skip('webviews should be able to send and receive messages', async () => { // TODO@mjbvz https://github.com/microsoft/vscode/issues/150682 - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { enableScripts: true })); - const firstResponse = getMessage(webview); - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - `); - - webview.webview.postMessage({ value: 1 }); - assert.strictEqual((await firstResponse).value, 2); - }); - - test('webviews should not have scripts enabled by default', async () => { - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, {})); - const response = Promise.race([ - getMessage(webview), - new Promise<{}>(resolve => setTimeout(() => resolve({ value: '🎉' }), 1000)) - ]); - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - `); - - assert.strictEqual((await response).value, '🎉'); - }); - - test('webviews should update html', async () => { - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { enableScripts: true })); - - { - const response = getMessage(webview); - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - `); - - assert.strictEqual((await response).value, 'first'); - } - { - const response = getMessage(webview); - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - `); - - assert.strictEqual((await response).value, 'second'); - } - }); - - test.skip('webviews should preserve vscode API state when they are hidden', async () => { - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { enableScripts: true })); - const ready = getMessage(webview); - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - `); - await ready; - - const firstResponse = await sendReceiveMessage(webview, { type: 'add' }); - assert.strictEqual(firstResponse.value, 1); - - // Swap away from the webview - const doc = await vscode.workspace.openTextDocument(workspaceFile('bower.json')); - await vscode.window.showTextDocument(doc); - - // And then back - const ready2 = getMessage(webview); - webview.reveal(vscode.ViewColumn.One); - await ready2; - - // We should still have old state - const secondResponse = await sendReceiveMessage(webview, { type: 'get' }); - assert.strictEqual(secondResponse.value, 1); - }); - - test.skip('webviews should preserve their context when they are moved between view columns', async () => { // TODO@mjbvz https://github.com/microsoft/vscode/issues/141001 - const doc = await vscode.workspace.openTextDocument(workspaceFile('bower.json')); - await vscode.window.showTextDocument(doc, vscode.ViewColumn.One); - - // Open webview in same column - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { enableScripts: true })); - const ready = getMessage(webview); - webview.webview.html = statefulWebviewHtml; - await ready; - - const firstResponse = await sendReceiveMessage(webview, { type: 'add' }); - assert.strictEqual(firstResponse.value, 1); - - // Now move webview to new view column - webview.reveal(vscode.ViewColumn.Two); - - // We should still have old state - const secondResponse = await sendReceiveMessage(webview, { type: 'get' }); - assert.strictEqual(secondResponse.value, 1); - }); - - test.skip('webviews with retainContextWhenHidden should preserve their context when they are hidden', async function () { - this.retries(3); - - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { enableScripts: true, retainContextWhenHidden: true })); - const ready = getMessage(webview); - - webview.webview.html = statefulWebviewHtml; - await ready; - - const firstResponse = await sendReceiveMessage(webview, { type: 'add' }); - assert.strictEqual((await firstResponse).value, 1); - - // Swap away from the webview - const doc = await vscode.workspace.openTextDocument(workspaceFile('bower.json')); - await vscode.window.showTextDocument(doc); - - // And then back - webview.reveal(vscode.ViewColumn.One); - - // We should still have old state - const secondResponse = await sendReceiveMessage(webview, { type: 'get' }); - assert.strictEqual(secondResponse.value, 1); - }); - - test.skip('webviews with retainContextWhenHidden should preserve their page position when hidden', async () => { - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { enableScripts: true, retainContextWhenHidden: true })); - const ready = getMessage(webview); - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - ${'

Header

'.repeat(200)} - `); - await ready; - - const firstResponse = getMessage(webview); - - assert.strictEqual(Math.round((await firstResponse).value), 100); - - // Swap away from the webview - const doc = await vscode.workspace.openTextDocument(workspaceFile('bower.json')); - await vscode.window.showTextDocument(doc); - - // And then back - webview.reveal(vscode.ViewColumn.One); - - // We should still have old scroll pos - const secondResponse = await sendReceiveMessage(webview, { type: 'get' }); - assert.strictEqual(Math.round(secondResponse.value), 100); - }); - - test.skip('webviews with retainContextWhenHidden should be able to recive messages while hidden', async () => { // TODO@mjbvz https://github.com/microsoft/vscode/issues/139960 - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { enableScripts: true, retainContextWhenHidden: true })); - const ready = getMessage(webview); - - webview.webview.html = statefulWebviewHtml; - await ready; - - const firstResponse = await sendReceiveMessage(webview, { type: 'add' }); - assert.strictEqual((await firstResponse).value, 1); - - // Swap away from the webview - const doc = await vscode.workspace.openTextDocument(workspaceFile('bower.json')); - await vscode.window.showTextDocument(doc); - - // Try posting a message to our hidden webview - const secondResponse = await sendReceiveMessage(webview, { type: 'add' }); - assert.strictEqual((await secondResponse).value, 2); - - // Now show webview again - webview.reveal(vscode.ViewColumn.One); - - // We should still have old state - const thirdResponse = await sendReceiveMessage(webview, { type: 'get' }); - assert.strictEqual(thirdResponse.value, 2); - }); - - - test.skip('webviews should only be able to load resources from workspace by default', async () => { // TODO@mjbvz https://github.com/microsoft/vscode/issues/139960 - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { - viewColumn: vscode.ViewColumn.One - }, { - enableScripts: true - })); - - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - `); - - const ready = getMessage(webview); - if ((await ready).userAgent.indexOf('Firefox') >= 0) { - // Skip on firefox web for now. - // Firefox service workers never seem to get any 'fetch' requests here. Other browsers work fine - return; - } - - { - const imagePath = webview.webview.asWebviewUri(workspaceFile('image.png')); - const response = await sendReceiveMessage(webview, { src: imagePath.toString() }); - assert.strictEqual(response.value, true); - } - // { - // // #102188. Resource filename containing special characters like '%', '#', '?'. - // const imagePath = webview.webview.asWebviewUri(workspaceFile('image%02.png')); - // const response = await sendReceiveMessage(webview, { src: imagePath.toString() }); - // assert.strictEqual(response.value, true); - // } - // { - // // #102188. Resource filename containing special characters like '%', '#', '?'. - // const imagePath = webview.webview.asWebviewUri(workspaceFile('image%.png')); - // const response = await sendReceiveMessage(webview, { src: imagePath.toString() }); - // assert.strictEqual(response.value, true); - // } - { - const imagePath = webview.webview.asWebviewUri(workspaceFile('no-such-image.png')); - const response = await sendReceiveMessage(webview, { src: imagePath.toString() }); - assert.strictEqual(response.value, false); - } - { - const imagePath = webview.webview.asWebviewUri(workspaceFile('..', '..', '..', 'resources', 'linux', 'code.png')); - const response = await sendReceiveMessage(webview, { src: imagePath.toString() }); - assert.strictEqual(response.value, false); - } - }); - - test.skip('webviews should allow overriding allowed resource paths using localResourceRoots', async () => { - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { - enableScripts: true, - localResourceRoots: [workspaceFile('sub')] - })); - - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - `); - - { - const response = sendReceiveMessage(webview, { src: webview.webview.asWebviewUri(workspaceFile('sub', 'image.png')).toString() }); - assert.strictEqual((await response).value, true); - } - { - const response = sendReceiveMessage(webview, { src: webview.webview.asWebviewUri(workspaceFile('image.png')).toString() }); - assert.strictEqual((await response).value, false); - } - }); - - test.skip('webviews using hard-coded old style vscode-resource uri should work', async () => { // TODO@mjbvz https://github.com/microsoft/vscode/issues/139572 - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { - enableScripts: true, - localResourceRoots: [workspaceFile('sub')] - })); - - const imagePath = workspaceFile('sub', 'image.png').with({ scheme: 'vscode-resource' }).toString(); - - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - - `); - - const ready = getMessage(webview); - if ((await ready).userAgent.indexOf('Firefox') >= 0) { - // Skip on firefox web for now. - // Firefox service workers never seem to get any 'fetch' requests here. Other browsers work fine - return; - } - const firstResponse = await sendReceiveMessage(webview, { src: imagePath.toString() }); - - assert.strictEqual(firstResponse.value, true); - }); - - test('webviews should have real view column after they are created, #56097', async () => { - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.Active }, { enableScripts: true })); - - // Since we used a symbolic column, we don't know what view column the webview will actually show in at first - assert.strictEqual(webview.viewColumn, undefined); - - let changed = false; - const viewStateChanged = new Promise((resolve) => { - webview.onDidChangeViewState(e => { - if (changed) { - throw new Error('Only expected a single view state change'); - } - changed = true; - resolve(e); - }, undefined, disposables); - }); - - assert.strictEqual((await viewStateChanged).webviewPanel.viewColumn, vscode.ViewColumn.One); - - const firstResponse = getMessage(webview); - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - `); - - webview.webview.postMessage({ value: 1 }); - await firstResponse; - assert.strictEqual(webview.viewColumn, vscode.ViewColumn.One); - }); - - if (os.platform() === 'darwin') { - test.skip('webview can copy text from webview', async () => { - const expectedText = `webview text from: ${Date.now()}!`; - - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { enableScripts: true, retainContextWhenHidden: true })); - const ready = getMessage(webview); - - - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - ${expectedText} - `); - await ready; - - await vscode.commands.executeCommand('editor.action.clipboardCopyAction'); - await delay(200); // Make sure copy has time to reach webview - assert.strictEqual(await vscode.env.clipboard.readText(), expectedText); - }); - } - - test.skip('webviews should transfer ArrayBuffers to and from webviews', async () => { - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { enableScripts: true, retainContextWhenHidden: true })); - const ready = getMessage(webview); - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - `); - await ready; - - const responsePromise = getMessage(webview); - - const bufferLen = 100; - - { - const arrayBuffer = new ArrayBuffer(bufferLen); - const uint8Array = new Uint8Array(arrayBuffer); - for (let i = 0; i < bufferLen; ++i) { - uint8Array[i] = i; - } - webview.webview.postMessage({ - type: 'add1', - array: arrayBuffer - }); - } - { - const response = await responsePromise; - assert.ok(response.array instanceof ArrayBuffer); - - const uint8Array = new Uint8Array(response.array); - for (let i = 0; i < bufferLen; ++i) { - assert.strictEqual(uint8Array[i], i + 1); - } - } - }); - - test.skip('webviews should transfer Typed arrays to and from webviews', async () => { - const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { enableScripts: true, retainContextWhenHidden: true })); - const ready = getMessage(webview); - webview.webview.html = createHtmlDocumentWithBody(/*html*/` - `); - await ready; - - const responsePromise = getMessage(webview); - - const bufferLen = 100; - { - const arrayBuffer = new ArrayBuffer(bufferLen); - const uint8Array = new Uint8Array(arrayBuffer); - const uint16Array = new Uint16Array(arrayBuffer); - for (let i = 0; i < uint16Array.length; ++i) { - uint16Array[i] = i; - } - - webview.webview.postMessage({ - type: 'add1', - array1: uint8Array, - array2: uint16Array, - }); - } - { - const response = await responsePromise; - - assert.ok(response.array1 instanceof Uint8Array); - assert.ok(response.array2 instanceof Uint16Array); - assert.ok(response.array1.buffer === response.array2.buffer); - - const uint8Array = response.array1; - for (let i = 0; i < bufferLen; ++i) { - if (i % 2 === 0) { - assert.strictEqual(uint8Array[i], Math.floor(i / 2) + 1); - } else { - assert.strictEqual(uint8Array[i], 0); - } - } - } - }); -}); - -function createHtmlDocumentWithBody(body: string): string { - return /*html*/` - - - - - - Document - - - ${body} - -`; -} - -const statefulWebviewHtml = createHtmlDocumentWithBody(/*html*/ ` - `); - - -function getMessage(webview: vscode.WebviewPanel): Promise { - return new Promise(resolve => { - const sub = webview.webview.onDidReceiveMessage(message => { - sub.dispose(); - resolve(message); - }); - }); -} - -function sendReceiveMessage(webview: vscode.WebviewPanel, message: T): Promise { - const p = getMessage(webview); - webview.webview.postMessage(message); - return p; -} From 0d5d5a0fb5cb3518880da0ca3d2bc14c254427d7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 14:50:24 -0700 Subject: [PATCH 251/303] Remove decoder and LineProcess (#157150) * Remove decoder and LineProcess These classes don't seem to be used anywhere * Also remove test --- src/vs/base/node/decoder.ts | 62 ----- src/vs/base/node/processes.ts | 371 +------------------------- src/vs/base/test/node/decoder.test.ts | 22 -- 3 files changed, 1 insertion(+), 454 deletions(-) delete mode 100644 src/vs/base/node/decoder.ts delete mode 100644 src/vs/base/test/node/decoder.test.ts diff --git a/src/vs/base/node/decoder.ts b/src/vs/base/node/decoder.ts deleted file mode 100644 index 36a3de5175c..00000000000 --- a/src/vs/base/node/decoder.ts +++ /dev/null @@ -1,62 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as sd from 'string_decoder'; -import { CharCode } from 'vs/base/common/charCode'; - -/** - * Convenient way to iterate over output line by line. This helper accommodates for the fact that - * a buffer might not end with new lines all the way. - * - * To use: - * - call the write method - * - forEach() over the result to get the lines - */ -export class LineDecoder { - private stringDecoder: sd.StringDecoder; - private remaining: string | null; - - constructor(encoding: BufferEncoding = 'utf8') { - this.stringDecoder = new sd.StringDecoder(encoding); - this.remaining = null; - } - - write(buffer: Buffer): string[] { - const result: string[] = []; - const value = this.remaining - ? this.remaining + this.stringDecoder.write(buffer) - : this.stringDecoder.write(buffer); - - if (value.length < 1) { - return result; - } - let start = 0; - let ch: number; - let idx = start; - while (idx < value.length) { - ch = value.charCodeAt(idx); - if (ch === CharCode.CarriageReturn || ch === CharCode.LineFeed) { - result.push(value.substring(start, idx)); - idx++; - if (idx < value.length) { - const lastChar = ch; - ch = value.charCodeAt(idx); - if ((lastChar === CharCode.CarriageReturn && ch === CharCode.LineFeed) || (lastChar === CharCode.LineFeed && ch === CharCode.CarriageReturn)) { - idx++; - } - } - start = idx; - } else { - idx++; - } - } - this.remaining = start < value.length ? value.substr(start) : null; - return result; - } - - end(): string | null { - return this.remaining; - } -} diff --git a/src/vs/base/node/processes.ts b/src/vs/base/node/processes.ts index 1a27f7543c3..a71a7b8cb4e 100644 --- a/src/vs/base/node/processes.ts +++ b/src/vs/base/node/processes.ts @@ -5,392 +5,23 @@ import * as cp from 'child_process'; import { Stats } from 'fs'; -import { IStringDictionary } from 'vs/base/common/collections'; -import * as extpath from 'vs/base/common/extpath'; -import { FileAccess } from 'vs/base/common/network'; -import * as Objects from 'vs/base/common/objects'; import * as path from 'vs/base/common/path'; import * as Platform from 'vs/base/common/platform'; import * as process from 'vs/base/common/process'; -import { CommandOptions, Executable, ForkOptions, Source, SuccessData, TerminateResponse, TerminateResponseCode } from 'vs/base/common/processes'; +import { CommandOptions, ForkOptions, Source, SuccessData, TerminateResponse, TerminateResponseCode } from 'vs/base/common/processes'; import * as Types from 'vs/base/common/types'; -import { LineDecoder } from 'vs/base/node/decoder'; import * as pfs from 'vs/base/node/pfs'; -import * as nls from 'vs/nls'; export { CommandOptions, ForkOptions, SuccessData, Source, TerminateResponse, TerminateResponseCode }; export type ValueCallback = (value: T | Promise) => void; export type ErrorCallback = (error?: any) => void; export type ProgressCallback = (progress: T) => void; -export interface LineData { - line: string; - source: Source; -} - -function getWindowsCode(status: number): TerminateResponseCode { - switch (status) { - case 0: - return TerminateResponseCode.Success; - case 1: - return TerminateResponseCode.AccessDenied; - case 128: - return TerminateResponseCode.ProcessNotFound; - default: - return TerminateResponseCode.Unknown; - } -} - -function terminateProcess(process: cp.ChildProcess, cwd?: string): Promise { - if (Platform.isWindows) { - try { - const options: any = { - stdio: ['pipe', 'pipe', 'ignore'] - }; - if (cwd) { - options.cwd = cwd; - } - const killProcess = cp.execFile('taskkill', ['/T', '/F', '/PID', process.pid!.toString()], options); - return new Promise(resolve => { - killProcess.once('error', (err) => { - resolve({ success: false, error: err }); - }); - killProcess.once('exit', (code, signal) => { - if (code === 0) { - resolve({ success: true }); - } else { - resolve({ success: false, code: code !== null ? code : TerminateResponseCode.Unknown }); - } - }); - }); - } catch (err) { - return Promise.resolve({ success: false, error: err, code: err.status ? getWindowsCode(err.status) : TerminateResponseCode.Unknown }); - } - } else if (Platform.isLinux || Platform.isMacintosh) { - try { - const cmd = FileAccess.asFileUri('vs/base/node/terminateProcess.sh', require).fsPath; - return new Promise(resolve => { - cp.execFile(cmd, [process.pid!.toString()], { encoding: 'utf8', shell: true } as cp.ExecFileOptions, (err, stdout, stderr) => { - if (err) { - resolve({ success: false, error: err }); - } else { - resolve({ success: true }); - } - }); - }); - } catch (err) { - return Promise.resolve({ success: false, error: err }); - } - } else { - process.kill('SIGKILL'); - } - return Promise.resolve({ success: true }); -} export function getWindowsShell(env = process.env as Platform.IProcessEnvironment): string { return env['comspec'] || 'cmd.exe'; } -export abstract class AbstractProcess { - private cmd: string; - private args: string[]; - private options: CommandOptions | ForkOptions; - protected shell: boolean; - - private childProcess: cp.ChildProcess | null; - protected childProcessPromise: Promise | null; - private pidResolve: ValueCallback | undefined; - protected terminateRequested: boolean; - - private static WellKnowCommands: IStringDictionary = { - 'ant': true, - 'cmake': true, - 'eslint': true, - 'gradle': true, - 'grunt': true, - 'gulp': true, - 'jake': true, - 'jenkins': true, - 'jshint': true, - 'make': true, - 'maven': true, - 'msbuild': true, - 'msc': true, - 'nmake': true, - 'npm': true, - 'rake': true, - 'tsc': true, - 'xbuild': true - }; - - public constructor(executable: Executable); - public constructor(cmd: string, args: string[] | undefined, shell: boolean, options: CommandOptions | undefined); - public constructor(arg1: string | Executable, arg2?: string[], arg3?: boolean, arg4?: CommandOptions) { - if (arg2 !== undefined && arg3 !== undefined && arg4 !== undefined) { - this.cmd = arg1; - this.args = arg2; - this.shell = arg3; - this.options = arg4; - } else { - const executable = arg1; - this.cmd = executable.command; - this.shell = executable.isShellCommand; - this.args = executable.args.slice(0); - this.options = executable.options || {}; - } - - this.childProcess = null; - this.childProcessPromise = null; - this.terminateRequested = false; - - if (this.options.env) { - const newEnv: IStringDictionary = Object.create(null); - Object.keys(process.env).forEach((key) => { - newEnv[key] = process.env[key]!; - }); - Object.keys(this.options.env).forEach((key) => { - newEnv[key] = this.options.env![key]!; - }); - this.options.env = newEnv; - } - } - - public getSanitizedCommand(): string { - let result = this.cmd.toLowerCase(); - const index = result.lastIndexOf(path.sep); - if (index !== -1) { - result = result.substring(index + 1); - } - if (AbstractProcess.WellKnowCommands[result]) { - return result; - } - return 'other'; - } - - public start(pp: ProgressCallback): Promise { - if (Platform.isWindows && ((this.options && this.options.cwd && extpath.isUNC(this.options.cwd)) || !this.options && extpath.isUNC(process.cwd()))) { - return Promise.reject(new Error(nls.localize('TaskRunner.UNC', 'Can\'t execute a shell command on a UNC drive.'))); - } - return this.useExec().then((useExec) => { - let cc: ValueCallback; - let ee: ErrorCallback; - const result = new Promise((c, e) => { - cc = c; - ee = e; - }); - - if (useExec) { - let cmd: string = this.cmd; - if (this.args) { - cmd = cmd + ' ' + this.args.join(' '); - } - this.childProcess = cp.exec(cmd, this.options, (error, stdout, stderr) => { - this.childProcess = null; - const err: any = error; - // This is tricky since executing a command shell reports error back in case the executed command return an - // error or the command didn't exist at all. So we can't blindly treat an error as a failed command. So we - // always parse the output and report success unless the job got killed. - if (err && err.killed) { - ee({ killed: this.terminateRequested, stdout: stdout.toString(), stderr: stderr.toString() }); - } else { - this.handleExec(cc, pp, error, stdout as any, stderr as any); - } - }); - } else { - let childProcess: cp.ChildProcess | null = null; - const closeHandler = (data: any) => { - this.childProcess = null; - this.childProcessPromise = null; - this.handleClose(data, cc, pp, ee); - const result: SuccessData = { - terminated: this.terminateRequested - }; - if (Types.isNumber(data)) { - result.cmdCode = data; - } - cc(result); - }; - if (this.shell && Platform.isWindows) { - const options: any = Objects.deepClone(this.options); - options.windowsVerbatimArguments = true; - options.detached = false; - let quotedCommand: boolean = false; - let quotedArg: boolean = false; - const commandLine: string[] = []; - let quoted = this.ensureQuotes(this.cmd); - commandLine.push(quoted.value); - quotedCommand = quoted.quoted; - if (this.args) { - this.args.forEach((elem) => { - quoted = this.ensureQuotes(elem); - commandLine.push(quoted.value); - quotedArg = quotedArg && quoted.quoted; - }); - } - const args: string[] = [ - '/s', - '/c', - ]; - if (quotedCommand) { - if (quotedArg) { - args.push('"' + commandLine.join(' ') + '"'); - } else if (commandLine.length > 1) { - args.push('"' + commandLine[0] + '"' + ' ' + commandLine.slice(1).join(' ')); - } else { - args.push('"' + commandLine[0] + '"'); - } - } else { - args.push(commandLine.join(' ')); - } - childProcess = cp.spawn(getWindowsShell(), args, options); - } else { - if (this.cmd) { - childProcess = cp.spawn(this.cmd, this.args, this.options); - } - } - if (childProcess) { - this.childProcess = childProcess; - this.childProcessPromise = Promise.resolve(childProcess); - if (this.pidResolve) { - this.pidResolve(Types.isNumber(childProcess.pid) ? childProcess.pid : -1); - this.pidResolve = undefined; - } - childProcess.on('error', (error: Error) => { - this.childProcess = null; - ee({ terminated: this.terminateRequested, error: error }); - }); - if (childProcess.pid) { - this.childProcess.on('close', closeHandler); - this.handleSpawn(childProcess, cc!, pp, ee!, true); - } - } - } - return result; - }); - } - - protected abstract handleExec(cc: ValueCallback, pp: ProgressCallback, error: Error | null, stdout: Buffer, stderr: Buffer): void; - protected abstract handleSpawn(childProcess: cp.ChildProcess, cc: ValueCallback, pp: ProgressCallback, ee: ErrorCallback, sync: boolean): void; - - protected handleClose(data: any, cc: ValueCallback, pp: ProgressCallback, ee: ErrorCallback): void { - // Default is to do nothing. - } - - private static readonly regexp = /^[^"].* .*[^"]/; - private ensureQuotes(value: string) { - if (AbstractProcess.regexp.test(value)) { - return { - value: '"' + value + '"', //`"${value}"`, - quoted: true - }; - } else { - return { - value: value, - quoted: value.length > 0 && value[0] === '"' && value[value.length - 1] === '"' - }; - } - } - - public get pid(): Promise { - if (this.childProcessPromise) { - return this.childProcessPromise.then(childProcess => childProcess.pid!, err => -1); - } else { - return new Promise((resolve) => { - this.pidResolve = resolve; - }); - } - } - - public terminate(): Promise { - if (!this.childProcessPromise) { - return Promise.resolve({ success: true }); - } - return this.childProcessPromise.then((childProcess) => { - this.terminateRequested = true; - return terminateProcess(childProcess, this.options.cwd).then(response => { - if (response.success) { - this.childProcess = null; - } - return response; - }); - }, (err) => { - return { success: true }; - }); - } - - private useExec(): Promise { - return new Promise(resolve => { - if (!this.shell || !Platform.isWindows) { - return resolve(false); - } - const cmdShell = cp.spawn(getWindowsShell(), ['/s', '/c']); - cmdShell.on('error', (error: Error) => { - return resolve(true); - }); - cmdShell.on('exit', (data: any) => { - return resolve(false); - }); - }); - } -} - -export class LineProcess extends AbstractProcess { - - private stdoutLineDecoder: LineDecoder | null; - private stderrLineDecoder: LineDecoder | null; - - public constructor(executable: Executable); - public constructor(cmd: string, args: string[], shell: boolean, options: CommandOptions); - public constructor(arg1: string | Executable, arg2?: string[], arg3?: boolean | ForkOptions, arg4?: CommandOptions) { - super(arg1, arg2, arg3, arg4); - - this.stdoutLineDecoder = null; - this.stderrLineDecoder = null; - } - - protected handleExec(cc: ValueCallback, pp: ProgressCallback, error: Error, stdout: Buffer, stderr: Buffer) { - [stdout, stderr].forEach((buffer: Buffer, index: number) => { - const lineDecoder = new LineDecoder(); - const lines = lineDecoder.write(buffer); - lines.forEach((line) => { - pp({ line: line, source: index === 0 ? Source.stdout : Source.stderr }); - }); - const line = lineDecoder.end(); - if (line) { - pp({ line: line, source: index === 0 ? Source.stdout : Source.stderr }); - } - }); - cc({ terminated: this.terminateRequested, error: error }); - } - - protected handleSpawn(childProcess: cp.ChildProcess, cc: ValueCallback, pp: ProgressCallback, ee: ErrorCallback, sync: boolean): void { - const stdoutLineDecoder = new LineDecoder(); - const stderrLineDecoder = new LineDecoder(); - childProcess.stdout!.on('data', (data: Buffer) => { - const lines = stdoutLineDecoder.write(data); - lines.forEach(line => pp({ line: line, source: Source.stdout })); - }); - childProcess.stderr!.on('data', (data: Buffer) => { - const lines = stderrLineDecoder.write(data); - lines.forEach(line => pp({ line: line, source: Source.stderr })); - }); - - this.stdoutLineDecoder = stdoutLineDecoder; - this.stderrLineDecoder = stderrLineDecoder; - } - - protected override handleClose(data: any, cc: ValueCallback, pp: ProgressCallback, ee: ErrorCallback): void { - const stdoutLine = this.stdoutLineDecoder ? this.stdoutLineDecoder.end() : null; - if (stdoutLine) { - pp({ line: stdoutLine, source: Source.stdout }); - } - const stderrLine = this.stderrLineDecoder ? this.stderrLineDecoder.end() : null; - if (stderrLine) { - pp({ line: stderrLine, source: Source.stderr }); - } - } -} - export interface IQueuedSender { send: (msg: any) => void; } diff --git a/src/vs/base/test/node/decoder.test.ts b/src/vs/base/test/node/decoder.test.ts deleted file mode 100644 index aa2e867c741..00000000000 --- a/src/vs/base/test/node/decoder.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; -import { LineDecoder } from 'vs/base/node/decoder'; - -suite('Decoder', () => { - - test('decoding', () => { - const lineDecoder = new LineDecoder(); - let res = lineDecoder.write(Buffer.from('hello')); - assert.strictEqual(res.length, 0); - - res = lineDecoder.write(Buffer.from('\nworld')); - assert.strictEqual(res[0], 'hello'); - assert.strictEqual(res.length, 1); - - assert.strictEqual(lineDecoder.end(), 'world'); - }); -}); From d859b334cbb314473b2fb763bcb2c57c93b785fe Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 4 Aug 2022 14:55:51 -0700 Subject: [PATCH 252/303] We only need to wait on the input box for un-supported environments (#157157) we only need to wait on the input box for un-supported environments --- extensions/microsoft-authentication/src/AADHelper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/microsoft-authentication/src/AADHelper.ts b/extensions/microsoft-authentication/src/AADHelper.ts index 4c3b9f2a38e..45e0f9a89f0 100644 --- a/extensions/microsoft-authentication/src/AADHelper.ts +++ b/extensions/microsoft-authentication/src/AADHelper.ts @@ -369,7 +369,7 @@ export class AzureActiveDirectoryService { existingPromise = this.handleCodeResponse(scopeData); } else { inputBox = vscode.window.createInputBox(); - existingPromise = Promise.race([this.handleCodeInputBox(inputBox, codeVerifier, scopeData), this.handleCodeResponse(scopeData)]); + existingPromise = this.handleCodeInputBox(inputBox, codeVerifier, scopeData); } this._codeExchangePromises.set(scopeData.scopeStr, existingPromise); } From 1fcf6d942f21a1de5e2664cca109c919c7966f76 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 4 Aug 2022 14:59:14 -0700 Subject: [PATCH 253/303] Remove unused messages in nb webview (#157158) --- .../notebook/browser/notebookEditorWidget.ts | 4 ++++ .../browser/view/renderers/backLayerWebView.ts | 17 ----------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index 80053311f5a..f802ab61bdc 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -2571,6 +2571,10 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD return; } + if (this.viewModel.getCellIndex(cell) === -1) { + return; + } + if (this.cellIsHidden(cell)) { return; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index c3b91419cef..fbf7324d65f 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1310,19 +1310,6 @@ var requirejs = (function() { }); } - clearInsets() { - if (this._disposed) { - return; - } - - this._sendMessageToWebview({ - type: 'clear' - }); - - this.insetMapping = new Map(); - this.reversedInsetMapping = new Map(); - } - focusWebview() { if (this._disposed) { return; @@ -1473,10 +1460,6 @@ var requirejs = (function() { this.webview?.postMessage(message); } - clearPreloadsCache() { - this._preloadsCache.clear(); - } - override dispose() { this._disposed = true; this.webview?.dispose(); From 631628bf3148512127657ee6d8ca0b2d330c91bd Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Thu, 4 Aug 2022 15:25:44 -0700 Subject: [PATCH 254/303] =?UTF-8?q?=F0=9F=86=99=20distro=20(#157161)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b447b323ee4..c9a24421f9c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.71.0", - "distro": "7dc7a14b0f0031128c799f96c856bd3290c3ebee", + "distro": "eb23fca20abeeed869f14d2581658864b99ba1e2", "author": { "name": "Microsoft Corporation" }, From 125ae4af2999c13096d8c1bb9d188b4c6e24bd0d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 15:29:29 -0700 Subject: [PATCH 255/303] Inline CurrentDragAndDropData (#157162) This type is only used by the list. It makes sense to move it into the list class instead of having it as a generic concept. We can always move it back if needed --- src/vs/base/browser/dnd.ts | 21 --------------------- src/vs/base/browser/ui/list/listView.ts | 6 +++++- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/src/vs/base/browser/dnd.ts b/src/vs/base/browser/dnd.ts index e1a0872271a..8b557e01bef 100644 --- a/src/vs/base/browser/dnd.ts +++ b/src/vs/base/browser/dnd.ts @@ -92,24 +92,3 @@ export interface IDragAndDropData { update(dataTransfer: DataTransfer): void; getData(): unknown; } - -export class DragAndDropData implements IDragAndDropData { - - constructor(private data: T) { } - - update(): void { - // noop - } - - getData(): T { - return this.data; - } -} - -export interface IStaticDND { - CurrentDragAndDropData: IDragAndDropData | undefined; -} - -export const StaticDND: IStaticDND = { - CurrentDragAndDropData: undefined -}; diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index a396809facb..7e9f2aecba6 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { isFirefox } from 'vs/base/browser/browser'; -import { DataTransfers, IDragAndDropData, StaticDND } from 'vs/base/browser/dnd'; +import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd'; import { $, addDisposableListener, animate, getContentHeight, getContentWidth, getTopLeftOffset, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; @@ -38,6 +38,10 @@ interface IItem { checkedDisposable: IDisposable; } +const StaticDND = { + CurrentDragAndDropData: undefined as IDragAndDropData | undefined +}; + export interface IListViewDragAndDrop extends IListDragAndDrop { getDragElements(element: T): T[]; } From 0eec29c2545b9a41bdcf19e77aea9c91bcc5de86 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 15:30:59 -0700 Subject: [PATCH 256/303] Remove dom.getElementsByTagName (#157163) This was just calling document.getElementsByTagName --- src/vs/base/browser/dom.ts | 4 ---- src/vs/base/browser/ui/sash/sash.ts | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index d378b5f6542..8ef36bb32ab 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -1155,10 +1155,6 @@ export function removeTabIndexAndUpdateFocus(node: HTMLElement): void { node.removeAttribute('tabindex'); } -export function getElementsByTagName(tag: string): HTMLElement[] { - return Array.prototype.slice.call(document.getElementsByTagName(tag), 0); -} - export function finalHandler(fn: (event: T) => any): (event: T) => any { return e => { e.preventDefault(); diff --git a/src/vs/base/browser/ui/sash/sash.ts b/src/vs/base/browser/ui/sash/sash.ts index 80ab505126e..4bc8ff1b8ee 100644 --- a/src/vs/base/browser/ui/sash/sash.ts +++ b/src/vs/base/browser/ui/sash/sash.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { $, append, createStyleSheet, EventHelper, EventLike, getElementsByTagName } from 'vs/base/browser/dom'; +import { $, append, createStyleSheet, EventHelper, EventLike } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { EventType, Gesture, GestureEvent } from 'vs/base/browser/touch'; import { Delayer } from 'vs/base/common/async'; @@ -493,7 +493,7 @@ export class Sash extends Disposable { return; } - const iframes = getElementsByTagName('iframe'); + const iframes = document.getElementsByTagName('iframe'); for (const iframe of iframes) { iframe.classList.add(PointerEventsDisabledCssClass); // disable mouse events on iframes as long as we drag the sash } From af6c12f97cc7543e262006e62e99222d225a572f Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Thu, 4 Aug 2022 15:36:37 -0700 Subject: [PATCH 257/303] enable WCO by default (#157140) --- src/vs/workbench/electron-sandbox/desktop.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts index 95e31623896..b41ce4d5aa7 100644 --- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts +++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts @@ -206,7 +206,7 @@ import product from 'vs/platform/product/common/product'; }, 'window.experimental.windowControlsOverlay.enabled': { 'type': 'boolean', - 'default': false, + 'default': true, 'scope': ConfigurationScope.APPLICATION, 'description': localize('windowControlsOverlay', "Use window controls provided by the platform instead of our HTML-based window controls. Changes require a full restart to apply."), 'included': isWindows From 35ed75909b8cd8da63a6b8ffb6982cb49e361ced Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Thu, 4 Aug 2022 15:39:54 -0700 Subject: [PATCH 258/303] use consistent key for reconnecting tasks (#157126) * fix #156899 * get full buffer line --- .../tasks/browser/terminalTaskSystem.ts | 9 +------- .../terminal/browser/xterm/xtermTerminal.ts | 23 ++++++++++++++++--- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 94352dcce88..f19a3df394f 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -963,13 +963,6 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { for (let i = bufferLines.length - 1; i >= 0; i--) { watchingProblemMatcher.processLine(bufferLines[i]); } - if (!delayer) { - delayer = new Async.Delayer(3000); - } - delayer.trigger(() => { - watchingProblemMatcher.forceDelivery(); - delayer = undefined; - }); } } else { [terminal, error] = await this._createTerminal(task, resolver, workspaceFolder); @@ -1444,7 +1437,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { this._terminalCreationQueue = this._terminalCreationQueue.then(() => this._doCreateTerminal(task, group, launchConfigs!)); const terminal: ITerminalInstance = (await this._terminalCreationQueue)!; - terminal.shellLaunchConfig.reconnectionProperties = { ownerId: ReconnectionType, data: { lastTask: taskKey, group, label: task._label, id: task._id } }; + terminal.shellLaunchConfig.reconnectionProperties = { ownerId: ReconnectionType, data: { lastTask: task.getRecentlyUsedKey(), group, label: task._label, id: task._id } }; const terminalKey = terminal.instanceId.toString(); const terminalData = { terminal: terminal, lastTask: taskKey, group }; terminal.onDisposed(() => this._deleteTaskAndTerminal(terminal, terminalData)); diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index d05f15bbe10..302dc530b17 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -50,6 +50,22 @@ let SerializeAddon: typeof SerializeAddonType; let Unicode11Addon: typeof Unicode11AddonType; let WebglAddon: typeof WebglAddonType; +function getFullBufferLineAsString(lineIndex: number, buffer: IBuffer): { lineData: string | undefined; lineIndex: number } { + let line = buffer.getLine(lineIndex); + if (!line) { + return { lineData: undefined, lineIndex }; + } + let lineData = line.translateToString(true); + while (lineIndex > 0 && line.isWrapped) { + line = buffer.getLine(--lineIndex); + if (!line) { + break; + } + lineData = line.translateToString(false) + lineData; + } + return { lineData, lineIndex }; +} + /** * Wraps the xterm object with additional functionality. Interaction with the backing process is out * of the scope of this class. @@ -60,9 +76,10 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II *getBufferReverseIterator(): IterableIterator { for (let i = this.raw.buffer.active.length; i >= 0; i--) { - const line = this.raw.buffer.active.getLine(i)?.translateToString().trim(); - if (line) { - yield line; + const { lineData, lineIndex } = getFullBufferLineAsString(i, this.raw.buffer.active); + if (lineData) { + i = lineIndex; + yield lineData; } } } From 5128ff1c6aa0bad9b0e6435ffac31b5791c24137 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 4 Aug 2022 17:42:07 -0500 Subject: [PATCH 259/303] Fix error when evaluating lazy expression that doesn't exist in the variables view (#157167) Fixes #154753 --- src/vs/workbench/contrib/debug/browser/variablesView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/variablesView.ts b/src/vs/workbench/contrib/debug/browser/variablesView.ts index d4e995fb9f1..aefd3c5c6b1 100644 --- a/src/vs/workbench/contrib/debug/browser/variablesView.ts +++ b/src/vs/workbench/contrib/debug/browser/variablesView.ts @@ -171,7 +171,7 @@ export class VariablesView extends ViewPane { } })); this._register(this.debugService.getViewModel().onDidEvaluateLazyExpression(async e => { - if (e instanceof Variable) { + if (e instanceof Variable && this.tree.hasNode(e)) { await this.tree.updateChildren(e, false, true); await this.tree.expand(e); } From 85c03e0238e4bfcb9754d2da4d6d66e8559fe66f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 16:05:07 -0700 Subject: [PATCH 260/303] clearNode should use `replaceChildren` (#157169) The new-ish `replaceChildren` api lets us quickly remove all children of an html element without having to iterate through the children --- src/vs/base/browser/dom.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 8ef36bb32ab..14a2556b333 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -19,9 +19,7 @@ import { withNullAsUndefined } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; export function clearNode(node: HTMLElement): void { - while (node.firstChild) { - node.firstChild.remove(); - } + node.replaceChildren(); } /** From 508486f886982c48c8acd97103b185323870b6e4 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 16:07:38 -0700 Subject: [PATCH 261/303] Try using AbortController for disposable dom listeners This makes `addDisposableListener` use an abortcontroller to unregister the listener. This lets us avoid having to null out references to the handler and the node --- src/vs/base/browser/dom.ts | 56 ++++++++++++-------------------------- 1 file changed, 17 insertions(+), 39 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 8ef36bb32ab..a760dcec833 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -31,40 +31,20 @@ export function isInDOM(node: Node | null): boolean { return node?.isConnected ?? false; } -class DomListener implements IDisposable { - - private _handler: (e: any) => void; - private _node: EventTarget; - private readonly _type: string; - private readonly _options: boolean | AddEventListenerOptions; - - constructor(node: EventTarget, type: string, handler: (e: any) => void, options?: boolean | AddEventListenerOptions) { - this._node = node; - this._type = type; - this._handler = handler; - this._options = (options || false); - this._node.addEventListener(this._type, this._handler, this._options); - } - - public dispose(): void { - if (!this._handler) { - // Already disposed - return; - } - - this._node.removeEventListener(this._type, this._handler, this._options); - - // Prevent leakers from holding on to the dom or handler func - this._node = null!; - this._handler = null!; - } -} - -export function addDisposableListener(node: EventTarget, type: K, handler: (event: GlobalEventHandlersEventMap[K]) => void, useCapture?: boolean): IDisposable; -export function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable; -export function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, options: AddEventListenerOptions): IDisposable; +export function addDisposableListener(node: EventTarget, type: K, handler: (event: GlobalEventHandlersEventMap[K]) => void, useCaptureOrOptions?: boolean | AddEventListenerOptions): IDisposable; +export function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCaptureOrOptions?: boolean | AddEventListenerOptions): IDisposable; export function addDisposableListener(node: EventTarget, type: string, handler: (event: any) => void, useCaptureOrOptions?: boolean | AddEventListenerOptions): IDisposable { - return new DomListener(node, type, handler, useCaptureOrOptions); + let controller: AbortController | undefined = new AbortController(); + + const opts: AddEventListenerOptions = typeof useCaptureOrOptions === 'boolean' + ? { capture: useCaptureOrOptions, signal: controller.signal } + : { signal: controller.signal, ...(useCaptureOrOptions ?? {}) }; + + node.addEventListener(type, handler, opts); + return toDisposable(() => { + controller?.abort(); + controller = undefined; + }); } export interface IAddStandardDisposableListenerSignature { @@ -124,18 +104,16 @@ export function addDisposableGenericMouseUpListener(node: EventTarget, handler: } export function createEventEmitter(target: HTMLElement, type: K, options?: boolean | AddEventListenerOptions): event.Emitter { - let domListener: DomListener | null = null; + let domListener: IDisposable | undefined = undefined; const handler = (e: HTMLElementEventMap[K]) => result.fire(e); const onFirstListenerAdd = () => { if (!domListener) { - domListener = new DomListener(target, type, handler, options); + domListener = addDisposableListener(target, type, handler, options); } }; const onLastListenerRemove = () => { - if (domListener) { - domListener.dispose(); - domListener = null; - } + domListener?.dispose(); + domListener = undefined; }; const result = new event.Emitter({ onFirstListenerAdd, onLastListenerRemove }); return result; From 1917657bd0531633d50b855ab83db1967e5bf695 Mon Sep 17 00:00:00 2001 From: Najmieh Sadat <98463228+najmiehsa@users.noreply.github.com> Date: Fri, 5 Aug 2022 03:47:18 +0430 Subject: [PATCH 262/303] Changed the method in the indexTreeModel.test.ts (#148948) * Changed the method in the indexTreeModel.test.ts * Edited the method and the location Co-authored-by: najmieh Co-authored-by: Connor Peet --- src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts b/src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts index 91e83ec4476..9ae0e08b0f1 100644 --- a/src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts +++ b/src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts @@ -358,7 +358,7 @@ suite('IndexTreeModel', () => { assert.deepStrictEqual(list.length, 3); - model.setCollapsed([0], false); + model.expandTo([0, 1]); assert.deepStrictEqual(list.length, 6); assert.deepStrictEqual(list[0].element, 0); assert.deepStrictEqual(list[0].collapsed, false); From 81bc5f3326c6b1769fa9b1dea9a1a739e6d7b347 Mon Sep 17 00:00:00 2001 From: Mikhail Po <8371890+dirondin@users.noreply.github.com> Date: Fri, 5 Aug 2022 02:22:11 +0300 Subject: [PATCH 263/303] Fix #147912 (multipleSessionWarning debug option) (#147914) * Fix #147912 (multipleSessionWarning debug option) * Fix #147912 (suppressMultipleSessionWarning debug option) * Fix description and condition Co-authored-by: Rob Lourens --- .../workbench/contrib/debug/browser/debugAdapterManager.ts | 5 +++++ src/vs/workbench/contrib/debug/browser/debugService.ts | 2 +- src/vs/workbench/contrib/debug/common/debug.ts | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts b/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts index c4fbab00e3a..7f08c57a578 100644 --- a/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts @@ -171,6 +171,11 @@ export class AdapterManager extends Disposable implements IAdapterManager { }, 'presentation': presentationSchema, 'internalConsoleOptions': INTERNAL_CONSOLE_OPTIONS_SCHEMA, + 'suppressMultipleSessionWarning': { + type: 'boolean', + description: nls.localize('suppressMultipleSessionWarning', "Disable the warning when trying to start the same debug configuration more than once."), + default: true + } } } }; diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index 6ecdf57aa2f..0cf0497bec2 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -544,7 +544,7 @@ export class DebugService implements IDebugService { private async doCreateSession(sessionId: string, root: IWorkspaceFolder | undefined, configuration: { resolved: IConfig; unresolved: IConfig | undefined }, options?: IDebugSessionOptions): Promise { const session = this.instantiationService.createInstance(DebugSession, sessionId, configuration, root, this.model, options); - if (options?.startedByUser && this.model.getSessions().some(s => s.getLabel() === session.getLabel())) { + if (options?.startedByUser && this.model.getSessions().some(s => s.getLabel() === session.getLabel()) && configuration.resolved.suppressMultipleSessionWarning !== true) { // There is already a session with the same name, prompt user #127721 const result = await this.dialogService.confirm({ message: nls.localize('multipleSession', "'{0}' is already running. Do you want to start another instance?", session.getLabel()) }); if (!result.confirmed) { diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index 44fec50c3d1..027588ad529 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -667,6 +667,7 @@ export interface IEnvConfig { postDebugTask?: string | ITaskIdentifier; debugServer?: number; noDebug?: boolean; + suppressMultipleSessionWarning?: boolean; } export interface IConfigPresentation { From a43e9acd682e4ba583240aaa720ed9e589f629a6 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 16:26:18 -0700 Subject: [PATCH 264/303] Add AbortController to core types --- build/lib/layersChecker.js | 1 + build/lib/layersChecker.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/build/lib/layersChecker.js b/build/lib/layersChecker.js index 2580ebe4e3a..29bc918be45 100644 --- a/build/lib/layersChecker.js +++ b/build/lib/layersChecker.js @@ -51,6 +51,7 @@ const CORE_TYPES = [ 'BigInt64Array', 'btoa', 'atob', + 'AbortController', 'AbortSignal', 'MessageChannel', 'MessagePort', diff --git a/build/lib/layersChecker.ts b/build/lib/layersChecker.ts index 7e93c1413b0..a6f71473867 100644 --- a/build/lib/layersChecker.ts +++ b/build/lib/layersChecker.ts @@ -52,6 +52,7 @@ const CORE_TYPES = [ 'BigInt64Array', 'btoa', 'atob', + 'AbortController', 'AbortSignal', 'MessageChannel', 'MessagePort', From a6e87ed2eb7357a0dcfe458a4761551101b879c5 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 4 Aug 2022 17:08:32 -0700 Subject: [PATCH 265/303] Handle edge case if fig is installed/activated --- src/vs/platform/terminal/node/terminalProcess.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/terminal/node/terminalProcess.ts b/src/vs/platform/terminal/node/terminalProcess.ts index ad3dce8b523..a8e86c1201e 100644 --- a/src/vs/platform/terminal/node/terminalProcess.ts +++ b/src/vs/platform/terminal/node/terminalProcess.ts @@ -403,7 +403,9 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess } this._currentTitle = ptyProcess.process; this._onDidChangeProperty.fire({ type: ProcessPropertyType.Title, value: this._currentTitle }); - this._onDidChangeProperty.fire({ type: ProcessPropertyType.ShellType, value: posixShellTypeMap.get(this.currentTitle) }); + // If fig is installed it may change the title of the process + const sanitizedTitle = this.currentTitle.replace(/ \(figterm\)$/g, ''); + this._onDidChangeProperty.fire({ type: ProcessPropertyType.ShellType, value: posixShellTypeMap.get(sanitizedTitle) }); } shutdown(immediate: boolean): void { From 7ab8872dfe15197108be3bf817706190fc05b23c Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 20:01:07 -0700 Subject: [PATCH 266/303] Fix interactive and untitled notebook base uri (#157198) Fixes #133698 For untitled/interactive, we should use the workspace as the base uri instead of using the notebook uri (which isn't meaningful in this case) --- .../view/renderers/backLayerWebView.ts | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index fbf7324d65f..a82b4e723cf 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -440,7 +440,7 @@ export class BackLayerWebView extends Disposable { } async createWebview(): Promise { - const baseUrl = this.asWebviewUri(dirname(this.documentUri), undefined); + const baseUrl = this.asWebviewUri(this.getNotebookBaseUri(), undefined); // Python notebooks assume that requirejs is a global. // For all other notebooks, they need to provide their own loader. @@ -504,6 +504,22 @@ var requirejs = (function() { await this._initialized; } + private getNotebookBaseUri() { + if (this.documentUri.scheme === Schemas.untitled || this.documentUri.scheme === Schemas.vscodeInteractive) { + const folder = this.workspaceContextService.getWorkspaceFolder(this.documentUri); + if (folder) { + return folder.uri; + } + + const folders = this.workspaceContextService.getWorkspace().folders; + if (folders.length) { + return folders[0].uri; + } + } + + return dirname(this.documentUri); + } + private getBuiltinLocalResourceRoots(): URI[] { // Python notebooks assume that requirejs is a global. // For all other notebooks, they need to provide their own loader. @@ -884,7 +900,7 @@ var requirejs = (function() { private _createInset(webviewService: IWebviewService, content: string) { const workspaceFolders = this.contextService.getWorkspace().folders.map(x => x.uri); - const notebookDir = dirname(this.documentUri); + const notebookDir = this.getNotebookBaseUri(); this.localResourceRootsCache = [ ...this.notebookService.getNotebookProviderResourceRoots(), From 5908f177507f160e8d402c59b619a00ec52ed6b8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 21:21:59 -0700 Subject: [PATCH 267/303] Remove a few IE8 conditions (#157179) These should no longer be needed --- src/vs/base/browser/dom.ts | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 14a2556b333..1fce5d53ada 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -361,16 +361,8 @@ class SizeUtils { } private static getDimension(element: HTMLElement, cssPropertyName: string, jsPropertyName: string): number { - const computedStyle: CSSStyleDeclaration = getComputedStyle(element); - let value = '0'; - if (computedStyle) { - if (computedStyle.getPropertyValue) { - value = computedStyle.getPropertyValue(cssPropertyName); - } else { - // IE8 - value = (computedStyle).getAttribute(jsPropertyName); - } - } + const computedStyle = getComputedStyle(element); + const value = computedStyle ? computedStyle.getPropertyValue(cssPropertyName) : '0'; return SizeUtils.convertToPixels(element, value); } @@ -891,20 +883,9 @@ export interface EventLike { export const EventHelper = { stop: function (e: EventLike, cancelBubble?: boolean) { - if (e.preventDefault) { - e.preventDefault(); - } else { - // IE8 - (e).returnValue = false; - } - + e.preventDefault(); if (cancelBubble) { - if (e.stopPropagation) { - e.stopPropagation(); - } else { - // IE8 - (e).cancelBubble = true; - } + e.stopPropagation(); } } }; From 5589b81019babf3ff21c3e3a67d63cd942187ce2 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 21:22:28 -0700 Subject: [PATCH 268/303] Remove IStandardWindow (#157181) This was added to support old IE versions which we no longer support https://github.com/microsoft/monaco-editor/issues/26 --- src/vs/base/browser/dom.ts | 28 ++----------------- src/vs/editor/browser/editorDom.ts | 4 +-- .../contentWidgets/contentWidgets.ts | 6 ++-- 3 files changed, 7 insertions(+), 31 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 1fce5d53ada..1ff6fda0127 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -531,8 +531,8 @@ export function position(element: HTMLElement, top: number, right?: number, bott export function getDomNodePagePosition(domNode: HTMLElement): IDomNodePagePosition { const bb = domNode.getBoundingClientRect(); return { - left: bb.left + StandardWindow.scrollX, - top: bb.top + StandardWindow.scrollY, + left: bb.left + window.scrollX, + top: bb.top + window.scrollY, width: bb.width, height: bb.height }; @@ -556,30 +556,6 @@ export function getDomNodeZoomLevel(domNode: HTMLElement): number { return zoom; } -export interface IStandardWindow { - readonly scrollX: number; - readonly scrollY: number; -} - -export const StandardWindow: IStandardWindow = new class implements IStandardWindow { - get scrollX(): number { - if (typeof window.scrollX === 'number') { - // modern browsers - return window.scrollX; - } else { - return document.body.scrollLeft + document.documentElement!.scrollLeft; - } - } - - get scrollY(): number { - if (typeof window.scrollY === 'number') { - // modern browsers - return window.scrollY; - } else { - return document.body.scrollTop + document.documentElement!.scrollTop; - } - } -}; // Adapted from WinJS // Gets the width of the element, including margins. diff --git a/src/vs/editor/browser/editorDom.ts b/src/vs/editor/browser/editorDom.ts index cd36e6c200e..4cfc92f8a6e 100644 --- a/src/vs/editor/browser/editorDom.ts +++ b/src/vs/editor/browser/editorDom.ts @@ -24,7 +24,7 @@ export class PageCoordinates { ) { } public toClientCoordinates(): ClientCoordinates { - return new ClientCoordinates(this.x - dom.StandardWindow.scrollX, this.y - dom.StandardWindow.scrollY); + return new ClientCoordinates(this.x - window.scrollX, this.y - window.scrollY); } } @@ -44,7 +44,7 @@ export class ClientCoordinates { ) { } public toPageCoordinates(): PageCoordinates { - return new PageCoordinates(this.clientX + dom.StandardWindow.scrollX, this.clientY + dom.StandardWindow.scrollY); + return new PageCoordinates(this.clientX + window.scrollX, this.clientY + window.scrollY); } } diff --git a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts index 056c24f5c73..f45578d9f15 100644 --- a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts +++ b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts @@ -340,7 +340,7 @@ class Widget { const MIN_LIMIT = Math.max(0, domNodePosition.left - width); const MAX_LIMIT = Math.min(domNodePosition.left + domNodePosition.width + width, windowSize.width); - let absoluteLeft = domNodePosition.left + left - dom.StandardWindow.scrollX; + let absoluteLeft = domNodePosition.left + left - window.scrollX; if (absoluteLeft + width > MAX_LIMIT) { const delta = absoluteLeft - (MAX_LIMIT - width); @@ -362,8 +362,8 @@ class Widget { const belowTop = bottomLeft.top + this._lineHeight; const domNodePosition = dom.getDomNodePagePosition(this._viewDomNode.domNode); - const absoluteAboveTop = domNodePosition.top + aboveTop - dom.StandardWindow.scrollY; - const absoluteBelowTop = domNodePosition.top + belowTop - dom.StandardWindow.scrollY; + const absoluteAboveTop = domNodePosition.top + aboveTop - window.scrollY; + const absoluteBelowTop = domNodePosition.top + belowTop - window.scrollY; const windowSize = dom.getClientArea(document.body); const [aboveLeft, absoluteAboveLeft] = this._layoutHorizontalSegmentInPage(windowSize, domNodePosition, topLeft.left - ctx.scrollLeft + this._contentLeft, width); From b012216211e7f9eb6c24ac8690e5d073f9fb9081 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 21:31:42 -0700 Subject: [PATCH 269/303] Fix markdown images having duplicate ids (#157177) Fixes #153144 --- .../src/markdownEngine.ts | 13 +++------- .../src/preview/documentRenderer.ts | 4 +-- .../src/preview/preview.ts | 4 +-- .../src/test/engine.test.ts | 25 ++++++++++--------- .../src/util/hash.ts | 16 ------------ 5 files changed, 20 insertions(+), 42 deletions(-) delete mode 100644 extensions/markdown-language-features/src/util/hash.ts diff --git a/extensions/markdown-language-features/src/markdownEngine.ts b/extensions/markdown-language-features/src/markdownEngine.ts index b8d060e2099..9f7142fc91a 100644 --- a/extensions/markdown-language-features/src/markdownEngine.ts +++ b/extensions/markdown-language-features/src/markdownEngine.ts @@ -11,7 +11,6 @@ import { MarkdownContributionProvider } from './markdownExtensions'; import { Slugifier } from './slugify'; import { ITextDocument } from './types/textDocument'; import { Disposable } from './util/dispose'; -import { stringHash } from './util/hash'; import { WebviewResourceProvider } from './util/resources'; import { isOfScheme, Schemes } from './util/schemes'; import { MdDocumentInfoCache } from './util/workspaceCache'; @@ -86,11 +85,11 @@ class TokenCache { export interface RenderOutput { html: string; - containingImages: { src: string }[]; + containingImages: Set; } interface RenderEnv { - containingImages: { src: string }[]; + containingImages: Set; currentDocument: vscode.Uri | undefined; resourceProvider: WebviewResourceProvider | undefined; } @@ -209,7 +208,7 @@ export class MarkdownItEngine implements IMdParser { : this.tokenizeDocument(input, config, engine); const env: RenderEnv = { - containingImages: [], + containingImages: new Set(), currentDocument: typeof input === 'string' ? undefined : input.uri, resourceProvider, }; @@ -248,13 +247,9 @@ export class MarkdownItEngine implements IMdParser { const original = md.renderer.rules.image; md.renderer.rules.image = (tokens: Token[], idx: number, options, env: RenderEnv, self) => { const token = tokens[idx]; - token.attrJoin('class', 'loading'); - const src = token.attrGet('src'); if (src) { - env.containingImages?.push({ src }); - const imgHash = stringHash(src); - token.attrSet('id', `image-hash-${imgHash}`); + env.containingImages?.add(src); if (!token.attrGet('data-src')) { token.attrSet('src', this.toResourceUri(src, env.currentDocument, env.resourceProvider)); diff --git a/extensions/markdown-language-features/src/preview/documentRenderer.ts b/extensions/markdown-language-features/src/preview/documentRenderer.ts index 28e25cef6ef..8acbb9db2a9 100644 --- a/extensions/markdown-language-features/src/preview/documentRenderer.ts +++ b/extensions/markdown-language-features/src/preview/documentRenderer.ts @@ -38,7 +38,7 @@ const previewStrings = { export interface MarkdownContentProviderOutput { html: string; - containingImages: { src: string }[]; + containingImages: Set; } @@ -88,7 +88,7 @@ export class MdDocumentRenderer { const body = await this.renderBody(markdownDocument, resourceProvider); if (token.isCancellationRequested) { - return { html: '', containingImages: [] }; + return { html: '', containingImages: new Set() }; } const html = ` diff --git a/extensions/markdown-language-features/src/preview/preview.ts b/extensions/markdown-language-features/src/preview/preview.ts index 6e792d36edc..6ce2b644f1c 100644 --- a/extensions/markdown-language-features/src/preview/preview.ts +++ b/extensions/markdown-language-features/src/preview/preview.ts @@ -396,9 +396,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { } } - private updateImageWatchers(containingImages: { src: string }[]) { - const srcs = new Set(containingImages.map(img => img.src)); - + private updateImageWatchers(srcs: Set) { // Delete stale file watchers. for (const [src, watcher] of this._fileWatchersBySrc) { if (!srcs.has(src)) { diff --git a/extensions/markdown-language-features/src/test/engine.test.ts b/extensions/markdown-language-features/src/test/engine.test.ts index c0644ee20d9..424844d1ad7 100644 --- a/extensions/markdown-language-features/src/test/engine.test.ts +++ b/extensions/markdown-language-features/src/test/engine.test.ts @@ -30,22 +30,23 @@ suite('markdown.engine', () => { }); }); - suite('image-caching', () => { + suite.only('image-caching', () => { const input = '![](img.png) [](no-img.png) ![](http://example.org/img.png) ![](img.png) ![](./img2.png)'; test('Extracts all images', async () => { const engine = createNewMarkdownEngine(); - assert.deepStrictEqual((await engine.render(input)), { - html: '

' - + ' ' - + ' ' - + ' ' - + ' ' - + '' - + '

\n' - , - containingImages: [{ src: 'img.png' }, { src: 'http://example.org/img.png' }, { src: 'img.png' }, { src: './img2.png' }], - }); + const result = await engine.render(input); + assert.deepStrictEqual(result.html, + '

' + + ' ' + + ' ' + + ' ' + + ' ' + + '' + + '

\n' + ); + + assert.deepStrictEqual([...result.containingImages], ['img.png', 'http://example.org/img.png', './img2.png']); }); }); }); diff --git a/extensions/markdown-language-features/src/util/hash.ts b/extensions/markdown-language-features/src/util/hash.ts deleted file mode 100644 index 36365f18fd6..00000000000 --- a/extensions/markdown-language-features/src/util/hash.ts +++ /dev/null @@ -1,16 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -function numberHash(val: number, initialHashVal: number): number { - return (((initialHashVal << 5) - initialHashVal) + val) | 0; // hashVal * 31 + ch, keep as int32 -} - -export function stringHash(s: string) { - let hashVal = numberHash(149417, 0); - for (let i = 0, length = s.length; i < length; i++) { - hashVal = numberHash(s.charCodeAt(i), hashVal); - } - return hashVal; -} From 7b5e82ebcfaa165b1446ae81df19f71c9ea821d7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 21:32:02 -0700 Subject: [PATCH 270/303] Rename context to align with other webview context keys (#157174) For #30066 --- src/vs/workbench/contrib/webview/browser/webviewElement.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 73c6baaf38e..08cc8253839 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -116,6 +116,8 @@ interface WebviewActionContext { [key: string]: unknown; } +const webviewIdContext = 'webviewId'; + export class WebviewElement extends Disposable implements IWebview, WebviewFindDelegate { /** @@ -342,7 +344,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD getActions: () => { const contextKeyService = this._contextKeyService!.createOverlay([ ...Object.entries(data.context), - ['webview', this.providedViewType], + [webviewIdContext, this.providedViewType], ]); const result: IAction[] = []; From 07e45c5a71b338bac1815417f4c69d29cd643d05 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 4 Aug 2022 21:40:06 -0700 Subject: [PATCH 271/303] Fix package version (#157202) Not sure why this was not caught by earlier builds --- .../server/package.json | 2 +- .../markdown-language-features/server/yarn.lock | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/extensions/markdown-language-features/server/package.json b/extensions/markdown-language-features/server/package.json index ada9661b0b2..ee4d642a4c6 100644 --- a/extensions/markdown-language-features/server/package.json +++ b/extensions/markdown-language-features/server/package.json @@ -10,7 +10,7 @@ "main": "./out/node/main", "browser": "./dist/browser/main", "dependencies": { - "vscode-languageserver": "^8.0.2`", + "vscode-languageserver": "^8.0.2", "vscode-languageserver-textdocument": "^1.0.5", "vscode-languageserver-types": "^3.17.1", "vscode-markdown-languageservice": "^0.0.0-alpha.13", diff --git a/extensions/markdown-language-features/server/yarn.lock b/extensions/markdown-language-features/server/yarn.lock index e01f1001c29..6d8871a746a 100644 --- a/extensions/markdown-language-features/server/yarn.lock +++ b/extensions/markdown-language-features/server/yarn.lock @@ -3,9 +3,9 @@ "@types/node@16.x": - version "16.11.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.43.tgz#555e5a743f76b6b897d47f945305b618525ddbe6" - integrity sha512-GqWykok+3uocgfAJM8imbozrqLnPyTrpFlrryURQlw1EesPUCx5XxTiucWDSFF9/NUEXDuD4bnvHm8xfVGWTpQ== + version "16.11.47" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.47.tgz#efa9e3e0f72e7aa6a138055dace7437a83d9f91c" + integrity sha512-fpP+jk2zJ4VW66+wAMFoBJlx1bxmBKx4DUFf68UHgdGCOuyUTDlLWqsaNPJh7xhNDykyJ9eIzAygilP/4WoN8g== picomatch@^2.3.1: version "2.3.1" @@ -30,17 +30,12 @@ vscode-languageserver-textdocument@^1.0.5: resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.5.tgz#838769940ece626176ec5d5a2aa2d0aa69f5095c" integrity sha512-1ah7zyQjKBudnMiHbZmxz5bYNM9KKZYz+5VQLj+yr8l+9w3g+WAhCkUkWbhMEdC5u0ub4Ndiye/fDyS8ghIKQg== -vscode-languageserver-types@3.17.2: +vscode-languageserver-types@3.17.2, vscode-languageserver-types@^3.17.1: version "3.17.2" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz#b2c2e7de405ad3d73a883e91989b850170ffc4f2" integrity sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA== -vscode-languageserver-types@^3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.1.tgz#c2d87fa7784f8cac389deb3ff1e2d9a7bef07e16" - integrity sha512-K3HqVRPElLZVVPtMeKlsyL9aK0GxGQpvtAUTfX4k7+iJ4mc1M+JM+zQwkgGy2LzY0f0IAafe8MKqIkJrxfGGjQ== - -vscode-languageserver@^8.0.2`: +vscode-languageserver@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.2.tgz#cfe2f0996d9dfd40d3854e786b2821604dfec06d" integrity sha512-bpEt2ggPxKzsAOZlXmCJ50bV7VrxwCS5BI4+egUmure/oI/t4OlFzi/YNtVvY24A2UDOZAgwFGgnZPwqSJubkA== From 73fd3f11032e7b83c2ae011b5516e6ddd19e3db2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 5 Aug 2022 09:16:20 +0200 Subject: [PATCH 272/303] fix build (#157217) * fix build * fix compile * flaky * . --- build/lib/policies.js | 16 ++++++++++++++-- build/lib/policies.ts | 14 ++++++++++++-- .../singlefolder-tests/notebook.document.test.ts | 2 +- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/build/lib/policies.js b/build/lib/policies.js index 7b1bbdf394a..83ca05abc89 100644 --- a/build/lib/policies.js +++ b/build/lib/policies.js @@ -438,8 +438,20 @@ async function getNLS(resourceUrlTemplate, languageId, version) { } catch (err) { if (/\[404\]/.test(err.message)) { - console.warn(`Language pack ${languageId}@${version} is missing. Downloading previous version...`); - return await getSpecificNLS(resourceUrlTemplate, languageId, previousVersion(version)); + const thePreviousVersion = previousVersion(version); + console.warn(`Language pack ${languageId}@${version} is missing. Downloading previous version ${thePreviousVersion}...`); + try { + return await getSpecificNLS(resourceUrlTemplate, languageId, thePreviousVersion); + } + catch (err) { + if (/\[404\]/.test(err.message)) { + console.warn(`Language pack ${languageId}@${thePreviousVersion} is missing. Downloading previous version...`); + return await getSpecificNLS(resourceUrlTemplate, languageId, previousVersion(thePreviousVersion)); + } + else { + throw err; + } + } } else { throw err; diff --git a/build/lib/policies.ts b/build/lib/policies.ts index eaa8cb719a2..cd3997e4e1d 100644 --- a/build/lib/policies.ts +++ b/build/lib/policies.ts @@ -622,8 +622,18 @@ async function getNLS(resourceUrlTemplate: string, languageId: string, version: return await getSpecificNLS(resourceUrlTemplate, languageId, version); } catch (err) { if (/\[404\]/.test(err.message)) { - console.warn(`Language pack ${languageId}@${version} is missing. Downloading previous version...`); - return await getSpecificNLS(resourceUrlTemplate, languageId, previousVersion(version)); + const thePreviousVersion = previousVersion(version); + console.warn(`Language pack ${languageId}@${version} is missing. Downloading previous version ${thePreviousVersion}...`); + try { + return await getSpecificNLS(resourceUrlTemplate, languageId, thePreviousVersion); + } catch (err) { + if (/\[404\]/.test(err.message)) { + console.warn(`Language pack ${languageId}@${thePreviousVersion} is missing. Downloading previous version...`); + return await getSpecificNLS(resourceUrlTemplate, languageId, previousVersion(thePreviousVersion)); + } else { + throw err; + } + } } else { throw err; } diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts index 1f34fc7998f..3a28ea9909f 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.document.test.ts @@ -423,7 +423,7 @@ suite('Notebook Document', function () { assert.strictEqual(document.isDirty, false); }); - test('onDidOpenNotebookDocument - emit event only once when opened in two editors', async function () { + test.skip('onDidOpenNotebookDocument - emit event only once when opened in two editors', async function () { // TODO@rebornix https://github.com/microsoft/vscode/issues/157222 const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest'); let counter = 0; testDisposables.push(vscode.workspace.onDidOpenNotebookDocument(nb => { From cc068ee992b67960509fd14ce485c73cfd718c1f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 5 Aug 2022 12:06:07 +0200 Subject: [PATCH 273/303] sandbox - log if sandboxed in telemetry (#157221) * sandbox - log if sandboxed in telemetry * add todo --- .../telemetry/electron-sandbox/workbenchCommonProperties.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/services/telemetry/electron-sandbox/workbenchCommonProperties.ts b/src/vs/workbench/services/telemetry/electron-sandbox/workbenchCommonProperties.ts index 83f9b2c2a7b..d04876a17b7 100644 --- a/src/vs/workbench/services/telemetry/electron-sandbox/workbenchCommonProperties.ts +++ b/src/vs/workbench/services/telemetry/electron-sandbox/workbenchCommonProperties.ts @@ -38,6 +38,8 @@ export async function resolveWorkbenchCommonProperties( result['common.isNewSession'] = !lastSessionDate ? '1' : '0'; // __GDPR__COMMON__ "common.remoteAuthority" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } result['common.remoteAuthority'] = cleanRemoteAuthority(remoteAuthority); + // __GDPR__COMMON__ "common.sandboxed" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + result['common.sandboxed'] = process.sandboxed ? '1' : '0'; // TODO@bpasero remove this property when sandbox is on return result; } From ce5685e34fdd18b7feb70d092c9c696bdaa1e4da Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 5 Aug 2022 13:30:32 +0200 Subject: [PATCH 274/303] themes - disable window border on windows (#157223) --- src/vs/platform/window/common/window.ts | 10 ---------- src/vs/workbench/browser/layout.ts | 9 +++++++-- src/vs/workbench/common/theme.ts | 4 ++-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/vs/platform/window/common/window.ts b/src/vs/platform/window/common/window.ts index e25a1573fed..f50c4f9b38d 100644 --- a/src/vs/platform/window/common/window.ts +++ b/src/vs/platform/window/common/window.ts @@ -138,11 +138,6 @@ export interface IWindowSettings { readonly experimental?: { useSandbox: boolean }; } -interface IWindowBorderColors { - readonly 'window.activeBorder'?: string; - readonly 'window.inactiveBorder'?: string; -} - export function getTitleBarStyle(configurationService: IConfigurationService): 'native' | 'custom' { if (isWeb) { return 'custom'; @@ -160,11 +155,6 @@ export function getTitleBarStyle(configurationService: IConfigurationService): ' return 'native'; // simple fullscreen does not work well with custom title style (https://github.com/microsoft/vscode/issues/63291) } - const colorCustomizations = configurationService.getValue('workbench.colorCustomizations'); - if (colorCustomizations?.['window.activeBorder'] || colorCustomizations?.['window.inactiveBorder']) { - return 'custom'; // window border colors do not work with native title style - } - const style = configuration.titleBarStyle; if (style === 'native' || style === 'custom') { return style; diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index ef74671541d..ec50fb9eff1 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -320,7 +320,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Change edge snapping accordingly this.workbenchGrid.edgeSnapping = this.windowState.runtime.fullscreen; - // Changing fullscreen state of the window has an impact on custom title bar visibility, so we need to update + // Changing fullscreen state of the window has an impact + // on custom title bar visibility, so we need to update if (getTitleBarStyle(this.configurationService) === 'custom') { // Propagate to grid @@ -386,7 +387,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } private updateWindowBorder(skipLayout: boolean = false) { - if (isWeb || getTitleBarStyle(this.configurationService) !== 'custom') { + if ( + isWeb || + isWindows || // not working well with zooming and window control overlays + getTitleBarStyle(this.configurationService) !== 'custom' + ) { return; } diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index 7258b951aff..4c7a41c2fcb 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -860,11 +860,11 @@ export const WINDOW_ACTIVE_BORDER = registerColor('window.activeBorder', { light: null, hcDark: contrastBorder, hcLight: contrastBorder -}, localize('windowActiveBorder', "The color used for the border of the window when it is active. Only supported in the desktop client when using the custom title bar.")); +}, localize('windowActiveBorder', "The color used for the border of the window when it is active. Only supported in the macOS and Linux desktop client when using the custom title bar.")); export const WINDOW_INACTIVE_BORDER = registerColor('window.inactiveBorder', { dark: null, light: null, hcDark: contrastBorder, hcLight: contrastBorder -}, localize('windowInactiveBorder', "The color used for the border of the window when it is inactive. Only supported in the desktop client when using the custom title bar.")); +}, localize('windowInactiveBorder', "The color used for the border of the window when it is inactive. Only supported in the macOS and Linux desktop client when using the custom title bar.")); From e60f7a9d8ad9c146325f8968a48e53f43fc1a2b4 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 5 Aug 2022 13:40:01 +0200 Subject: [PATCH 275/303] actionViewItem - make sure to also set the aira-label on the label element fixes #155880 --- src/vs/base/browser/ui/actionbar/actionViewItems.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/base/browser/ui/actionbar/actionViewItems.ts b/src/vs/base/browser/ui/actionbar/actionViewItems.ts index fea999ce34f..7b9a6cb481e 100644 --- a/src/vs/base/browser/ui/actionbar/actionViewItems.ts +++ b/src/vs/base/browser/ui/actionbar/actionViewItems.ts @@ -388,6 +388,14 @@ export class ActionViewItem extends BaseActionViewItem { } } + override updateTooltip(): void { + super.updateTooltip(); + if (this.label) { + const title = this.getTooltip() ?? ''; + this.label.setAttribute('aria-label', title); + } + } + override updateChecked(): void { if (this.label) { if (this.action.checked) { From 0fa4923c85ac009b6c55d42fcd9921b765737401 Mon Sep 17 00:00:00 2001 From: zhuowei Date: Fri, 5 Aug 2022 08:53:35 -0400 Subject: [PATCH 276/303] simpleFileDialog: ask user if we should create directory if it doesn't exist when saving (#152536) When saving a file using the SimpleFileDialog (for example, when editing a file over SSH), if the directory doesn't exist, the user currently has to cancel saving, create the directory, then try saving again. This adds a prompt to allow the user to create any missing directories from the save dialog directly. Tested with the TestResolver in Code - OSS. I wasn't able to get the Remote - SSH extension working in Code - OSS, but it should work there, since FileService.writeFile calls mkdirp to create missing folders, so this should work with all remote providers. Fixes #71425. Co-authored-by: Alex Ross --- .../workbench/services/dialogs/browser/simpleFileDialog.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts b/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts index 8dbfc92efa9..fc45926ffc9 100644 --- a/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts @@ -803,8 +803,11 @@ export class SimpleFileDialog { // Filename not allowed this.filePickBox.validationMessage = nls.localize('remoteFileDialog.validateBadFilename', 'Please enter a valid file name.'); return Promise.resolve(false); - } else if (!statDirname || !statDirname.isDirectory) { + } else if (!statDirname) { // Folder to save in doesn't exist + const message = nls.localize('remoteFileDialog.validateCreateDirectory', 'The folder {0} does not exist. Would you like to create it?', resources.basename(resources.dirname(uri))); + return this.yesNoPrompt(uri, message); + } else if (!statDirname.isDirectory) { this.filePickBox.validationMessage = nls.localize('remoteFileDialog.validateNonexistentDir', 'Please enter a path that exists.'); return Promise.resolve(false); } From 4cc23f1ecb82dd8fa1e7fb4a3c520e33d3dabdbf Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 5 Aug 2022 07:02:52 -0700 Subject: [PATCH 277/303] Ignore shell integration script errors Part of #157083 --- src/vs/platform/terminal/node/terminalEnvironment.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/terminal/node/terminalEnvironment.ts b/src/vs/platform/terminal/node/terminalEnvironment.ts index a1c2461be9d..e1d2428631b 100644 --- a/src/vs/platform/terminal/node/terminalEnvironment.ts +++ b/src/vs/platform/terminal/node/terminalEnvironment.ts @@ -223,8 +223,9 @@ export enum ShellIntegrationExecutable { } export const shellIntegrationArgs: Map = new Map(); -shellIntegrationArgs.set(ShellIntegrationExecutable.WindowsPwsh, ['-noexit', '-command', '. \"{0}\\out\\vs\\workbench\\contrib\\terminal\\browser\\media\\shellIntegration.ps1\"{1}']); -shellIntegrationArgs.set(ShellIntegrationExecutable.WindowsPwshLogin, ['-l', '-noexit', '-command', '. \"{0}\\out\\vs\\workbench\\contrib\\terminal\\browser\\media\\shellIntegration.ps1\"{1}']); +// The try catch swallows execution policy errors in the case of the archive distributable +shellIntegrationArgs.set(ShellIntegrationExecutable.WindowsPwsh, ['-noexit', '-command', 'try { . \"{0}\\out\\vs\\workbench\\contrib\\terminal\\browser\\media\\shellIntegration.ps1\" } catch {}{1}']); +shellIntegrationArgs.set(ShellIntegrationExecutable.WindowsPwshLogin, ['-l', '-noexit', '-command', 'try { . \"{0}\\out\\vs\\workbench\\contrib\\terminal\\browser\\media\\shellIntegration.ps1\" } catch {}{1}']); shellIntegrationArgs.set(ShellIntegrationExecutable.Pwsh, ['-noexit', '-command', '. "{0}/out/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1"{1}']); shellIntegrationArgs.set(ShellIntegrationExecutable.PwshLogin, ['-l', '-noexit', '-command', '. "{0}/out/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1"']); shellIntegrationArgs.set(ShellIntegrationExecutable.Zsh, ['-i']); From 5b23b086ffde3e3927db87186f56372e8fce7ff3 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 5 Aug 2022 07:29:12 -0700 Subject: [PATCH 278/303] Escape % in bash shell integration Part of #157226 --- .../contrib/terminal/browser/media/shellIntegration-bash.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh index a7b1e8acf36..0d9d6734655 100755 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh @@ -59,7 +59,8 @@ __vsc_update_cwd() { __vsc_command_output_start() { builtin printf "\033]633;C\007" - builtin printf "\033]633;E;$__vsc_current_command\007" + # Send command line, escaping printf format chars % + builtin printf "\033]633;E;$(echo $__vsc_current_command | sed s/%/%%/g)\007" } __vsc_continuation_start() { From b524d80d9c5e2934f047b8da9aeb2a5d39bfbe65 Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Fri, 5 Aug 2022 17:37:45 +0200 Subject: [PATCH 279/303] Send a disconnection message via the management connection before killing the local extension host (#157269) Fixes #156690: Send a disconnection message via the management connection before killing the local extension host --- .../services/extensions/common/abstractExtensionService.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index c53aba431d5..5a4ba551f23 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -258,6 +258,12 @@ export abstract class AbstractExtensionService extends Disposable implements IEx })); this._register(this._lifecycleService.onDidShutdown(() => { + // We need to disconnect the management connection before killing the local extension host. + // Otherwise, the local extension host might terminate the underlying tunnel before the + // management connection has a chance to send its disconnection message. + const connection = this._remoteAgentService.getConnection(); + connection?.dispose(); + this.stopExtensionHosts(); })); } From 31cc3b89876046f10002e1db59424e6a9fbd079c Mon Sep 17 00:00:00 2001 From: David Dossett Date: Fri, 5 Aug 2022 09:05:12 -0700 Subject: [PATCH 280/303] Fix suggestEnabledInput text selection contrast (#157172) --- .../suggestEnabledInput.ts | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput.ts b/src/vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput.ts index 753c32d24c0..b3d2c5104fe 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput.ts @@ -429,32 +429,29 @@ export class ContextScopedSuggestEnabledInputWithHistory extends SuggestEnabledI // Override styles in selections.ts registerThemingParticipant((theme, collector) => { - let selectionColor = theme.getColor(selectionBackground); - if (selectionColor) { - selectionColor = selectionColor.transparent(0.4); + const selectionBackgroundColor = theme.getColor(selectionBackground); + + if (selectionBackgroundColor) { + // Override inactive selection bg + const inputBackgroundColor = theme.getColor(inputBackground); + if (inputBackgroundColor) { + collector.addRule(`.suggest-input-container .monaco-editor .selected-text { background-color: ${inputBackgroundColor.transparent(0.4)}; }`); + } + + // Override selected fg + const inputForegroundColor = theme.getColor(inputForeground); + if (inputForegroundColor) { + collector.addRule(`.suggest-input-container .monaco-editor .view-line span.inline-selected-text { color: ${inputForegroundColor}; }`); + } + + const backgroundColor = theme.getColor(inputBackground); + if (backgroundColor) { + collector.addRule(`.suggest-input-container .monaco-editor-background { background-color: ${backgroundColor}; } `); + } + collector.addRule(`.suggest-input-container .monaco-editor .focused .selected-text { background-color: ${selectionBackgroundColor}; }`); } else { - selectionColor = theme.getColor(editorSelectionBackground); - } - - if (selectionColor) { - collector.addRule(`.suggest-input-container .monaco-editor .focused .selected-text { background-color: ${selectionColor}; }`); - } - - // Override inactive selection bg - const inputBackgroundColor = theme.getColor(inputBackground); - if (inputBackgroundColor) { - collector.addRule(`.suggest-input-container .monaco-editor .selected-text { background-color: ${inputBackgroundColor.transparent(0.4)}; }`); - } - - // Override selected fg - const inputForegroundColor = theme.getColor(inputForeground); - if (inputForegroundColor) { - collector.addRule(`.suggest-input-container .monaco-editor .view-line span.inline-selected-text { color: ${inputForegroundColor}; }`); - } - - const backgroundColor = theme.getColor(inputBackground); - if (backgroundColor) { - collector.addRule(`.suggest-input-container .monaco-editor-background { background-color: ${backgroundColor}; } `); + // Use editor selection color if theme has not set a selection background color + collector.addRule(`.suggest-input-container .monaco-editor .focused .selected-text { background-color: ${theme.getColor(editorSelectionBackground)}; }`); } }); From 39e77d74cae29aaca6cd2c6f3d60d23201e52114 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 5 Aug 2022 09:27:40 -0700 Subject: [PATCH 281/303] fix: parse errors in coverage command (#156837) Fixes #155615 --- package.json | 8 +- test/unit/coverage.js | 7 +- yarn.lock | 385 ++++++++++++++++++++++++++++-------------- 3 files changed, 271 insertions(+), 129 deletions(-) diff --git a/package.json b/package.json index c9a24421f9c..f8cfd0e725a 100644 --- a/package.json +++ b/package.json @@ -170,11 +170,11 @@ "husky": "^0.13.1", "innosetup": "6.0.5", "is": "^3.1.0", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.2.0", "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.1.5", "lazy.js": "^0.4.2", "merge-options": "^1.0.1", "mime": "^1.4.1", diff --git a/test/unit/coverage.js b/test/unit/coverage.js index 49b748e3bf1..ac0c1440f4a 100644 --- a/test/unit/coverage.js +++ b/test/unit/coverage.js @@ -28,7 +28,12 @@ exports.initialize = function (loaderConfig) { } catch (err) { // missing source map... } - return instrumenter.instrumentSync(contents, source, map); + try { + return instrumenter.instrumentSync(contents, source, map); + } catch (e) { + console.error(`Error instrumenting ${source}: ${e}`); + throw e; + } }; }; diff --git a/yarn.lock b/yarn.lock index 8e979f354bb..f53cbf6caf3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,6 +7,14 @@ resolved "https://registry.yarnpkg.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30" integrity sha1-nK+xca+CMpSQNTtIFvAzR6oVCjA= +"@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + "@azure/abort-controller@^1.0.0": version "1.0.4" resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.0.4.tgz#fd3c4d46c8ed67aace42498c8e2270960250eafd" @@ -102,80 +110,141 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" - integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== +"@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== dependencies: - "@babel/highlight" "^7.8.3" + "@babel/highlight" "^7.18.6" -"@babel/core@^7.7.5": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.3.tgz#30b0ebb4dd1585de6923a0b4d179e0b9f5d82941" - integrity sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA== +"@babel/compat-data@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== + +"@babel/core@^7.12.3": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8" + integrity sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw== dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.3" - "@babel/helpers" "^7.8.3" - "@babel/parser" "^7.8.3" - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.3" - "@babel/types" "^7.8.3" + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.10" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.10" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.18.10" + "@babel/types" "^7.18.10" convert-source-map "^1.7.0" debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.0" - lodash "^4.17.13" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" -"@babel/generator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.3.tgz#0e22c005b0a94c1c74eafe19ef78ce53a4d45c03" - integrity sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug== +"@babel/generator@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.10.tgz#794f328bfabdcbaf0ebf9bf91b5b57b61fa77a2a" + integrity sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA== dependencies: - "@babel/types" "^7.8.3" + "@babel/types" "^7.18.10" + "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" - lodash "^4.17.13" - source-map "^0.5.0" -"@babel/helper-function-name@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" - integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== +"@babel/helper-compilation-targets@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" + integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== dependencies: - "@babel/helper-get-function-arity" "^7.8.3" - "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/compat-data" "^7.18.8" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.20.2" + semver "^6.3.0" -"@babel/helper-get-function-arity@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" - integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== - dependencies: - "@babel/types" "^7.8.3" +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== -"@babel/helper-split-export-declaration@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" - integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== +"@babel/helper-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" + integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== dependencies: - "@babel/types" "^7.8.3" + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.9" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-transforms@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" + integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" + integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== "@babel/helper-validator-identifier@^7.10.4": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== -"@babel/helpers@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.3.tgz#382fbb0382ce7c4ce905945ab9641d688336ce85" - integrity sha512-LmU3q9Pah/XyZU89QvBgGt+BCsTPoQa+73RxAQh8fb8qkDyIfeQnmgs+hvzhTCKTzqOyk7JTkS3MS1S8Mq5yrQ== +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helpers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" + integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== dependencies: - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" "@babel/highlight@^7.10.4": version "7.10.4" @@ -186,51 +255,52 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/highlight@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" - integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg== +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== dependencies: + "@babel/helper-validator-identifier" "^7.18.6" chalk "^2.0.0" - esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.7.5", "@babel/parser@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.3.tgz#790874091d2001c9be6ec426c2eed47bc7679081" - integrity sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ== +"@babel/parser@^7.14.7", "@babel/parser@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.10.tgz#94b5f8522356e69e8277276adf67ed280c90ecc1" + integrity sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg== -"@babel/template@^7.7.4", "@babel/template@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8" - integrity sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ== +"@babel/template@^7.18.10", "@babel/template@^7.18.6": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/parser" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" -"@babel/traverse@^7.7.4", "@babel/traverse@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.3.tgz#a826215b011c9b4f73f3a893afbc05151358bf9a" - integrity sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg== +"@babel/traverse@^7.18.10", "@babel/traverse@^7.18.9": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.10.tgz#37ad97d1cb00efa869b91dd5d1950f8a6cf0cb08" + integrity sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g== dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.3" - "@babel/helper-function-name" "^7.8.3" - "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/parser" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.10" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.13" -"@babel/types@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" - integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== +"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.10.tgz#4908e81b6b339ca7c6b7a555a5fc29446f26dde6" + integrity sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ== dependencies: - esutils "^2.0.2" - lodash "^4.17.13" + "@babel/helper-string-parser" "^7.18.10" + "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" "@discoveryjs/json-ext@^0.5.0": @@ -316,6 +386,46 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@koa/cors@^3.3.0": version "3.3.0" resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.3.0.tgz#b4c1c7ee303b7c968c8727f2a638a74675b50bb2" @@ -2075,6 +2185,16 @@ browserslist@^4.0.0, browserslist@^4.14.5: escalade "^3.1.1" node-releases "^1.1.71" +browserslist@^4.20.2: + version "4.21.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" + integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== + dependencies: + caniuse-lite "^1.0.30001370" + electron-to-chromium "^1.4.202" + node-releases "^2.0.6" + update-browserslist-db "^1.0.5" + buffer-alloc-unsafe@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" @@ -2290,6 +2410,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001219: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== +caniuse-lite@^1.0.30001370: + version "1.0.30001373" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz#2dc3bc3bfcb5d5a929bec11300883040d7b4b4be" + integrity sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ== + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -3578,6 +3703,11 @@ electron-to-chromium@^1.3.723: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.737.tgz#196f2e9656f4f3c31930750e1899c091b72d36b5" integrity sha512-P/B84AgUSQXaum7a8m11HUsYL8tj9h/Pt5f7Hg7Ty6bm5DxlFq+e5+ouHUoNQMsKDJ7u4yGfI8mOErCmSH9wyg== +electron-to-chromium@^1.4.202: + version "1.4.207" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.207.tgz#9c3310ebace2952903d05dcaba8abe3a4ed44c01" + integrity sha512-piH7MJDJp4rJCduWbVvmUd59AUne1AFBJ8JaRQvk0KzNTSUnZrVXHCZc+eg+CGE4OujkcLJznhGKD6tuAshj5Q== + electron@19.0.11: version "19.0.11" resolved "https://registry.yarnpkg.com/electron/-/electron-19.0.11.tgz#0c0a52abc08694fd38916d9270baf45bb7752a27" @@ -4674,10 +4804,10 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== get-caller-file@^1.0.1: version "1.0.3" @@ -6132,17 +6262,20 @@ istanbul-lib-coverage@^3.0.0: resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== -istanbul-lib-instrument@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.0.tgz#53321a7970f076262fd3292c8f9b2e4ac544aae1" - integrity sha512-Nm4wVHdo7ZXSG30KjZ2Wl5SU/Bw7bDx1PdaiIFzEStdjs0H12mOTncn1GVYuqQSaZxpg87VGBRsVRPGD2cD1AQ== +istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== dependencies: - "@babel/core" "^7.7.5" - "@babel/parser" "^7.7.5" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" + istanbul-lib-coverage "^3.2.0" semver "^6.3.0" istanbul-lib-report@^3.0.0: @@ -6154,19 +6287,19 @@ istanbul-lib-report@^3.0.0: make-dir "^3.0.0" supports-color "^7.1.0" -istanbul-lib-source-maps@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" - integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== +istanbul-lib-source-maps@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== dependencies: debug "^4.1.1" istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.0.tgz#d4d16d035db99581b6194e119bbf36c963c5eb70" - integrity sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A== +istanbul-reports@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -6276,13 +6409,6 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" - integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== - dependencies: - minimist "^1.2.0" - json5@^2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" @@ -6290,6 +6416,11 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" +json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -6624,7 +6755,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: +lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -7372,6 +7503,11 @@ node-releases@^1.1.71: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + node.extend@~1.1.2: version "1.1.8" resolved "https://registry.yarnpkg.com/node.extend/-/node.extend-1.1.8.tgz#0aab3e63789f4e6d68b42bc00073ad1881243cf0" @@ -8982,13 +9118,6 @@ resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.4.0: is-core-module "^2.1.0" path-parse "^1.0.6" -resolve@^1.3.2: - version "1.14.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.14.2.tgz#dbf31d0fa98b1f29aa5169783b9c290cb865fea2" - integrity sha512-EjlOBLBO1kxsUxsKjLt7TAECyKW6fOh1VRkykQkKGzcBbjjPIxBqGh0jf7GJ3k/f5mxMqW3htMD3WdTUVtW8HQ== - dependencies: - path-parse "^1.0.6" - resolve@^1.9.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" @@ -9481,7 +9610,7 @@ source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.6: +source-map@^0.5.1, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -10559,6 +10688,14 @@ upath@^1.1.1: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== +update-browserslist-db@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" From 408fa026da7b11eab8b57cb01d3aca471de30db2 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 5 Aug 2022 09:30:59 -0700 Subject: [PATCH 282/303] Also escape % in zsh --- .../contrib/terminal/browser/media/shellIntegration-rc.zsh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh index 7db2583a817..c2361a51312 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh @@ -50,7 +50,8 @@ __vsc_update_cwd() { __vsc_command_output_start() { builtin printf "\033]633;C\007" - builtin printf "\033]633;E;$__vsc_current_command\007" + # Send command line, escaping printf format chars % + builtin printf "\033]633;E;$(echo $__vsc_current_command | sed s/%/%%/g)\007" } __vsc_continuation_start() { From 02505d349941657f0a7af060d48ec5c65e6b6d13 Mon Sep 17 00:00:00 2001 From: FantasqueX Date: Sat, 6 Aug 2022 00:52:55 +0800 Subject: [PATCH 283/303] Fix typos in files.ts (#157280) Fix typo in files.ts Signed-off-by: Letu Ren --- src/vs/platform/files/common/files.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index c5a327c71e7..9b6968f03aa 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -31,7 +31,7 @@ export interface IFileService { readonly onDidChangeFileSystemProviderRegistrations: Event; /** - * An event that is fired when a registered file system provider changes it's capabilities. + * An event that is fired when a registered file system provider changes its capabilities. */ readonly onDidChangeFileSystemProviderCapabilities: Event; @@ -80,7 +80,7 @@ export interface IFileService { hasCapability(resource: URI, capability: FileSystemProviderCapabilities): boolean; /** - * List the schemes and capabilies for registered file system providers + * List the schemes and capabilities for registered file system providers */ listCapabilities(): Iterable<{ scheme: string; capabilities: FileSystemProviderCapabilities }>; @@ -982,7 +982,7 @@ interface IBaseFileStat { readonly ctime?: number; /** - * A unique identifier thet represents the + * A unique identifier that represents the * current state of the file or directory. * * The value may or may not be resolved as From 427530e884b33be2451bb37d726841b897ba6b77 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 5 Aug 2022 10:16:45 -0700 Subject: [PATCH 284/303] Remove event.ts stopEvent (#157182) Remove event.stopEvent This function has the same function as EventHelper.stop but is only used in one place --- src/vs/base/browser/dom.ts | 3 ++- src/vs/base/browser/event.ts | 15 --------------- src/vs/base/browser/ui/list/listWidget.ts | 10 +++++----- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 3ddc0d543ba..788c5cecea4 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -836,11 +836,12 @@ export interface EventLike { } export const EventHelper = { - stop: function (e: EventLike, cancelBubble?: boolean) { + stop: (e: T, cancelBubble?: boolean): T => { e.preventDefault(); if (cancelBubble) { e.stopPropagation(); } + return e; } }; diff --git a/src/vs/base/browser/event.ts b/src/vs/base/browser/event.ts index adef057e119..600a5f78248 100644 --- a/src/vs/base/browser/event.ts +++ b/src/vs/base/browser/event.ts @@ -45,18 +45,3 @@ export class DomEmitter implements IDisposable { this.emitter.dispose(); } } - -export interface CancellableEvent { - preventDefault(): void; - stopPropagation(): void; -} - -export function stopEvent(event: T): T { - event.preventDefault(); - event.stopPropagation(); - return event; -} - -export function stop(event: BaseEvent): BaseEvent { - return BaseEvent.map(event, stopEvent); -} diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 0cea984085d..8ed5f2d8602 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { IDragAndDropData } from 'vs/base/browser/dnd'; -import { createStyleSheet } from 'vs/base/browser/dom'; -import { DomEmitter, stopEvent } from 'vs/base/browser/event'; +import { createStyleSheet, EventHelper } from 'vs/base/browser/dom'; +import { DomEmitter } from 'vs/base/browser/event'; import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { Gesture } from 'vs/base/browser/touch'; import { alert } from 'vs/base/browser/ui/aria/aria'; @@ -457,7 +457,7 @@ class TypeNavigationController implements IDisposable { .map(event => new StandardKeyboardEvent(event)) .filter(e => typing || this.keyboardNavigationEventFilter(e)) .filter(e => this.delegate.mightProducePrintableCharacter(e)) - .forEach(stopEvent) + .forEach(e => EventHelper.stop(e, true)) .map(event => event.browserEvent.key) .event; @@ -1288,7 +1288,7 @@ export class List implements ISpliceable, IThemable, IDisposable { const fromKeyDown = this.disposables.add(Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event)) .map(e => new StandardKeyboardEvent(e)) .filter(e => didJustPressContextMenuKey = e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10)) - .map(stopEvent) + .map(e => EventHelper.stop(e, true)) .filter(() => false) .event as Event; @@ -1296,7 +1296,7 @@ export class List implements ISpliceable, IThemable, IDisposable { .forEach(() => didJustPressContextMenuKey = false) .map(e => new StandardKeyboardEvent(e)) .filter(e => e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10)) - .map(stopEvent) + .map(e => EventHelper.stop(e, true)) .map(({ browserEvent }) => { const focus = this.getFocus(); const index = focus.length ? focus[0] : undefined; From 6d24a019d8784650fe1a63b7d7326f2d206104af Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 5 Aug 2022 10:24:40 -0700 Subject: [PATCH 285/303] Remove dom.createEventEmitter (#157296) As far as I can tell this class has the same functionality as `DomEmitter` --- src/vs/base/browser/dom.ts | 16 ----------- .../browser/controller/textAreaInput.ts | 27 ++++++++++--------- 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 788c5cecea4..1c69a349c09 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -101,22 +101,6 @@ export function addDisposableGenericMouseUpListener(node: EventTarget, handler: return addDisposableListener(node, platform.isIOS && BrowserFeatures.pointerEvents ? EventType.POINTER_UP : EventType.MOUSE_UP, handler, useCapture); } -export function createEventEmitter(target: HTMLElement, type: K, options?: boolean | AddEventListenerOptions): event.Emitter { - let domListener: IDisposable | undefined = undefined; - const handler = (e: HTMLElementEventMap[K]) => result.fire(e); - const onFirstListenerAdd = () => { - if (!domListener) { - domListener = addDisposableListener(target, type, handler, options); - } - }; - const onLastListenerRemove = () => { - domListener?.dispose(); - domListener = undefined; - }; - const result = new event.Emitter({ onFirstListenerAdd, onLastListenerRemove }); - return result; -} - interface IRequestAnimationFrame { (callback: (time: number) => void): number; } diff --git a/src/vs/editor/browser/controller/textAreaInput.ts b/src/vs/editor/browser/controller/textAreaInput.ts index 3e7e9a3252e..1e785855191 100644 --- a/src/vs/editor/browser/controller/textAreaInput.ts +++ b/src/vs/editor/browser/controller/textAreaInput.ts @@ -5,6 +5,7 @@ import * as browser from 'vs/base/browser/browser'; import * as dom from 'vs/base/browser/dom'; +import { DomEmitter } from 'vs/base/browser/event'; import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; @@ -672,19 +673,19 @@ class ClipboardEventUtils { export class TextAreaWrapper extends Disposable implements ICompleteTextAreaWrapper { - public readonly onKeyDown = this._register(dom.createEventEmitter(this._actual, 'keydown')).event; - public readonly onKeyPress = this._register(dom.createEventEmitter(this._actual, 'keypress')).event; - public readonly onKeyUp = this._register(dom.createEventEmitter(this._actual, 'keyup')).event; - public readonly onCompositionStart = this._register(dom.createEventEmitter(this._actual, 'compositionstart')).event; - public readonly onCompositionUpdate = this._register(dom.createEventEmitter(this._actual, 'compositionupdate')).event; - public readonly onCompositionEnd = this._register(dom.createEventEmitter(this._actual, 'compositionend')).event; - public readonly onBeforeInput = this._register(dom.createEventEmitter(this._actual, 'beforeinput')).event; - public readonly onInput = >this._register(dom.createEventEmitter(this._actual, 'input')).event; - public readonly onCut = this._register(dom.createEventEmitter(this._actual, 'cut')).event; - public readonly onCopy = this._register(dom.createEventEmitter(this._actual, 'copy')).event; - public readonly onPaste = this._register(dom.createEventEmitter(this._actual, 'paste')).event; - public readonly onFocus = this._register(dom.createEventEmitter(this._actual, 'focus')).event; - public readonly onBlur = this._register(dom.createEventEmitter(this._actual, 'blur')).event; + public readonly onKeyDown = this._register(new DomEmitter(this._actual, 'keydown')).event; + public readonly onKeyPress = this._register(new DomEmitter(this._actual, 'keypress')).event; + public readonly onKeyUp = this._register(new DomEmitter(this._actual, 'keyup')).event; + public readonly onCompositionStart = this._register(new DomEmitter(this._actual, 'compositionstart')).event; + public readonly onCompositionUpdate = this._register(new DomEmitter(this._actual, 'compositionupdate')).event; + public readonly onCompositionEnd = this._register(new DomEmitter(this._actual, 'compositionend')).event; + public readonly onBeforeInput = this._register(new DomEmitter(this._actual, 'beforeinput')).event; + public readonly onInput = >this._register(new DomEmitter(this._actual, 'input')).event; + public readonly onCut = this._register(new DomEmitter(this._actual, 'cut')).event; + public readonly onCopy = this._register(new DomEmitter(this._actual, 'copy')).event; + public readonly onPaste = this._register(new DomEmitter(this._actual, 'paste')).event; + public readonly onFocus = this._register(new DomEmitter(this._actual, 'focus')).event; + public readonly onBlur = this._register(new DomEmitter(this._actual, 'blur')).event; private _onSyntheticTap = this._register(new Emitter()); public readonly onSyntheticTap: Event = this._onSyntheticTap.event; From 8671778f8d693e9c953d3f96807654b1afa6de6d Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 5 Aug 2022 13:07:20 -0500 Subject: [PATCH 286/303] Fix notebook execution test failures (#157290) * Fix notebook execution test failures An error thrown in an event handler did not cause the test to fail, using DeferredPromise. Adjusting the api event to account for Unconfirmed vs Pending states. And accounting for onDidChangeNotebookDocument being fired multiple times during a test, causing the test to complete early while execution was still happening. Fixes #157067 * Remove log --- .../notebook.kernel.test.ts | 63 ++++++++++--------- extensions/vscode-api-tests/src/utils.ts | 58 +++++++++++++++++ src/vs/base/common/async.ts | 2 +- .../api/common/extHostNotebookKernels.ts | 11 ++-- .../api/common/extHostTypeConverters.ts | 13 ++-- 5 files changed, 105 insertions(+), 42 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts index d41129e04f4..923ee4cfc73 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import 'mocha'; import { TextDecoder } from 'util'; import * as vscode from 'vscode'; -import { asPromise, assertNoRpc, closeAllEditors, createRandomFile, disposeAll, revertAllDirty, saveAllEditors } from '../utils'; +import { asPromise, assertNoRpc, closeAllEditors, createRandomFile, DeferredPromise, disposeAll, revertAllDirty, saveAllEditors } from '../utils'; async function createRandomNotebookFile() { return createRandomFile('', undefined, '.vsctestnb'); @@ -181,7 +181,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { const editor = vscode.window.activeNotebookEditor!; const cell = editor.notebook.cellAt(0); - await withEvent(vscode.workspace.onDidChangeNotebookDocument, async (event) => { + await withEvent(vscode.workspace.onDidChangeNotebookDocument, async event => { await vscode.commands.executeCommand('notebook.execute'); await event; assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked @@ -196,7 +196,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { const secondResource = await createRandomNotebookFile(); await vscode.commands.executeCommand('vscode.openWith', secondResource, 'notebookCoreTest'); - await withEvent(vscode.workspace.onDidChangeNotebookDocument, async (event) => { + await withEvent(vscode.workspace.onDidChangeNotebookDocument, async event => { await vscode.commands.executeCommand('notebook.cell.execute', { start: 0, end: 1 }, notebook.uri); await event; assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked @@ -204,35 +204,33 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { }); }); - // #126371 - test('cell execute command takes arguments', async () => { + test('cell execute command takes arguments 2', async () => { const notebook = await openRandomNotebookDocument(); await vscode.window.showNotebookDocument(notebook); let firstCellExecuted = false; let secondCellExecuted = false; - let resolve: () => void; - const p = new Promise(r => resolve = r); - const listener = vscode.workspace.onDidChangeNotebookDocument(e => { + + const def = new DeferredPromise(); + testDisposables.push(vscode.workspace.onDidChangeNotebookDocument(e => { e.cellChanges.forEach(change => { - if (change.cell.index === 0) { + if (change.cell.index === 0 && change.executionSummary) { firstCellExecuted = true; } - if (change.cell.index === 1) { + if (change.cell.index === 1 && change.executionSummary) { secondCellExecuted = true; } }); if (firstCellExecuted && secondCellExecuted) { - resolve(); + def.complete(); } - }); + })); vscode.commands.executeCommand('notebook.cell.execute', { document: notebook.uri, ranges: [{ start: 0, end: 1 }, { start: 1, end: 2 }] }); - await p; - listener.dispose(); + await def.p; await saveAllFilesAndCloseAll(); }); @@ -301,27 +299,30 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { const cell = editor.notebook.cellAt(0); let eventCount = 0; - let resolve: () => void; - const p = new Promise(r => resolve = r); - const listener = vscode.notebooks.onDidChangeNotebookCellExecutionState(e => { - if (eventCount === 0) { - assert.strictEqual(e.state, vscode.NotebookCellExecutionState.Pending, 'should be set to Pending'); - } else if (eventCount === 1) { - assert.strictEqual(e.state, vscode.NotebookCellExecutionState.Executing, 'should be set to Executing'); - assert.strictEqual(cell.outputs.length, 0, 'no outputs yet: ' + JSON.stringify(cell.outputs[0])); - } else if (eventCount === 2) { - assert.strictEqual(e.state, vscode.NotebookCellExecutionState.Idle, 'should be set to Idle'); - assert.strictEqual(cell.outputs.length, 1, 'should have an output'); - resolve(); - } + const def = new DeferredPromise(); + testDisposables.push(vscode.notebooks.onDidChangeNotebookCellExecutionState(e => { + try { + assert.strictEqual(e.cell.document.uri.toString(), cell.document.uri.toString(), 'event should be fired for the executing cell'); - eventCount++; - }); + if (eventCount === 0) { + assert.strictEqual(e.state, vscode.NotebookCellExecutionState.Pending, 'should be set to Pending'); + } else if (eventCount === 1) { + assert.strictEqual(e.state, vscode.NotebookCellExecutionState.Executing, 'should be set to Executing'); + assert.strictEqual(cell.outputs.length, 0, 'no outputs yet: ' + JSON.stringify(cell.outputs[0])); + } else if (e.state === vscode.NotebookCellExecutionState.Idle) { + assert.strictEqual(cell.outputs.length, 1, 'should have an output'); + def.complete(); + } + + eventCount++; + } catch (err) { + def.error(err); + } + })); vscode.commands.executeCommand('notebook.cell.execute', { document: notebook.uri, ranges: [{ start: 0, end: 1 }] }); - await p; - listener.dispose(); + await def.p; }); test('Output changes are applied once the promise resolves', async function () { diff --git a/extensions/vscode-api-tests/src/utils.ts b/extensions/vscode-api-tests/src/utils.ts index cd2a653bee8..7c506694289 100644 --- a/extensions/vscode-api-tests/src/utils.ts +++ b/extensions/vscode-api-tests/src/utils.ts @@ -184,3 +184,61 @@ export async function poll( trial++; } } + +export type ValueCallback = (value: T | Promise) => void; + +/** + * Creates a promise whose resolution or rejection can be controlled imperatively. + */ +export class DeferredPromise { + + private completeCallback!: ValueCallback; + private errorCallback!: (err: unknown) => void; + private rejected = false; + private resolved = false; + + public get isRejected() { + return this.rejected; + } + + public get isResolved() { + return this.resolved; + } + + public get isSettled() { + return this.rejected || this.resolved; + } + + public readonly p: Promise; + + constructor() { + this.p = new Promise((c, e) => { + this.completeCallback = c; + this.errorCallback = e; + }); + } + + public complete(value: T) { + return new Promise(resolve => { + this.completeCallback(value); + this.resolved = true; + resolve(); + }); + } + + public error(err: unknown) { + return new Promise(resolve => { + this.errorCallback(err); + this.rejected = true; + resolve(); + }); + } + + public cancel() { + new Promise(resolve => { + this.errorCallback(new Error('Canceled')); + this.rejected = true; + resolve(); + }); + } +} diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index e45c78ae5e3..562710d4c84 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -1389,7 +1389,7 @@ export class DeferredPromise { return this.rejected || this.resolved; } - public p: Promise; + public readonly p: Promise; constructor() { this.p = new Promise((c, e) => { diff --git a/src/vs/workbench/api/common/extHostNotebookKernels.ts b/src/vs/workbench/api/common/extHostNotebookKernels.ts index 6cc843c39dc..cd0ab1203ed 100644 --- a/src/vs/workbench/api/common/extHostNotebookKernels.ts +++ b/src/vs/workbench/api/common/extHostNotebookKernels.ts @@ -348,10 +348,13 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape { const document = this._extHostNotebook.getNotebookDocument(URI.revive(uri)); const cell = document.getCell(cellHandle); if (cell) { - this._onDidChangeCellExecutionState.fire({ - cell: cell.apiCell, - state: state ? extHostTypeConverters.NotebookCellExecutionState.to(state) : ExtHostNotebookCellExecutionState.Idle - }); + const newState = state ? extHostTypeConverters.NotebookCellExecutionState.to(state) : ExtHostNotebookCellExecutionState.Idle; + if (newState !== undefined) { + this._onDidChangeCellExecutionState.fire({ + cell: cell.apiCell, + state: newState + }); + } } } diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index c71c6adcd1e..24a67b8d68c 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -1538,13 +1538,14 @@ export namespace NotebookCellExecutionSummary { } export namespace NotebookCellExecutionState { - export function to(state: notebooks.NotebookCellExecutionState): vscode.NotebookCellExecutionState { - if (state === notebooks.NotebookCellExecutionState.Executing) { - return types.NotebookCellExecutionState.Executing; + export function to(state: notebooks.NotebookCellExecutionState): vscode.NotebookCellExecutionState | undefined { + if (state === notebooks.NotebookCellExecutionState.Unconfirmed) { + return types.NotebookCellExecutionState.Pending; } else if (state === notebooks.NotebookCellExecutionState.Pending) { - return types.NotebookCellExecutionState.Pending; - } else if (state === notebooks.NotebookCellExecutionState.Unconfirmed) { - return types.NotebookCellExecutionState.Pending; + // Since the (proposed) extension API doesn't have the distinction between Unconfirmed and Pending, we don't want to fire an update for Pending twice + return undefined; + } else if (state === notebooks.NotebookCellExecutionState.Executing) { + return types.NotebookCellExecutionState.Executing; } else { throw new Error(`Unknown state: ${state}`); } From f314f642da2376c86c7c6ec8d6268827abb18f29 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 5 Aug 2022 11:08:06 -0700 Subject: [PATCH 287/303] testing: ensure tests run in multiple profiles are in the same task (#157302) --- .../api/browser/mainThreadTesting.ts | 2 +- .../workbench/api/common/extHost.protocol.ts | 2 +- src/vs/workbench/api/common/extHostTesting.ts | 17 +++++++++---- .../contrib/testing/common/testService.ts | 4 +-- .../contrib/testing/common/testServiceImpl.ts | 25 +++++++++++-------- .../contrib/testing/common/testTypes.ts | 4 +++ 6 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTesting.ts b/src/vs/workbench/api/browser/mainThreadTesting.ts index fb9a562b3d0..e21387242da 100644 --- a/src/vs/workbench/api/browser/mainThreadTesting.ts +++ b/src/vs/workbench/api/browser/mainThreadTesting.ts @@ -173,7 +173,7 @@ export class MainThreadTesting extends Disposable implements MainThreadTestingSh canRefresh, refreshTests: token => this.proxy.$refreshTests(controllerId, token), configureRunProfile: id => this.proxy.$configureRunProfile(controllerId, id), - runTests: (req, token) => this.proxy.$runControllerTests(req, token), + runTests: (reqs, token) => this.proxy.$runControllerTests(reqs, token), expandTest: (testId, levels) => this.proxy.$expandTest(testId, isFinite(levels) ? levels : -1), }; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index ed17dcc5b4c..615572cdb03 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -2173,7 +2173,7 @@ export const enum ExtHostTestingResource { } export interface ExtHostTestingShape { - $runControllerTests(req: RunTestForControllerRequest, token: CancellationToken): Promise; + $runControllerTests(req: RunTestForControllerRequest[], token: CancellationToken): Promise<{ error?: string }[]>; $cancelExtensionTestRun(runId: string | undefined): void; /** Handles a diff of tests, as a result of a subscribeToDiffs() call */ $acceptDiff(diff: TestsDiffOp.Serialized[]): void; diff --git a/src/vs/workbench/api/common/extHostTesting.ts b/src/vs/workbench/api/common/extHostTesting.ts index 559d09d0aa0..2f0a2caa370 100644 --- a/src/vs/workbench/api/common/extHostTesting.ts +++ b/src/vs/workbench/api/common/extHostTesting.ts @@ -22,7 +22,7 @@ import * as Convert from 'vs/workbench/api/common/extHostTypeConverters'; import { TestRunProfileKind, TestRunRequest } from 'vs/workbench/api/common/extHostTypes'; import { TestId, TestIdPathParts, TestPosition } from 'vs/workbench/contrib/testing/common/testId'; import { InvalidTestItemError } from 'vs/workbench/contrib/testing/common/testItemCollection'; -import { AbstractIncrementalTestCollection, CoverageDetails, IFileCoverage, IncrementalChangeCollector, IncrementalTestCollectionItem, InternalTestItem, ISerializedTestResults, ITestItem, RunTestForControllerRequest, TestResultState, TestRunProfileBitset, TestsDiff, TestsDiffOp } from 'vs/workbench/contrib/testing/common/testTypes'; +import { AbstractIncrementalTestCollection, CoverageDetails, IFileCoverage, IncrementalChangeCollector, IncrementalTestCollectionItem, InternalTestItem, ISerializedTestResults, ITestItem, RunTestForControllerRequest, RunTestForControllerResult, TestResultState, TestRunProfileBitset, TestsDiff, TestsDiffOp } from 'vs/workbench/contrib/testing/common/testTypes'; import type * as vscode from 'vscode'; interface ControllerInfo { @@ -227,16 +227,20 @@ export class ExtHostTesting implements ExtHostTestingShape { * providers to be run. * @override */ - public async $runControllerTests(req: RunTestForControllerRequest, token: CancellationToken): Promise { + public async $runControllerTests(reqs: RunTestForControllerRequest[], token: CancellationToken): Promise { + return Promise.all(reqs.map(req => this.runControllerTestRequest(req, token))); + } + + public async runControllerTestRequest(req: RunTestForControllerRequest, token: CancellationToken): Promise { const lookup = this.controllers.get(req.controllerId); if (!lookup) { - return; + return {}; } const { collection, profiles } = lookup; const profile = profiles.get(req.profileId); if (!profile) { - return; + return {}; } const includeTests = req.testIds @@ -251,7 +255,7 @@ export class ExtHostTesting implements ExtHostTestingShape { )); if (!includeTests.length) { - return; + return {}; } const publicReq = new TestRunRequest( @@ -268,6 +272,9 @@ export class ExtHostTesting implements ExtHostTestingShape { try { await profile.runHandler(publicReq, token); + return {}; + } catch (e) { + return { error: String(e) }; } finally { if (tracker.isRunning && !token.isCancellationRequested) { await Event.toPromise(tracker.onEnd); diff --git a/src/vs/workbench/contrib/testing/common/testService.ts b/src/vs/workbench/contrib/testing/common/testService.ts index 7c2450a2e94..f4a19c91d99 100644 --- a/src/vs/workbench/contrib/testing/common/testService.ts +++ b/src/vs/workbench/contrib/testing/common/testService.ts @@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { IObservableValue, MutableObservableValue } from 'vs/workbench/contrib/testing/common/observableValue'; -import { AbstractIncrementalTestCollection, IncrementalTestCollectionItem, InternalTestItem, ITestItemContext, ResolvedTestRunRequest, RunTestForControllerRequest, TestItemExpandState, TestRunProfileBitset, TestsDiff } from 'vs/workbench/contrib/testing/common/testTypes'; +import { AbstractIncrementalTestCollection, IncrementalTestCollectionItem, InternalTestItem, ITestItemContext, ResolvedTestRunRequest, RunTestForControllerRequest, RunTestForControllerResult, TestItemExpandState, TestRunProfileBitset, TestsDiff } from 'vs/workbench/contrib/testing/common/testTypes'; import { TestExclusions } from 'vs/workbench/contrib/testing/common/testExclusions'; import { TestId } from 'vs/workbench/contrib/testing/common/testId'; import { ITestResult } from 'vs/workbench/contrib/testing/common/testResult'; @@ -26,7 +26,7 @@ export interface IMainThreadTestController { refreshTests(token: CancellationToken): Promise; configureRunProfile(profileId: number): void; expandTest(id: string, levels: number): Promise; - runTests(request: RunTestForControllerRequest, token: CancellationToken): Promise; + runTests(request: RunTestForControllerRequest[], token: CancellationToken): Promise; } export type TestDiffListener = (diff: TestsDiff) => void; diff --git a/src/vs/workbench/contrib/testing/common/testServiceImpl.ts b/src/vs/workbench/contrib/testing/common/testServiceImpl.ts index efc2afbd0ca..3b107fabf85 100644 --- a/src/vs/workbench/contrib/testing/common/testServiceImpl.ts +++ b/src/vs/workbench/contrib/testing/common/testServiceImpl.ts @@ -28,6 +28,7 @@ import { AmbiguousRunTestsRequest, IMainThreadTestController, ITestService } fro import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { getTestingConfiguration, TestingConfigKeys } from 'vs/workbench/contrib/testing/common/configuration'; +import { isDefined } from 'vs/base/common/types'; export class TestService extends Disposable implements ITestService { declare readonly _serviceBrand: undefined; @@ -194,18 +195,22 @@ export class TestService extends Disposable implements ITestService { const cancelSource = new CancellationTokenSource(token); this.uiRunningTests.set(result.id, cancelSource); - const requests = req.targets.map( - group => this.testControllers.get(group.controllerId)?.runTests( - { + const byController = groupBy(req.targets, (a, b) => a.controllerId.localeCompare(b.controllerId)); + const requests = byController.map( + group => this.testControllers.get(group[0].controllerId)?.runTests( + group.map(controlReq => ({ runId: result.id, - excludeExtIds: req.exclude!.filter(t => !group.testIds.includes(t)), - profileId: group.profileId, - controllerId: group.controllerId, - testIds: group.testIds, - }, + excludeExtIds: req.exclude!.filter(t => !controlReq.testIds.includes(t)), + profileId: controlReq.profileId, + controllerId: controlReq.controllerId, + testIds: controlReq.testIds, + })), cancelSource.token, - ).catch(err => { - this.notificationService.error(localize('testError', 'An error occurred attempting to run tests: {0}', err.message)); + ).then(result => { + const errs = result.map(r => r.error).filter(isDefined); + if (errs.length) { + this.notificationService.error(localize('testError', 'An error occurred attempting to run tests: {0}', errs.join(' '))); + } }) ); await this.saveAllBeforeTest(req); diff --git a/src/vs/workbench/contrib/testing/common/testTypes.ts b/src/vs/workbench/contrib/testing/common/testTypes.ts index 4f9620cc4a8..e9b714fb36f 100644 --- a/src/vs/workbench/contrib/testing/common/testTypes.ts +++ b/src/vs/workbench/contrib/testing/common/testTypes.ts @@ -90,6 +90,10 @@ export interface RunTestForControllerRequest { testIds: string[]; } +export interface RunTestForControllerResult { + error?: string; +} + /** * Location with a fully-instantiated Range and URI. */ From 46b6f3eb644fa6ee29e6245094b8777340696b2e Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Fri, 5 Aug 2022 14:20:48 -0400 Subject: [PATCH 288/303] Better telemetry adblock check (#157279) Dynamic adblock check based on telemetry setting --- .../sharedProcess/sharedProcessMain.ts | 4 +-- .../telemetry/browser/telemetryService.ts | 35 ++++++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index d959a938e93..2e6d00020c0 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -103,9 +103,9 @@ import { ExtensionsProfileScannerService, IExtensionsProfileScannerService } fro import { PolicyChannelClient } from 'vs/platform/policy/common/policyIpc'; import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy'; import { UserDataProfilesNativeService } from 'vs/platform/userDataProfile/electron-sandbox/userDataProfile'; -import { OneDataSystemWebAppender } from 'vs/platform/telemetry/browser/1dsAppender'; import { DefaultExtensionsProfileInitService } from 'vs/platform/extensionManagement/electron-sandbox/defaultExtensionsProfileInit'; import { SharedProcessRequestService } from 'vs/platform/request/electron-browser/sharedProcessRequestService'; +import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; class SharedProcessMain extends Disposable { @@ -283,7 +283,7 @@ class SharedProcessMain extends Disposable { appenders.push(logAppender); const { installSourcePath } = environmentService; if (productService.aiConfig?.ariaKey) { - const collectorAppender = new OneDataSystemWebAppender(internalTelemetry, 'monacoworkbench', null, productService.aiConfig.ariaKey); + const collectorAppender = new OneDataSystemAppender(internalTelemetry, 'monacoworkbench', null, productService.aiConfig.ariaKey); this._register(toDisposable(() => collectorAppender.flush())); // Ensure the 1DS appender is disposed so that it flushes remaining data appenders.push(collectorAppender); } diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index 2c12f5a3305..d466a303e14 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -12,7 +12,7 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { OneDataSystemWebAppender } from 'vs/platform/telemetry/browser/1dsAppender'; import { ClassifiedEvent, IGDPRProperty, OmitMetadata, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; -import { ITelemetryData, ITelemetryInfo, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; +import { ITelemetryData, ITelemetryInfo, ITelemetryService, TelemetryLevel, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender'; import { ITelemetryServiceConfig, TelemetryService as BaseTelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { isInternalTelemetry, ITelemetryAppender, NullTelemetryService, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; @@ -38,6 +38,34 @@ export class TelemetryService extends Disposable implements ITelemetryService { super(); if (supportsTelemetry(productService, environmentService) && productService.aiConfig?.ariaKey) { + this.impl = this.initializeService(environmentService, loggerService, configurationService, storageService, productService, remoteAgentService); + } else { + this.impl = NullTelemetryService; + } + + // When the level changes it could change from off to on and we want to make sure telemetry is properly intialized + this._register(configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(TELEMETRY_SETTING_ID)) { + this.impl = this.initializeService(environmentService, loggerService, configurationService, storageService, productService, remoteAgentService); + } + })); + } + + /** + * Initializes the telemetry service to be a full fledged service. + * This is only done once and only when telemetry is enabled as this will also ping the endpoint to + * ensure its not adblocked and we can send telemetry + */ + private initializeService( + environmentService: IBrowserWorkbenchEnvironmentService, + loggerService: ILoggerService, + configurationService: IConfigurationService, + storageService: IStorageService, + productService: IProductService, + remoteAgentService: IRemoteAgentService + ) { + const telemetrySupported = supportsTelemetry(productService, environmentService) && productService.aiConfig?.ariaKey; + if (telemetrySupported && this.impl === NullTelemetryService && this.telemetryLevel.value !== TelemetryLevel.NONE) { // If remote server is present send telemetry through that, else use the client side appender const appenders = []; const isInternal = isInternalTelemetry(productService, configurationService); @@ -50,10 +78,9 @@ export class TelemetryService extends Disposable implements ITelemetryService { sendErrorTelemetry: this.sendErrorTelemetry, }; - this.impl = this._register(new BaseTelemetryService(config, configurationService, productService)); - } else { - this.impl = NullTelemetryService; + return this._register(new BaseTelemetryService(config, configurationService, productService)); } + return NullTelemetryService; } setExperimentProperty(name: string, value: string): void { From 0f9323e41100845e1ad12f7d6b49b8b1d9102ef3 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 5 Aug 2022 11:48:01 -0700 Subject: [PATCH 289/303] Fix #157301. Fix process explorer scrolling (#157305) --- .../processExplorer/media/processExplorer.css | 12 ++++++++++++ .../processExplorer/processExplorerMain.ts | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/src/vs/code/electron-sandbox/processExplorer/media/processExplorer.css b/src/vs/code/electron-sandbox/processExplorer/media/processExplorer.css index 3baf48ce1af..080049662de 100644 --- a/src/vs/code/electron-sandbox/processExplorer/media/processExplorer.css +++ b/src/vs/code/electron-sandbox/processExplorer/media/processExplorer.css @@ -84,3 +84,15 @@ body { padding-left: 20px; white-space: nowrap; } + +.monaco-scrollable-element .scrollbar > .slider { + background: #64646457 !important; +} + +.monaco-scrollable-element .scrollbar > .slider:hover { + background: highlight !important; +} + +.monaco-scrollable-element .scrollbar > .slider.active { + background: highlight !important; +} diff --git a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts b/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts index 8e756e829d9..10d2243c333 100644 --- a/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts @@ -257,6 +257,7 @@ class ProcessExplorer { await this.createProcessTree(processRoots); } else { this.tree.setInput({ processes: { processRoots } }); + this.tree.layout(window.innerHeight, window.innerWidth); } this.requestProcessList(0); @@ -342,6 +343,13 @@ class ProcessExplorer { this.showContextMenu(e.element, true); } }); + + container.style.height = `${window.innerHeight}px`; + + window.addEventListener('resize', () => { + container.style.height = `${window.innerHeight}px`; + this.tree?.layout(window.innerHeight, window.innerWidth); + }); } private isDebuggable(cmd: string): boolean { From a97d84d3754065a6b54c2f89ca04cba6fb0b1d2b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 5 Aug 2022 11:58:54 -0700 Subject: [PATCH 290/303] Don't re-render markdown cells on `initializeWebViewState` (#157173) Fixes #156914 I don't really understand what `initializeWebViewState` is doing here but there are two things: - I've removed a list of renderers it creates and then never uses - I've removed the part where it calls back into `initializeMarkup`. This should have already been called during `_warmupViewport` --- .../browser/view/renderers/backLayerWebView.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index a82b4e723cf..d6d51a27ed2 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -929,13 +929,6 @@ var requirejs = (function() { } private initializeWebViewState() { - const renderers = new Set(); - for (const inset of this.insetMapping.values()) { - if (inset.renderer) { - renderers.add(inset.renderer); - } - } - this._preloadsCache.clear(); if (this._currentKernel) { this._updatePreloadsFromKernel(this._currentKernel); @@ -945,9 +938,6 @@ var requirejs = (function() { this._sendMessageToWebview({ ...inset.cachedCreation, initiallyHidden: this.hiddenInsetMapping.has(output) }); } - const mdCells = [...this.markupPreviewMapping.values()]; - this.markupPreviewMapping.clear(); - this.initializeMarkup(mdCells); this._updateStyles(); this._updateOptions(); } From 60c53f18dd03d9ff1ad9a1fbf86885ab7df0004a Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 5 Aug 2022 12:00:13 -0700 Subject: [PATCH 291/303] fix #155222. Adjust focus gutter indicator for markup cell. (#157286) * fix #155222. Adjust focus gutter indicator for markup cell. * :lipstick: --- .../browser/view/cellParts/cellFocusIndicator.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts index 5f68d74056c..6ce381f5145 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts @@ -81,7 +81,7 @@ export class CellFocusIndicator extends CellPart { this.bottom.domNode.style.transform = `translateY(${indicatorPostion.bottomIndicatorTop}px)`; this.left.setHeight(indicatorPostion.verticalIndicatorHeight); this.right.setHeight(indicatorPostion.verticalIndicatorHeight); - this.codeFocusIndicator.setHeight(indicatorPostion.verticalIndicatorHeight); + this.codeFocusIndicator.setHeight(indicatorPostion.verticalIndicatorHeight - this.getIndicatorTopMargin() * 2); } else { // code cell const cell = element as CodeCellViewModel; @@ -99,13 +99,17 @@ export class CellFocusIndicator extends CellPart { } private updateFocusIndicatorsForTitleMenu(): void { + this.left.domNode.style.transform = `translateY(${this.getIndicatorTopMargin()}px)`; + this.right.domNode.style.transform = `translateY(${this.getIndicatorTopMargin()}px)`; + } + + private getIndicatorTopMargin() { const layoutInfo = this.notebookEditor.notebookOptions.getLayoutConfiguration(); + if (this.titleToolbar.hasActions) { - this.left.domNode.style.transform = `translateY(${layoutInfo.editorToolbarHeight + layoutInfo.cellTopMargin}px)`; - this.right.domNode.style.transform = `translateY(${layoutInfo.editorToolbarHeight + layoutInfo.cellTopMargin}px)`; + return layoutInfo.editorToolbarHeight + layoutInfo.cellTopMargin; } else { - this.left.domNode.style.transform = `translateY(${layoutInfo.cellTopMargin}px)`; - this.right.domNode.style.transform = `translateY(${layoutInfo.cellTopMargin}px)`; + return layoutInfo.cellTopMargin; } } } From 97d94fc23b7e48575333a5a78b128a56fa542815 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Fri, 5 Aug 2022 12:20:53 -0700 Subject: [PATCH 292/303] Add delete and undo support for get most recently failed cell (#157032) * "Go To" last failing cell should disappear when deleting that cell Fixes #156299 --- .../notebookExecutionStateServiceImpl.ts | 74 ++++++++++++++++--- .../notebookEditorWidgetContextKeys.ts | 2 +- .../common/notebookExecutionStateService.ts | 9 ++- 3 files changed, 74 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/notebookExecutionStateServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/notebookExecutionStateServiceImpl.ts index 845cc72df8e..f5ad835726c 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookExecutionStateServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookExecutionStateServiceImpl.ts @@ -13,7 +13,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; import { CellEditType, CellUri, ICellEditOperation, NotebookCellExecutionState, NotebookCellInternalMetadata, NotebookTextModelWillAddRemoveEvent } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { CellExecutionUpdateType, INotebookExecutionService } from 'vs/workbench/contrib/notebook/common/notebookExecutionService'; -import { ICellExecuteUpdate, ICellExecutionComplete, ICellExecutionStateChangedEvent, ICellExecutionStateUpdate, INotebookCellExecution, INotebookExecutionStateService, INotebookFailStateChangedEvent } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService'; +import { ICellExecuteUpdate, ICellExecutionComplete, ICellExecutionStateChangedEvent, ICellExecutionStateUpdate, IFailedCellInfo, INotebookCellExecution, INotebookExecutionStateService, INotebookFailStateChangedEvent } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; export class NotebookExecutionStateService extends Disposable implements INotebookExecutionStateService { @@ -22,7 +22,7 @@ export class NotebookExecutionStateService extends Disposable implements INotebo private readonly _executions = new ResourceMap>(); private readonly _notebookListeners = new ResourceMap(); private readonly _cellListeners = new ResourceMap(); - private readonly _lastFailedCells = new ResourceMap(); + private readonly _lastFailedCells = new ResourceMap(); private readonly _onDidChangeCellExecution = this._register(new Emitter()); onDidChangeCellExecution = this._onDidChangeCellExecution.event; @@ -39,7 +39,8 @@ export class NotebookExecutionStateService extends Disposable implements INotebo } getLastFailedCellForNotebook(notebook: URI): number | undefined { - return this._lastFailedCells.get(notebook); + const failedCell = this._lastFailedCells.get(notebook); + return failedCell?.visible ? failedCell.cellHandle : undefined; } forceCancelNotebookExecutions(notebookUri: URI): void { @@ -142,14 +143,68 @@ export class NotebookExecutionStateService extends Disposable implements INotebo return exe; } - private _setLastFailedCell(notebook: URI, cellHandle: number) { - this._lastFailedCells.set(notebook, cellHandle); - this._onDidChangeLastRunFailState.fire({ failed: true, notebook }); + private _setLastFailedCell(notebookURI: URI, cellHandle: number): void { + const prevLastFailedCellInfo = this._lastFailedCells.get(notebookURI); + const notebook = this._notebookService.getNotebookTextModel(notebookURI); + if (!notebook) { + return; + } + + const newLastFailedCellInfo: IFailedCellInfo = { + cellHandle: cellHandle, + disposable: prevLastFailedCellInfo ? prevLastFailedCellInfo.disposable : this._getFailedCellListener(notebook), + visible: true + }; + + this._lastFailedCells.set(notebookURI, newLastFailedCellInfo); + + this._onDidChangeLastRunFailState.fire({ visible: true, notebook: notebookURI }); } - private _clearLastFailedCell(notebook: URI) { - this._lastFailedCells.delete(notebook); - this._onDidChangeLastRunFailState.fire({ failed: false, notebook: notebook }); + private _setLastFailedCellVisibility(notebookURI: URI, visible: boolean): void { + const lastFailedCellInfo = this._lastFailedCells.get(notebookURI); + + if (lastFailedCellInfo) { + this._lastFailedCells.set(notebookURI, { + cellHandle: lastFailedCellInfo.cellHandle, + disposable: lastFailedCellInfo.disposable, + visible: visible, + }); + } + + this._onDidChangeLastRunFailState.fire({ visible: visible, notebook: notebookURI }); + } + + private _clearLastFailedCell(notebookURI: URI): void { + const lastFailedCellInfo = this._lastFailedCells.get(notebookURI); + + if (lastFailedCellInfo) { + lastFailedCellInfo.disposable?.dispose(); + this._lastFailedCells.delete(notebookURI); + } + + this._onDidChangeLastRunFailState.fire({ visible: false, notebook: notebookURI }); + } + + private _getFailedCellListener(notebook: NotebookTextModel): IDisposable { + return notebook.onWillAddRemoveCells((e: NotebookTextModelWillAddRemoveEvent) => { + const lastFailedCell = this._lastFailedCells.get(notebook.uri)?.cellHandle; + if (lastFailedCell !== undefined) { + const lastFailedCellPos = notebook.cells.findIndex(c => c.handle === lastFailedCell); + e.rawEvent.changes.forEach(([start, deleteCount, addedCells]) => { + if (deleteCount) { + if (lastFailedCellPos >= start && lastFailedCellPos < start + deleteCount) { + this._setLastFailedCellVisibility(notebook.uri, false); + } + } + + if (addedCells.some(cell => cell.handle === lastFailedCell)) { + this._setLastFailedCellVisibility(notebook.uri, true); + } + + }); + } + }); } override dispose(): void { @@ -162,6 +217,7 @@ export class NotebookExecutionStateService extends Disposable implements INotebo this._cellListeners.forEach(disposable => disposable.dispose()); this._notebookListeners.forEach(disposable => disposable.dispose()); + this._lastFailedCells.forEach(elem => elem.disposable.dispose()); } } diff --git a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts index 27384f830d4..d71b45a02fa 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorWidgetContextKeys.ts @@ -137,7 +137,7 @@ export class NotebookEditorContextKeys { private _updateForLastRunFailState(e: INotebookFailStateChangedEvent): void { if (e.notebook === this._editor.textModel?.uri) { - this._lastCellFailed.set(e.failed); + this._lastCellFailed.set(e.visible); } } diff --git a/src/vs/workbench/contrib/notebook/common/notebookExecutionStateService.ts b/src/vs/workbench/contrib/notebook/common/notebookExecutionStateService.ts index d1fbe75907f..996364b1eb0 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookExecutionStateService.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookExecutionStateService.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Event } from 'vs/base/common/event'; +import { IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { NotebookCellExecutionState } from 'vs/workbench/contrib/notebook/common/notebookCommon'; @@ -40,10 +41,16 @@ export interface ICellExecutionStateChangedEvent { affectsNotebook(notebook: URI): boolean; } export interface INotebookFailStateChangedEvent { - failed: boolean; + visible: boolean; notebook: URI; } +export interface IFailedCellInfo { + cellHandle: number; + disposable: IDisposable; + visible: boolean; +} + export const INotebookExecutionStateService = createDecorator('INotebookExecutionStateService'); export interface INotebookExecutionStateService { From 81978e984b49c72b56daab04a11c646ed96d65ab Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 5 Aug 2022 14:34:40 -0500 Subject: [PATCH 293/303] Don't try to reveal an element that doesn't exist in the tree (#157309) --- src/vs/workbench/contrib/debug/browser/variablesView.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/variablesView.ts b/src/vs/workbench/contrib/debug/browser/variablesView.ts index aefd3c5c6b1..65cb8246dd3 100644 --- a/src/vs/workbench/contrib/debug/browser/variablesView.ts +++ b/src/vs/workbench/contrib/debug/browser/variablesView.ts @@ -99,7 +99,10 @@ export class VariablesView extends ViewPane { // Automatically expand the first non-expensive scope const scopes = await stackFrame.getScopes(); const toExpand = scopes.find(s => !s.expensive); - if (toExpand) { + + // A race condition could be present causing the scopes here to be different from the scopes that the tree just retrieved. + // If that happened, don't try to reveal anything, it will be straightened out on the next update + if (toExpand && this.tree.hasNode(toExpand)) { this.autoExpandedScopes.add(toExpand.getId()); await this.tree.expand(toExpand); } From fbda011715d076b58b1c820517b141d20ce4a55c Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 5 Aug 2022 13:00:33 -0700 Subject: [PATCH 294/303] build: do proper hashing for built-in dependencies (#157295) Fixes #157244 --- .../common/computeBuiltInDepsCacheKey.js | 15 +++++++++++++++ .../common/computeBuiltInDepsCacheKey.ts | 17 +++++++++++++++++ .../darwin/product-build-darwin-sign.yml | 3 ++- .../darwin/product-build-darwin-universal.yml | 3 ++- .../darwin/product-build-darwin.yml | 3 ++- .../linux/product-build-alpine.yml | 3 ++- .../linux/product-build-linux-client.yml | 3 ++- .../azure-pipelines/product-build-pr-cache.yml | 3 ++- build/azure-pipelines/product-compile.yml | 3 ++- build/azure-pipelines/web/product-build-web.yml | 3 ++- .../win32/product-build-win32.yml | 3 ++- 11 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 build/azure-pipelines/common/computeBuiltInDepsCacheKey.js create mode 100644 build/azure-pipelines/common/computeBuiltInDepsCacheKey.ts diff --git a/build/azure-pipelines/common/computeBuiltInDepsCacheKey.js b/build/azure-pipelines/common/computeBuiltInDepsCacheKey.js new file mode 100644 index 00000000000..abc90f6ed2c --- /dev/null +++ b/build/azure-pipelines/common/computeBuiltInDepsCacheKey.js @@ -0,0 +1,15 @@ +"use strict"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = require("fs"); +const path = require("path"); +const crypto = require("crypto"); +const productjson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../../product.json'), 'utf8')); +const shasum = crypto.createHash('sha1'); +for (const ext of productjson.builtInExtensions) { + shasum.update(`${ext.name}@${ext.version}`); +} +process.stdout.write(shasum.digest('hex')); diff --git a/build/azure-pipelines/common/computeBuiltInDepsCacheKey.ts b/build/azure-pipelines/common/computeBuiltInDepsCacheKey.ts new file mode 100644 index 00000000000..f0554361607 --- /dev/null +++ b/build/azure-pipelines/common/computeBuiltInDepsCacheKey.ts @@ -0,0 +1,17 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as fs from 'fs'; +import * as path from 'path'; +import * as crypto from 'crypto'; + +const productjson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../../product.json'), 'utf8')); +const shasum = crypto.createHash('sha1'); + +for (const ext of productjson.builtInExtensions) { + shasum.update(`${ext.name}@${ext.version}`); +} + +process.stdout.write(shasum.digest('hex')); diff --git a/build/azure-pipelines/darwin/product-build-darwin-sign.yml b/build/azure-pipelines/darwin/product-build-darwin-sign.yml index c7baec86b5f..72fd19ab27d 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-sign.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-sign.yml @@ -38,6 +38,7 @@ steps: - script: | mkdir -p .build node build/azure-pipelines/common/computeNodeModulesCacheKey.js x64 $ENABLE_TERRAPIN > .build/yarnlockhash + node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash displayName: Prepare yarn cache flags - task: Cache@2 @@ -49,7 +50,7 @@ steps: - task: Cache@2 inputs: - key: '"$(Agent.OS)" | product.json' + key: '"builtInDeps" | .build/builtindepshash' path: .build/builtInExtensions displayName: Restore built-in extensions diff --git a/build/azure-pipelines/darwin/product-build-darwin-universal.yml b/build/azure-pipelines/darwin/product-build-darwin-universal.yml index 80c16f5acff..ebc7104d6ce 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-universal.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-universal.yml @@ -38,6 +38,7 @@ steps: - script: | mkdir -p .build node build/azure-pipelines/common/computeNodeModulesCacheKey.js x64 $ENABLE_TERRAPIN > .build/yarnlockhash + node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash displayName: Prepare yarn cache flags - task: Cache@2 @@ -49,7 +50,7 @@ steps: - task: Cache@2 inputs: - key: '"$(Agent.OS)" | product.json' + key: '"builtInDeps" | .build/builtindepshash' path: .build/builtInExtensions displayName: Restore built-in extensions diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index f33df4096d6..e82a7cfa2e6 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -72,6 +72,7 @@ steps: - script: | mkdir -p .build node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash + node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash displayName: Prepare yarn cache flags - task: Cache@2 @@ -83,7 +84,7 @@ steps: - task: Cache@2 inputs: - key: '"$(Agent.OS)" | product.json' + key: '"builtInDeps" | .build/builtindepshash' path: .build/builtInExtensions displayName: Restore built-in extensions diff --git a/build/azure-pipelines/linux/product-build-alpine.yml b/build/azure-pipelines/linux/product-build-alpine.yml index 0faef3e7571..c60f16d0804 100644 --- a/build/azure-pipelines/linux/product-build-alpine.yml +++ b/build/azure-pipelines/linux/product-build-alpine.yml @@ -58,6 +58,7 @@ steps: - script: | mkdir -p .build node build/azure-pipelines/common/computeNodeModulesCacheKey.js "alpine" $ENABLE_TERRAPIN > .build/yarnlockhash + node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash displayName: Prepare yarn cache flags - task: Cache@2 @@ -69,7 +70,7 @@ steps: - task: Cache@2 inputs: - key: '"$(Agent.OS)" | product.json' + key: '"builtInDeps" | .build/builtindepshash' path: .build/builtInExtensions displayName: Restore built-in extensions diff --git a/build/azure-pipelines/linux/product-build-linux-client.yml b/build/azure-pipelines/linux/product-build-linux-client.yml index 2031e1d9f38..a2deeb9f5a9 100644 --- a/build/azure-pipelines/linux/product-build-linux-client.yml +++ b/build/azure-pipelines/linux/product-build-linux-client.yml @@ -91,6 +91,7 @@ steps: - script: | mkdir -p .build node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash + node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash displayName: Prepare yarn cache flags - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: @@ -111,7 +112,7 @@ steps: - task: Cache@2 inputs: - key: '"$(Agent.OS)" | product.json' + key: '"builtInDeps" | .build/builtindepshash' path: .build/builtInExtensions displayName: Restore built-in extensions diff --git a/build/azure-pipelines/product-build-pr-cache.yml b/build/azure-pipelines/product-build-pr-cache.yml index 17dd3b71919..042325394d3 100644 --- a/build/azure-pipelines/product-build-pr-cache.yml +++ b/build/azure-pipelines/product-build-pr-cache.yml @@ -10,6 +10,7 @@ steps: - script: | mkdir -p .build node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash + node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash displayName: Prepare yarn cache flags - task: Cache@2 @@ -21,7 +22,7 @@ steps: - task: Cache@2 inputs: - key: '"$(Agent.OS)" | product.json' + key: '"builtInDeps" | .build/builtindepshash' path: .build/builtInExtensions displayName: Restore built-in extensions diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index 5b67ef001f5..2b5bdc5b53a 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -46,6 +46,7 @@ steps: - script: | mkdir -p .build node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash + node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash displayName: Prepare yarn cache flags # using `genericNodeModules` instead of `nodeModules` here to avoid sharing the cache with builds running inside containers @@ -59,7 +60,7 @@ steps: # Cache built-in extensions to avoid GH rate limits. - task: Cache@2 inputs: - key: '"$(Agent.OS)" | product.json' + key: '"builtInDeps" | .build/builtindepshash' path: .build/builtInExtensions displayName: Restore built-in extensions diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 01130cf089a..61e409d4859 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -49,6 +49,7 @@ steps: - script: | mkdir -p .build node build/azure-pipelines/common/computeNodeModulesCacheKey.js "web" $ENABLE_TERRAPIN > .build/yarnlockhash + node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash displayName: Prepare yarn cache flags - task: Cache@2 @@ -60,7 +61,7 @@ steps: - task: Cache@2 inputs: - key: '"$(Agent.OS)" | product.json' + key: '"builtInDeps" | .build/builtindepshash' path: .build/builtInExtensions displayName: Restore built-in extensions diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index a12612737c0..bb19e4c0068 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -80,6 +80,7 @@ steps: "$(VSCODE_ARCH)" | Out-File -Encoding ascii -NoNewLine .build\arch "$env:ENABLE_TERRAPIN" | Out-File -Encoding ascii -NoNewLine .build\terrapin node build/azure-pipelines/common/computeNodeModulesCacheKey.js > .build/yarnlockhash + node build/azure-pipelines/common/computeBuiltInDepsCacheKey.js > .build/builtindepshash displayName: Prepare yarn cache flags - task: Cache@2 @@ -91,7 +92,7 @@ steps: - task: Cache@2 inputs: - key: '"$(Agent.OS)" | product.json' + key: '"builtInDeps" | .build/builtindepshash' path: .build/builtInExtensions displayName: Restore built-in extensions From b3a5653de78f3b32f7168715615a50531652cf82 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 5 Aug 2022 15:01:46 -0500 Subject: [PATCH 295/303] Don't show unbound breakpoint indicator for disabled breakpoints (#157319) Fixes #157317 --- src/vs/workbench/contrib/debug/browser/breakpointsView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 5e00363d505..35a3c09535d 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -287,7 +287,7 @@ export class BreakpointsView extends ViewPane { const dbg = currentType ? this.debugService.getAdapterManager().getDebugger(currentType) : undefined; const message = dbg?.uiMessages && dbg.uiMessages[DebuggerUiMessage.UnverifiedBreakpoints]; const debuggerHasUnverifiedBps = message && this.debugService.getModel().getBreakpoints().filter(bp => { - if (bp.verified) { + if (bp.verified || !bp.enabled) { return false; } From 24547bcd8e6417514441be86b19ab467d04e0cce Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 5 Aug 2022 13:13:58 -0700 Subject: [PATCH 296/303] labels: fix caching of unintended formatters (#157313) * labels: fix caching of unintended formatters `this.formatters` was the same list instance stored in the memo, so we could cache things we didn't want to. I believe this caused #156135, since things we _intend_ to cache from the extension host are parsed from JSON and cannot be circular. Fixes #156135 * labels: rev label storage to avoid previous bugs Fixes #155844 * fixup! tets --- src/vs/workbench/services/label/common/labelService.ts | 4 ++-- src/vs/workbench/services/label/test/browser/label.test.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/label/common/labelService.ts b/src/vs/workbench/services/label/common/labelService.ts index 4135a251e94..e969fc50dce 100644 --- a/src/vs/workbench/services/label/common/labelService.ts +++ b/src/vs/workbench/services/label/common/labelService.ts @@ -143,9 +143,9 @@ export class LabelService extends Disposable implements ILabelService { this.os = OS; this.userHome = pathService.defaultUriScheme === Schemas.file ? this.pathService.userHome({ preferLocal: true }) : undefined; - const memento = this.storedFormattersMemento = new Memento('cachedResourceLabelFormatters', storageService); + const memento = this.storedFormattersMemento = new Memento('cachedResourceLabelFormatters2', storageService); this.storedFormatters = memento.getMemento(StorageScope.PROFILE, StorageTarget.MACHINE); - this.formatters = this.storedFormatters?.formatters || []; + this.formatters = this.storedFormatters?.formatters?.slice() || []; // Remote environment is potentially long running this.resolveRemoteEnvironment(); diff --git a/src/vs/workbench/services/label/test/browser/label.test.ts b/src/vs/workbench/services/label/test/browser/label.test.ts index 745055c930e..813df9e5585 100644 --- a/src/vs/workbench/services/label/test/browser/label.test.ts +++ b/src/vs/workbench/services/label/test/browser/label.test.ts @@ -166,7 +166,7 @@ suite('URI Label', () => { test('label caching', () => { - const m = new Memento('cachedResourceLabelFormatters', storageService).getMemento(StorageScope.PROFILE, StorageTarget.MACHINE); + const m = new Memento('cachedResourceLabelFormatters2', storageService).getMemento(StorageScope.PROFILE, StorageTarget.MACHINE); const makeFormatter = (scheme: string): ResourceLabelFormatter => ({ formatting: { label: `\${path} (${scheme})`, separator: '/' }, scheme }); assert.deepStrictEqual(m, {}); From 0df35483c2be7e1675a7e2dc44040a53cb92d3d7 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 5 Aug 2022 13:25:34 -0700 Subject: [PATCH 297/303] Align Cell Markup/Markdown (#157289) --- .../contrib/notebook/browser/contrib/find/findModel.ts | 2 +- .../workbench/contrib/notebook/browser/notebookBrowser.ts | 4 ++-- .../notebook/browser/view/cellParts/cellFocusIndicator.ts | 2 -- .../view/cellParts/{markdownCell.ts => markupCell.ts} | 2 +- .../notebook/browser/view/renderers/cellRenderer.ts | 4 ++-- .../notebook/browser/viewModel/markupCellViewModel.ts | 8 ++++---- 6 files changed, 10 insertions(+), 12 deletions(-) rename src/vs/workbench/contrib/notebook/browser/view/cellParts/{markdownCell.ts => markupCell.ts} (99%) diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts b/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts index 2f5d35ba93f..be1e1c5c07d 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/find/findModel.ts @@ -225,7 +225,7 @@ export class FindModel extends Disposable { return; } - // the cell is a markdown cell in editing mode or a code cell, both should have monaco editor rendered + // the cell is a markup cell in editing mode or a code cell, both should have monaco editor rendered if (!this._currentMatchDecorations) { // no current highlight decoration diff --git a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts index 9b245482c3d..18e9294742b 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts @@ -180,7 +180,7 @@ export interface CodeCellLayoutChangeEvent { font?: FontInfo; } -export interface MarkdownCellLayoutInfo { +export interface MarkupCellLayoutInfo { readonly fontInfo: FontInfo | null; readonly editorWidth: number; readonly editorHeight: number; @@ -196,7 +196,7 @@ export enum CellLayoutContext { Fold } -export interface MarkdownCellLayoutChangeEvent { +export interface MarkupCellLayoutChangeEvent { font?: FontInfo; outerWidth?: number; editorHeight?: number; diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts index 6ce381f5145..0b27d730a1d 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts @@ -76,14 +76,12 @@ export class CellFocusIndicator extends CellPart { override updateInternalLayoutNow(element: ICellViewModel): void { if (element.cellKind === CellKind.Markup) { - // markdown cell const indicatorPostion = this.notebookEditor.notebookOptions.computeIndicatorPosition(element.layoutInfo.totalHeight, (element as MarkupCellViewModel).layoutInfo.foldHintHeight, this.notebookEditor.textModel?.viewType); this.bottom.domNode.style.transform = `translateY(${indicatorPostion.bottomIndicatorTop}px)`; this.left.setHeight(indicatorPostion.verticalIndicatorHeight); this.right.setHeight(indicatorPostion.verticalIndicatorHeight); this.codeFocusIndicator.setHeight(indicatorPostion.verticalIndicatorHeight - this.getIndicatorTopMargin() * 2); } else { - // code cell const cell = element as CodeCellViewModel; const layoutInfo = this.notebookEditor.notebookOptions.getLayoutConfiguration(); const bottomToolbarDimensions = this.notebookEditor.notebookOptions.computeBottomToolbarDimensions(this.notebookEditor.textModel?.viewType); diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/markupCell.ts similarity index 99% rename from src/vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell.ts rename to src/vs/workbench/contrib/notebook/browser/view/cellParts/markupCell.ts index ac666a052eb..698bf885de4 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/markupCell.ts @@ -29,7 +29,7 @@ import { MarkdownCellRenderTemplate } from 'vs/workbench/contrib/notebook/browse import { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel'; import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService'; -export class StatefulMarkdownCell extends Disposable { +export class MarkupCell extends Disposable { private editor: CodeEditorWidget | null = null; diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts index 8e3ab0b4640..5bbf9dd0be2 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -41,7 +41,7 @@ import { RunToolbar } from 'vs/workbench/contrib/notebook/browser/view/cellParts import { CollapsedCellInput } from 'vs/workbench/contrib/notebook/browser/view/cellParts/collapsedCellInput'; import { CollapsedCellOutput } from 'vs/workbench/contrib/notebook/browser/view/cellParts/collapsedCellOutput'; import { FoldedCellHint } from 'vs/workbench/contrib/notebook/browser/view/cellParts/foldedCellHint'; -import { StatefulMarkdownCell } from 'vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell'; +import { MarkupCell } from 'vs/workbench/contrib/notebook/browser/view/cellParts/markupCell'; import { CodeCellRenderTemplate, MarkdownCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon'; import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; import { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel'; @@ -210,7 +210,7 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen return; } - templateData.elementDisposables.add(templateData.instantiationService.createInstance(StatefulMarkdownCell, this.notebookEditor, element, templateData, this.renderedEditors)); + templateData.elementDisposables.add(templateData.instantiationService.createInstance(MarkupCell, this.notebookEditor, element, templateData, this.renderedEditors)); } disposeTemplate(templateData: MarkdownCellRenderTemplate): void { diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts index d603fa80208..892e19b433f 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts @@ -7,7 +7,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import * as UUID from 'vs/base/common/uuid'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { CellEditState, CellFindMatch, CellFoldingState, CellLayoutContext, CellLayoutState, EditorFoldingStateDelegate, ICellOutputViewModel, ICellViewModel, MarkdownCellLayoutChangeEvent, MarkdownCellLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellEditState, CellFindMatch, CellFoldingState, CellLayoutContext, CellLayoutState, EditorFoldingStateDelegate, ICellOutputViewModel, ICellViewModel, MarkupCellLayoutChangeEvent, MarkupCellLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { BaseCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel'; import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel'; import { CellKind, INotebookSearchOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; @@ -23,7 +23,7 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM readonly cellKind = CellKind.Markup; - private _layoutInfo: MarkdownCellLayoutInfo; + private _layoutInfo: MarkupCellLayoutInfo; private _renderedHtml?: string; @@ -58,7 +58,7 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM throw new Error('MarkdownCellViewModel.editorHeight is write only'); } - protected readonly _onDidChangeLayout = this._register(new Emitter()); + protected readonly _onDidChangeLayout = this._register(new Emitter()); readonly onDidChangeLayout = this._onDidChangeLayout.event; get foldingState() { @@ -185,7 +185,7 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM } } - layoutChange(state: MarkdownCellLayoutChangeEvent) { + layoutChange(state: MarkupCellLayoutChangeEvent) { // recompute const foldHintHeight = this._computeFoldHintHeight(); if (!this.isInputCollapsed) { From 49dfe32df2da4db0b43eaf9a2668da5a8133122c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 5 Aug 2022 13:55:26 -0700 Subject: [PATCH 298/303] Change log level for reconnect related logs Part of #133542 --- src/vs/platform/terminal/node/ptyService.ts | 8 ++++---- .../terminal/electron-sandbox/localTerminalBackend.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 615de9d6b5a..048cf2d12fb 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -213,9 +213,9 @@ export class PtyService extends Disposable implements IPtyService { async attachToProcess(id: number): Promise { try { await this._throwIfNoPty(id).attach(); - this._logService.trace(`Persistent process reconnection "${id}"`); + this._logService.info(`Persistent process reconnection "${id}"`); } catch (e) { - this._logService.trace(`Persistent process reconnection "${id}" failed`, e.message); + this._logService.warn(`Persistent process reconnection "${id}" failed`, e.message); throw e; } } @@ -341,7 +341,7 @@ export class PtyService extends Disposable implements IPtyService { try { return this._revivedPtyIdMap.get(id)?.newId; } catch (e) { - this._logService.trace(`Couldn't find terminal ID ${id}`, e.message); + this._logService.warn(`Couldn't find terminal ID ${id}`, e.message); } return undefined; } @@ -384,7 +384,7 @@ export class PtyService extends Disposable implements IPtyService { relativeSize: t.relativeSize }; } catch (e) { - this._logService.trace(`Couldn't get layout info, a terminal was probably disconnected`, e.message); + this._logService.warn(`Couldn't get layout info, a terminal was probably disconnected`, e.message); // this will be filtered out and not reconnected return { terminal: null, diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts index d61acd4c4a4..410cb5de5ae 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts @@ -163,7 +163,7 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke this._ptys.set(id, pty); return pty; } catch (e) { - this._logService.trace(`Couldn't attach to process ${e.message}`); + this._logService.warn(`Couldn't attach to process ${e.message}`); } return undefined; } @@ -173,7 +173,7 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke const newId = await this._localPtyService.getRevivedPtyNewId(id) ?? id; return await this.attachToProcess(newId); } catch (e) { - this._logService.trace(`Couldn't attach to process ${e.message}`); + this._logService.warn(`Couldn't attach to process ${e.message}`); } return undefined; } From b134ea9ec2b3dbbcc8d56c93c93fec1932432496 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 5 Aug 2022 14:01:05 -0700 Subject: [PATCH 299/303] Always throw when attaching to orphan processes Part of #133542 --- src/vs/platform/terminal/node/ptyService.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 048cf2d12fb..4c81a3d1f30 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -582,12 +582,12 @@ export class PersistentTerminalProcess extends Disposable { async attach(): Promise { this._logService.trace('persistentTerminalProcess#attach', this._persistentProcessId); + // Something wrong happened if the disconnect runner is not canceled, this likely means + // multiple windows attempted to attach. + if (!await this._isOrphaned()) { + throw new Error(`Cannot attach to persistent process "${this._persistentProcessId}", it is already adopted`); + } if (!this._disconnectRunner1.isScheduled() && !this._disconnectRunner2.isScheduled()) { - // Something wrong happened if the disconnect runner is not canceled, this likely means - // multiple windows attempted to attach. - if (!await this._isOrphaned()) { - throw new Error(`Cannot attach to persistent process "${this._persistentProcessId}", it is already adopted`); - } this._logService.warn(`Persistent process "${this._persistentProcessId}": Process had no disconnect runners but was an orphan`); } this._disconnectRunner1.cancel(); From 4a0555d9489a676d6651bcbbc00a2fb374ffb37c Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 5 Aug 2022 14:38:03 -0700 Subject: [PATCH 300/303] Fix #149606. Refresh notebook editor focus on tab switching. (#157333) --- .../workbench/contrib/notebook/browser/notebookEditorWidget.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index f802ab61bdc..9bd30b4ad13 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -1855,6 +1855,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD // The notebook editor doesn't have focus yet if (!this.hasEditorFocus()) { this.focusContainer(); + // trigger editor to update as FocusTracker might not emit focus change event + this.updateEditorFocus(); } if (element && element.focusMode === CellFocusMode.Editor) { From 8cfae763ead3050789e9e8131e7fa598c3e043da Mon Sep 17 00:00:00 2001 From: meganrogge Date: Fri, 5 Aug 2022 16:08:26 -0700 Subject: [PATCH 301/303] fix #157128 --- .../contrib/terminal/browser/media/shellIntegration-rc.zsh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh index 7db2583a817..a3734127716 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh @@ -125,3 +125,7 @@ __vsc_preexec() { } add-zsh-hook precmd __vsc_precmd add-zsh-hook preexec __vsc_preexec + +if [[ $options[login] = off ]]; then + ZDOTDIR=$USER_ZDOTDIR +fi From 8eeac1fb2907531d9e23af69a89ba096fd833636 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 5 Aug 2022 16:33:19 -0700 Subject: [PATCH 302/303] Fix pwsh shell integration tests Part of #157083 --- .../terminal/test/node/terminalEnvironment.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/platform/terminal/test/node/terminalEnvironment.test.ts b/src/vs/platform/terminal/test/node/terminalEnvironment.test.ts index b6f76ccafbe..3f460194c30 100644 --- a/src/vs/platform/terminal/test/node/terminalEnvironment.test.ts +++ b/src/vs/platform/terminal/test/node/terminalEnvironment.test.ts @@ -25,14 +25,14 @@ suite('platform - terminalEnvironment', () => { suite('pwsh', () => { const expectedPs1 = process.platform === 'win32' - ? `${repoRoot}\\out\\vs\\workbench\\contrib\\terminal\\browser\\media\\shellIntegration.ps1` - : `${repoRoot}/out/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1`; + ? `try { . "${repoRoot}\\out\\vs\\workbench\\contrib\\terminal\\browser\\media\\shellIntegration.ps1" } catch {}` + : `. "${repoRoot}/out/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1"`; suite('should override args', () => { const enabledExpectedResult = Object.freeze({ newArgs: [ '-noexit', '-command', - `. "${expectedPs1}"` + expectedPs1 ], envMixin: { VSCODE_INJECTION: '1' @@ -63,7 +63,7 @@ suite('platform - terminalEnvironment', () => { '-l', '-noexit', '-command', - `. "${expectedPs1}"` + expectedPs1 ], envMixin: { VSCODE_INJECTION: '1' From e58c66c819a9739dc3d70e04943db03f213c3735 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 6 Aug 2022 19:37:34 +0200 Subject: [PATCH 303/303] Issue reporter fails to report when `sandbox` is enabled (#157368) issue repoter misses data --- src/vs/code/electron-sandbox/issue/issueReporterMain.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts index dc4a1692710..ed78a7d1963 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts @@ -73,6 +73,7 @@ export class IssueReporter extends Disposable { const targetExtension = configuration.data.extensionId ? configuration.data.enabledExtensions.find(extension => extension.id === configuration.data.extensionId) : undefined; this.issueReporterModel = new IssueReporterModel({ + ...configuration.data, issueType: configuration.data.issueType || IssueType.Bug, versionInfo: { vscodeVersion: `${configuration.product.nameShort} ${!!configuration.product.darwinUniversalAssetId ? `${configuration.product.version} (Universal)` : configuration.product.version} (${configuration.product.commit || 'Commit unknown'}, ${configuration.product.date || 'Date unknown'})`, @@ -80,7 +81,7 @@ export class IssueReporter extends Disposable { }, extensionsDisabled: !!configuration.disableExtensions, fileOnExtension: configuration.data.extensionId ? !targetExtension?.isBuiltin : undefined, - selectedExtension: targetExtension, + selectedExtension: targetExtension }); const issueReporterElement = this.getElementById('issue-reporter');