diff --git a/.github/classifier.json b/.github/classifier.json index 3b23ece3ce8..5b5625f6e93 100644 --- a/.github/classifier.json +++ b/.github/classifier.json @@ -23,7 +23,7 @@ "context-keys": {"assign": []}, "css-less-scss": {"assign": ["aeschli"]}, "custom-editors": {"assign": ["mjbvz"]}, - "debug": {"assign": ["roblourens"]}, + "debug": {"assign": ["weinand"]}, "dialogs": {"assign": ["sbatten"]}, "diff-editor": {"assign": ["alexdima"]}, "dropdown": {"assign": []}, diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9260f4dc88..a9317a9e382 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: 16 @@ -113,7 +113,7 @@ jobs: sudo update-rc.d xvfb defaults sudo service xvfb start - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: 16 @@ -185,7 +185,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: 16 @@ -259,7 +259,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: 16 diff --git a/.github/workflows/monaco-editor.yml b/.github/workflows/monaco-editor.yml index 24ea5fea85e..e52713a3e99 100644 --- a/.github/workflows/monaco-editor.yml +++ b/.github/workflows/monaco-editor.yml @@ -20,9 +20,9 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: - node-version: 14 + node-version: 16 - name: Compute node modules cache key id: nodeModulesCacheKey diff --git a/.github/workflows/rich-navigation.yml b/.github/workflows/rich-navigation.yml index 90d7383e6da..da11ba22759 100644 --- a/.github/workflows/rich-navigation.yml +++ b/.github/workflows/rich-navigation.yml @@ -22,7 +22,7 @@ jobs: key: ${{ runner.os }}-dependencies-${{ hashfiles('yarn.lock') }} restore-keys: ${{ runner.os }}-dependencies- - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: 16 diff --git a/.vscode/extensions.json b/.vscode/extensions.json index e8d77d395ad..20d53a66c6e 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -3,6 +3,7 @@ // for the documentation about the extensions.json format "recommendations": [ "dbaeumer.vscode-eslint", - "EditorConfig.EditorConfig" + "EditorConfig.EditorConfig", + "ms-vscode.vscode-selfhost-test-provider" ] } diff --git a/.vscode/notebooks/endgame.github-issues b/.vscode/notebooks/endgame.github-issues index 90cc4971f43..48195c79000 100644 --- a/.vscode/notebooks/endgame.github-issues +++ b/.vscode/notebooks/endgame.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-remotehub repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-unpkg\n\n$MILESTONE=milestone:\"April 2022\"" + "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-remotehub repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-unpkg\r\n\r\n$MILESTONE=milestone:\"May 2022\"" }, { "kind": 1, diff --git a/.vscode/notebooks/my-endgame.github-issues b/.vscode/notebooks/my-endgame.github-issues index e2356a2d8a9..4ce504b017f 100644 --- a/.vscode/notebooks/my-endgame.github-issues +++ b/.vscode/notebooks/my-endgame.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remotehub repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal\n\n$MILESTONE=milestone:\"April 2022\"\n\n$MINE=assignee:@me" + "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remotehub repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal\n\n$MILESTONE=milestone:\"May 2022\"\n\n$MINE=assignee:@me" }, { "kind": 1, diff --git a/.vscode/notebooks/verification.github-issues b/.vscode/notebooks/verification.github-issues index b4a61ec261c..7015a401be5 100644 --- a/.vscode/notebooks/verification.github-issues +++ b/.vscode/notebooks/verification.github-issues @@ -12,7 +12,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-jupyter repo:microsoft/vscode-python\n$milestone=milestone:\"March 2022\"" + "value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-jupyter repo:microsoft/vscode-python\n$milestone=milestone:\"May 2022\"" }, { "kind": 1, diff --git a/.vscode/notebooks/vscode-dev.github-issues b/.vscode/notebooks/vscode-dev.github-issues index 2178fa29d59..9266fd7654c 100644 --- a/.vscode/notebooks/vscode-dev.github-issues +++ b/.vscode/notebooks/vscode-dev.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "repo:microsoft/vscode-dev milestone:\"December 2021\" is:open" + "value": "repo:microsoft/vscode-dev milestone:\"May 2022\" is:open" }, { "kind": 2, @@ -32,11 +32,11 @@ { "kind": 2, "language": "github-issues", - "value": "repo:microsoft/vscode-remote-repositories-github milestone:\"December 2021\" is:open" + "value": "repo:microsoft/vscode-remote-repositories-github milestone:\"May 2022\" is:open" }, { "kind": 2, "language": "github-issues", - "value": "repo:microsoft/vscode-remotehub milestone:\"December 2021\" is:open" + "value": "repo:microsoft/vscode-remotehub milestone:\"May 2022\" is:open" } -] +] \ No newline at end of file diff --git a/.yarnrc b/.yarnrc index f2811eb170a..bd8b717272f 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,4 +1,4 @@ disturl "https://electronjs.org/headers" -target "17.4.4" +target "17.4.7" runtime "electron" build_from_source "true" diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 0d0c0c47bba..0fca6a19272 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -11,7 +11,7 @@ This project incorporates components from the projects listed below. The origina 4. atom/language-java version 0.32.1 (https://github.com/atom/language-java) 5. atom/language-sass version 0.62.1 (https://github.com/atom/language-sass) 6. atom/language-shellscript version 0.28.2 (https://github.com/atom/language-shellscript) -7. atom/language-xml version 0.14.0 (https://github.com/atom/language-xml) +7. atom/language-xml version 0.35.2 (https://github.com/atom/language-xml) 8. better-go-syntax version 1.0.0 (https://github.com/jeff-hykin/better-go-syntax/ ) 9. Colorsublime-Themes version 0.1.0 (https://github.com/Colorsublime/Colorsublime-Themes) 10. daaain/Handlebars version 1.8.0 (https://github.com/daaain/Handlebars) @@ -32,15 +32,15 @@ This project incorporates components from the projects listed below. The origina 25. James-Yu/LaTeX-Workshop version 8.19.1 (https://github.com/James-Yu/LaTeX-Workshop) 26. jeff-hykin/cpp-textmate-grammar version 1.12.11 (https://github.com/jeff-hykin/cpp-textmate-grammar) 27. jeff-hykin/cpp-textmate-grammar version 1.15.6 (https://github.com/jeff-hykin/cpp-textmate-grammar) -28. jlelong/vscode-latex-basics version 1.2.0 (https://github.com/jlelong/vscode-latex-basics) +28. jlelong/vscode-latex-basics version 1.3.0 (https://github.com/jlelong/vscode-latex-basics) 29. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify) 30. JuliaEditorSupport/atom-language-julia version 0.22.1 (https://github.com/JuliaEditorSupport/atom-language-julia) 31. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert) 32. language-docker (https://github.com/moby/moby) 33. language-less version 0.34.2 (https://github.com/atom/language-less) -34. language-php version 0.48.0 (https://github.com/atom/language-php) +34. language-php version 0.48.1 (https://github.com/atom/language-php) 35. MagicStack/MagicPython version 1.1.1 (https://github.com/MagicStack/MagicPython) -36. marked version 3.0.2 (https://github.com/markedjs/marked) +36. marked version 4.0.16 (https://github.com/markedjs/marked) 37. mdn-data version 1.1.12 (https://github.com/mdn/data) 38. microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/microsoft/TypeScript-TmLanguage) 39. microsoft/vscode-JSON.tmLanguage (https://github.com/microsoft/vscode-JSON.tmLanguage) @@ -1072,7 +1072,7 @@ END OF HTML 5.1 W3C Working Draft NOTICES AND INFORMATION ========================================= MIT License -Copyright (c) 2021 REditorSupport +Copyright (c) 2022 REditorSupport Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/build/azure-pipelines/linux/product-build-linux-client.yml b/build/azure-pipelines/linux/product-build-linux-client.yml index 7dba0eef378..8f3b4aad146 100644 --- a/build/azure-pipelines/linux/product-build-linux-client.yml +++ b/build/azure-pipelines/linux/product-build-linux-client.yml @@ -121,7 +121,16 @@ steps: - script: | set -e - export npm_config_arch=$(NPM_ARCH) + if [ "$NPM_ARCH" = "armv7l" ]; then + # There is no target_arch="armv7l" supported by node_gyp, + # arm versions for compilation are decided based on the CC + # macros. + # Mapping value is based on + # https://github.com/nodejs/node/blob/0903515e126c2697042d6546c6aa4b72e1a4b33e/configure.py#L49-L50 + export npm_config_arch="arm" + else + export npm_config_arch=$(NPM_ARCH) + fi if [ -z "$CC" ] || [ -z "$CXX" ]; then # Download clang based on chromium revision used by vscode diff --git a/build/azure-pipelines/product-build-pr.yml b/build/azure-pipelines/product-build-pr.yml index 5b09f8ee77e..3c45858413e 100644 --- a/build/azure-pipelines/product-build-pr.yml +++ b/build/azure-pipelines/product-build-pr.yml @@ -21,7 +21,7 @@ variables: - name: skipComponentGovernanceDetection value: true - name: ENABLE_TERRAPIN - value: true + value: false - name: VSCODE_PUBLISH value: false - name: VSCODE_QUALITY diff --git a/build/azure-pipelines/upload-configuration.js b/build/azure-pipelines/upload-configuration.js index 8be7f4492cc..be1bfd018fd 100644 --- a/build/azure-pipelines/upload-configuration.js +++ b/build/azure-pipelines/upload-configuration.js @@ -52,7 +52,7 @@ function generateVSCodeConfigurationTask() { const timer = setTimeout(() => { codeProc.kill(); reject(new Error('export-default-configuration process timed out')); - }, 30 * 1000); + }, 60 * 1000); codeProc.on('error', err => { clearTimeout(timer); reject(err); diff --git a/build/azure-pipelines/upload-configuration.ts b/build/azure-pipelines/upload-configuration.ts index 49bc00fc46f..1e718cadfd0 100644 --- a/build/azure-pipelines/upload-configuration.ts +++ b/build/azure-pipelines/upload-configuration.ts @@ -63,7 +63,7 @@ function generateVSCodeConfigurationTask(): Promise { const timer = setTimeout(() => { codeProc.kill(); reject(new Error('export-default-configuration process timed out')); - }, 30 * 1000); + }, 60 * 1000); codeProc.on('error', err => { clearTimeout(timer); diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 4b746afc2a1..7501869b57d 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -136,13 +136,6 @@ steps: displayName: Download Electron condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { node build\lib\policies } - displayName: Generate Group Policy definitions - condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 94b22026a07..268650959cd 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -288,6 +288,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op all = es.merge(all, gulp.src('resources/linux/code.png', { base: '.' })); } else if (platform === 'darwin') { const shortcut = gulp.src('resources/darwin/bin/code.sh') + .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename('bin/code')); all = es.merge(all, shortcut); @@ -330,13 +331,10 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op result = es.merge(result, gulp.src('resources/win32/VisualElementsManifest.xml', { base: 'resources/win32' }) .pipe(rename(product.nameShort + '.VisualElementsManifest.xml'))); - result = es.merge(result, gulp.src('.build/policies/win32/**', { base: '.build/policies/win32' }) - .pipe(rename(f => f.dirname = `policies/${f.dirname}`))); - } else if (platform === 'linux') { result = es.merge(result, gulp.src('resources/linux/bin/code.sh', { base: '.' }) .pipe(replace('@@PRODNAME@@', product.nameLong)) - .pipe(replace('@@NAME@@', product.applicationName)) + .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename('bin/' + product.applicationName))); } diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index 7c99da42ae7..b7b2cd1833e 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -118,6 +118,10 @@ "name": "vs/workbench/contrib/markers", "project": "vscode-workbench" }, + { + "name": "vs/workbench/contrib/mergeEditor", + "project": "vscode-workbench" + }, { "name": "vs/workbench/contrib/localization", "project": "vscode-workbench" diff --git a/build/linux/rpm/dep-lists.js b/build/linux/rpm/dep-lists.js index 99064a1f7e6..0896b1bb6ca 100644 --- a/build/linux/rpm/dep-lists.js +++ b/build/linux/rpm/dep-lists.js @@ -77,7 +77,6 @@ exports.referenceGeneratedDepsByArch = { 'libgdk_pixbuf-2.0.so.0()(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', - 'libgmodule-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', @@ -161,7 +160,6 @@ exports.referenceGeneratedDepsByArch = { 'libgdk_pixbuf-2.0.so.0', 'libgio-2.0.so.0', 'libglib-2.0.so.0', - 'libgmodule-2.0.so.0', 'libgobject-2.0.so.0', 'libgtk-3.so.0', 'libgtk-3.so.0()(64bit)', @@ -252,7 +250,6 @@ exports.referenceGeneratedDepsByArch = { 'libgdk_pixbuf-2.0.so.0()(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', - 'libgmodule-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', diff --git a/build/linux/rpm/dep-lists.ts b/build/linux/rpm/dep-lists.ts index 524cc0d7edd..8ef34d0320f 100644 --- a/build/linux/rpm/dep-lists.ts +++ b/build/linux/rpm/dep-lists.ts @@ -77,7 +77,6 @@ export const referenceGeneratedDepsByArch = { 'libgdk_pixbuf-2.0.so.0()(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', - 'libgmodule-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', @@ -161,7 +160,6 @@ export const referenceGeneratedDepsByArch = { 'libgdk_pixbuf-2.0.so.0', 'libgio-2.0.so.0', 'libglib-2.0.so.0', - 'libgmodule-2.0.so.0', 'libgobject-2.0.so.0', 'libgtk-3.so.0', 'libgtk-3.so.0()(64bit)', @@ -252,7 +250,6 @@ export const referenceGeneratedDepsByArch = { 'libgdk_pixbuf-2.0.so.0()(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', - 'libgmodule-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', diff --git a/build/npm/preinstall.js b/build/npm/preinstall.js index b217c7bc12d..a839653f75c 100644 --- a/build/npm/preinstall.js +++ b/build/npm/preinstall.js @@ -9,10 +9,13 @@ const majorNodeVersion = parseInt(nodeVersion[1]); const minorNodeVersion = parseInt(nodeVersion[2]); const patchNodeVersion = parseInt(nodeVersion[3]); -if (majorNodeVersion < 14 || (majorNodeVersion === 14 && minorNodeVersion < 17) || (majorNodeVersion === 14 && minorNodeVersion === 17 && patchNodeVersion < 4) || majorNodeVersion >= 17) { - console.error('\033[1;31m*** Please use node.js versions >=14.17.4 and <17.\033[0;0m'); +if (majorNodeVersion < 16 || (majorNodeVersion === 16 && minorNodeVersion < 14)) { + console.error('\033[1;31m*** Please use node.js versions >=16.14.x and <17.\033[0;0m'); err = true; } +if (majorNodeVersion >= 17) { + console.warn('\033[1;31m*** Warning: Versions of node.js >= 17 have not been tested.\033[0;0m') +} const path = require('path'); const fs = require('fs'); diff --git a/cgmanifest.json b/cgmanifest.json index d153e97eb0f..7d3d6ac325a 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -60,12 +60,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "085a15fd95969f3c61a52b39d64a7048d306dabe" + "commitHash": "66dd03293be5c6c7a06e1517bb80100030973be6" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "17.4.4" + "version": "17.4.7" }, { "component": { diff --git a/extensions/configuration-editing/schemas/devContainer.schema.generated.json b/extensions/configuration-editing/schemas/devContainer.schema.generated.json index d47f1192400..4ae5033f3f1 100644 --- a/extensions/configuration-editing/schemas/devContainer.schema.generated.json +++ b/extensions/configuration-editing/schemas/devContainer.schema.generated.json @@ -406,6 +406,7 @@ }, "customizations": { "type": "object", + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -429,13 +430,186 @@ } }, "additionalProperties": false + }, + "codespaces": { + "type": "object", + "description": "Customizations specific to GitHub Codespaces", + "properties": { + "repositories": { + "type": "object", + "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", + "patternProperties": { + "^[a-zA-Z0-9-_.]+[.]*/[a-zA-Z0-9-_*]+[.]*$": { + "type": "object", + "additionalProperties": true, + "oneOf": [ + { + "properties": { + "permissions": { + "type": "object", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "additionalProperties": true, + "anyOf": [ + { + "properties": { + "actions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "checks": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "contents": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "deployments": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "discussions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "issues": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "packages": { + "type": "string", + "enum": [ + "read" + ] + } + } + }, + { + "properties": { + "pages": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "pull_requests": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "repository_projects": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "statuses": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "workflows": { + "type": "string", + "enum": [ + "write" + ] + } + } + } + ] + } + } + }, + { + "properties": { + "permissions": { + "type": "string", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "enum": [ + "read-all", + "write-all" + ] + } + } + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } }, - "additionalProperties": { - "type": "object", - "additionalProperties": true - }, - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." + "additionalProperties": false + }, + "additionalProperties": { + "type": "object", + "additionalProperties": true } }, "required": [ @@ -842,6 +1016,7 @@ }, "customizations": { "type": "object", + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -865,13 +1040,186 @@ } }, "additionalProperties": false + }, + "codespaces": { + "type": "object", + "description": "Customizations specific to GitHub Codespaces", + "properties": { + "repositories": { + "type": "object", + "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", + "patternProperties": { + "^[a-zA-Z0-9-_.]+[.]*/[a-zA-Z0-9-_*]+[.]*$": { + "type": "object", + "additionalProperties": true, + "oneOf": [ + { + "properties": { + "permissions": { + "type": "object", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "additionalProperties": true, + "anyOf": [ + { + "properties": { + "actions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "checks": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "contents": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "deployments": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "discussions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "issues": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "packages": { + "type": "string", + "enum": [ + "read" + ] + } + } + }, + { + "properties": { + "pages": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "pull_requests": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "repository_projects": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "statuses": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "workflows": { + "type": "string", + "enum": [ + "write" + ] + } + } + } + ] + } + } + }, + { + "properties": { + "permissions": { + "type": "string", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "enum": [ + "read-all", + "write-all" + ] + } + } + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } }, - "additionalProperties": { - "type": "object", - "additionalProperties": true - }, - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." + "additionalProperties": false + }, + "additionalProperties": { + "type": "object", + "additionalProperties": true } }, "required": [ @@ -1244,6 +1592,7 @@ }, "customizations": { "type": "object", + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -1267,13 +1616,186 @@ } }, "additionalProperties": false + }, + "codespaces": { + "type": "object", + "description": "Customizations specific to GitHub Codespaces", + "properties": { + "repositories": { + "type": "object", + "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", + "patternProperties": { + "^[a-zA-Z0-9-_.]+[.]*/[a-zA-Z0-9-_*]+[.]*$": { + "type": "object", + "additionalProperties": true, + "oneOf": [ + { + "properties": { + "permissions": { + "type": "object", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "additionalProperties": true, + "anyOf": [ + { + "properties": { + "actions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "checks": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "contents": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "deployments": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "discussions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "issues": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "packages": { + "type": "string", + "enum": [ + "read" + ] + } + } + }, + { + "properties": { + "pages": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "pull_requests": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "repository_projects": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "statuses": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "workflows": { + "type": "string", + "enum": [ + "write" + ] + } + } + } + ] + } + } + }, + { + "properties": { + "permissions": { + "type": "string", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "enum": [ + "read-all", + "write-all" + ] + } + } + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } }, - "additionalProperties": { - "type": "object", - "additionalProperties": true - }, - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." + "additionalProperties": false + }, + "additionalProperties": { + "type": "object", + "additionalProperties": true } }, "required": [ @@ -1620,6 +2142,7 @@ }, "customizations": { "type": "object", + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -1643,13 +2166,186 @@ } }, "additionalProperties": false + }, + "codespaces": { + "type": "object", + "description": "Customizations specific to GitHub Codespaces", + "properties": { + "repositories": { + "type": "object", + "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", + "patternProperties": { + "^[a-zA-Z0-9-_.]+[.]*/[a-zA-Z0-9-_*]+[.]*$": { + "type": "object", + "additionalProperties": true, + "oneOf": [ + { + "properties": { + "permissions": { + "type": "object", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "additionalProperties": true, + "anyOf": [ + { + "properties": { + "actions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "checks": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "contents": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "deployments": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "discussions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "issues": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "packages": { + "type": "string", + "enum": [ + "read" + ] + } + } + }, + { + "properties": { + "pages": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "pull_requests": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "repository_projects": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "statuses": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "workflows": { + "type": "string", + "enum": [ + "write" + ] + } + } + } + ] + } + } + }, + { + "properties": { + "permissions": { + "type": "string", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "enum": [ + "read-all", + "write-all" + ] + } + } + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } }, - "additionalProperties": { - "type": "object", - "additionalProperties": true - }, - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." + "additionalProperties": false + }, + "additionalProperties": { + "type": "object", + "additionalProperties": true } }, "required": [ @@ -1961,6 +2657,7 @@ }, "customizations": { "type": "object", + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -1984,13 +2681,186 @@ } }, "additionalProperties": false + }, + "codespaces": { + "type": "object", + "description": "Customizations specific to GitHub Codespaces", + "properties": { + "repositories": { + "type": "object", + "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", + "patternProperties": { + "^[a-zA-Z0-9-_.]+[.]*/[a-zA-Z0-9-_*]+[.]*$": { + "type": "object", + "additionalProperties": true, + "oneOf": [ + { + "properties": { + "permissions": { + "type": "object", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "additionalProperties": true, + "anyOf": [ + { + "properties": { + "actions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "checks": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "contents": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "deployments": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "discussions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "issues": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "packages": { + "type": "string", + "enum": [ + "read" + ] + } + } + }, + { + "properties": { + "pages": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "pull_requests": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "repository_projects": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "statuses": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "workflows": { + "type": "string", + "enum": [ + "write" + ] + } + } + } + ] + } + } + }, + { + "properties": { + "permissions": { + "type": "string", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "enum": [ + "read-all", + "write-all" + ] + } + } + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } }, - "additionalProperties": { - "type": "object", - "additionalProperties": true - }, - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." + "additionalProperties": false + }, + "additionalProperties": { + "type": "object", + "additionalProperties": true } }, "additionalProperties": false diff --git a/extensions/configuration-editing/schemas/devContainer.schema.src.json b/extensions/configuration-editing/schemas/devContainer.schema.src.json index b0e5b5c6f4a..73456101bb9 100644 --- a/extensions/configuration-editing/schemas/devContainer.schema.src.json +++ b/extensions/configuration-editing/schemas/devContainer.schema.src.json @@ -309,6 +309,7 @@ }, "customizations": { "type": "object", + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -331,13 +332,183 @@ "description": "The port VS Code can use to connect to its backend." } } + }, + "codespaces": { + "type": "object", + "description": "Customizations specific to GitHub Codespaces", + "properties": { + "repositories": { + "type": "object", + "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", + "patternProperties": { + "^[a-zA-Z0-9-_.]+[.]*\/[a-zA-Z0-9-_*]+[.]*$": { + "type": "object", + "additionalProperties": true, + "oneOf": [ + { + "properties": { + "permissions": { + "type": "object", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "additionalProperties": true, + "anyOf": [ + { + "properties": { + "actions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "checks": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "contents": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "deployments": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "discussions": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "issues": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "packages": { + "type": "string", + "enum": [ + "read" + ] + } + } + }, + { + "properties": { + "pages": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "pull_requests": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "repository_projects": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "statuses": { + "type": "string", + "enum": [ + "read", + "write" + ] + } + } + }, + { + "properties": { + "workflows": { + "type": "string", + "enum": [ + "write" + ] + } + } + } + ] + } + } + }, + { + "properties": { + "permissions": { + "type": "string", + "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", + "enum": [ + "read-all", + "write-all" + ] + } + } + } + ] + } + } + } + } } - }, - "additionalProperties": { - "type": "object", - "additionalProperties": true - }, - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." + } + }, + "additionalProperties": { + "type": "object", + "additionalProperties": true } } }, diff --git a/extensions/css-language-features/package.json b/extensions/css-language-features/package.json index c4955243c8f..ccf0518633f 100644 --- a/extensions/css-language-features/package.json +++ b/extensions/css-language-features/package.json @@ -994,7 +994,7 @@ ] }, "dependencies": { - "vscode-languageclient": "^8.0.1", + "vscode-languageclient": "^8.0.2-next.4", "vscode-nls": "^5.0.0", "vscode-uri": "^3.0.3" }, diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json index d2f0443e65b..0885f1b1d07 100644 --- a/extensions/css-language-features/server/package.json +++ b/extensions/css-language-features/server/package.json @@ -11,7 +11,7 @@ "browser": "./dist/browser/cssServerMain", "dependencies": { "vscode-css-languageservice": "^6.0.1", - "vscode-languageserver": "^8.0.1", + "vscode-languageserver": "^8.0.2-next.4", "vscode-uri": "^3.0.3" }, "devDependencies": { diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock index 8749dcdebad..9a9938963fd 100644 --- a/extensions/css-language-features/server/yarn.lock +++ b/extensions/css-language-features/server/yarn.lock @@ -22,35 +22,40 @@ vscode-css-languageservice@^6.0.1: vscode-nls "^5.0.1" vscode-uri "^3.0.3" -vscode-jsonrpc@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.1.tgz#f30b0625ebafa0fb3bc53e934ca47b706445e57e" - integrity sha512-N/WKvghIajmEvXpatSzvTvOIz61ZSmOSa4BRA4pTLi+1+jozquQKP/MkaylP9iB68k73Oua1feLQvH3xQuigiQ== +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-languageserver-protocol@3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.1.tgz#e801762c304f740208b6c804a0cf21f2c87509ed" - integrity sha512-BNlAYgQoYwlSgDLJhSG+DeA8G1JyECqRzM2YO6tMmMji3Ad9Mw6AW7vnZMti90qlAKb0LqAlJfSVGEdqMMNzKg== +vscode-languageserver-protocol@3.17.2-next.5: + version "3.17.2-next.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.5.tgz#9bc747411c3ce9e1d73c2714bf6555e0199eec26" + integrity sha512-UlH+QL4Q4lX94of/UPDDwwWIkd8w7dtMW4khzvEDUoykiG9tba0iG6V0bAiv8XVpnBIUYjL2FNFiL3zl+TY1Sw== dependencies: - vscode-jsonrpc "8.0.1" - vscode-languageserver-types "3.17.1" + vscode-jsonrpc "8.0.2-next.1" + vscode-languageserver-types "3.17.2-next.2" vscode-languageserver-textdocument@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.4.tgz#3cd56dd14cec1d09e86c4bb04b09a246cb3df157" integrity sha512-/xhqXP/2A2RSs+J8JNXpiiNVvvNM0oTosNVmQnunlKvq9o4mupHOBAnnzH0lwIPKazXKvAKsVp1kr+H/K4lgoQ== -vscode-languageserver-types@3.17.1, vscode-languageserver-types@^3.17.1: +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.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.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.1.tgz#56bd7a01f5c88af075a77f1d220edcb30fc4bdc7" - integrity sha512-sn7SjBwWm3OlmLtgg7jbM0wBULppyL60rj8K5HF0ny/MzN+GzPBX1kCvYdybhl7UW63V5V5tRVnyB8iwC73lSQ== +vscode-languageserver@^8.0.2-next.4: + version "8.0.2-next.4" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.2-next.4.tgz#c10cc95be06325b56b7ec1d10271c9e4adf3ef07" + integrity sha512-B3roWH4TmJiB6Zh5+r7zu0QdlLqJsPdGo0LeEi6OiLfrHYCDlcI7DNcQ7F17vWmxC3C82SrxMt/EuLBMpKQM0A== dependencies: - vscode-languageserver-protocol "3.17.1" + vscode-languageserver-protocol "3.17.2-next.5" vscode-nls@^5.0.1: version "5.0.1" diff --git a/extensions/css-language-features/yarn.lock b/extensions/css-language-features/yarn.lock index 76af92973f2..9b7854145e5 100644 --- a/extensions/css-language-features/yarn.lock +++ b/extensions/css-language-features/yarn.lock @@ -46,32 +46,32 @@ semver@^7.3.5: dependencies: lru-cache "^6.0.0" -vscode-jsonrpc@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.1.tgz#f30b0625ebafa0fb3bc53e934ca47b706445e57e" - integrity sha512-N/WKvghIajmEvXpatSzvTvOIz61ZSmOSa4BRA4pTLi+1+jozquQKP/MkaylP9iB68k73Oua1feLQvH3xQuigiQ== +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-languageclient@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.0.1.tgz#bf5535c4463a78daeaca0bcb4f5868aec86bb301" - integrity sha512-9XoE+HJfaWvu7Y75H3VmLo5WLCtsbxEgEhrLPqwt7eyoR49lUIyyrjb98Yfa50JCMqF2cePJAEVI6oe2o1sIhw== +vscode-languageclient@^8.0.2-next.4: + version "8.0.2-next.4" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.0.2-next.4.tgz#87dd364ffbd4356aff3af14e7b557d9fe34d2b67" + integrity sha512-j9BEiCYMN9IoKwYdk9iickV6WNPVGPoVO11SMdoxFnWPIT3y5UAe3qf/WsfA9OdklAIaxxYasfgyKCpBjSPNuw== dependencies: minimatch "^3.0.4" semver "^7.3.5" - vscode-languageserver-protocol "3.17.1" + vscode-languageserver-protocol "3.17.2-next.5" -vscode-languageserver-protocol@3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.1.tgz#e801762c304f740208b6c804a0cf21f2c87509ed" - integrity sha512-BNlAYgQoYwlSgDLJhSG+DeA8G1JyECqRzM2YO6tMmMji3Ad9Mw6AW7vnZMti90qlAKb0LqAlJfSVGEdqMMNzKg== +vscode-languageserver-protocol@3.17.2-next.5: + version "3.17.2-next.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.5.tgz#9bc747411c3ce9e1d73c2714bf6555e0199eec26" + integrity sha512-UlH+QL4Q4lX94of/UPDDwwWIkd8w7dtMW4khzvEDUoykiG9tba0iG6V0bAiv8XVpnBIUYjL2FNFiL3zl+TY1Sw== dependencies: - vscode-jsonrpc "8.0.1" - vscode-languageserver-types "3.17.1" + vscode-jsonrpc "8.0.2-next.1" + vscode-languageserver-types "3.17.2-next.2" -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-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-nls@^5.0.0: version "5.0.0" diff --git a/extensions/css/cgmanifest.json b/extensions/css/cgmanifest.json index 0ff1e899c0a..7a81a87b30f 100644 --- a/extensions/css/cgmanifest.json +++ b/extensions/css/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "atom/language-css", "repositoryUrl": "https://github.com/atom/language-css", - "commitHash": "672168274c7b457f3c118788b5171ae888c1bf07" + "commitHash": "4a6dc90f332bfa72c88192513435a64013d9aad4" } }, "licenseDetail": [ @@ -44,7 +44,7 @@ ], "license": "GitHub License", "description": "The file syntaxes/css.tmLanguage.json was derived from https://github.com/atom/language-css which was originally converted from the TextMate bundle https://github.com/textmate/css.tmbundle.", - "version": "0.45.0" + "version": "0.45.1" } ], "version": 1 diff --git a/extensions/css/syntaxes/css.tmLanguage.json b/extensions/css/syntaxes/css.tmLanguage.json index 213bcefe22d..64ef1addc59 100644 --- a/extensions/css/syntaxes/css.tmLanguage.json +++ b/extensions/css/syntaxes/css.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/atom/language-css/commit/672168274c7b457f3c118788b5171ae888c1bf07", + "version": "https://github.com/atom/language-css/commit/4a6dc90f332bfa72c88192513435a64013d9aad4", "name": "CSS", "scopeName": "source.css", "patterns": [ @@ -850,7 +850,7 @@ ] }, { - "begin": "(?i)(? s.replace(/^HEAD ->/, '')).join(', '); + input1.description = head.hash.substring(0, 7); + + // theirs + input2.detail = mergeHead.refNames.join(', '); + input2.description = mergeHead.hash.substring(0, 7); + + } catch (error) { + // not so bad, can continue with just uris + console.error('FAILED to read HEAD, MERGE_HEAD commits'); + console.error(error); + } + + const options = { + ancestor: mergeUris.base, + input1, + input2, + output: uri + }; + + await commands.executeCommand( + '_open.mergeEditor', + options + ); + } + async cloneRepository(url?: string, parentPath?: string, options: { recursive?: boolean } = {}): Promise { if (!url || typeof url !== 'string') { url = await pickRemoteSource({ @@ -1040,6 +1085,34 @@ export class CommandCenter { await this._stageChanges(textEditor, selectedChanges); } + @command('git.acceptMerge') + async acceptMerge(uri: Uri | unknown): Promise { + if (!(uri instanceof Uri)) { + return; + } + const repository = this.model.getRepository(uri); + if (!repository) { + console.log(`FAILED to accept merge because uri ${uri.toString()} doesn't belong to any repository`); + return; + } + + const doc = workspace.textDocuments.find(doc => doc.uri.toString() === uri.toString()); + if (!doc) { + console.log(`FAILED to accept merge because uri ${uri.toString()} doesn't match a document`); + return; + } + + await doc.save(); + await repository.add([uri]); + + // TODO@jrieken there isn't a `TabInputTextMerge` instance yet, till now the merge editor + // uses the `TabInputText` for the out-resource and we use that to identify and CLOSE the tab + const { activeTab } = window.tabGroups.activeTabGroup; + if (activeTab && activeTab?.input instanceof TabInputText && activeTab.input.uri.toString() === uri.toString()) { + await window.tabGroups.close(activeTab, true); + } + } + private async _stageChanges(textEditor: TextEditor, changes: LineChange[]): Promise { const modifiedDocument = textEditor.document; const modifiedUri = modifiedDocument.uri; diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 8fdab7f659b..a511db761a6 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -354,7 +354,7 @@ function sanitizePath(path: string): string { return path.replace(/^([a-z]):\\/i, (_, letter) => `${letter.toUpperCase()}:\\`); } -const COMMIT_FORMAT = '%H%n%aN%n%aE%n%at%n%ct%n%P%n%B'; +const COMMIT_FORMAT = '%H%n%aN%n%aE%n%at%n%ct%n%P%n%D%n%B'; export interface ICloneOptions { readonly parentPath: string; @@ -660,6 +660,7 @@ export interface Commit { authorName?: string; authorEmail?: string; commitDate?: Date; + refNames: string[]; } export class GitStatusParser { @@ -790,7 +791,7 @@ export function parseGitmodules(raw: string): Submodule[] { return result; } -const commitRegex = /([0-9a-f]{40})\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)(?:\n([^]*?))?(?:\x00)/gm; +const commitRegex = /([0-9a-f]{40})\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)(?:\n([^]*?))?(?:\x00)/gm; export function parseGitCommits(data: string): Commit[] { let commits: Commit[] = []; @@ -801,6 +802,7 @@ export function parseGitCommits(data: string): Commit[] { let authorDate; let commitDate; let parents; + let refNames; let message; let match; @@ -810,7 +812,7 @@ export function parseGitCommits(data: string): Commit[] { break; } - [, ref, authorName, authorEmail, authorDate, commitDate, parents, message] = match; + [, ref, authorName, authorEmail, authorDate, commitDate, parents, refNames, message] = match; if (message[message.length - 1] === '\n') { message = message.substr(0, message.length - 1); @@ -825,6 +827,7 @@ export function parseGitCommits(data: string): Commit[] { authorName: ` ${authorName}`.substr(1), authorEmail: ` ${authorEmail}`.substr(1), commitDate: new Date(Number(commitDate) * 1000), + refNames: refNames.split(',').map(s => s.trim()) }); } while (true); diff --git a/extensions/git/src/log.ts b/extensions/git/src/log.ts index 570e90c5d85..c0f96ff0216 100644 --- a/extensions/git/src/log.ts +++ b/extensions/git/src/log.ts @@ -30,12 +30,22 @@ export class OutputChannelLogger { private _onDidChangeLogLevel = new EventEmitter(); readonly onDidChangeLogLevel: Event = this._onDidChangeLogLevel.event; - private _currentLogLevel: LogLevel; + private _currentLogLevel!: LogLevel; get currentLogLevel(): LogLevel { return this._currentLogLevel; } + set currentLogLevel(value: LogLevel) { + if (this._currentLogLevel === value) { + return; + } - private _defaultLogLevel: LogLevel; + this._currentLogLevel = value; + this._onDidChangeLogLevel.fire(value); + + this.log(localize('gitLogLevel', "Log level: {0}", LogLevel[value])); + } + + private _defaultLogLevel!: LogLevel; get defaultLogLevel(): LogLevel { return this._defaultLogLevel; } @@ -49,20 +59,26 @@ export class OutputChannelLogger { commands.registerCommand('git.showOutput', () => this.showOutputChannel()); this._disposables.push(this._outputChannel); - // Initialize log level - const config = workspace.getConfiguration('git'); - const logLevel: keyof typeof LogLevel = config.get('logLevel', 'Info'); - this._currentLogLevel = this._defaultLogLevel = LogLevel[logLevel] ?? LogLevel.Info; - - this.logInfo(localize('gitLogLevel', "Log level: {0}", LogLevel[this._currentLogLevel])); + this._disposables.push(workspace.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('git.logLevel')) { + this.onLogLevelChange(); + } + })); + this.onLogLevelChange(); } - private log(message: string, logLevel: LogLevel): void { - if (logLevel < this._currentLogLevel) { + private onLogLevelChange(): void { + const config = workspace.getConfiguration('git'); + const logLevel: keyof typeof LogLevel = config.get('logLevel', 'Info'); + this.currentLogLevel = this._defaultLogLevel = LogLevel[logLevel] ?? LogLevel.Info; + } + + log(message: string, logLevel?: LogLevel): void { + if (logLevel && logLevel < this._currentLogLevel) { return; } - this._outputChannel.appendLine(`[${new Date().toISOString()}] [${LogLevel[logLevel].toLowerCase()}] ${message}`); + this._outputChannel.appendLine(`[${new Date().toISOString()}]${logLevel ? ` [${LogLevel[logLevel].toLowerCase()}]` : ''} ${message}`); } logCritical(message: string): void { @@ -89,21 +105,6 @@ export class OutputChannelLogger { this.log(message, LogLevel.Warning); } - logGitCommand(command: string): void { - this._outputChannel.appendLine(`[${new Date().toISOString()}] ${command}`); - } - - setLogLevel(logLevel: LogLevel): void { - if (this._currentLogLevel === logLevel) { - return; - } - - this._currentLogLevel = logLevel; - this._onDidChangeLogLevel.fire(logLevel); - - this.logInfo(localize('changed', "Log level changed to: {0}", LogLevel[logLevel])); - } - showOutputChannel(): void { this._outputChannel.show(); } diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index ee60d2cb1b1..a5e7c060f00 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -90,7 +90,7 @@ async function createModel(context: ExtensionContext, outputChannelLogger: Outpu lines.pop(); } - outputChannelLogger.logGitCommand(lines.join('\n')); + outputChannelLogger.log(lines.join('\n')); }; git.onOutput.addListener('log', onOutput); disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput))); diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index c337f91a7f5..69c184209fa 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -296,6 +296,10 @@ export class Resource implements SourceControlResourceState { const command = this._commandResolver.resolveChangeCommand(this); await commands.executeCommand(command.command, ...(command.arguments || [])); } + + clone() { + return new Resource(this._commandResolver, this._resourceGroupType, this._resourceUri, this._type, this._useIcons, this._renameResourceUri); + } } export const enum Operation { @@ -603,11 +607,20 @@ class ResourceCommandResolver { const title = this.getTitle(resource); if (!resource.leftUri) { - return { - command: 'vscode.open', - title: localize('open', "Open"), - arguments: [resource.rightUri, { override: resource.type === Status.BOTH_MODIFIED ? false : undefined }, title] - }; + const bothModified = resource.type === Status.BOTH_MODIFIED; + if (resource.rightUri && bothModified && workspace.getConfiguration('git').get('experimental.mergeEditor', false)) { + return { + command: '_git.openMergeEditor', + title: localize('open.merge', "Open Merge"), + arguments: [resource.rightUri] + }; + } else { + return { + command: 'vscode.open', + title: localize('open', "Open"), + arguments: [resource.rightUri, { override: bothModified ? false : undefined }, title] + }; + } } else { return { command: 'vscode.diff', @@ -912,6 +925,12 @@ export class Repository implements Disposable { onConfigListener(updateIndexGroupVisibility, this, this.disposables); updateIndexGroupVisibility(); + workspace.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('git.experimental.mergeEditor')) { + this.mergeGroup.resourceStates = this.mergeGroup.resourceStates.map(r => r.clone()); + } + }, undefined, this.disposables); + filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.branchSortOrder', root) || e.affectsConfiguration('git.untrackedChanges', root) @@ -1382,15 +1401,15 @@ export class Repository implements Disposable { } @throttle - async fetchAll(): Promise { - await this._fetch({ all: true }); + async fetchAll(cancellationToken?: CancellationToken): Promise { + await this._fetch({ all: true, cancellationToken }); } async fetch(options: FetchOptions): Promise { await this._fetch(options); } - private async _fetch(options: { remote?: string; ref?: string; all?: boolean; prune?: boolean; depth?: number; silent?: boolean } = {}): Promise { + private async _fetch(options: { remote?: string; ref?: string; all?: boolean; prune?: boolean; depth?: number; silent?: boolean; cancellationToken?: CancellationToken } = {}): Promise { if (!options.prune) { const config = workspace.getConfiguration('git', Uri.file(this.root)); const prune = config.get('pruneOnFetch'); @@ -1435,7 +1454,7 @@ export class Repository implements Disposable { // When fetchOnPull is enabled, fetch all branches when pulling if (fetchOnPull) { - await this.repository.fetch({ all: true }); + await this.fetchAll(); } if (await this.checkIfMaybeRebased(this.HEAD?.name)) { @@ -1506,7 +1525,7 @@ export class Repository implements Disposable { const fn = async (cancellationToken?: CancellationToken) => { // When fetchOnPull is enabled, fetch all branches when pulling if (fetchOnPull) { - await this.repository.fetch({ all: true, cancellationToken }); + await this.fetchAll(cancellationToken); } if (await this.checkIfMaybeRebased(this.HEAD?.name)) { diff --git a/extensions/git/src/test/git.test.ts b/extensions/git/src/test/git.test.ts index c0d0d2003c9..3b225157c3b 100644 --- a/extensions/git/src/test/git.test.ts +++ b/extensions/git/src/test/git.test.ts @@ -205,6 +205,7 @@ john.doe@mail.com 1580811030 1580811031 8e5a374372b8393906c7e380dbb09349c5385554 +main,branch This is a commit message.\x00`; assert.deepStrictEqual(parseGitCommits(GIT_OUTPUT_SINGLE_PARENT), [{ @@ -215,6 +216,7 @@ This is a commit message.\x00`; authorName: 'John Doe', authorEmail: 'john.doe@mail.com', commitDate: new Date(1580811031000), + refNames: ['main', 'branch'], }]); }); @@ -225,6 +227,7 @@ john.doe@mail.com 1580811030 1580811031 8e5a374372b8393906c7e380dbb09349c5385554 df27d8c75b129ab9b178b386077da2822101b217 +main This is a commit message.\x00`; assert.deepStrictEqual(parseGitCommits(GIT_OUTPUT_MULTIPLE_PARENTS), [{ @@ -235,6 +238,7 @@ This is a commit message.\x00`; authorName: 'John Doe', authorEmail: 'john.doe@mail.com', commitDate: new Date(1580811031000), + refNames: ['main'], }]); }); @@ -245,6 +249,7 @@ john.doe@mail.com 1580811030 1580811031 +main This is a commit message.\x00`; assert.deepStrictEqual(parseGitCommits(GIT_OUTPUT_NO_PARENTS), [{ @@ -255,6 +260,7 @@ This is a commit message.\x00`; authorName: 'John Doe', authorEmail: 'john.doe@mail.com', commitDate: new Date(1580811031000), + refNames: ['main'], }]); }); }); diff --git a/extensions/git/src/uri.ts b/extensions/git/src/uri.ts index 94e6b5e38ae..5694c920d6b 100644 --- a/extensions/git/src/uri.ts +++ b/extensions/git/src/uri.ts @@ -51,3 +51,14 @@ export function toGitUri(uri: Uri, ref: string, options: GitUriOptions = {}): Ur query: JSON.stringify(params) }); } + +/** + * Assuming `uri` is being merged it creates uris for `base`, `ours`, and `theirs` + */ +export function toMergeUris(uri: Uri): { base: Uri; ours: Uri; theirs: Uri } { + return { + base: toGitUri(uri, ':1'), + ours: toGitUri(uri, ':2'), + theirs: toGitUri(uri, ':3'), + }; +} diff --git a/extensions/github-authentication/src/github.ts b/extensions/github-authentication/src/github.ts index 6d5b042ac0c..52865e6502e 100644 --- a/extensions/github-authentication/src/github.ts +++ b/extensions/github-authentication/src/github.ts @@ -153,8 +153,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid const scopesSeen = new Set(); const sessionPromises = sessionData.map(async (session: SessionData) => { // For GitHub scope list, order doesn't matter so we immediately sort the scopes - const sortedScopes = session.scopes.sort(); - const scopesStr = sortedScopes.join(' '); + const scopesStr = [...session.scopes].sort().join(' '); if (scopesSeen.has(scopesStr)) { return undefined; } @@ -181,7 +180,9 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid : userInfo?.accountName ?? '', id: session.account?.id ?? userInfo?.id ?? '' }, - scopes: sortedScopes, + // we set this to session.scopes to maintain the original order of the scopes requested + // by the extension that called getSession() + scopes: session.scopes, accessToken: session.accessToken }; }); @@ -208,8 +209,9 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid public async createSession(scopes: string[]): Promise { try { - // For GitHub scope list, order doesn't matter so we immediately sort the scopes - const sortedScopes = scopes.sort(); + // For GitHub scope list, order doesn't matter so we use a sorted scope to determine + // if we've got a session already. + const sortedScopes = [...scopes].sort(); /* __GDPR__ "login" : { @@ -219,13 +221,13 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid } */ this._telemetryReporter?.sendTelemetryEvent('login', { - scopes: JSON.stringify(sortedScopes), + scopes: JSON.stringify(scopes), }); const scopeString = sortedScopes.join(' '); const token = await this._githubServer.login(scopeString); - const session = await this.tokenToSession(token, sortedScopes); + const session = await this.tokenToSession(token, scopes); this.afterSessionLoad(session); const sessions = await this._sessionsPromise; diff --git a/extensions/github/src/auth.ts b/extensions/github/src/auth.ts index af91374e91f..859fe9fa821 100644 --- a/extensions/github/src/auth.ts +++ b/extensions/github/src/auth.ts @@ -24,7 +24,7 @@ function getAgent(url: string | undefined = process.env.HTTPS_PROXY): Agent { } } -const scopes = ['repo', 'workflow']; +const scopes = ['repo', 'workflow', 'user:email', 'read:user']; export async function getSession(): Promise { return await authentication.getSession('github', scopes, { createIfNone: true }); diff --git a/extensions/github/src/pushErrorHandler.ts b/extensions/github/src/pushErrorHandler.ts index 5569d4fb480..2ddae480c2c 100644 --- a/extensions/github/src/pushErrorHandler.ts +++ b/extensions/github/src/pushErrorHandler.ts @@ -220,7 +220,7 @@ export class GithubPushErrorHandler implements PushErrorHandler { return false; } - const match = /^(?:https:\/\/github\.com\/|git@github\.com:)([^/]+)\/([^/.]+)(?:\.git)?$/i.exec(remoteUrl); + const match = /^(?:https:\/\/github\.com\/|git@github\.com:)([^\/]+)\/([^\/.]+)/i.exec(remoteUrl); if (!match) { return false; } diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index 2f2dc4d1067..16a38088f5b 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -262,7 +262,7 @@ }, "dependencies": { "@vscode/extension-telemetry": "0.5.1", - "vscode-languageclient": "^8.0.1", + "vscode-languageclient": "^8.0.2-next.4", "vscode-nls": "^5.0.1", "vscode-uri": "^3.0.3" }, diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json index affcf98e566..322f6b81f85 100644 --- a/extensions/html-language-features/server/package.json +++ b/extensions/html-language-features/server/package.json @@ -11,7 +11,7 @@ "dependencies": { "vscode-css-languageservice": "^6.0.1", "vscode-html-languageservice": "^5.0.0", - "vscode-languageserver": "^8.0.1", + "vscode-languageserver": "^8.0.2-next.4", "vscode-languageserver-textdocument": "^1.0.4", "vscode-nls": "^5.0.1", "vscode-uri": "^3.0.3" diff --git a/extensions/html-language-features/server/yarn.lock b/extensions/html-language-features/server/yarn.lock index f086cbf6898..6f3a8b7b5b1 100644 --- a/extensions/html-language-features/server/yarn.lock +++ b/extensions/html-language-features/server/yarn.lock @@ -32,35 +32,40 @@ vscode-html-languageservice@^5.0.0: vscode-nls "^5.0.1" vscode-uri "^3.0.3" -vscode-jsonrpc@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.1.tgz#f30b0625ebafa0fb3bc53e934ca47b706445e57e" - integrity sha512-N/WKvghIajmEvXpatSzvTvOIz61ZSmOSa4BRA4pTLi+1+jozquQKP/MkaylP9iB68k73Oua1feLQvH3xQuigiQ== +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-languageserver-protocol@3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.1.tgz#e801762c304f740208b6c804a0cf21f2c87509ed" - integrity sha512-BNlAYgQoYwlSgDLJhSG+DeA8G1JyECqRzM2YO6tMmMji3Ad9Mw6AW7vnZMti90qlAKb0LqAlJfSVGEdqMMNzKg== +vscode-languageserver-protocol@3.17.2-next.5: + version "3.17.2-next.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.5.tgz#9bc747411c3ce9e1d73c2714bf6555e0199eec26" + integrity sha512-UlH+QL4Q4lX94of/UPDDwwWIkd8w7dtMW4khzvEDUoykiG9tba0iG6V0bAiv8XVpnBIUYjL2FNFiL3zl+TY1Sw== dependencies: - vscode-jsonrpc "8.0.1" - vscode-languageserver-types "3.17.1" + vscode-jsonrpc "8.0.2-next.1" + vscode-languageserver-types "3.17.2-next.2" vscode-languageserver-textdocument@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.4.tgz#3cd56dd14cec1d09e86c4bb04b09a246cb3df157" integrity sha512-/xhqXP/2A2RSs+J8JNXpiiNVvvNM0oTosNVmQnunlKvq9o4mupHOBAnnzH0lwIPKazXKvAKsVp1kr+H/K4lgoQ== -vscode-languageserver-types@3.17.1, vscode-languageserver-types@^3.17.1: +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.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.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.1.tgz#56bd7a01f5c88af075a77f1d220edcb30fc4bdc7" - integrity sha512-sn7SjBwWm3OlmLtgg7jbM0wBULppyL60rj8K5HF0ny/MzN+GzPBX1kCvYdybhl7UW63V5V5tRVnyB8iwC73lSQ== +vscode-languageserver@^8.0.2-next.4: + version "8.0.2-next.4" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.2-next.4.tgz#c10cc95be06325b56b7ec1d10271c9e4adf3ef07" + integrity sha512-B3roWH4TmJiB6Zh5+r7zu0QdlLqJsPdGo0LeEi6OiLfrHYCDlcI7DNcQ7F17vWmxC3C82SrxMt/EuLBMpKQM0A== dependencies: - vscode-languageserver-protocol "3.17.1" + vscode-languageserver-protocol "3.17.2-next.5" vscode-nls@^5.0.1: version "5.0.1" diff --git a/extensions/html-language-features/yarn.lock b/extensions/html-language-features/yarn.lock index 5157b15d877..c7c2faeae0f 100644 --- a/extensions/html-language-features/yarn.lock +++ b/extensions/html-language-features/yarn.lock @@ -51,32 +51,32 @@ semver@^7.3.5: dependencies: lru-cache "^6.0.0" -vscode-jsonrpc@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.1.tgz#f30b0625ebafa0fb3bc53e934ca47b706445e57e" - integrity sha512-N/WKvghIajmEvXpatSzvTvOIz61ZSmOSa4BRA4pTLi+1+jozquQKP/MkaylP9iB68k73Oua1feLQvH3xQuigiQ== +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-languageclient@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.0.1.tgz#bf5535c4463a78daeaca0bcb4f5868aec86bb301" - integrity sha512-9XoE+HJfaWvu7Y75H3VmLo5WLCtsbxEgEhrLPqwt7eyoR49lUIyyrjb98Yfa50JCMqF2cePJAEVI6oe2o1sIhw== +vscode-languageclient@^8.0.2-next.4: + version "8.0.2-next.4" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.0.2-next.4.tgz#87dd364ffbd4356aff3af14e7b557d9fe34d2b67" + integrity sha512-j9BEiCYMN9IoKwYdk9iickV6WNPVGPoVO11SMdoxFnWPIT3y5UAe3qf/WsfA9OdklAIaxxYasfgyKCpBjSPNuw== dependencies: minimatch "^3.0.4" semver "^7.3.5" - vscode-languageserver-protocol "3.17.1" + vscode-languageserver-protocol "3.17.2-next.5" -vscode-languageserver-protocol@3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.1.tgz#e801762c304f740208b6c804a0cf21f2c87509ed" - integrity sha512-BNlAYgQoYwlSgDLJhSG+DeA8G1JyECqRzM2YO6tMmMji3Ad9Mw6AW7vnZMti90qlAKb0LqAlJfSVGEdqMMNzKg== +vscode-languageserver-protocol@3.17.2-next.5: + version "3.17.2-next.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.5.tgz#9bc747411c3ce9e1d73c2714bf6555e0199eec26" + integrity sha512-UlH+QL4Q4lX94of/UPDDwwWIkd8w7dtMW4khzvEDUoykiG9tba0iG6V0bAiv8XVpnBIUYjL2FNFiL3zl+TY1Sw== dependencies: - vscode-jsonrpc "8.0.1" - vscode-languageserver-types "3.17.1" + vscode-jsonrpc "8.0.2-next.1" + vscode-languageserver-types "3.17.2-next.2" -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-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-nls@^5.0.1: version "5.0.1" diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index 1fc6753efbb..1a5d679e950 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -149,7 +149,7 @@ "dependencies": { "@vscode/extension-telemetry": "0.5.1", "request-light": "^0.5.8", - "vscode-languageclient": "^8.0.1", + "vscode-languageclient": "^8.0.2-next.4", "vscode-nls": "^5.0.1" }, "devDependencies": { diff --git a/extensions/json-language-features/server/package.json b/extensions/json-language-features/server/package.json index a60bc177dc1..ae471f515cd 100644 --- a/extensions/json-language-features/server/package.json +++ b/extensions/json-language-features/server/package.json @@ -15,7 +15,7 @@ "jsonc-parser": "^3.0.0", "request-light": "^0.5.8", "vscode-json-languageservice": "^5.0.0", - "vscode-languageserver": "^8.0.1", + "vscode-languageserver": "^8.0.2-next.4", "vscode-uri": "^3.0.3" }, "devDependencies": { diff --git a/extensions/json-language-features/server/yarn.lock b/extensions/json-language-features/server/yarn.lock index 2e74a77e9d3..83a722965dd 100644 --- a/extensions/json-language-features/server/yarn.lock +++ b/extensions/json-language-features/server/yarn.lock @@ -33,35 +33,40 @@ vscode-json-languageservice@^5.0.0: vscode-nls "^5.0.1" vscode-uri "^3.0.3" -vscode-jsonrpc@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.1.tgz#f30b0625ebafa0fb3bc53e934ca47b706445e57e" - integrity sha512-N/WKvghIajmEvXpatSzvTvOIz61ZSmOSa4BRA4pTLi+1+jozquQKP/MkaylP9iB68k73Oua1feLQvH3xQuigiQ== +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-languageserver-protocol@3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.1.tgz#e801762c304f740208b6c804a0cf21f2c87509ed" - integrity sha512-BNlAYgQoYwlSgDLJhSG+DeA8G1JyECqRzM2YO6tMmMji3Ad9Mw6AW7vnZMti90qlAKb0LqAlJfSVGEdqMMNzKg== +vscode-languageserver-protocol@3.17.2-next.5: + version "3.17.2-next.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.5.tgz#9bc747411c3ce9e1d73c2714bf6555e0199eec26" + integrity sha512-UlH+QL4Q4lX94of/UPDDwwWIkd8w7dtMW4khzvEDUoykiG9tba0iG6V0bAiv8XVpnBIUYjL2FNFiL3zl+TY1Sw== dependencies: - vscode-jsonrpc "8.0.1" - vscode-languageserver-types "3.17.1" + vscode-jsonrpc "8.0.2-next.1" + vscode-languageserver-types "3.17.2-next.2" vscode-languageserver-textdocument@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.4.tgz#3cd56dd14cec1d09e86c4bb04b09a246cb3df157" integrity sha512-/xhqXP/2A2RSs+J8JNXpiiNVvvNM0oTosNVmQnunlKvq9o4mupHOBAnnzH0lwIPKazXKvAKsVp1kr+H/K4lgoQ== -vscode-languageserver-types@3.17.1, vscode-languageserver-types@^3.17.1: +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.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.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.1.tgz#56bd7a01f5c88af075a77f1d220edcb30fc4bdc7" - integrity sha512-sn7SjBwWm3OlmLtgg7jbM0wBULppyL60rj8K5HF0ny/MzN+GzPBX1kCvYdybhl7UW63V5V5tRVnyB8iwC73lSQ== +vscode-languageserver@^8.0.2-next.4: + version "8.0.2-next.4" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.2-next.4.tgz#c10cc95be06325b56b7ec1d10271c9e4adf3ef07" + integrity sha512-B3roWH4TmJiB6Zh5+r7zu0QdlLqJsPdGo0LeEi6OiLfrHYCDlcI7DNcQ7F17vWmxC3C82SrxMt/EuLBMpKQM0A== dependencies: - vscode-languageserver-protocol "3.17.1" + vscode-languageserver-protocol "3.17.2-next.5" vscode-nls@^5.0.1: version "5.0.1" diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index 3b6ad62624a..983804a240d 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -56,32 +56,32 @@ semver@^7.3.5: dependencies: lru-cache "^6.0.0" -vscode-jsonrpc@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.1.tgz#f30b0625ebafa0fb3bc53e934ca47b706445e57e" - integrity sha512-N/WKvghIajmEvXpatSzvTvOIz61ZSmOSa4BRA4pTLi+1+jozquQKP/MkaylP9iB68k73Oua1feLQvH3xQuigiQ== +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-languageclient@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.0.1.tgz#bf5535c4463a78daeaca0bcb4f5868aec86bb301" - integrity sha512-9XoE+HJfaWvu7Y75H3VmLo5WLCtsbxEgEhrLPqwt7eyoR49lUIyyrjb98Yfa50JCMqF2cePJAEVI6oe2o1sIhw== +vscode-languageclient@^8.0.2-next.4: + version "8.0.2-next.4" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.0.2-next.4.tgz#87dd364ffbd4356aff3af14e7b557d9fe34d2b67" + integrity sha512-j9BEiCYMN9IoKwYdk9iickV6WNPVGPoVO11SMdoxFnWPIT3y5UAe3qf/WsfA9OdklAIaxxYasfgyKCpBjSPNuw== dependencies: minimatch "^3.0.4" semver "^7.3.5" - vscode-languageserver-protocol "3.17.1" + vscode-languageserver-protocol "3.17.2-next.5" -vscode-languageserver-protocol@3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.1.tgz#e801762c304f740208b6c804a0cf21f2c87509ed" - integrity sha512-BNlAYgQoYwlSgDLJhSG+DeA8G1JyECqRzM2YO6tMmMji3Ad9Mw6AW7vnZMti90qlAKb0LqAlJfSVGEdqMMNzKg== +vscode-languageserver-protocol@3.17.2-next.5: + version "3.17.2-next.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.5.tgz#9bc747411c3ce9e1d73c2714bf6555e0199eec26" + integrity sha512-UlH+QL4Q4lX94of/UPDDwwWIkd8w7dtMW4khzvEDUoykiG9tba0iG6V0bAiv8XVpnBIUYjL2FNFiL3zl+TY1Sw== dependencies: - vscode-jsonrpc "8.0.1" - vscode-languageserver-types "3.17.1" + vscode-jsonrpc "8.0.2-next.1" + vscode-languageserver-types "3.17.2-next.2" -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-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-nls@^5.0.1: version "5.0.1" diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index f2ad883243f..f78e85fa0cb 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -417,15 +417,21 @@ }, "markdown.experimental.editor.pasteLinks.enabled": { "type": "boolean", - "default": false, + "scope": "resource", "markdownDescription": "%configuration.markdown.editor.pasteLinks.enabled%", - "scope": "resource" + "default": false, + "tags": [ + "experimental" + ] }, "markdown.experimental.validate.enabled": { "type": "boolean", "scope": "resource", "description": "%configuration.markdown.experimental.validate.enabled.description%", - "default": false + "default": false, + "tags": [ + "experimental" + ] }, "markdown.experimental.validate.referenceLinks.enabled": { "type": "string", @@ -436,6 +442,9 @@ "ignore", "warning", "error" + ], + "tags": [ + "experimental" ] }, "markdown.experimental.validate.headerLinks.enabled": { @@ -447,6 +456,9 @@ "ignore", "warning", "error" + ], + "tags": [ + "experimental" ] }, "markdown.experimental.validate.fileLinks.enabled": { @@ -458,6 +470,9 @@ "ignore", "warning", "error" + ], + "tags": [ + "experimental" ] }, "markdown.experimental.validate.ignoreLinks": { @@ -466,7 +481,10 @@ "markdownDescription": "%configuration.markdown.experimental.validate.ignoreLinks.description%", "items": { "type": "string" - } + }, + "tags": [ + "experimental" + ] } } }, diff --git a/extensions/markdown-language-features/package.nls.json b/extensions/markdown-language-features/package.nls.json index 1f3598e3fd8..c7c4c6e5c21 100644 --- a/extensions/markdown-language-features/package.nls.json +++ b/extensions/markdown-language-features/package.nls.json @@ -28,7 +28,7 @@ "configuration.markdown.links.openLocation.currentGroup": "Open links in the active editor group.", "configuration.markdown.links.openLocation.beside": "Open links beside the active editor.", "configuration.markdown.suggest.paths.enabled.description": "Enable/disable path suggestions for markdown links", - "configuration.markdown.editor.drop.enabled": "Enable/disable dropping into the markdown editor to insert shift. Requires enabling `#workbenck.experimental.editor.dropIntoEditor.enabled#`.", + "configuration.markdown.editor.drop.enabled": "Enable/disable dropping into the markdown editor to insert shift. Requires enabling `#workbench.experimental.editor.dropIntoEditor.enabled#`.", "configuration.markdown.editor.pasteLinks.enabled": "Enable/disable pasting files into a Markdown editor inserts Markdown links.", "configuration.markdown.experimental.validate.enabled.description": "Enable/disable all error reporting in Markdown files.", "configuration.markdown.experimental.validate.referenceLinks.enabled.description": "Validate reference links in Markdown files, e.g. `[link][ref]`. Requires enabling `#markdown.experimental.validate.enabled#`.", diff --git a/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts b/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts index 10547f2000e..4db32d614f7 100644 --- a/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts +++ b/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts @@ -448,7 +448,7 @@ export class DiagnosticComputer { if (link.href.kind === 'reference' && !definitionSet.lookup(link.href.ref)) { yield new vscode.Diagnostic( link.source.hrefRange, - localize('invalidReferenceLink', 'No link reference found: \'{0}\'', link.href.ref), + localize('invalidReferenceLink', 'No link definition found: \'{0}\'', link.href.ref), severity); } } diff --git a/extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts b/extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts index e58094d7b7f..92e0e6d1164 100644 --- a/extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts +++ b/extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts @@ -187,6 +187,12 @@ function stripAngleBrackets(link: string) { */ const linkPattern = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*)(([^\s\(\)]|\([^\s\(\)]*?\))+)\s*(".*?")?\)/g; +/** + * Matches `[text]()` + */ +const linkPatternAngle = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*<)(([^<>]|\([^\s\(\)]*?\))+)>\s*(".*?")?\)/g; + + /** * Matches `[text][ref]` or `[shorthand]` */ @@ -271,9 +277,11 @@ export class MdLinkProvider implements vscode.DocumentLinkProvider { case 'reference': { const def = definitionSet.lookup(link.href.ref); if (def) { - return new vscode.DocumentLink( + const documentLink = new vscode.DocumentLink( link.source.hrefRange, vscode.Uri.parse(`command:_markdown.moveCursorToPosition?${encodeURIComponent(JSON.stringify([def.source.hrefRange.start.line, def.source.hrefRange.start.character]))}`)); + documentLink.tooltip = localize('documentLink.referenceTooltip', 'Go to link definition'); + return documentLink; } else { return undefined; } @@ -298,11 +306,27 @@ export class MdLinkProvider implements vscode.DocumentLinkProvider { private *getInlineLinks(document: SkinnyTextDocument, noLinkRanges: NoLinkRanges): Iterable { const text = document.getText(); + for (const match of text.matchAll(linkPatternAngle)) { + const matchImageData = match[4] && extractDocumentLink(document, match[3].length + 1, match[4], match.index); + if (matchImageData && !noLinkRanges.contains(matchImageData.source.hrefRange)) { + yield matchImageData; + } + const matchLinkData = extractDocumentLink(document, match[1].length, match[5], match.index); + if (matchLinkData && !noLinkRanges.contains(matchLinkData.source.hrefRange)) { + yield matchLinkData; + } + } + for (const match of text.matchAll(linkPattern)) { const matchImageData = match[4] && extractDocumentLink(document, match[3].length + 1, match[4], match.index); if (matchImageData && !noLinkRanges.contains(matchImageData.source.hrefRange)) { yield matchImageData; } + + if (match[5] !== undefined && match[5].startsWith('<')) { + continue; + } + const matchLinkData = extractDocumentLink(document, match[1].length, match[5], match.index); if (matchLinkData && !noLinkRanges.contains(matchLinkData.source.hrefRange)) { yield matchLinkData; @@ -353,6 +377,12 @@ export class MdLinkProvider implements vscode.DocumentLinkProvider { reference = match[5]; const offset = ((match.index ?? 0) + match[1].length) + 1; linkStart = document.positionAt(offset); + const line = document.lineAt(linkStart.line); + // See if link looks like a checkbox + const checkboxMatch = line.text.match(/^\s*[\-\*]\s*\[x\]/i); + if (checkboxMatch && linkStart.character <= checkboxMatch[0].length) { + continue; + } linkEnd = document.positionAt(offset + reference.length); } else { continue; diff --git a/extensions/markdown-language-features/src/test/diagnostic.test.ts b/extensions/markdown-language-features/src/test/diagnostic.test.ts index 3d0ffd06a6e..1c6ae3dd6e8 100644 --- a/extensions/markdown-language-features/src/test/diagnostic.test.ts +++ b/extensions/markdown-language-features/src/test/diagnostic.test.ts @@ -268,4 +268,17 @@ suite('markdown: Diagnostics', () => { const { diagnostics } = await manager.recomputeDiagnosticState(doc1, noopToken); assert.deepStrictEqual(diagnostics.length, 0); }); + + test('Should not detect checkboxes as invalid links', async () => { + const doc1 = new InMemoryDocument(workspacePath('doc1.md'), joinLines( + `- [x]`, + `- [X]`, + `- [ ]`, + )); + + const contents = new InMemoryWorkspaceMarkdownDocuments([doc1]); + const manager = createDiagnosticsManager(contents, new MemoryDiagnosticConfiguration(true, ['/doc2.md'])); + const { diagnostics } = await manager.recomputeDiagnosticState(doc1, noopToken); + assert.deepStrictEqual(diagnostics.length, 0); + }); }); diff --git a/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts b/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts index 1f9960d08a1..29793b2a5d8 100644 --- a/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts +++ b/extensions/markdown-language-features/src/test/documentLinkProvider.test.ts @@ -21,6 +21,14 @@ function getLinksForFile(fileContents: string) { return provider.provideDocumentLinks(doc, noopToken); } +function assertLinksEqual(actualLinks: readonly vscode.DocumentLink[], expectedRanges: readonly vscode.Range[]) { + assert.strictEqual(actualLinks.length, expectedRanges.length); + + for (let i = 0; i < actualLinks.length; ++i) { + assertRangeEqual(actualLinks[i].range, expectedRanges[i], `Range ${i} to be equal`); + } +} + suite('markdown.DocumentLinkProvider', () => { test('Should not return anything for empty document', async () => { const links = await getLinksForFile(''); @@ -37,94 +45,93 @@ suite('markdown.DocumentLinkProvider', () => { test('Should detect basic http links', async () => { const links = await getLinksForFile('a [b](https://example.com) c'); - assert.strictEqual(links.length, 1); - const [link] = links; - assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 25)); + assertLinksEqual(links, [ + new vscode.Range(0, 6, 0, 25) + ]); }); test('Should detect basic workspace links', async () => { { const links = await getLinksForFile('a [b](./file) c'); - assert.strictEqual(links.length, 1); - const [link] = links; - assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 12)); + assertLinksEqual(links, [ + new vscode.Range(0, 6, 0, 12) + ]); } { const links = await getLinksForFile('a [b](file.png) c'); - assert.strictEqual(links.length, 1); - const [link] = links; - assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 14)); + assertLinksEqual(links, [ + new vscode.Range(0, 6, 0, 14) + ]); } }); test('Should detect links with title', async () => { const links = await getLinksForFile('a [b](https://example.com "abc") c'); - assert.strictEqual(links.length, 1); - const [link] = links; - assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 25)); + assertLinksEqual(links, [ + new vscode.Range(0, 6, 0, 25) + ]); }); test('Should handle links with escaped characters in name (#35245)', async () => { const links = await getLinksForFile('a [b\\]](./file)'); - assert.strictEqual(links.length, 1); - const [link] = links; - assertRangeEqual(link.range, new vscode.Range(0, 8, 0, 14)); + assertLinksEqual(links, [ + new vscode.Range(0, 8, 0, 14) + ]); }); test('Should handle links with balanced parens', async () => { { const links = await getLinksForFile('a [b](https://example.com/a()c) c'); - assert.strictEqual(links.length, 1); - const [link] = links; - assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 30)); + assertLinksEqual(links, [ + new vscode.Range(0, 6, 0, 30) + ]); } { const links = await getLinksForFile('a [b](https://example.com/a(b)c) c'); - assert.strictEqual(links.length, 1); - const [link] = links; - assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 31)); - + assertLinksEqual(links, [ + new vscode.Range(0, 6, 0, 31) + ]); } { // #49011 const links = await getLinksForFile('[A link](http://ThisUrlhasParens/A_link(in_parens))'); - assert.strictEqual(links.length, 1); - const [link] = links; - assertRangeEqual(link.range, new vscode.Range(0, 9, 0, 50)); + assertLinksEqual(links, [ + new vscode.Range(0, 9, 0, 50) + ]); } }); test('Should handle two links without space', async () => { const links = await getLinksForFile('a ([test](test)[test2](test2)) c'); - assert.strictEqual(links.length, 2); - const [link1, link2] = links; - assertRangeEqual(link1.range, new vscode.Range(0, 10, 0, 14)); - assertRangeEqual(link2.range, new vscode.Range(0, 23, 0, 28)); + assertLinksEqual(links, [ + new vscode.Range(0, 10, 0, 14), + new vscode.Range(0, 23, 0, 28) + ]); }); test('should handle hyperlinked images (#49238)', async () => { { const links = await getLinksForFile('[![alt text](image.jpg)](https://example.com)'); - assert.strictEqual(links.length, 2); - const [link1, link2] = links; - assertRangeEqual(link1.range, new vscode.Range(0, 13, 0, 22)); - assertRangeEqual(link2.range, new vscode.Range(0, 25, 0, 44)); + assertLinksEqual(links, [ + new vscode.Range(0, 13, 0, 22), + new vscode.Range(0, 25, 0, 44) + ]); } { const links = await getLinksForFile('[![a]( whitespace.jpg )]( https://whitespace.com )'); - assert.strictEqual(links.length, 2); - const [link1, link2] = links; - assertRangeEqual(link1.range, new vscode.Range(0, 7, 0, 21)); - assertRangeEqual(link2.range, new vscode.Range(0, 26, 0, 48)); + assertLinksEqual(links, [ + new vscode.Range(0, 7, 0, 21), + new vscode.Range(0, 26, 0, 48) + ]); } { const links = await getLinksForFile('[![a](img1.jpg)](file1.txt) text [![a](img2.jpg)](file2.txt)'); - assert.strictEqual(links.length, 4); - const [link1, link2, link3, link4] = links; - assertRangeEqual(link1.range, new vscode.Range(0, 6, 0, 14)); - assertRangeEqual(link2.range, new vscode.Range(0, 17, 0, 26)); - assertRangeEqual(link3.range, new vscode.Range(0, 39, 0, 47)); - assertRangeEqual(link4.range, new vscode.Range(0, 50, 0, 59)); + assertLinksEqual(links, [ + new vscode.Range(0, 6, 0, 14), + new vscode.Range(0, 17, 0, 26), + new vscode.Range(0, 39, 0, 47), + new vscode.Range(0, 50, 0, 59), + ]); } }); @@ -138,11 +145,11 @@ suite('markdown.DocumentLinkProvider', () => { '[a]: ', '[b]: ', )); - assert.strictEqual(links.length, 2); - const [link1, link2] = links; - assertRangeEqual(link1.range, new vscode.Range(0, 6, 0, 9)); - assertRangeEqual(link2.range, new vscode.Range(1, 6, 1, 8)); + assertLinksEqual(links, [ + new vscode.Range(0, 6, 0, 9), + new vscode.Range(1, 6, 1, 8), + ]); }); test('Should only find one link for reference sources [a]: source (#141285)', async () => { @@ -178,8 +185,9 @@ suite('markdown.DocumentLinkProvider', () => { `\\[good]`, `[good]: http://example.com`, )); - assert.strictEqual(links.length, 1); - assertRangeEqual(links[0].range, new vscode.Range(2, 8, 2, 26)); // Should only find the definition + assertLinksEqual(links, [ + new vscode.Range(2, 8, 2, 26) // Should only find the definition + ]); }); test('Should not consider links in code fenced with backticks', async () => { @@ -265,10 +273,9 @@ suite('markdown.DocumentLinkProvider', () => { test('Should find autolinks', async () => { const links = await getLinksForFile('pre post'); - assert.strictEqual(links.length, 1); - - const link = links[0]; - assertRangeEqual(link.range, new vscode.Range(0, 5, 0, 23)); + assertLinksEqual(links, [ + new vscode.Range(0, 5, 0, 23) + ]); }); test('Should not detect links inside html comment blocks', async () => { @@ -313,4 +320,93 @@ suite('markdown.DocumentLinkProvider', () => { )); assert.strictEqual(links.length, 0); }); + + test('Should not mark checkboxes as links', async () => { + const links = await getLinksForFile(joinLines( + '- [x]', + '- [X]', + '- [ ]', + '* [x]', + '* [X]', + '* [ ]', + ``, + `[x]: http://example.com` + )); + assertLinksEqual(links, [ + new vscode.Range(7, 5, 7, 23) + ]); + }); + + test('Should still find links on line with checkbox', async () => { + const links = await getLinksForFile(joinLines( + '- [x] [x]', + '- [X] [x]', + '- [] [x]', + ``, + `[x]: http://example.com` + )); + + assertLinksEqual(links, [ + new vscode.Range(0, 7, 0, 8), + new vscode.Range(1, 7, 1, 8), + new vscode.Range(2, 6, 2, 7), + new vscode.Range(4, 5, 4, 23), + ]); + }); + + test('Should find link only within angle brackets.', async () => { + const links = await getLinksForFile(joinLines( + `[link]()` + )); + assertLinksEqual(links, [new vscode.Range(0, 8, 0, 12)]); + }); + + test('Should find link within angle brackets even with link title.', async () => { + const links = await getLinksForFile(joinLines( + `[link]( "test title")` + )); + assertLinksEqual(links, [new vscode.Range(0, 8, 0, 12)]); + }); + + test('Should find link within angle brackets even with surrounding spaces.', async () => { + const links = await getLinksForFile(joinLines( + `[link]( )` + )); + assertLinksEqual(links, [new vscode.Range(0, 9, 0, 13)]); + }); + + test('Should find link within angle brackets for image hyperlinks.', async () => { + const links = await getLinksForFile(joinLines( + `![link]()` + )); + assertLinksEqual(links, [new vscode.Range(0, 9, 0, 13)]); + }); + + test('Should find link with spaces in angle brackets for image hyperlinks with titles.', async () => { + const links = await getLinksForFile(joinLines( + `![link](< path > "test")` + )); + assertLinksEqual(links, [new vscode.Range(0, 9, 0, 15)]); + }); + + + test('Should not find link due to incorrect angle bracket notation or usage.', async () => { + const links = await getLinksForFile(joinLines( + `[link]( path>)`, + `[link](> path)`, + )); + assert.strictEqual(links.length, 0); + }); + + test('Should find link within angle brackets even with space inside link.', async () => { + + const links = await getLinksForFile(joinLines( + `[link]()` + )); + + assertLinksEqual(links, [new vscode.Range(0, 8, 0, 13)]); + }); + + }); diff --git a/extensions/markdown-language-features/src/test/references.test.ts b/extensions/markdown-language-features/src/test/references.test.ts index 5eb8c54c5fd..5280a72e308 100644 --- a/extensions/markdown-language-features/src/test/references.test.ts +++ b/extensions/markdown-language-features/src/test/references.test.ts @@ -577,5 +577,19 @@ suite('markdown: find all references', () => { { uri: docUri, line: 2 }, ); }); + + test('Should not consider checkboxes as reference links', async () => { + const docUri = workspacePath('doc.md'); + const doc = new InMemoryDocument(docUri, joinLines( + `- [x]`, + `- [X]`, + `- [ ]`, + ``, + `[x]: https://example.com` + )); + + const refs = await getReferences(doc, new vscode.Position(0, 4), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.strictEqual(refs?.length!, 0); + }); }); }); diff --git a/extensions/package.json b/extensions/package.json index 3d89442d04f..2c89538c8a2 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" + "typescript": "4.7.3" }, "scripts": { "postinstall": "node ./postinstall.mjs" diff --git a/extensions/scss/language-configuration.json b/extensions/scss/language-configuration.json index 8ed82ad4a6c..ffa53ddf958 100644 --- a/extensions/scss/language-configuration.json +++ b/extensions/scss/language-configuration.json @@ -32,5 +32,14 @@ "increaseIndentPattern": "(^.*\\{[^}]*$)", "decreaseIndentPattern": "^\\s*\\}" }, - "wordPattern": "(#?-?\\d*\\.\\d\\w*%?)|(::?[\\w-]*(?=[^,{;]*[,{]))|(([@$#.!])?[\\w-?]+%?|[@#!$.])" + "wordPattern": "(#?-?\\d*\\.\\d\\w*%?)|(::?[\\w-]*(?=[^,{;]*[,{]))|(([@$#.!])?[\\w-?]+%?|[@#!$.])", + "onEnterRules": [ + { + "beforeText": "^[\\s]*///.*$", + "action": { + "indent": "none", + "appendText": "/// " + } + } + ] } diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index 84aa4259a3b..3ebb9c62b52 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -151,6 +151,7 @@ const browserPlugins = [ ] }), new DefinePlugin({ + 'process.platform': JSON.stringify('web'), 'process.env': JSON.stringify({}), 'process.env.BROWSER_ENV': JSON.stringify('true') }) diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 14618b75330..2a7fd5151a1 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -301,6 +301,12 @@ "markdownDescription": "%configuration.inlayHints.variableTypes.enabled%", "scope": "resource" }, + "typescript.inlayHints.variableTypes.suppressWhenTypeMatchesName": { + "type": "boolean", + "default": true, + "markdownDescription": "%configuration.inlayHints.variableTypes.suppressWhenTypeMatchesName%", + "scope": "resource" + }, "typescript.inlayHints.propertyDeclarationTypes.enabled": { "type": "boolean", "default": false, @@ -353,6 +359,12 @@ "markdownDescription": "%configuration.inlayHints.variableTypes.enabled%", "scope": "resource" }, + "javascript.inlayHints.variableTypes.suppressWhenTypeMatchesName": { + "type": "boolean", + "default": true, + "markdownDescription": "%configuration.inlayHints.variableTypes.suppressWhenTypeMatchesName%", + "scope": "resource" + }, "javascript.inlayHints.propertyDeclarationTypes.enabled": { "type": "boolean", "default": false, @@ -1091,7 +1103,10 @@ "type": "boolean", "default": false, "description": "%configuration.tsserver.experimental.enableProjectDiagnostics%", - "scope": "window" + "scope": "window", + "tags": [ + "experimental" + ] }, "typescript.tsserver.watchOptions": { "type": "object", diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index 5a91821e729..513bcfbaaa1 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -88,10 +88,7 @@ "message": "Enable/disable inlay hints for parameter names:\n```typescript\n\nparseInt(/* str: */ '123', /* radix: */ 8)\n \n```\nRequires using TypeScript 4.4+ in the workspace.", "comment": "The text inside the ``` block is code and should not be localized." }, - "configuration.inlayHints.parameterNames.suppressWhenArgumentMatchesName": { - "message": "Suppress parameter name hints on arguments whose text is identical to the parameter name.", - "comment": "The text inside the ``` block is code and should not be localized." - }, + "configuration.inlayHints.parameterNames.suppressWhenArgumentMatchesName": "Suppress parameter name hints on arguments whose text is identical to the parameter name.", "configuration.inlayHints.parameterTypes.enabled": { "message": "Enable/disable inlay hints for implicit parameter types:\n```typescript\n\nel.addEventListener('click', e /* :MouseEvent */ => ...)\n \n```\nRequires using TypeScript 4.4+ in the workspace.", "comment": "The text inside the ``` block is code and should not be localized." @@ -100,6 +97,7 @@ "message": "Enable/disable inlay hints for implicit variable types:\n```typescript\n\nconst foo /* :number */ = Date.now();\n \n```\nRequires using TypeScript 4.4+ in the workspace.", "comment": "The text inside the ``` block is code and should not be localized." }, + "configuration.inlayHints.variableTypes.suppressWhenTypeMatchesName": "Suppress type hints on variables whose name is identical to the type name. Requires using TypeScript 4.8+ in the workspace.", "configuration.inlayHints.propertyDeclarationTypes.enabled": { "message": "Enable/disable inlay hints for implicit types on property declarations:\n```typescript\n\nclass Foo {\n\tprop /* :number */ = Date.now();\n}\n \n```\nRequires using TypeScript 4.4+ in the workspace.", "comment": "The text inside the ``` block is code and should not be localized." diff --git a/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts b/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts index be91f9db4c5..c35aa35aee0 100644 --- a/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts +++ b/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts @@ -210,6 +210,7 @@ export class InlayHintSettingNames { static readonly parameterNamesSuppressWhenArgumentMatchesName = 'inlayHints.parameterNames.suppressWhenArgumentMatchesName'; static readonly parameterNamesEnabled = 'inlayHints.parameterTypes.enabled'; static readonly variableTypesEnabled = 'inlayHints.variableTypes.enabled'; + static readonly variableTypesSuppressWhenTypeMatchesName = 'inlayHints.variableTypes.suppressWhenTypeMatchesName'; static readonly propertyDeclarationTypesEnabled = 'inlayHints.propertyDeclarationTypes.enabled'; static readonly functionLikeReturnTypesEnabled = 'inlayHints.functionLikeReturnTypes.enabled'; static readonly enumMemberValuesEnabled = 'inlayHints.enumMemberValues.enabled'; @@ -221,6 +222,7 @@ export function getInlayHintsPreferences(config: vscode.WorkspaceConfiguration) includeInlayParameterNameHintsWhenArgumentMatchesName: !config.get(InlayHintSettingNames.parameterNamesSuppressWhenArgumentMatchesName, true), includeInlayFunctionParameterTypeHints: config.get(InlayHintSettingNames.parameterNamesEnabled, false), includeInlayVariableTypeHints: config.get(InlayHintSettingNames.variableTypesEnabled, false), + includeInlayVariableTypeHintsWhenTypeMatchesName: !config.get(InlayHintSettingNames.variableTypesSuppressWhenTypeMatchesName, true), includeInlayPropertyDeclarationTypeHints: config.get(InlayHintSettingNames.propertyDeclarationTypesEnabled, false), includeInlayFunctionLikeReturnTypeHints: config.get(InlayHintSettingNames.functionLikeReturnTypesEnabled, false), includeInlayEnumMemberValueHints: config.get(InlayHintSettingNames.enumMemberValuesEnabled, false), diff --git a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts index b3a90b993b0..b0f6d257200 100644 --- a/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts +++ b/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts @@ -15,14 +15,15 @@ import { Position } from '../utils/typeConverters'; import FileConfigurationManager, { getInlayHintsPreferences, InlayHintSettingNames } from './fileConfigurationManager'; -const inlayHintSettingNames = [ +const inlayHintSettingNames = Object.freeze([ InlayHintSettingNames.parameterNamesSuppressWhenArgumentMatchesName, InlayHintSettingNames.parameterNamesEnabled, InlayHintSettingNames.variableTypesEnabled, + InlayHintSettingNames.variableTypesSuppressWhenTypeMatchesName, InlayHintSettingNames.propertyDeclarationTypesEnabled, InlayHintSettingNames.functionLikeReturnTypesEnabled, InlayHintSettingNames.enumMemberValuesEnabled, -]; +]); class TypeScriptInlayHintsProvider extends Disposable implements vscode.InlayHintsProvider { diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts new file mode 100644 index 00000000000..6880607ca7d --- /dev/null +++ b/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts @@ -0,0 +1,88 @@ +/*--------------------------------------------------------------------------------------------- + * 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 vscode from 'vscode'; +import { disposeAll } from '../utils'; +import { Kernel, saveAllFilesAndCloseAll } from './notebook.test'; + +export type INativeInteractiveWindow = { notebookUri: vscode.Uri; inputUri: vscode.Uri; notebookEditor: vscode.NotebookEditor }; + +async function createInteractiveWindow(kernel: Kernel) { + const { notebookEditor } = (await vscode.commands.executeCommand( + 'interactive.open', + // Keep focus on the owning file if there is one + { viewColumn: vscode.ViewColumn.Beside, preserveFocus: false }, + undefined, + kernel.controller.id, + undefined + )) as unknown as INativeInteractiveWindow; + + return notebookEditor; +} + +async function addCell(code: string, notebook: vscode.NotebookDocument) { + const cell = new vscode.NotebookCellData(vscode.NotebookCellKind.Code, code, 'typescript'); + const edit = vscode.NotebookEdit.insertCells(notebook.cellCount, [cell]); + const workspaceEdit = new vscode.WorkspaceEdit(); + workspaceEdit.set(notebook.uri, [edit]); + await vscode.workspace.applyEdit(workspaceEdit); + return notebook.cellAt(notebook.cellCount - 1); +} + +async function addCellAndRun(code: string, notebook: vscode.NotebookDocument) { + const cell = await addCell(code, notebook); + await vscode.commands.executeCommand('notebook.execute'); + assert.strictEqual(cell.outputs.length, 1, 'execute failed'); + return cell; +} + + +(vscode.env.uiKind === vscode.UIKind.Web ? suite.skip : suite)('Interactive Window', function () { + + const testDisposables: vscode.Disposable[] = []; + let defaultKernel: Kernel; + + setup(async function () { + // there should be ONE default kernel in this suite + defaultKernel = new Kernel('mainKernel', 'Notebook Default Kernel', 'interactive'); + testDisposables.push(defaultKernel.controller); + await saveAllFilesAndCloseAll(); + }); + + teardown(async function () { + disposeAll(testDisposables); + testDisposables.length = 0; + await saveAllFilesAndCloseAll(); + }); + + test('Can open an interactive window', async () => { + assert.ok(vscode.workspace.workspaceFolders); + const notebookEditor = await createInteractiveWindow(defaultKernel); + assert.ok(notebookEditor); + + // Try adding a cell and running it. + await addCell('print foo', notebookEditor.notebook); + + assert.strictEqual(notebookEditor.notebook.cellCount, 1); + assert.strictEqual(notebookEditor.notebook.cellAt(0).kind, vscode.NotebookCellKind.Code); + }); + + test('Interactive window scrolls after execute', async () => { + assert.ok(vscode.workspace.workspaceFolders); + const notebookEditor = await createInteractiveWindow(defaultKernel); + assert.ok(notebookEditor); + + // Run and add a bunch of cells + for (let i = 0; i < 20; i++) { + await addCellAndRun(`print ${i}`, notebookEditor.notebook); + } + + // Verify visible range has the last cell + assert.strictEqual(notebookEditor.visibleRanges[notebookEditor.visibleRanges.length - 1].end, notebookEditor.notebook.cellCount, `Last cell is not visible`); + + }); +}); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts index dd30fce0aa4..d0594904374 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts @@ -96,6 +96,8 @@ suite('vscode API - languages', () => { assert.ok(found); }); + // HINT: If this test fails, and you have been modifying code used in workers, you might have + // accidentally broken the workers. Check the logs for errors. test('link detector', async function () { const uri = await createRandomFile('class A { // http://a.com }', undefined, '.java'); const doc = await vscode.workspace.openTextDocument(uri); 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 462e3113698..f863bf014b6 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.test.ts @@ -18,7 +18,7 @@ async function openRandomNotebookDocument() { return vscode.workspace.openNotebookDocument(uri); } -async function saveAllFilesAndCloseAll() { +export async function saveAllFilesAndCloseAll() { await saveAllEditors(); await closeAllEditors(); } @@ -29,14 +29,20 @@ async function withEvent(event: vscode.Event, callback: (e: Promise) => } -class Kernel { +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) { - this.controller = vscode.notebooks.createNotebookController(id, 'notebookCoreTest', label); + 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']; @@ -59,8 +65,9 @@ class Kernel { // 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(); + 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') ])]); @@ -256,14 +263,25 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { const editor = await vscode.window.showNotebookDocument(notebook); const notebookChangeEvent = asPromise(vscode.workspace.onDidChangeNotebookDocument); - const version = editor.document.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 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; - assert.strictEqual(version + 1, editor.document.version); + + 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; + + 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`); }); test('edit API batch edits undo/redo', async function () { diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 4ab30e237c6..da2bcfbff02 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: - version "4.7.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.2.tgz#1f9aa2ceb9af87cca227813b4310fff0b51593c4" - integrity sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A== +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== vscode-grammar-updater@^1.1.0: version "1.1.0" diff --git a/package.json b/package.json index 0874bacbd1f..2ea6bb32ba3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.68.0", - "distro": "36f3417e7298756bb2943725f4bce75f6096f246", + "distro": "2966cd72fc1a3a5fb89bf2d85a1a66e56206961a", "author": { "name": "Microsoft Corporation" }, @@ -78,19 +78,19 @@ "native-watchdog": "1.4.0", "node-pty": "0.11.0-beta11", "spdlog": "^0.13.0", - "tas-client-umd": "0.1.5", + "tas-client-umd": "0.1.6", "v8-inspect-profiler": "^0.1.0", "vscode-oniguruma": "1.6.1", - "vscode-policy-watcher": "^1.1.0", + "vscode-policy-watcher": "^1.1.1", "vscode-proxy-agent": "^0.12.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "7.0.1", - "xterm": "4.19.0-beta.49", - "xterm-addon-search": "0.9.0-beta.37", + "xterm": "4.19.0-beta.58", + "xterm-addon-search": "0.9.0-beta.39", "xterm-addon-serialize": "0.7.0-beta.12", "xterm-addon-unicode11": "0.4.0-beta.3", - "xterm-addon-webgl": "0.12.0-beta.36", - "xterm-headless": "4.19.0-beta.49", + "xterm-addon-webgl": "0.12.0-beta.37", + "xterm-headless": "4.19.0-beta.58", "yauzl": "^2.9.2", "yazl": "^2.4.3" }, @@ -138,7 +138,7 @@ "cssnano": "^4.1.11", "debounce": "^1.0.0", "deemon": "^1.4.0", - "electron": "17.4.4", + "electron": "17.4.7", "eslint": "8.7.0", "eslint-plugin-header": "3.1.1", "eslint-plugin-jsdoc": "^19.1.0", diff --git a/product.json b/product.json index ca0f29df1da..d16abf8de29 100644 --- a/product.json +++ b/product.json @@ -46,7 +46,7 @@ }, { "name": "ms-vscode.js-debug", - "version": "1.67.2", + "version": "1.68.0", "repo": "https://github.com/microsoft/vscode-js-debug", "metadata": { "id": "25629058-ddac-4e17-abba-74678e126c5d", diff --git a/remote/package.json b/remote/package.json index 3e833d3c5f6..49e3d17b354 100644 --- a/remote/package.json +++ b/remote/package.json @@ -19,17 +19,17 @@ "native-watchdog": "1.4.0", "node-pty": "0.11.0-beta11", "spdlog": "^0.13.0", - "tas-client-umd": "0.1.5", + "tas-client-umd": "0.1.6", "vscode-oniguruma": "1.6.1", "vscode-proxy-agent": "^0.12.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "7.0.1", - "xterm": "4.19.0-beta.49", - "xterm-addon-search": "0.9.0-beta.37", + "xterm": "4.19.0-beta.58", + "xterm-addon-search": "0.9.0-beta.39", "xterm-addon-serialize": "0.7.0-beta.12", "xterm-addon-unicode11": "0.4.0-beta.3", - "xterm-addon-webgl": "0.12.0-beta.36", - "xterm-headless": "4.19.0-beta.49", + "xterm-addon-webgl": "0.12.0-beta.37", + "xterm-headless": "4.19.0-beta.58", "yauzl": "^2.9.2", "yazl": "^2.4.3" }, diff --git a/remote/web/package.json b/remote/web/package.json index 4ec42b01f12..387c0fb40e8 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -7,12 +7,12 @@ "@vscode/iconv-lite-umd": "0.7.0", "@vscode/vscode-languagedetection": "1.0.21", "jschardet": "3.0.0", - "tas-client-umd": "0.1.5", + "tas-client-umd": "0.1.6", "vscode-oniguruma": "1.6.1", "vscode-textmate": "7.0.1", - "xterm": "4.19.0-beta.49", - "xterm-addon-search": "0.9.0-beta.37", + "xterm": "4.19.0-beta.58", + "xterm-addon-search": "0.9.0-beta.39", "xterm-addon-unicode11": "0.4.0-beta.3", - "xterm-addon-webgl": "0.12.0-beta.36" + "xterm-addon-webgl": "0.12.0-beta.37" } } diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index d8eac016d98..27f754d7394 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -98,10 +98,10 @@ jschardet@3.0.0: resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== -tas-client-umd@0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/tas-client-umd/-/tas-client-umd-0.1.5.tgz#743c02e344afdec55a68bb9d62805e30a1ae83d4" - integrity sha512-NL9eFzYBBHfiYja6tP27084j4YbqtGEk68C5BTyTNHapsM9dizZ/RoSUGst5L1xUiw1zO1WbHf4Lir2e/wgT8g== +tas-client-umd@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/tas-client-umd/-/tas-client-umd-0.1.6.tgz#a0cf70a68f50d406773457630666224f0eb545a6" + integrity sha512-eOz5IK4cuNmSZI9QlqlT0FdvgfnnHDB6rjqleFaYAbzYE4RdJzYNiM28zFIXgmOVEgESvfabMFxG8WX5M4z3HA== vscode-oniguruma@1.6.1: version "1.6.1" @@ -113,22 +113,22 @@ 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-search@0.9.0-beta.37: - version "0.9.0-beta.37" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.9.0-beta.37.tgz#84a020f03b2cacc5afac78ca6ff2f1eb86fb6710" - integrity sha512-bfeFgKJkDYyIgqpWiV1oWYqDiTo+SHTeIPEbpOfxDr97pc3PtDF1Tyd79PrvJNfoxaV3VMUo//UEOy4D+KY9OQ== +xterm-addon-search@0.9.0-beta.39: + version "0.9.0-beta.39" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.9.0-beta.39.tgz#e8376e1485ee7d763c07d1a8f1354114f65b3e3e" + integrity sha512-h45wkecgfqXXoAUqgNytAfSd6g0xNT6rZy/enVaEU0aes7QoL9pxHUKkCry8PP6hs03Slk0VxQ4AGsbSZGvK/w== xterm-addon-unicode11@0.4.0-beta.3: version "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.12.0-beta.36: - version "0.12.0-beta.36" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.12.0-beta.36.tgz#460f80829a78c979a448d5b764699af3f0366ff1" - integrity sha512-sgX7OHSGZQZE5b4xtPqd/5NEcll0Z+00tnTVxKZlXf5XEENcG0tnBF4I4f+k9K3cmjE1UIUVG2yYPrqWlYCdpA== +xterm-addon-webgl@0.12.0-beta.37: + version "0.12.0-beta.37" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.12.0-beta.37.tgz#e465100041a7e0b1d32b01cd0b0ba5a516ac13c2" + integrity sha512-d4GfKlMrWZGzsMfMHd2siG+QiOvwikhwiu+JQlIhlnAShT/wU5BOGbNfDDA1tHmkW7G1UCFgucBuVxrs5wjuBQ== -xterm@4.19.0-beta.49: - version "4.19.0-beta.49" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.19.0-beta.49.tgz#96d0d748c97a2f0cfa4c6112bc4de8b0d5d559fe" - integrity sha512-qPhOeGtnB357mZOvfDckVlPDR7EDkSASQrB3aujhjgJlOiBBqcNRJcuSvF7v1DOho7xdEI9UQxiSiT5diHhMlg== +xterm@4.19.0-beta.58: + version "4.19.0-beta.58" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.19.0-beta.58.tgz#cbe535b0b85bc7f8ae3cc242df006bea04cdf541" + integrity sha512-fr3QC2qS2NBab8X7kwA/3QZELzQqhAKsngvK8NkhsrFN1DAuyEETkzqXuKbO7OKpCB6VqGDN6GPkNlUB9VrIDA== diff --git a/remote/yarn.lock b/remote/yarn.lock index 52a1cc813ed..0f479f0fd51 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -842,10 +842,10 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" -tas-client-umd@0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/tas-client-umd/-/tas-client-umd-0.1.5.tgz#743c02e344afdec55a68bb9d62805e30a1ae83d4" - integrity sha512-NL9eFzYBBHfiYja6tP27084j4YbqtGEk68C5BTyTNHapsM9dizZ/RoSUGst5L1xUiw1zO1WbHf4Lir2e/wgT8g== +tas-client-umd@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/tas-client-umd/-/tas-client-umd-0.1.6.tgz#a0cf70a68f50d406773457630666224f0eb545a6" + integrity sha512-eOz5IK4cuNmSZI9QlqlT0FdvgfnnHDB6rjqleFaYAbzYE4RdJzYNiM28zFIXgmOVEgESvfabMFxG8WX5M4z3HA== tunnel-agent@^0.6.0: version "0.6.0" @@ -914,10 +914,10 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -xterm-addon-search@0.9.0-beta.37: - version "0.9.0-beta.37" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.9.0-beta.37.tgz#84a020f03b2cacc5afac78ca6ff2f1eb86fb6710" - integrity sha512-bfeFgKJkDYyIgqpWiV1oWYqDiTo+SHTeIPEbpOfxDr97pc3PtDF1Tyd79PrvJNfoxaV3VMUo//UEOy4D+KY9OQ== +xterm-addon-search@0.9.0-beta.39: + version "0.9.0-beta.39" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.9.0-beta.39.tgz#e8376e1485ee7d763c07d1a8f1354114f65b3e3e" + integrity sha512-h45wkecgfqXXoAUqgNytAfSd6g0xNT6rZy/enVaEU0aes7QoL9pxHUKkCry8PP6hs03Slk0VxQ4AGsbSZGvK/w== xterm-addon-serialize@0.7.0-beta.12: version "0.7.0-beta.12" @@ -929,20 +929,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.12.0-beta.36: - version "0.12.0-beta.36" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.12.0-beta.36.tgz#460f80829a78c979a448d5b764699af3f0366ff1" - integrity sha512-sgX7OHSGZQZE5b4xtPqd/5NEcll0Z+00tnTVxKZlXf5XEENcG0tnBF4I4f+k9K3cmjE1UIUVG2yYPrqWlYCdpA== +xterm-addon-webgl@0.12.0-beta.37: + version "0.12.0-beta.37" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.12.0-beta.37.tgz#e465100041a7e0b1d32b01cd0b0ba5a516ac13c2" + integrity sha512-d4GfKlMrWZGzsMfMHd2siG+QiOvwikhwiu+JQlIhlnAShT/wU5BOGbNfDDA1tHmkW7G1UCFgucBuVxrs5wjuBQ== -xterm-headless@4.19.0-beta.49: - version "4.19.0-beta.49" - resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-4.19.0-beta.49.tgz#8e4178620be9a9dee25a586ef992a6fc621a829a" - integrity sha512-uRnHpR2pv1MJPbE3sa7XbP6x0uHubAWVMbiD26e3a5ICtWJQVVpLojkA0t4qU7CoMX85pRL1rIclg9CKY0B0xA== +xterm-headless@4.19.0-beta.58: + version "4.19.0-beta.58" + resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-4.19.0-beta.58.tgz#3a38cf3b9cd2606fb342a5cf8f2a0cfb963a62e8" + integrity sha512-wKQW8VzkFjyYDvcaM26gulo+YghyocfkZnKMH7gc/+/mFn3YXUPBPuOcX6e0M7NibyMlewpQpZjHQUPLBjkzfw== -xterm@4.19.0-beta.49: - version "4.19.0-beta.49" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.19.0-beta.49.tgz#96d0d748c97a2f0cfa4c6112bc4de8b0d5d559fe" - integrity sha512-qPhOeGtnB357mZOvfDckVlPDR7EDkSASQrB3aujhjgJlOiBBqcNRJcuSvF7v1DOho7xdEI9UQxiSiT5diHhMlg== +xterm@4.19.0-beta.58: + version "4.19.0-beta.58" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.19.0-beta.58.tgz#cbe535b0b85bc7f8ae3cc242df006bea04cdf541" + integrity sha512-fr3QC2qS2NBab8X7kwA/3QZELzQqhAKsngvK8NkhsrFN1DAuyEETkzqXuKbO7OKpCB6VqGDN6GPkNlUB9VrIDA== yallist@^4.0.0: version "4.0.0" diff --git a/resources/darwin/bin/code.sh b/resources/darwin/bin/code.sh index eecdf9c68b5..8c058727071 100755 --- a/resources/darwin/bin/code.sh +++ b/resources/darwin/bin/code.sh @@ -3,6 +3,15 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. +# when run in remote terminal, use the remote cli +if [ -n "$VSCODE_IPC_HOOK_CLI" ]; then + REMOTE_CLI="$(which -a '@@APPNAME@@' | grep /remote-cli/)" + if [ -n "$REMOTE_CLI" ]; then + "$REMOTE_CLI" "$@" + exit $? + fi +fi + function app_realpath() { SOURCE=$1 while [ -h "$SOURCE" ]; do diff --git a/resources/linux/bin/code.sh b/resources/linux/bin/code.sh index bfebec1aa8e..5fe68cb4f3e 100755 --- a/resources/linux/bin/code.sh +++ b/resources/linux/bin/code.sh @@ -3,9 +3,18 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. +# when run in remote terminal, use the remote cli +if [ -n "$VSCODE_IPC_HOOK_CLI" ]; then + REMOTE_CLI="$(which -a '@@APPNAME@@' | grep /remote-cli/)" + if [ -n "$REMOTE_CLI" ]; then + "$REMOTE_CLI" "$@" + exit $? + fi +fi + # test that VSCode wasn't installed inside WSL if grep -qi Microsoft /proc/version && [ -z "$DONT_PROMPT_WSL_INSTALL" ]; then - echo "To use @@PRODNAME@@ with the Windows Subsystem for Linux, please install @@PRODNAME@@ in Windows and uninstall the Linux version in WSL. You can then use the \`@@NAME@@\` command in a WSL terminal just as you would in a normal command prompt." 1>&2 + echo "To use @@PRODNAME@@ with the Windows Subsystem for Linux, please install @@PRODNAME@@ in Windows and uninstall the Linux version in WSL. You can then use the \`@@APPNAME@@\` command in a WSL terminal just as you would in a normal command prompt." 1>&2 printf "Do you want to continue anyway? [y/N] " 1>&2 read -r YN YN=$(printf '%s' "$YN" | tr '[:upper:]' '[:lower:]') @@ -44,11 +53,11 @@ else VSCODE_PATH="$(dirname "$(readlink -f "$0")")/.." else # else use the standard install location - VSCODE_PATH="/usr/share/@@NAME@@" + VSCODE_PATH="/usr/share/@@APPNAME@@" fi fi -ELECTRON="$VSCODE_PATH/@@NAME@@" +ELECTRON="$VSCODE_PATH/@@APPNAME@@" CLI="$VSCODE_PATH/resources/app/out/cli.js" ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" --ms-enable-electron-run-as-node "$@" exit $? diff --git a/scripts/test-remote-integration.sh b/scripts/test-remote-integration.sh index 7decdf3798f..68c740784a6 100755 --- a/scripts/test-remote-integration.sh +++ b/scripts/test-remote-integration.sh @@ -63,7 +63,7 @@ else export ELECTRON_ENABLE_LOGGING=1 # Running from a build, we need to enable the vscode-test-resolver extension - EXTRA_INTEGRATION_TEST_ARGUMENTS="--extensions-dir=$EXT_PATH --enable-proposed-api=vscode.vscode-test-resolver --enable-proposed-api=vscode.vscode-api-tests" + EXTRA_INTEGRATION_TEST_ARGUMENTS="--extensions-dir=$EXT_PATH --enable-proposed-api=vscode.vscode-test-resolver --enable-proposed-api=vscode.vscode-api-tests --enable-proposed-api=vscode.markdown-language-features --enable-proposed-api=vscode.git" echo "Storing crash reports into '$VSCODECRASHDIR'." echo "Storing log files into '$VSCODELOGSDIR'." diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 55082221467..0bfef7f8ae7 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -1597,20 +1597,25 @@ export class List implements ISpliceable, IThemable, IDisposable { async focusNextPage(browserEvent?: UIEvent, filter?: (element: T) => boolean): Promise { let lastPageIndex = this.view.indexAt(this.view.getScrollTop() + this.view.renderHeight); lastPageIndex = lastPageIndex === 0 ? 0 : lastPageIndex - 1; - const lastPageElement = this.view.element(lastPageIndex); - const currentlyFocusedElement = this.getFocusedElements()[0]; + const currentlyFocusedElementIndex = this.getFocus()[0]; - if (currentlyFocusedElement !== lastPageElement) { + if (currentlyFocusedElementIndex !== lastPageIndex && (currentlyFocusedElementIndex === undefined || lastPageIndex > currentlyFocusedElementIndex)) { const lastGoodPageIndex = this.findPreviousIndex(lastPageIndex, false, filter); - if (lastGoodPageIndex > -1 && currentlyFocusedElement !== this.view.element(lastGoodPageIndex)) { + if (lastGoodPageIndex > -1 && currentlyFocusedElementIndex !== lastGoodPageIndex) { this.setFocus([lastGoodPageIndex], browserEvent); } else { this.setFocus([lastPageIndex], browserEvent); } } else { const previousScrollTop = this.view.getScrollTop(); - this.view.setScrollTop(previousScrollTop + this.view.renderHeight - this.view.elementHeight(lastPageIndex)); + let nextpageScrollTop = previousScrollTop + this.view.renderHeight; + if (lastPageIndex > currentlyFocusedElementIndex) { + // scroll last page element to the top only if the last page element is below the focused element + nextpageScrollTop -= this.view.elementHeight(lastPageIndex); + } + + this.view.setScrollTop(nextpageScrollTop); if (this.view.getScrollTop() !== previousScrollTop) { this.setFocus([]); @@ -1632,13 +1637,12 @@ export class List implements ISpliceable, IThemable, IDisposable { firstPageIndex = this.view.indexAfter(scrollTop - 1); } - const firstPageElement = this.view.element(firstPageIndex); - const currentlyFocusedElement = this.getFocusedElements()[0]; + const currentlyFocusedElementIndex = this.getFocus()[0]; - if (currentlyFocusedElement !== firstPageElement) { + if (currentlyFocusedElementIndex !== firstPageIndex && (currentlyFocusedElementIndex === undefined || currentlyFocusedElementIndex >= firstPageIndex)) { const firstGoodPageIndex = this.findNextIndex(firstPageIndex, false, filter); - if (firstGoodPageIndex > -1 && currentlyFocusedElement !== this.view.element(firstGoodPageIndex)) { + if (firstGoodPageIndex > -1 && currentlyFocusedElementIndex !== firstGoodPageIndex) { this.setFocus([firstGoodPageIndex], browserEvent); } else { this.setFocus([firstPageIndex], browserEvent); diff --git a/src/vs/base/browser/ui/menu/menubar.css b/src/vs/base/browser/ui/menu/menubar.css index b9dd13780e9..c4a57a11c0f 100644 --- a/src/vs/base/browser/ui/menu/menubar.css +++ b/src/vs/base/browser/ui/menu/menubar.css @@ -17,7 +17,7 @@ .fullscreen .menubar:not(.compact) { margin: 0px; - padding: 0px 5px; + padding: 4px 5px; } .menubar > .menubar-menu-button { diff --git a/src/vs/base/browser/ui/toggle/toggle.ts b/src/vs/base/browser/ui/toggle/toggle.ts index dafff0bf5ff..8d2387dbc26 100644 --- a/src/vs/base/browser/ui/toggle/toggle.ts +++ b/src/vs/base/browser/ui/toggle/toggle.ts @@ -98,6 +98,7 @@ export class Toggle extends Widget { readonly onKeyDown: Event = this._onKeyDown.event; private readonly _opts: IToggleOpts; + private _icon: CSSIcon | undefined; readonly domNode: HTMLElement; private _checked: boolean; @@ -110,7 +111,8 @@ export class Toggle extends Widget { const classes = ['monaco-custom-toggle']; if (this._opts.icon) { - classes.push(...CSSIcon.asClassNameArray(this._opts.icon)); + this._icon = this._opts.icon; + classes.push(...CSSIcon.asClassNameArray(this._icon)); } if (this._opts.actionClassName) { classes.push(...this._opts.actionClassName.split(' ')); @@ -174,6 +176,16 @@ export class Toggle extends Widget { this.applyStyles(); } + setIcon(icon: CSSIcon | undefined): void { + if (this._icon) { + this.domNode.classList.remove(...CSSIcon.asClassNameArray(this._icon)); + } + this._icon = icon; + if (this._icon) { + this.domNode.classList.add(...CSSIcon.asClassNameArray(this._icon)); + } + } + width(): number { return 2 /*margin left*/ + 2 /*border*/ + 2 /*padding*/ + 16 /* icon width */; } diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index 8f6ab7661ae..826d3558c35 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -640,12 +640,38 @@ function getActualStartIndex(array: T[], start: number): number { return start < 0 ? Math.max(start + array.length, 0) : Math.min(start, array.length); } +/** + * When comparing two values, + * a negative number indicates that the first value is less than the second, + * a positive number indicates that the first value is greater than the second, + * and zero indicates that neither is the case. +*/ +export type CompareResult = number; + +export namespace CompareResult { + export function isLessThan(result: CompareResult): boolean { + return result < 0; + } + + export function isGreaterThan(result: CompareResult): boolean { + return result > 0; + } + + export function isNeitherLessOrGreaterThan(result: CompareResult): boolean { + return result === 0; + } + + export const greaterThan = 1; + export const lessThan = -1; + export const neitherLessOrGreaterThan = 0; +} + /** * A comparator `c` defines a total order `<=` on `T` as following: * `c(a, b) <= 0` iff `a` <= `b`. * We also have `c(a, b) == 0` iff `c(b, a) == 0`. */ -export type Comparator = (a: T, b: T) => number; +export type Comparator = (a: T, b: T) => CompareResult; export function compareBy(selector: (item: TItem) => TCompareBy, comparator: Comparator): Comparator { return (a, b) => comparator(selector(a), selector(b)); @@ -706,7 +732,7 @@ export class ArrayQueue { /** * Constructs a queue that is backed by the given array. Runtime is O(1). */ - constructor(private readonly items: T[]) { } + constructor(private readonly items: readonly T[]) { } get length(): number { return this.lastIdx - this.firstIdx + 1; @@ -748,15 +774,31 @@ export class ArrayQueue { } peek(): T | undefined { + if (this.length === 0) { + return undefined; + } return this.items[this.firstIdx]; } + peekLast(): T | undefined { + if (this.length === 0) { + return undefined; + } + return this.items[this.lastIdx]; + } + dequeue(): T | undefined { const result = this.items[this.firstIdx]; this.firstIdx++; return result; } + removeLast(): T | undefined { + const result = this.items[this.lastIdx]; + this.lastIdx--; + return result; + } + takeCount(count: number): T[] { const result = this.items.slice(this.firstIdx, this.firstIdx + count); this.firstIdx += count; diff --git a/src/vs/base/common/dataTransfer.ts b/src/vs/base/common/dataTransfer.ts index d5d99bd283b..5074f30c75e 100644 --- a/src/vs/base/common/dataTransfer.ts +++ b/src/vs/base/common/dataTransfer.ts @@ -17,55 +17,74 @@ export interface IDataTransferItem { value: any; } +export function createStringDataTransferItem(stringOrPromise: string | Promise): IDataTransferItem { + return { + asString: async () => stringOrPromise, + asFile: () => undefined, + value: typeof stringOrPromise === 'string' ? stringOrPromise : undefined, + }; +} + +export function createFileDataTransferItem(fileName: string, uri: URI | undefined, data: () => Promise): IDataTransferItem { + return { + asString: async () => '', + asFile: () => ({ name: fileName, uri, data }), + value: undefined, + }; +} + export class VSDataTransfer { - private readonly _data = new Map(); + private readonly _entries = new Map(); public get size(): number { - return this._data.size; + return this._entries.size; } public has(mimeType: string): boolean { - return this._data.has(mimeType); + return this._entries.has(this.toKey(mimeType)); } public get(mimeType: string): IDataTransferItem | undefined { - return this._data.get(mimeType); + return this._entries.get(this.toKey(mimeType))?.[0]; } - public set(mimeType: string, value: IDataTransferItem): void { - this._data.set(mimeType, value); + public append(mimeType: string, value: IDataTransferItem): void { + const existing = this._entries.get(mimeType); + if (existing) { + existing.push(value); + } else { + this._entries.set(this.toKey(mimeType), [value]); + } + } + + public replace(mimeType: string, value: IDataTransferItem): void { + this._entries.set(this.toKey(mimeType), [value]); } public delete(mimeType: string) { - this._data.delete(mimeType); + this._entries.delete(this.toKey(mimeType)); } - public setString(mimeType: string, stringOrPromise: string | Promise) { - this.set(mimeType, { - asString: async () => stringOrPromise, - asFile: () => undefined, - value: typeof stringOrPromise === 'string' ? stringOrPromise : undefined, - }); + public *entries(): Iterable<[string, IDataTransferItem]> { + for (const [mine, items] of this._entries.entries()) { + for (const item of items) { + yield [mine, item]; + } + } } - public setFile(mimeType: string, fileName: string, uri: URI | undefined, data: () => Promise) { - this.set(mimeType, { - asString: async () => '', - asFile: () => ({ name: fileName, uri, data }), - value: undefined, - }); - } - - public entries(): IterableIterator<[string, IDataTransferItem]> { - return this._data.entries(); - } - - public values(): IterableIterator { - return this._data.values(); + public values(): Iterable { + return Array.from(this._entries.values()).flat(); } public forEach(f: (value: IDataTransferItem, key: string) => void) { - this._data.forEach(f); + for (const [mime, item] of this.entries()) { + f(item, mime); + } + } + + private toKey(mimeType: string): string { + return mimeType.toLowerCase(); } } diff --git a/src/vs/base/common/errors.ts b/src/vs/base/common/errors.ts index 4f397866ae4..38ca3e4e102 100644 --- a/src/vs/base/common/errors.ts +++ b/src/vs/base/common/errors.ts @@ -259,8 +259,8 @@ export class ErrorNoTelemetry extends Error { * Only catch this error to recover gracefully from bugs. */ export class BugIndicatingError extends Error { - constructor(message: string) { - super(message); + constructor(message?: string) { + super(message || 'An unexpected bug occurred.'); Object.setPrototypeOf(this, BugIndicatingError.prototype); // Because we know for sure only buggy code throws this, diff --git a/src/vs/base/common/platform.ts b/src/vs/base/common/platform.ts index e0ea1d62c64..78704d04368 100644 --- a/src/vs/base/common/platform.ts +++ b/src/vs/base/common/platform.ts @@ -80,7 +80,19 @@ if (typeof navigator === 'object' && !isElectronRenderer) { _isIOS = (_userAgent.indexOf('Macintosh') >= 0 || _userAgent.indexOf('iPad') >= 0 || _userAgent.indexOf('iPhone') >= 0) && !!navigator.maxTouchPoints && navigator.maxTouchPoints > 0; _isLinux = _userAgent.indexOf('Linux') >= 0; _isWeb = true; - _locale = navigator.language; + + // Gather loader configuration since that contains the locale + let loaderConfiguration: any = null; + if (typeof globals.require !== 'undefined' && typeof globals.require.getConfig === 'function') { + // Get the configuration from the Monaco AMD Loader + loaderConfiguration = globals.require.getConfig(); + } else if (typeof globals.requirejs !== 'undefined') { + // Get the configuration from requirejs + loaderConfiguration = globals.requirejs.s.contexts._.config; + } + const configuredLocale = loaderConfiguration?.['vs/nls']?.['availableLanguages']?.['*'] as string | undefined; + _locale = configuredLocale || navigator.language; + _language = _locale; } @@ -195,6 +207,8 @@ export const locale = _locale; */ export const translationsConfigFile = _translationsConfigFile; +export const setTimeout0IsFaster = (typeof globals.postMessage === 'function' && !globals.importScripts); + /** * See https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#:~:text=than%204%2C%20then-,set%20timeout%20to%204,-. * @@ -202,7 +216,7 @@ export const translationsConfigFile = _translationsConfigFile; * that browsers set when the nesting level is > 5. */ export const setTimeout0 = (() => { - if (typeof globals.postMessage === 'function' && !globals.importScripts) { + if (setTimeout0IsFaster) { interface IQueueElement { id: number; callback: () => void; diff --git a/src/vs/base/common/product.ts b/src/vs/base/common/product.ts index c66cf41aa6c..f822373104d 100644 --- a/src/vs/base/common/product.ts +++ b/src/vs/base/common/product.ts @@ -71,9 +71,11 @@ export interface IProductConfiguration { readonly extensionsGallery?: { readonly serviceUrl: string; readonly itemUrl: string; + readonly publisherUrl: string; readonly resourceUrlTemplate: string; readonly controlUrl: string; readonly recommendationsUrl: string; + readonly nlsBaseUrl: string; }; readonly extensionTips?: { [id: string]: string }; diff --git a/src/vs/base/test/browser/ui/list/listWidget.test.ts b/src/vs/base/test/browser/ui/list/listWidget.test.ts new file mode 100644 index 00000000000..bb533961b2d --- /dev/null +++ b/src/vs/base/test/browser/ui/list/listWidget.test.ts @@ -0,0 +1,97 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; +import { List } from 'vs/base/browser/ui/list/listWidget'; +import { range } from 'vs/base/common/arrays'; +import { timeout } from 'vs/base/common/async'; + +suite('ListWidget', function () { + test('Page up and down', async function () { + const element = document.createElement('div'); + element.style.height = '200px'; + element.style.width = '200px'; + + const delegate: IListVirtualDelegate = { + getHeight() { return 20; }, + getTemplateId() { return 'template'; } + }; + + let templatesCount = 0; + + const renderer: IListRenderer = { + templateId: 'template', + renderTemplate() { templatesCount++; }, + renderElement() { }, + disposeTemplate() { templatesCount--; } + }; + + const listWidget = new List('test', element, delegate, [renderer]); + + listWidget.layout(200); + assert.strictEqual(templatesCount, 0, 'no templates have been allocated'); + listWidget.splice(0, 0, range(100)); + listWidget.focusFirst(); + + listWidget.focusNextPage(); + assert.strictEqual(listWidget.getFocus()[0], 9, 'first page down moves focus to element at bottom'); + + // scroll to next page is async + listWidget.focusNextPage(); + await timeout(0); + assert.strictEqual(listWidget.getFocus()[0], 19, 'page down to next page'); + + listWidget.focusPreviousPage(); + assert.strictEqual(listWidget.getFocus()[0], 10, 'first page up moves focus to element at top'); + + // scroll to previous page is async + listWidget.focusPreviousPage(); + await timeout(0); + assert.strictEqual(listWidget.getFocus()[0], 0, 'page down to previous page'); + + listWidget.dispose(); + }); + + test('Page up and down with item taller than viewport #149502', async function () { + const element = document.createElement('div'); + element.style.height = '200px'; + element.style.width = '200px'; + + const delegate: IListVirtualDelegate = { + getHeight() { return 200; }, + getTemplateId() { return 'template'; } + }; + + let templatesCount = 0; + + const renderer: IListRenderer = { + templateId: 'template', + renderTemplate() { templatesCount++; }, + renderElement() { }, + disposeTemplate() { templatesCount--; } + }; + + const listWidget = new List('test', element, delegate, [renderer]); + + listWidget.layout(200); + assert.strictEqual(templatesCount, 0, 'no templates have been allocated'); + listWidget.splice(0, 0, range(100)); + listWidget.focusFirst(); + assert.strictEqual(listWidget.getFocus()[0], 0, 'initial focus is first element'); + + // scroll to next page is async + listWidget.focusNextPage(); + await timeout(0); + assert.strictEqual(listWidget.getFocus()[0], 1, 'page down to next page'); + + // scroll to previous page is async + listWidget.focusPreviousPage(); + await timeout(0); + assert.strictEqual(listWidget.getFocus()[0], 0, 'page up to next page'); + + listWidget.dispose(); + }); +}); diff --git a/src/vs/base/test/common/timeTravelScheduler.ts b/src/vs/base/test/common/timeTravelScheduler.ts index 9081b7c5632..797f308dc06 100644 --- a/src/vs/base/test/common/timeTravelScheduler.ts +++ b/src/vs/base/test/common/timeTravelScheduler.ts @@ -5,6 +5,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { setTimeout0, setTimeout0IsFaster } from 'vs/base/common/platform'; interface PriorityQueue { length: number; @@ -177,6 +178,8 @@ export class AsyncSchedulerProcessor extends Disposable { Promise.resolve().then(() => { if (this.useSetImmediate) { originalGlobalValues.setImmediate(() => this.process()); + } else if (setTimeout0IsFaster) { + setTimeout0(() => this.process()); } else { originalGlobalValues.setTimeout(() => this.process()); } diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 2e4eddb19b4..4c5c3eb50b3 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -40,6 +40,19 @@ Object.keys(self.webPackagePaths).map(function (key, index) { self.webPackagePaths[key] = `${baseUrl}/node_modules/${key}/${self.webPackagePaths[key]}`; }); + + // Set up nls if the user is not using the default language (English) + const nlsConfig = {}; + const locale = window.localStorage.getItem('vscode.nls.locale') || navigator.language; + if (!locale.startsWith('en')) { + nlsConfig['vs/nls'] = { + availableLanguages: { + '*': locale + }, + baseUrl: '{{WORKBENCH_NLS_BASE_URL}}' + }; + } + require.config({ baseUrl: `${baseUrl}/out`, recordStats: true, @@ -48,7 +61,8 @@ return value; } }), - paths: self.webPackagePaths + paths: self.webPackagePaths, + ...nlsConfig });